fix: linting (#77)

## Description

<!-- **Please link some issue here describing what you are trying to achieve.**

In case there is no issue present for your PR, please consider creating one.
At least please give us some description what you are trying to achieve and why your change is needed. -->

relates to #1234

## Checklist

- [ ] Issue was linked above
- [ ] Code format was applied: `make fmt`
- [ ] Examples were added / adjusted (see `examples/` directory)
- [x] Docs are up-to-date: `make generate-docs` (will be checked by CI)
- [ ] Unit tests got implemented or updated
- [ ] Acceptance tests got implemented or updated (see e.g. [here](f5f99d1709/stackit/internal/services/dns/dns_acc_test.go))
- [x] Unit tests are passing: `make test` (will be checked by CI)
- [x] No linter issues: `make lint` (will be checked by CI)

Reviewed-on: #77
Co-authored-by: Andre Harms <andre.harms@stackit.cloud>
Co-committed-by: Andre Harms <andre.harms@stackit.cloud>
This commit is contained in:
Andre_Harms 2026-02-19 08:54:34 +00:00 committed by Marcel_Henselin
parent 36eccc52c3
commit 4a2819787d
Signed by: tf-provider.git.onstackit.cloud
GPG key ID: 6D7E8A1ED8955A9C
74 changed files with 3010 additions and 2432 deletions

View file

@ -32,7 +32,7 @@ const (
type EphemeralProviderData struct {
ProviderData
PrivateKey string
PrivateKey string //nolint:gosec //this is a placeholder and not used in this code
PrivateKeyPath string
ServiceAccountKey string
ServiceAccountKeyPath string
@ -105,11 +105,13 @@ func DiagsToError(diags diag.Diagnostics) error {
diagsError := diags.Errors()
diagsStrings := make([]string, 0)
for _, diagnostic := range diagsError {
diagsStrings = append(diagsStrings, fmt.Sprintf(
"(%s) %s",
diagnostic.Summary(),
diagnostic.Detail(),
))
diagsStrings = append(
diagsStrings, fmt.Sprintf(
"(%s) %s",
diagnostic.Summary(),
diagnostic.Detail(),
),
)
}
return fmt.Errorf("%s", strings.Join(diagsStrings, ";"))
}
@ -136,14 +138,22 @@ func LogAndAddWarning(ctx context.Context, diags *diag.Diagnostics, summary, det
func LogAndAddWarningBeta(ctx context.Context, diags *diag.Diagnostics, name string, resourceType ResourceType) {
warnTitle := fmt.Sprintf("The %s %q is in beta", resourceType, name)
warnContent := fmt.Sprintf("The %s %q is in beta and may be subject to breaking changes in the future. Use with caution.", resourceType, name)
warnContent := fmt.Sprintf(
"The %s %q is in beta and may be subject to breaking changes in the future. Use with caution.",
resourceType,
name,
)
tflog.Warn(ctx, fmt.Sprintf("%s | %s", warnTitle, warnContent))
diags.AddWarning(warnTitle, warnContent)
}
func LogAndAddErrorBeta(ctx context.Context, diags *diag.Diagnostics, name string, resourceType ResourceType) {
errTitle := fmt.Sprintf("The %s %q is in beta and beta is not enabled", resourceType, name)
errContent := fmt.Sprintf(`The %s %q is in beta and the beta functionality is currently not enabled. To enable it, set the environment variable STACKIT_TF_ENABLE_BETA_RESOURCES to "true" or set the "enable_beta_resources" provider field to true.`, resourceType, name)
errContent := fmt.Sprintf(
`The %s %q is in beta and the beta functionality is currently not enabled. To enable it, set the environment variable STACKIT_TF_ENABLE_BETA_RESOURCES to "true" or set the "enable_beta_resources" provider field to true.`,
resourceType,
name,
)
tflog.Error(ctx, fmt.Sprintf("%s | %s", errTitle, errContent))
diags.AddError(errTitle, errContent)
}
@ -161,8 +171,10 @@ func LogResponse(ctx context.Context) context.Context {
traceId := runtime.GetTraceId(ctx)
ctx = tflog.SetField(ctx, "x-trace-id", traceId)
tflog.Info(ctx, "response data", map[string]interface{}{
"x-trace-id": traceId,
})
tflog.Info(
ctx, "response data", map[string]interface{}{
"x-trace-id": traceId,
},
)
return ctx
}

View file

@ -98,7 +98,7 @@ func (rrt *RetryRoundTripper) retryLoop(
waitDuration := rrt.calculateWaitDurationWithJitter(ctx, currentDelay)
if err := rrt.waitForDelay(ctx, waitDuration); err != nil {
return nil, err // Context was cancelled during wait.
return nil, err // Context was canceled during wait.
}
// Exponential backoff for the next potential retry.
@ -153,7 +153,6 @@ func (rrt *RetryRoundTripper) handleFinalError(
) error {
if resp != nil {
if err := resp.Body.Close(); err != nil {
tflog.Warn(
ctx, "Failed to close response body", map[string]interface{}{
"error": err.Error(),
@ -194,7 +193,6 @@ func (rrt *RetryRoundTripper) shouldRetry(resp *http.Response, err error) bool {
}
return false
}
// calculateWaitDurationWithJitter calculates the backoff duration for the next retry,
@ -232,7 +230,7 @@ func (rrt *RetryRoundTripper) calculateWaitDurationWithJitter(
func (rrt *RetryRoundTripper) waitForDelay(ctx context.Context, delay time.Duration) error {
select {
case <-ctx.Done():
return fmt.Errorf("context cancelled during backoff wait: %w", ctx.Err())
return fmt.Errorf("context canceled during backoff wait: %w", ctx.Err())
case <-time.After(delay):
return nil
}

View file

@ -72,7 +72,7 @@ func TestRetryRoundTripper_RoundTrip(t *testing.T) {
},
}
tripper := testRetryConfig(mock)
req := httptest.NewRequest(http.MethodGet, "/", nil)
req := httptest.NewRequest(http.MethodGet, "/", http.NoBody)
resp, err := tripper.RoundTrip(req)
if resp != nil {
@ -110,7 +110,7 @@ func TestRetryRoundTripper_RoundTrip(t *testing.T) {
},
}
tripper := testRetryConfig(mock)
req := httptest.NewRequest(http.MethodGet, "/", nil)
req := httptest.NewRequest(http.MethodGet, "/", http.NoBody)
resp, err := tripper.RoundTrip(req)
if resp != nil {
@ -155,7 +155,7 @@ func TestRetryRoundTripper_RoundTrip(t *testing.T) {
}, nil
}
tripper := testRetryConfig(mock)
req := httptest.NewRequest(http.MethodGet, "/", nil)
req := httptest.NewRequest(http.MethodGet, "/", http.NoBody)
resp, err := tripper.RoundTrip(req)
if resp != nil {
@ -185,12 +185,12 @@ func TestRetryRoundTripper_RoundTrip(t *testing.T) {
mockErr := errors.New("simulated network error")
mock := &mockRoundTripper{
roundTripFunc: func(req *http.Request) (*http.Response, error) {
roundTripFunc: func(_ *http.Request) (*http.Response, error) {
return nil, mockErr
},
}
tripper := testRetryConfig(mock)
req := httptest.NewRequest(http.MethodGet, "/", nil)
req := httptest.NewRequest(http.MethodGet, "/", http.NoBody)
resp, err := tripper.RoundTrip(req)
if resp != nil {
@ -211,7 +211,7 @@ func TestRetryRoundTripper_RoundTrip(t *testing.T) {
)
t.Run(
"should abort retries if the main context is cancelled", func(t *testing.T) {
"should abort retries if the main context is canceled", func(t *testing.T) {
t.Parallel()
mock := &mockRoundTripper{
@ -230,7 +230,7 @@ func TestRetryRoundTripper_RoundTrip(t *testing.T) {
ctx, cancel := context.WithTimeout(baseCtx, 20*time.Millisecond)
defer cancel()
req := httptest.NewRequest(http.MethodGet, "/", nil).WithContext(ctx)
req := httptest.NewRequest(http.MethodGet, "/", http.NoBody).WithContext(ctx)
resp, err := tripper.RoundTrip(req)
if resp != nil {

View file

@ -33,15 +33,27 @@ func InstanceDataSourceSchema(ctx context.Context) schema.Schema {
},
"connection_info": schema.SingleNestedAttribute{
Attributes: map[string]schema.Attribute{
"host": schema.StringAttribute{
"write": schema.SingleNestedAttribute{
Attributes: map[string]schema.Attribute{
"host": schema.StringAttribute{
Computed: true,
Description: "The host of the instance.",
MarkdownDescription: "The host of the instance.",
},
"port": schema.Int64Attribute{
Computed: true,
Description: "The port of the instance.",
MarkdownDescription: "The port of the instance.",
},
},
CustomType: WriteType{
ObjectType: types.ObjectType{
AttrTypes: WriteValue{}.AttributeTypes(ctx),
},
},
Computed: true,
Description: "The host of the instance.",
MarkdownDescription: "The host of the instance.",
},
"port": schema.Int64Attribute{
Computed: true,
Description: "The port of the instance.",
MarkdownDescription: "The port of the instance.",
Description: "The DNS name and port in the instance overview",
MarkdownDescription: "The DNS name and port in the instance overview",
},
},
CustomType: ConnectionInfoType{
@ -50,8 +62,8 @@ func InstanceDataSourceSchema(ctx context.Context) schema.Schema {
},
},
Computed: true,
Description: "The DNS name and port in the instance overview",
MarkdownDescription: "The DNS name and port in the instance overview",
Description: "The connection information of the instance",
MarkdownDescription: "The connection information of the instance",
},
"encryption": schema.SingleNestedAttribute{
Attributes: map[string]schema.Attribute{
@ -243,40 +255,22 @@ func (t ConnectionInfoType) ValueFromObject(ctx context.Context, in basetypes.Ob
attributes := in.Attributes()
hostAttribute, ok := attributes["host"]
writeAttribute, ok := attributes["write"]
if !ok {
diags.AddError(
"Attribute Missing",
`host is missing from object`)
`write is missing from object`)
return nil, diags
}
hostVal, ok := hostAttribute.(basetypes.StringValue)
writeVal, ok := writeAttribute.(basetypes.ObjectValue)
if !ok {
diags.AddError(
"Attribute Wrong Type",
fmt.Sprintf(`host expected to be basetypes.StringValue, was: %T`, hostAttribute))
}
portAttribute, ok := attributes["port"]
if !ok {
diags.AddError(
"Attribute Missing",
`port is missing from object`)
return nil, diags
}
portVal, ok := portAttribute.(basetypes.Int64Value)
if !ok {
diags.AddError(
"Attribute Wrong Type",
fmt.Sprintf(`port expected to be basetypes.Int64Value, was: %T`, portAttribute))
fmt.Sprintf(`write expected to be basetypes.ObjectValue, was: %T`, writeAttribute))
}
if diags.HasError() {
@ -284,8 +278,7 @@ func (t ConnectionInfoType) ValueFromObject(ctx context.Context, in basetypes.Ob
}
return ConnectionInfoValue{
Host: hostVal,
Port: portVal,
Write: writeVal,
state: attr.ValueStateKnown,
}, diags
}
@ -353,40 +346,22 @@ func NewConnectionInfoValue(attributeTypes map[string]attr.Type, attributes map[
return NewConnectionInfoValueUnknown(), diags
}
hostAttribute, ok := attributes["host"]
writeAttribute, ok := attributes["write"]
if !ok {
diags.AddError(
"Attribute Missing",
`host is missing from object`)
`write is missing from object`)
return NewConnectionInfoValueUnknown(), diags
}
hostVal, ok := hostAttribute.(basetypes.StringValue)
writeVal, ok := writeAttribute.(basetypes.ObjectValue)
if !ok {
diags.AddError(
"Attribute Wrong Type",
fmt.Sprintf(`host expected to be basetypes.StringValue, was: %T`, hostAttribute))
}
portAttribute, ok := attributes["port"]
if !ok {
diags.AddError(
"Attribute Missing",
`port is missing from object`)
return NewConnectionInfoValueUnknown(), diags
}
portVal, ok := portAttribute.(basetypes.Int64Value)
if !ok {
diags.AddError(
"Attribute Wrong Type",
fmt.Sprintf(`port expected to be basetypes.Int64Value, was: %T`, portAttribute))
fmt.Sprintf(`write expected to be basetypes.ObjectValue, was: %T`, writeAttribute))
}
if diags.HasError() {
@ -394,8 +369,7 @@ func NewConnectionInfoValue(attributeTypes map[string]attr.Type, attributes map[
}
return ConnectionInfoValue{
Host: hostVal,
Port: portVal,
Write: writeVal,
state: attr.ValueStateKnown,
}, diags
}
@ -468,12 +442,401 @@ func (t ConnectionInfoType) ValueType(ctx context.Context) attr.Value {
var _ basetypes.ObjectValuable = ConnectionInfoValue{}
type ConnectionInfoValue struct {
Write basetypes.ObjectValue `tfsdk:"write"`
state attr.ValueState
}
func (v ConnectionInfoValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) {
attrTypes := make(map[string]tftypes.Type, 1)
var val tftypes.Value
var err error
attrTypes["write"] = basetypes.ObjectType{
AttrTypes: WriteValue{}.AttributeTypes(ctx),
}.TerraformType(ctx)
objectType := tftypes.Object{AttributeTypes: attrTypes}
switch v.state {
case attr.ValueStateKnown:
vals := make(map[string]tftypes.Value, 1)
val, err = v.Write.ToTerraformValue(ctx)
if err != nil {
return tftypes.NewValue(objectType, tftypes.UnknownValue), err
}
vals["write"] = val
if err := tftypes.ValidateValue(objectType, vals); err != nil {
return tftypes.NewValue(objectType, tftypes.UnknownValue), err
}
return tftypes.NewValue(objectType, vals), nil
case attr.ValueStateNull:
return tftypes.NewValue(objectType, nil), nil
case attr.ValueStateUnknown:
return tftypes.NewValue(objectType, tftypes.UnknownValue), nil
default:
panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state))
}
}
func (v ConnectionInfoValue) IsNull() bool {
return v.state == attr.ValueStateNull
}
func (v ConnectionInfoValue) IsUnknown() bool {
return v.state == attr.ValueStateUnknown
}
func (v ConnectionInfoValue) String() string {
return "ConnectionInfoValue"
}
func (v ConnectionInfoValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) {
var diags diag.Diagnostics
var write basetypes.ObjectValue
if v.Write.IsNull() {
write = types.ObjectNull(
WriteValue{}.AttributeTypes(ctx),
)
}
if v.Write.IsUnknown() {
write = types.ObjectUnknown(
WriteValue{}.AttributeTypes(ctx),
)
}
if !v.Write.IsNull() && !v.Write.IsUnknown() {
write = types.ObjectValueMust(
WriteValue{}.AttributeTypes(ctx),
v.Write.Attributes(),
)
}
attributeTypes := map[string]attr.Type{
"write": basetypes.ObjectType{
AttrTypes: WriteValue{}.AttributeTypes(ctx),
},
}
if v.IsNull() {
return types.ObjectNull(attributeTypes), diags
}
if v.IsUnknown() {
return types.ObjectUnknown(attributeTypes), diags
}
objVal, diags := types.ObjectValue(
attributeTypes,
map[string]attr.Value{
"write": write,
})
return objVal, diags
}
func (v ConnectionInfoValue) Equal(o attr.Value) bool {
other, ok := o.(ConnectionInfoValue)
if !ok {
return false
}
if v.state != other.state {
return false
}
if v.state != attr.ValueStateKnown {
return true
}
if !v.Write.Equal(other.Write) {
return false
}
return true
}
func (v ConnectionInfoValue) Type(ctx context.Context) attr.Type {
return ConnectionInfoType{
basetypes.ObjectType{
AttrTypes: v.AttributeTypes(ctx),
},
}
}
func (v ConnectionInfoValue) AttributeTypes(ctx context.Context) map[string]attr.Type {
return map[string]attr.Type{
"write": basetypes.ObjectType{
AttrTypes: WriteValue{}.AttributeTypes(ctx),
},
}
}
var _ basetypes.ObjectTypable = WriteType{}
type WriteType struct {
basetypes.ObjectType
}
func (t WriteType) Equal(o attr.Type) bool {
other, ok := o.(WriteType)
if !ok {
return false
}
return t.ObjectType.Equal(other.ObjectType)
}
func (t WriteType) String() string {
return "WriteType"
}
func (t WriteType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) {
var diags diag.Diagnostics
attributes := in.Attributes()
hostAttribute, ok := attributes["host"]
if !ok {
diags.AddError(
"Attribute Missing",
`host is missing from object`)
return nil, diags
}
hostVal, ok := hostAttribute.(basetypes.StringValue)
if !ok {
diags.AddError(
"Attribute Wrong Type",
fmt.Sprintf(`host expected to be basetypes.StringValue, was: %T`, hostAttribute))
}
portAttribute, ok := attributes["port"]
if !ok {
diags.AddError(
"Attribute Missing",
`port is missing from object`)
return nil, diags
}
portVal, ok := portAttribute.(basetypes.Int64Value)
if !ok {
diags.AddError(
"Attribute Wrong Type",
fmt.Sprintf(`port expected to be basetypes.Int64Value, was: %T`, portAttribute))
}
if diags.HasError() {
return nil, diags
}
return WriteValue{
Host: hostVal,
Port: portVal,
state: attr.ValueStateKnown,
}, diags
}
func NewWriteValueNull() WriteValue {
return WriteValue{
state: attr.ValueStateNull,
}
}
func NewWriteValueUnknown() WriteValue {
return WriteValue{
state: attr.ValueStateUnknown,
}
}
func NewWriteValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (WriteValue, diag.Diagnostics) {
var diags diag.Diagnostics
// Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521
ctx := context.Background()
for name, attributeType := range attributeTypes {
attribute, ok := attributes[name]
if !ok {
diags.AddError(
"Missing WriteValue Attribute Value",
"While creating a WriteValue value, a missing attribute value was detected. "+
"A WriteValue must contain values for all attributes, even if null or unknown. "+
"This is always an issue with the provider and should be reported to the provider developers.\n\n"+
fmt.Sprintf("WriteValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()),
)
continue
}
if !attributeType.Equal(attribute.Type(ctx)) {
diags.AddError(
"Invalid WriteValue Attribute Type",
"While creating a WriteValue value, an invalid attribute value was detected. "+
"A WriteValue must use a matching attribute type for the value. "+
"This is always an issue with the provider and should be reported to the provider developers.\n\n"+
fmt.Sprintf("WriteValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+
fmt.Sprintf("WriteValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)),
)
}
}
for name := range attributes {
_, ok := attributeTypes[name]
if !ok {
diags.AddError(
"Extra WriteValue Attribute Value",
"While creating a WriteValue value, an extra attribute value was detected. "+
"A WriteValue must not contain values beyond the expected attribute types. "+
"This is always an issue with the provider and should be reported to the provider developers.\n\n"+
fmt.Sprintf("Extra WriteValue Attribute Name: %s", name),
)
}
}
if diags.HasError() {
return NewWriteValueUnknown(), diags
}
hostAttribute, ok := attributes["host"]
if !ok {
diags.AddError(
"Attribute Missing",
`host is missing from object`)
return NewWriteValueUnknown(), diags
}
hostVal, ok := hostAttribute.(basetypes.StringValue)
if !ok {
diags.AddError(
"Attribute Wrong Type",
fmt.Sprintf(`host expected to be basetypes.StringValue, was: %T`, hostAttribute))
}
portAttribute, ok := attributes["port"]
if !ok {
diags.AddError(
"Attribute Missing",
`port is missing from object`)
return NewWriteValueUnknown(), diags
}
portVal, ok := portAttribute.(basetypes.Int64Value)
if !ok {
diags.AddError(
"Attribute Wrong Type",
fmt.Sprintf(`port expected to be basetypes.Int64Value, was: %T`, portAttribute))
}
if diags.HasError() {
return NewWriteValueUnknown(), diags
}
return WriteValue{
Host: hostVal,
Port: portVal,
state: attr.ValueStateKnown,
}, diags
}
func NewWriteValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) WriteValue {
object, diags := NewWriteValue(attributeTypes, attributes)
if diags.HasError() {
// This could potentially be added to the diag package.
diagsStrings := make([]string, 0, len(diags))
for _, diagnostic := range diags {
diagsStrings = append(diagsStrings, fmt.Sprintf(
"%s | %s | %s",
diagnostic.Severity(),
diagnostic.Summary(),
diagnostic.Detail()))
}
panic("NewWriteValueMust received error(s): " + strings.Join(diagsStrings, "\n"))
}
return object
}
func (t WriteType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) {
if in.Type() == nil {
return NewWriteValueNull(), nil
}
if !in.Type().Equal(t.TerraformType(ctx)) {
return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type())
}
if !in.IsKnown() {
return NewWriteValueUnknown(), nil
}
if in.IsNull() {
return NewWriteValueNull(), nil
}
attributes := map[string]attr.Value{}
val := map[string]tftypes.Value{}
err := in.As(&val)
if err != nil {
return nil, err
}
for k, v := range val {
a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v)
if err != nil {
return nil, err
}
attributes[k] = a
}
return NewWriteValueMust(WriteValue{}.AttributeTypes(ctx), attributes), nil
}
func (t WriteType) ValueType(ctx context.Context) attr.Value {
return WriteValue{}
}
var _ basetypes.ObjectValuable = WriteValue{}
type WriteValue struct {
Host basetypes.StringValue `tfsdk:"host"`
Port basetypes.Int64Value `tfsdk:"port"`
state attr.ValueState
}
func (v ConnectionInfoValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) {
func (v WriteValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) {
attrTypes := make(map[string]tftypes.Type, 2)
var val tftypes.Value
@ -518,19 +881,19 @@ func (v ConnectionInfoValue) ToTerraformValue(ctx context.Context) (tftypes.Valu
}
}
func (v ConnectionInfoValue) IsNull() bool {
func (v WriteValue) IsNull() bool {
return v.state == attr.ValueStateNull
}
func (v ConnectionInfoValue) IsUnknown() bool {
func (v WriteValue) IsUnknown() bool {
return v.state == attr.ValueStateUnknown
}
func (v ConnectionInfoValue) String() string {
return "ConnectionInfoValue"
func (v WriteValue) String() string {
return "WriteValue"
}
func (v ConnectionInfoValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) {
func (v WriteValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) {
var diags diag.Diagnostics
attributeTypes := map[string]attr.Type{
@ -556,8 +919,8 @@ func (v ConnectionInfoValue) ToObjectValue(ctx context.Context) (basetypes.Objec
return objVal, diags
}
func (v ConnectionInfoValue) Equal(o attr.Value) bool {
other, ok := o.(ConnectionInfoValue)
func (v WriteValue) Equal(o attr.Value) bool {
other, ok := o.(WriteValue)
if !ok {
return false
@ -582,15 +945,15 @@ func (v ConnectionInfoValue) Equal(o attr.Value) bool {
return true
}
func (v ConnectionInfoValue) Type(ctx context.Context) attr.Type {
return ConnectionInfoType{
func (v WriteValue) Type(ctx context.Context) attr.Type {
return WriteType{
basetypes.ObjectType{
AttrTypes: v.AttributeTypes(ctx),
},
}
}
func (v ConnectionInfoValue) AttributeTypes(ctx context.Context) map[string]attr.Type {
func (v WriteValue) AttributeTypes(ctx context.Context) map[string]attr.Type {
return map[string]attr.Type{
"host": basetypes.StringType{},
"port": basetypes.Int64Type{},

View file

@ -33,9 +33,9 @@ func mapGetInstanceResponseToModel(
)
}
isConnectionInfoIncomplete := resp.ConnectionInfo == nil ||
resp.ConnectionInfo.Host == nil || *resp.ConnectionInfo.Host == "" ||
resp.ConnectionInfo.Port == nil || *resp.ConnectionInfo.Port == 0
isConnectionInfoIncomplete := resp.ConnectionInfo == nil || resp.ConnectionInfo.Write == nil ||
resp.ConnectionInfo.Write.Host == nil || *resp.ConnectionInfo.Write.Host == "" ||
resp.ConnectionInfo.Write.Port == nil || *resp.ConnectionInfo.Write.Port == 0
if isConnectionInfoIncomplete {
m.ConnectionInfo = postgresflexalpharesource.NewConnectionInfoValueNull()
@ -43,22 +43,17 @@ func mapGetInstanceResponseToModel(
m.ConnectionInfo = postgresflexalpharesource.NewConnectionInfoValueMust(
postgresflexalpharesource.ConnectionInfoValue{}.AttributeTypes(ctx),
map[string]attr.Value{
"host": types.StringPointerValue(resp.ConnectionInfo.Host),
"port": types.Int64PointerValue(resp.ConnectionInfo.Port),
"write": postgresflexalpharesource.NewWriteValueMust(
postgresflexalpharesource.WriteValue{}.AttributeTypes(ctx),
map[string]attr.Value{
"host": types.StringPointerValue(resp.ConnectionInfo.Write.Host),
"port": types.Int64PointerValue(resp.ConnectionInfo.Write.Port),
},
),
},
)
}
m.ConnectionInfo.Host = types.StringValue("")
if host, ok := resp.ConnectionInfo.GetHostOk(); ok {
m.ConnectionInfo.Host = types.StringValue(host)
}
m.ConnectionInfo.Port = types.Int64Value(0)
if port, ok := resp.ConnectionInfo.GetPortOk(); ok {
m.ConnectionInfo.Port = types.Int64Value(port)
}
m.FlavorId = types.StringValue(resp.GetFlavorId())
if m.Id.IsNull() || m.Id.IsUnknown() {
m.Id = utils.BuildInternalTerraformId(
@ -164,9 +159,9 @@ func mapGetDataInstanceResponseToModel(
}
func handleConnectionInfo(ctx context.Context, m *dataSourceModel, resp *postgresflex.GetInstanceResponse) {
isConnectionInfoIncomplete := resp.ConnectionInfo == nil ||
resp.ConnectionInfo.Host == nil || *resp.ConnectionInfo.Host == "" ||
resp.ConnectionInfo.Port == nil || *resp.ConnectionInfo.Port == 0
isConnectionInfoIncomplete := resp.ConnectionInfo == nil || resp.ConnectionInfo.Write == nil ||
resp.ConnectionInfo.Write.Host == nil || *resp.ConnectionInfo.Write.Host == "" ||
resp.ConnectionInfo.Write.Port == nil || *resp.ConnectionInfo.Write.Port == 0
if isConnectionInfoIncomplete {
m.ConnectionInfo = postgresflexalphadatasource.NewConnectionInfoValueNull()
@ -174,8 +169,13 @@ func handleConnectionInfo(ctx context.Context, m *dataSourceModel, resp *postgre
m.ConnectionInfo = postgresflexalphadatasource.NewConnectionInfoValueMust(
postgresflexalphadatasource.ConnectionInfoValue{}.AttributeTypes(ctx),
map[string]attr.Value{
"host": types.StringPointerValue(resp.ConnectionInfo.Host),
"port": types.Int64PointerValue(resp.ConnectionInfo.Port),
"write": postgresflexalphadatasource.NewWriteValueMust(
postgresflexalphadatasource.WriteValue{}.AttributeTypes(ctx),
map[string]attr.Value{
"host": types.StringPointerValue(resp.ConnectionInfo.Write.Host),
"port": types.Int64PointerValue(resp.ConnectionInfo.Write.Port),
},
),
},
)
}

View file

@ -328,10 +328,6 @@ func (r *instanceResource) Read(
ctx = core.InitProviderContext(ctx)
// projectId := model.ProjectId.ValueString()
// region := r.providerData.GetRegionWithOverride(model.Region)
// instanceId := model.InstanceId.ValueString()
var projectId string
if !model.ProjectId.IsNull() && !model.ProjectId.IsUnknown() {
projectId = model.ProjectId.ValueString()
@ -435,18 +431,6 @@ func (r *instanceResource) Update(
return
}
// if model.InstanceId.IsNull() || model.InstanceId.IsUnknown() {
// core.LogAndAddError(ctx, &resp.Diagnostics, "Error updating instance", "instanceId is null or unknown")
// return
//}
//
// if model.ProjectId.IsNull() || model.ProjectId.IsUnknown() {
// core.LogAndAddError(ctx, &resp.Diagnostics, "Error updating instance", "projectId is null or unknown")
// return
//}
// projectId := model.ProjectId.ValueString()
// instanceId := model.InstanceId.ValueString()
projectId := identityData.ProjectID.ValueString()
instanceId := identityData.InstanceID.ValueString()
region := model.Region.ValueString()

View file

@ -35,15 +35,27 @@ func InstanceResourceSchema(ctx context.Context) schema.Schema {
},
"connection_info": schema.SingleNestedAttribute{
Attributes: map[string]schema.Attribute{
"host": schema.StringAttribute{
"write": schema.SingleNestedAttribute{
Attributes: map[string]schema.Attribute{
"host": schema.StringAttribute{
Computed: true,
Description: "The host of the instance.",
MarkdownDescription: "The host of the instance.",
},
"port": schema.Int64Attribute{
Computed: true,
Description: "The port of the instance.",
MarkdownDescription: "The port of the instance.",
},
},
CustomType: WriteType{
ObjectType: types.ObjectType{
AttrTypes: WriteValue{}.AttributeTypes(ctx),
},
},
Computed: true,
Description: "The host of the instance.",
MarkdownDescription: "The host of the instance.",
},
"port": schema.Int64Attribute{
Computed: true,
Description: "The port of the instance.",
MarkdownDescription: "The port of the instance.",
Description: "The DNS name and port in the instance overview",
MarkdownDescription: "The DNS name and port in the instance overview",
},
},
CustomType: ConnectionInfoType{
@ -52,8 +64,8 @@ func InstanceResourceSchema(ctx context.Context) schema.Schema {
},
},
Computed: true,
Description: "The DNS name and port in the instance overview",
MarkdownDescription: "The DNS name and port in the instance overview",
Description: "The connection information of the instance",
MarkdownDescription: "The connection information of the instance",
},
"encryption": schema.SingleNestedAttribute{
Attributes: map[string]schema.Attribute{
@ -263,40 +275,22 @@ func (t ConnectionInfoType) ValueFromObject(ctx context.Context, in basetypes.Ob
attributes := in.Attributes()
hostAttribute, ok := attributes["host"]
writeAttribute, ok := attributes["write"]
if !ok {
diags.AddError(
"Attribute Missing",
`host is missing from object`)
`write is missing from object`)
return nil, diags
}
hostVal, ok := hostAttribute.(basetypes.StringValue)
writeVal, ok := writeAttribute.(basetypes.ObjectValue)
if !ok {
diags.AddError(
"Attribute Wrong Type",
fmt.Sprintf(`host expected to be basetypes.StringValue, was: %T`, hostAttribute))
}
portAttribute, ok := attributes["port"]
if !ok {
diags.AddError(
"Attribute Missing",
`port is missing from object`)
return nil, diags
}
portVal, ok := portAttribute.(basetypes.Int64Value)
if !ok {
diags.AddError(
"Attribute Wrong Type",
fmt.Sprintf(`port expected to be basetypes.Int64Value, was: %T`, portAttribute))
fmt.Sprintf(`write expected to be basetypes.ObjectValue, was: %T`, writeAttribute))
}
if diags.HasError() {
@ -304,8 +298,7 @@ func (t ConnectionInfoType) ValueFromObject(ctx context.Context, in basetypes.Ob
}
return ConnectionInfoValue{
Host: hostVal,
Port: portVal,
Write: writeVal,
state: attr.ValueStateKnown,
}, diags
}
@ -373,40 +366,22 @@ func NewConnectionInfoValue(attributeTypes map[string]attr.Type, attributes map[
return NewConnectionInfoValueUnknown(), diags
}
hostAttribute, ok := attributes["host"]
writeAttribute, ok := attributes["write"]
if !ok {
diags.AddError(
"Attribute Missing",
`host is missing from object`)
`write is missing from object`)
return NewConnectionInfoValueUnknown(), diags
}
hostVal, ok := hostAttribute.(basetypes.StringValue)
writeVal, ok := writeAttribute.(basetypes.ObjectValue)
if !ok {
diags.AddError(
"Attribute Wrong Type",
fmt.Sprintf(`host expected to be basetypes.StringValue, was: %T`, hostAttribute))
}
portAttribute, ok := attributes["port"]
if !ok {
diags.AddError(
"Attribute Missing",
`port is missing from object`)
return NewConnectionInfoValueUnknown(), diags
}
portVal, ok := portAttribute.(basetypes.Int64Value)
if !ok {
diags.AddError(
"Attribute Wrong Type",
fmt.Sprintf(`port expected to be basetypes.Int64Value, was: %T`, portAttribute))
fmt.Sprintf(`write expected to be basetypes.ObjectValue, was: %T`, writeAttribute))
}
if diags.HasError() {
@ -414,8 +389,7 @@ func NewConnectionInfoValue(attributeTypes map[string]attr.Type, attributes map[
}
return ConnectionInfoValue{
Host: hostVal,
Port: portVal,
Write: writeVal,
state: attr.ValueStateKnown,
}, diags
}
@ -488,12 +462,401 @@ func (t ConnectionInfoType) ValueType(ctx context.Context) attr.Value {
var _ basetypes.ObjectValuable = ConnectionInfoValue{}
type ConnectionInfoValue struct {
Write basetypes.ObjectValue `tfsdk:"write"`
state attr.ValueState
}
func (v ConnectionInfoValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) {
attrTypes := make(map[string]tftypes.Type, 1)
var val tftypes.Value
var err error
attrTypes["write"] = basetypes.ObjectType{
AttrTypes: WriteValue{}.AttributeTypes(ctx),
}.TerraformType(ctx)
objectType := tftypes.Object{AttributeTypes: attrTypes}
switch v.state {
case attr.ValueStateKnown:
vals := make(map[string]tftypes.Value, 1)
val, err = v.Write.ToTerraformValue(ctx)
if err != nil {
return tftypes.NewValue(objectType, tftypes.UnknownValue), err
}
vals["write"] = val
if err := tftypes.ValidateValue(objectType, vals); err != nil {
return tftypes.NewValue(objectType, tftypes.UnknownValue), err
}
return tftypes.NewValue(objectType, vals), nil
case attr.ValueStateNull:
return tftypes.NewValue(objectType, nil), nil
case attr.ValueStateUnknown:
return tftypes.NewValue(objectType, tftypes.UnknownValue), nil
default:
panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state))
}
}
func (v ConnectionInfoValue) IsNull() bool {
return v.state == attr.ValueStateNull
}
func (v ConnectionInfoValue) IsUnknown() bool {
return v.state == attr.ValueStateUnknown
}
func (v ConnectionInfoValue) String() string {
return "ConnectionInfoValue"
}
func (v ConnectionInfoValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) {
var diags diag.Diagnostics
var write basetypes.ObjectValue
if v.Write.IsNull() {
write = types.ObjectNull(
WriteValue{}.AttributeTypes(ctx),
)
}
if v.Write.IsUnknown() {
write = types.ObjectUnknown(
WriteValue{}.AttributeTypes(ctx),
)
}
if !v.Write.IsNull() && !v.Write.IsUnknown() {
write = types.ObjectValueMust(
WriteValue{}.AttributeTypes(ctx),
v.Write.Attributes(),
)
}
attributeTypes := map[string]attr.Type{
"write": basetypes.ObjectType{
AttrTypes: WriteValue{}.AttributeTypes(ctx),
},
}
if v.IsNull() {
return types.ObjectNull(attributeTypes), diags
}
if v.IsUnknown() {
return types.ObjectUnknown(attributeTypes), diags
}
objVal, diags := types.ObjectValue(
attributeTypes,
map[string]attr.Value{
"write": write,
})
return objVal, diags
}
func (v ConnectionInfoValue) Equal(o attr.Value) bool {
other, ok := o.(ConnectionInfoValue)
if !ok {
return false
}
if v.state != other.state {
return false
}
if v.state != attr.ValueStateKnown {
return true
}
if !v.Write.Equal(other.Write) {
return false
}
return true
}
func (v ConnectionInfoValue) Type(ctx context.Context) attr.Type {
return ConnectionInfoType{
basetypes.ObjectType{
AttrTypes: v.AttributeTypes(ctx),
},
}
}
func (v ConnectionInfoValue) AttributeTypes(ctx context.Context) map[string]attr.Type {
return map[string]attr.Type{
"write": basetypes.ObjectType{
AttrTypes: WriteValue{}.AttributeTypes(ctx),
},
}
}
var _ basetypes.ObjectTypable = WriteType{}
type WriteType struct {
basetypes.ObjectType
}
func (t WriteType) Equal(o attr.Type) bool {
other, ok := o.(WriteType)
if !ok {
return false
}
return t.ObjectType.Equal(other.ObjectType)
}
func (t WriteType) String() string {
return "WriteType"
}
func (t WriteType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) {
var diags diag.Diagnostics
attributes := in.Attributes()
hostAttribute, ok := attributes["host"]
if !ok {
diags.AddError(
"Attribute Missing",
`host is missing from object`)
return nil, diags
}
hostVal, ok := hostAttribute.(basetypes.StringValue)
if !ok {
diags.AddError(
"Attribute Wrong Type",
fmt.Sprintf(`host expected to be basetypes.StringValue, was: %T`, hostAttribute))
}
portAttribute, ok := attributes["port"]
if !ok {
diags.AddError(
"Attribute Missing",
`port is missing from object`)
return nil, diags
}
portVal, ok := portAttribute.(basetypes.Int64Value)
if !ok {
diags.AddError(
"Attribute Wrong Type",
fmt.Sprintf(`port expected to be basetypes.Int64Value, was: %T`, portAttribute))
}
if diags.HasError() {
return nil, diags
}
return WriteValue{
Host: hostVal,
Port: portVal,
state: attr.ValueStateKnown,
}, diags
}
func NewWriteValueNull() WriteValue {
return WriteValue{
state: attr.ValueStateNull,
}
}
func NewWriteValueUnknown() WriteValue {
return WriteValue{
state: attr.ValueStateUnknown,
}
}
func NewWriteValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (WriteValue, diag.Diagnostics) {
var diags diag.Diagnostics
// Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521
ctx := context.Background()
for name, attributeType := range attributeTypes {
attribute, ok := attributes[name]
if !ok {
diags.AddError(
"Missing WriteValue Attribute Value",
"While creating a WriteValue value, a missing attribute value was detected. "+
"A WriteValue must contain values for all attributes, even if null or unknown. "+
"This is always an issue with the provider and should be reported to the provider developers.\n\n"+
fmt.Sprintf("WriteValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()),
)
continue
}
if !attributeType.Equal(attribute.Type(ctx)) {
diags.AddError(
"Invalid WriteValue Attribute Type",
"While creating a WriteValue value, an invalid attribute value was detected. "+
"A WriteValue must use a matching attribute type for the value. "+
"This is always an issue with the provider and should be reported to the provider developers.\n\n"+
fmt.Sprintf("WriteValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+
fmt.Sprintf("WriteValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)),
)
}
}
for name := range attributes {
_, ok := attributeTypes[name]
if !ok {
diags.AddError(
"Extra WriteValue Attribute Value",
"While creating a WriteValue value, an extra attribute value was detected. "+
"A WriteValue must not contain values beyond the expected attribute types. "+
"This is always an issue with the provider and should be reported to the provider developers.\n\n"+
fmt.Sprintf("Extra WriteValue Attribute Name: %s", name),
)
}
}
if diags.HasError() {
return NewWriteValueUnknown(), diags
}
hostAttribute, ok := attributes["host"]
if !ok {
diags.AddError(
"Attribute Missing",
`host is missing from object`)
return NewWriteValueUnknown(), diags
}
hostVal, ok := hostAttribute.(basetypes.StringValue)
if !ok {
diags.AddError(
"Attribute Wrong Type",
fmt.Sprintf(`host expected to be basetypes.StringValue, was: %T`, hostAttribute))
}
portAttribute, ok := attributes["port"]
if !ok {
diags.AddError(
"Attribute Missing",
`port is missing from object`)
return NewWriteValueUnknown(), diags
}
portVal, ok := portAttribute.(basetypes.Int64Value)
if !ok {
diags.AddError(
"Attribute Wrong Type",
fmt.Sprintf(`port expected to be basetypes.Int64Value, was: %T`, portAttribute))
}
if diags.HasError() {
return NewWriteValueUnknown(), diags
}
return WriteValue{
Host: hostVal,
Port: portVal,
state: attr.ValueStateKnown,
}, diags
}
func NewWriteValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) WriteValue {
object, diags := NewWriteValue(attributeTypes, attributes)
if diags.HasError() {
// This could potentially be added to the diag package.
diagsStrings := make([]string, 0, len(diags))
for _, diagnostic := range diags {
diagsStrings = append(diagsStrings, fmt.Sprintf(
"%s | %s | %s",
diagnostic.Severity(),
diagnostic.Summary(),
diagnostic.Detail()))
}
panic("NewWriteValueMust received error(s): " + strings.Join(diagsStrings, "\n"))
}
return object
}
func (t WriteType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) {
if in.Type() == nil {
return NewWriteValueNull(), nil
}
if !in.Type().Equal(t.TerraformType(ctx)) {
return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type())
}
if !in.IsKnown() {
return NewWriteValueUnknown(), nil
}
if in.IsNull() {
return NewWriteValueNull(), nil
}
attributes := map[string]attr.Value{}
val := map[string]tftypes.Value{}
err := in.As(&val)
if err != nil {
return nil, err
}
for k, v := range val {
a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v)
if err != nil {
return nil, err
}
attributes[k] = a
}
return NewWriteValueMust(WriteValue{}.AttributeTypes(ctx), attributes), nil
}
func (t WriteType) ValueType(ctx context.Context) attr.Value {
return WriteValue{}
}
var _ basetypes.ObjectValuable = WriteValue{}
type WriteValue struct {
Host basetypes.StringValue `tfsdk:"host"`
Port basetypes.Int64Value `tfsdk:"port"`
state attr.ValueState
}
func (v ConnectionInfoValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) {
func (v WriteValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) {
attrTypes := make(map[string]tftypes.Type, 2)
var val tftypes.Value
@ -538,19 +901,19 @@ func (v ConnectionInfoValue) ToTerraformValue(ctx context.Context) (tftypes.Valu
}
}
func (v ConnectionInfoValue) IsNull() bool {
func (v WriteValue) IsNull() bool {
return v.state == attr.ValueStateNull
}
func (v ConnectionInfoValue) IsUnknown() bool {
func (v WriteValue) IsUnknown() bool {
return v.state == attr.ValueStateUnknown
}
func (v ConnectionInfoValue) String() string {
return "ConnectionInfoValue"
func (v WriteValue) String() string {
return "WriteValue"
}
func (v ConnectionInfoValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) {
func (v WriteValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) {
var diags diag.Diagnostics
attributeTypes := map[string]attr.Type{
@ -576,8 +939,8 @@ func (v ConnectionInfoValue) ToObjectValue(ctx context.Context) (basetypes.Objec
return objVal, diags
}
func (v ConnectionInfoValue) Equal(o attr.Value) bool {
other, ok := o.(ConnectionInfoValue)
func (v WriteValue) Equal(o attr.Value) bool {
other, ok := o.(WriteValue)
if !ok {
return false
@ -602,15 +965,15 @@ func (v ConnectionInfoValue) Equal(o attr.Value) bool {
return true
}
func (v ConnectionInfoValue) Type(ctx context.Context) attr.Type {
return ConnectionInfoType{
func (v WriteValue) Type(ctx context.Context) attr.Type {
return WriteType{
basetypes.ObjectType{
AttrTypes: v.AttributeTypes(ctx),
},
}
}
func (v ConnectionInfoValue) AttributeTypes(ctx context.Context) map[string]attr.Type {
func (v WriteValue) AttributeTypes(ctx context.Context) map[string]attr.Type {
return map[string]attr.Type{
"host": basetypes.StringType{},
"port": basetypes.Int64Type{},

View file

@ -30,39 +30,46 @@ var testInstances []string
func init() {
sweeperName := fmt.Sprintf("%s_%s", pfx, "sweeper")
resource.AddTestSweepers(sweeperName, &resource.Sweeper{
Name: sweeperName,
F: func(region string) error {
ctx := context.Background()
apiClientConfigOptions := []config.ConfigurationOption{}
apiClient, err := postgresflexalpha2.NewAPIClient(apiClientConfigOptions...)
if err != nil {
log.Fatalln(err)
}
resource.AddTestSweepers(
sweeperName, &resource.Sweeper{
Name: sweeperName,
F: func(_ string) error { // region is passed by the testing framework
ctx := context.Background()
apiClientConfigOptions := []config.ConfigurationOption{}
apiClient, err := postgresflexalpha2.NewAPIClient(apiClientConfigOptions...)
if err != nil {
log.Fatalln(err)
}
instances, err := apiClient.ListInstancesRequest(ctx, testutils.ProjectId, testutils.Region).
Size(100).
Execute()
if err != nil {
log.Fatalln(err)
}
instances, err := apiClient.ListInstancesRequest(ctx, testutils.ProjectId, testutils.Region).
Size(100).
Execute()
if err != nil {
log.Fatalln(err)
}
for _, inst := range instances.GetInstances() {
if strings.HasPrefix(inst.GetName(), "tf-acc-") {
for _, item := range testInstances {
if inst.GetName() == item {
delErr := apiClient.DeleteInstanceRequestExecute(ctx, testutils.ProjectId, testutils.Region, inst.GetId())
if delErr != nil {
// TODO: maybe just warn?
log.Fatalln(delErr)
for _, inst := range instances.GetInstances() {
if strings.HasPrefix(inst.GetName(), "tf-acc-") {
for _, item := range testInstances {
if inst.GetName() == item {
delErr := apiClient.DeleteInstanceRequestExecute(
ctx,
testutils.ProjectId,
testutils.Region,
inst.GetId(),
)
if delErr != nil {
// TODO: maybe just warn?
log.Fatalln(delErr)
}
}
}
}
}
}
return nil
return nil
},
},
})
)
}
func TestInstanceResourceSchema(t *testing.T) {
@ -195,57 +202,67 @@ func TestAccInstance(t *testing.T) {
updSizeData := exData
updSizeData.Size = 25
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
t.Logf(" ... working on instance %s", exData.TfName)
testInstances = append(testInstances, exData.TfName)
},
ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
// Create and verify
{
Config: testutils.StringFromTemplateMust(
"testdata/instance_template.gompl",
exData,
),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr(testutils.ResStr(pfx, "instance", exData.TfName), "name", exData.Name),
resource.TestCheckResourceAttrSet(testutils.ResStr(pfx, "instance", exData.TfName), "id"),
),
resource.ParallelTest(
t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
t.Logf(" ... working on instance %s", exData.TfName)
testInstances = append(testInstances, exData.TfName)
},
// Update name and verify
{
Config: testutils.StringFromTemplateMust(
"testdata/instance_template.gompl",
updNameData,
),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(testutils.ResStr(pfx, "instance", exData.TfName), "name", updNameData.Name),
),
},
// Update size and verify
{
Config: testutils.StringFromTemplateMust(
"testdata/instance_template.gompl",
updSizeData,
),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(
testutils.ResStr(pfx, "instance", exData.TfName),
"storage.size",
strconv.Itoa(int(updSizeData.Size)),
ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
// Create and verify
{
Config: testutils.StringFromTemplateMust(
"testdata/instance_template.gompl",
exData,
),
),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr(
testutils.ResStr(pfx, "instance", exData.TfName),
"name",
exData.Name,
),
resource.TestCheckResourceAttrSet(testutils.ResStr(pfx, "instance", exData.TfName), "id"),
),
},
// Update name and verify
{
Config: testutils.StringFromTemplateMust(
"testdata/instance_template.gompl",
updNameData,
),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(
testutils.ResStr(pfx, "instance", exData.TfName),
"name",
updNameData.Name,
),
),
},
// Update size and verify
{
Config: testutils.StringFromTemplateMust(
"testdata/instance_template.gompl",
updSizeData,
),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(
testutils.ResStr(pfx, "instance", exData.TfName),
"storage.size",
strconv.Itoa(int(updSizeData.Size)),
),
),
},
//// Import test
//{
// ResourceName: "example_resource.test",
// ImportState: true,
// ImportStateVerify: true,
// },
},
//// Import test
//{
// ResourceName: "example_resource.test",
// ImportState: true,
// ImportStateVerify: true,
// },
},
})
)
}
func TestAccInstanceWithUsers(t *testing.T) {
@ -260,29 +277,35 @@ func TestAccInstanceWithUsers(t *testing.T) {
},
}
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
t.Logf(" ... working on instance %s", data.TfName)
testInstances = append(testInstances, data.TfName)
},
ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
// Create and verify
{
Config: testutils.StringFromTemplateMust(
"testdata/instance_template.gompl",
data,
),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr(testutils.ResStr(pfx, "instance", data.TfName), "name", data.Name),
resource.TestCheckResourceAttrSet(testutils.ResStr(pfx, "instance", data.TfName), "id"),
resource.TestCheckResourceAttr(testutils.ResStr(pfx, "user", userName), "name", userName),
resource.TestCheckResourceAttrSet(testutils.ResStr(pfx, "user", userName), "id"),
),
resource.ParallelTest(
t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
t.Logf(" ... working on instance %s", data.TfName)
testInstances = append(testInstances, data.TfName)
},
ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
// Create and verify
{
Config: testutils.StringFromTemplateMust(
"testdata/instance_template.gompl",
data,
),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr(
testutils.ResStr(pfx, "instance", data.TfName),
"name",
data.Name,
),
resource.TestCheckResourceAttrSet(testutils.ResStr(pfx, "instance", data.TfName), "id"),
resource.TestCheckResourceAttr(testutils.ResStr(pfx, "user", userName), "name", userName),
resource.TestCheckResourceAttrSet(testutils.ResStr(pfx, "user", userName), "id"),
),
},
},
},
})
)
}
func TestAccInstanceWithDatabases(t *testing.T) {
@ -306,32 +329,38 @@ func TestAccInstanceWithDatabases(t *testing.T) {
},
}
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
t.Logf(" ... working on instance %s", data.TfName)
testInstances = append(testInstances, data.TfName)
},
ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
// Create and verify
{
Config: testutils.StringFromTemplateMust(
"testdata/instance_template.gompl",
data,
),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr(testutils.ResStr(pfx, "instance", data.TfName), "name", data.Name),
resource.TestCheckResourceAttrSet(testutils.ResStr(pfx, "instance", data.TfName), "id"),
resource.TestCheckResourceAttr(testutils.ResStr(pfx, "user", userName), "name", userName),
resource.TestCheckResourceAttrSet(testutils.ResStr(pfx, "user", userName), "id"),
resource.TestCheckResourceAttr(testutils.ResStr(pfx, "database", dbName), "name", dbName),
resource.TestCheckResourceAttr(testutils.ResStr(pfx, "database", dbName), "owner", userName),
resource.TestCheckResourceAttrSet(testutils.ResStr(pfx, "database", dbName), "id"),
),
resource.ParallelTest(
t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
t.Logf(" ... working on instance %s", data.TfName)
testInstances = append(testInstances, data.TfName)
},
ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
// Create and verify
{
Config: testutils.StringFromTemplateMust(
"testdata/instance_template.gompl",
data,
),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr(
testutils.ResStr(pfx, "instance", data.TfName),
"name",
data.Name,
),
resource.TestCheckResourceAttrSet(testutils.ResStr(pfx, "instance", data.TfName), "id"),
resource.TestCheckResourceAttr(testutils.ResStr(pfx, "user", userName), "name", userName),
resource.TestCheckResourceAttrSet(testutils.ResStr(pfx, "user", userName), "id"),
resource.TestCheckResourceAttr(testutils.ResStr(pfx, "database", dbName), "name", dbName),
resource.TestCheckResourceAttr(testutils.ResStr(pfx, "database", dbName), "owner", userName),
resource.TestCheckResourceAttrSet(testutils.ResStr(pfx, "database", dbName), "id"),
),
},
},
},
})
)
}
// func setupMockServer() *httptest.Server {
@ -461,7 +490,7 @@ func TestAccInstanceWithDatabases(t *testing.T) {
// "project_id": testutils.ProjectId,
//}
//
//func configResources(backupSchedule string, _ *string) string {
// func configResources(backupSchedule string, _ *string) string {
// return fmt.Sprintf(
// `
// %s
@ -535,7 +564,7 @@ func TestAccInstanceWithDatabases(t *testing.T) {
// )
//}
//
//func TestAccPostgresFlexFlexResource(t *testing.T) {
// func TestAccPostgresFlexFlexResource(t *testing.T) {
// resource.ParallelTest(
// t, resource.TestCase{
// ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories,
@ -954,7 +983,7 @@ func TestAccInstanceWithDatabases(t *testing.T) {
// )
//}
//
//func testAccCheckPostgresFlexDestroy(s *terraform.State) error {
// func testAccCheckPostgresFlexDestroy(s *terraform.State) error {
// ctx := context.Background()
// var client *postgresflex.APIClient
// var err error

View file

@ -252,7 +252,6 @@ func (r *userResource) Create(
model.UserId = types.Int64Value(id)
model.Password = types.StringValue(userResp.GetPassword())
model.Status = types.StringValue(userResp.GetStatus())
//model.ConnectionString = types.StringValue(userResp.GetConnectionString())
waitResp, err := postgresflexalphaWait.GetUserByIdWaitHandler(
ctx,

View file

@ -143,7 +143,6 @@ func (d *databaseDataSource) Read(ctx context.Context, req datasource.ReadReques
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
tflog.Info(ctx, "SQL Server Flex beta database read")
}
// handleReadError centralizes API error handling for the Read operation.

View file

@ -36,10 +36,6 @@ var (
// Define errors
errDatabaseNotFound = errors.New("database not found")
// Error message constants
extractErrorSummary = "extracting failed"
extractErrorMessage = "Extracting identity data: %v"
)
func NewDatabaseResource() resource.Resource {
@ -186,26 +182,6 @@ func (r *databaseResource) Create(ctx context.Context, req resource.CreateReques
payLoad.Name = data.Name.ValueStringPointer()
payLoad.Owner = data.Owner.ValueStringPointer()
//_, err := wait.WaitForUserWaitHandler(
// ctx,
// r.client,
// projectId,
// instanceId,
// region,
// data.Owner.ValueString(),
//).
// SetSleepBeforeWait(10 * time.Second).
// WaitWithContext(ctx)
//if err != nil {
// core.LogAndAddError(
// ctx,
// &resp.Diagnostics,
// createErr,
// fmt.Sprintf("Calling API: %v", err),
// )
// return
//}
createResp, err := r.client.CreateDatabaseRequest(ctx, projectId, region, instanceId).
CreateDatabaseRequestPayload(payLoad).
Execute()
@ -451,7 +427,9 @@ func (r *databaseResource) Delete(ctx context.Context, req resource.DeleteReques
&resp.Diagnostics,
"Error deleting database",
fmt.Sprintf(
"Calling API: %v\nname: %s, region: %s, instanceId: %s", err, databaseName, region, instanceId))
"Calling API: %v\nname: %s, region: %s, instanceId: %s", err, databaseName, region, instanceId,
),
)
return
}
@ -468,7 +446,6 @@ func (r *databaseResource) ModifyPlan(
req resource.ModifyPlanRequest,
resp *resource.ModifyPlanResponse,
) { // nolint:gocritic // function signature required by Terraform
// skip initial empty configuration to avoid follow-up errors
if req.Config.Raw.IsNull() {
return

View file

@ -247,7 +247,6 @@ func toCreatePayload(
conversion.StringValueToPointer(model.Version),
),
}, nil
}
func toUpdatePayload(

View file

@ -54,7 +54,7 @@ type InstanceResourceIdentityModel struct {
}
func (r *instanceResource) Metadata(
ctx context.Context,
_ context.Context,
req resource.MetadataRequest,
resp *resource.MetadataResponse,
) {
@ -64,7 +64,7 @@ func (r *instanceResource) Metadata(
//go:embed planModifiers.yaml
var modifiersFileByte []byte
func (r *instanceResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
func (r *instanceResource) Schema(ctx context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {
s := sqlserverflexalphaResGen.InstanceResourceSchema(ctx)
fields, err := utils.ReadModifiersConfig(modifiersFileByte)
@ -147,7 +147,6 @@ func (r *instanceResource) ModifyPlan(
req resource.ModifyPlanRequest,
resp *resource.ModifyPlanResponse,
) { // nolint:gocritic // function signature required by Terraform
// skip initial empty configuration to avoid follow-up errors
if req.Config.Raw.IsNull() {
return

View file

@ -288,8 +288,8 @@ func TestAccInstanceNoEncryption(t *testing.T) {
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption"),
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.kek_key_id"),
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.kek_key_version"),
//resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.kek_key_ring_id"),
//resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.service_account"),
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.kek_key_ring_id"),
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.service_account"),
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "network.access_scope"),
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "network.acl"),
@ -389,8 +389,8 @@ func TestAccInstanceEncryption(t *testing.T) {
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption"),
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.kek_key_id"),
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.kek_key_version"),
//resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.kek_key_ring_id"),
//resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.service_account"),
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.kek_key_ring_id"),
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.service_account"),
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "network.access_scope"),
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "network.acl"),

View file

@ -20,8 +20,6 @@ import (
var _ datasource.DataSource = (*userDataSource)(nil)
const errorPrefix = "[sqlserverflexalpha - User]"
func NewUserDataSource() datasource.DataSource {
return &userDataSource{}
}

View file

@ -20,7 +20,6 @@ import (
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pkg_gen/sqlserverflexalpha"
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/conversion"
sqlserverflexalphagen "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/user/resources_gen"
sqlserverflexalphaUtils "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/utils"
sqlserverflexalphaWait "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/wait/sqlserverflexalpha"
@ -59,7 +58,7 @@ type userResource struct {
providerData core.ProviderData
}
func (r *userResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
func (r *userResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_sqlserverflexalpha_user"
}
@ -118,7 +117,7 @@ var modifiersFileByte []byte
// Schema defines the schema for the resource.
func (r *userResource) Schema(ctx context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {
s := sqlserverflexalphagen.UserResourceSchema(ctx)
s := sqlserverflexalphaResGen.UserResourceSchema(ctx)
fields, err := utils.ReadModifiersConfig(modifiersFileByte)
if err != nil {
@ -470,7 +469,6 @@ func (r *userResource) Delete(
// Delete existing record set
_, err = sqlserverflexalphaWait.DeleteUserWaitHandler(ctx, r.client, projectId, region, instanceId, userId).
WaitWithContext(ctx)
// err := r.client.DeleteUserRequest(ctx, arg.projectId, arg.region, arg.instanceId, userId).Execute()
if err != nil {
core.LogAndAddError(ctx, &resp.Diagnostics, "User Delete Error", fmt.Sprintf("Calling API: %v", err))
return

View file

@ -143,7 +143,6 @@ func (d *databaseDataSource) Read(ctx context.Context, req datasource.ReadReques
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
tflog.Info(ctx, "SQL Server Flex beta database read")
}
// handleReadError centralizes API error handling for the Read operation.

View file

@ -36,10 +36,6 @@ var (
// Define errors
errDatabaseNotFound = errors.New("database not found")
// Error message constants
extractErrorSummary = "extracting failed"
extractErrorMessage = "Extracting identity data: %v"
)
func NewDatabaseResource() resource.Resource {
@ -430,7 +426,9 @@ func (r *databaseResource) Delete(ctx context.Context, req resource.DeleteReques
&resp.Diagnostics,
"Error deleting database",
fmt.Sprintf(
"Calling API: %v\nname: %s, region: %s, instanceId: %s", err, databaseName, region, instanceId))
"Calling API: %v\nname: %s, region: %s, instanceId: %s", err, databaseName, region, instanceId,
),
)
return
}
@ -449,7 +447,6 @@ func (r *databaseResource) ModifyPlan(
req resource.ModifyPlanRequest,
resp *resource.ModifyPlanResponse,
) { // nolint:gocritic // function signature required by Terraform
// skip initial empty configuration to avoid follow-up errors
if req.Config.Raw.IsNull() {
return
@ -559,45 +556,4 @@ func (r *databaseResource) ImportState(
tflog.Info(ctx, "Sqlserverflexbeta database state imported")
}
// extractIdentityData extracts essential identifiers from the resource model, falling back to the identity model.
func (r *databaseResource) extractIdentityData(
model resourceModel,
identity DatabaseResourceIdentityModel,
) (projectId, region, instanceId, databaseName string, err error) {
if !model.Name.IsNull() && !model.Name.IsUnknown() {
databaseName = model.Name.ValueString()
} else {
if identity.DatabaseName.IsNull() || identity.DatabaseName.IsUnknown() {
return "", "", "", "", fmt.Errorf("database_name not found in config")
}
databaseName = identity.DatabaseName.ValueString()
}
if !model.ProjectId.IsNull() && !model.ProjectId.IsUnknown() {
projectId = model.ProjectId.ValueString()
} else {
if identity.ProjectID.IsNull() || identity.ProjectID.IsUnknown() {
return "", "", "", "", fmt.Errorf("project_id not found in config")
}
projectId = identity.ProjectID.ValueString()
}
if !model.Region.IsNull() && !model.Region.IsUnknown() {
region = r.providerData.GetRegionWithOverride(model.Region)
} else {
if identity.Region.IsNull() || identity.Region.IsUnknown() {
return "", "", "", "", fmt.Errorf("region not found in config")
}
region = r.providerData.GetRegionWithOverride(identity.Region)
}
if !model.InstanceId.IsNull() && !model.InstanceId.IsUnknown() {
instanceId = model.InstanceId.ValueString()
} else {
if identity.InstanceID.IsNull() || identity.InstanceID.IsUnknown() {
return "", "", "", "", fmt.Errorf("instance_id not found in config")
}
instanceId = identity.InstanceID.ValueString()
}
return projectId, region, instanceId, databaseName, nil
}
// extractIdentityData extracts essential identifiers from the resource model, falling back to the identity mode

View file

@ -236,7 +236,6 @@ func toCreatePayload(
conversion.StringValueToPointer(model.Version),
),
}, nil
}
func toUpdatePayload(

View file

@ -11,6 +11,7 @@ import (
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/stackitcloud/stackit-sdk-go/core/utils"
sqlserverflexbetaPkgGen "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pkg_gen/sqlserverflexbeta"
sqlserverflexbetaRs "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexbeta/instance/resources_gen"
)
@ -28,11 +29,13 @@ func Test_handleDSEncryption(t *testing.T) {
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := handleDSEncryption(tt.args.m, tt.args.resp); !reflect.DeepEqual(got, tt.want) {
t.Errorf("handleDSEncryption() = %v, want %v", got, tt.want)
}
})
t.Run(
tt.name, func(t *testing.T) {
if got := handleDSEncryption(t.Context(), tt.args.m, tt.args.resp); !reflect.DeepEqual(got, tt.want) {
t.Errorf("handleDSEncryption() = %v, want %v", got, tt.want)
}
},
)
}
}
@ -86,11 +89,13 @@ func Test_handleEncryption(t *testing.T) {
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := handleEncryption(tt.args.m, tt.args.resp); !reflect.DeepEqual(got, tt.want) {
t.Errorf("handleEncryption() = %v, want %v", got, tt.want)
}
})
t.Run(
tt.name, func(t *testing.T) {
if got := handleEncryption(t.Context(), tt.args.m, tt.args.resp); !reflect.DeepEqual(got, tt.want) {
t.Errorf("handleEncryption() = %v, want %v", got, tt.want)
}
},
)
}
}
@ -109,11 +114,18 @@ func Test_mapDataResponseToModel(t *testing.T) {
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := mapDataResponseToModel(tt.args.ctx, tt.args.resp, tt.args.m, tt.args.tfDiags); (err != nil) != tt.wantErr {
t.Errorf("mapDataResponseToModel() error = %v, wantErr %v", err, tt.wantErr)
}
})
t.Run(
tt.name, func(t *testing.T) {
if err := mapDataResponseToModel(
tt.args.ctx,
tt.args.resp,
tt.args.m,
tt.args.tfDiags,
); (err != nil) != tt.wantErr {
t.Errorf("mapDataResponseToModel() error = %v, wantErr %v", err, tt.wantErr)
}
},
)
}
}
@ -132,11 +144,18 @@ func Test_mapResponseToModel(t *testing.T) {
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := mapResponseToModel(tt.args.ctx, tt.args.resp, tt.args.m, tt.args.tfDiags); (err != nil) != tt.wantErr {
t.Errorf("mapResponseToModel() error = %v, wantErr %v", err, tt.wantErr)
}
})
t.Run(
tt.name, func(t *testing.T) {
if err := mapResponseToModel(
tt.args.ctx,
tt.args.resp,
tt.args.m,
tt.args.tfDiags,
); (err != nil) != tt.wantErr {
t.Errorf("mapResponseToModel() error = %v, wantErr %v", err, tt.wantErr)
}
},
)
}
}
@ -208,19 +227,18 @@ func Test_toCreatePayload(t *testing.T) {
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := toCreatePayload(tt.args.ctx, tt.args.model)
if (err != nil) != tt.wantErr {
t.Errorf("toCreatePayload() error = %v, wantErr %v", err, tt.wantErr)
return
}
if diff := cmp.Diff(tt.want, got); diff != "" {
t.Errorf("model mismatch (-want +got):\n%s", diff)
}
//if !reflect.DeepEqual(got, tt.want) {
// t.Errorf("toCreatePayload() got = %v, want %v", got, tt.want)
//}
})
t.Run(
tt.name, func(t *testing.T) {
got, err := toCreatePayload(tt.args.ctx, tt.args.model)
if (err != nil) != tt.wantErr {
t.Errorf("toCreatePayload() error = %v, wantErr %v", err, tt.wantErr)
return
}
if diff := cmp.Diff(tt.want, got); diff != "" {
t.Errorf("model mismatch (-want +got):\n%s", diff)
}
},
)
}
}
@ -239,15 +257,17 @@ func Test_toUpdatePayload(t *testing.T) {
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := toUpdatePayload(tt.args.ctx, tt.args.m, tt.args.resp)
if (err != nil) != tt.wantErr {
t.Errorf("toUpdatePayload() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("toUpdatePayload() got = %v, want %v", got, tt.want)
}
})
t.Run(
tt.name, func(t *testing.T) {
got, err := toUpdatePayload(tt.args.ctx, tt.args.m, tt.args.resp)
if (err != nil) != tt.wantErr {
t.Errorf("toUpdatePayload() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("toUpdatePayload() got = %v, want %v", got, tt.want)
}
},
)
}
}

View file

@ -54,7 +54,7 @@ type InstanceResourceIdentityModel struct {
}
func (r *instanceResource) Metadata(
ctx context.Context,
_ context.Context,
req resource.MetadataRequest,
resp *resource.MetadataResponse,
) {
@ -64,7 +64,7 @@ func (r *instanceResource) Metadata(
//go:embed planModifiers.yaml
var modifiersFileByte []byte
func (r *instanceResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
func (r *instanceResource) Schema(ctx context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {
s := sqlserverflexbetaResGen.InstanceResourceSchema(ctx)
fields, err := utils.ReadModifiersConfig(modifiersFileByte)
@ -147,7 +147,6 @@ func (r *instanceResource) ModifyPlan(
req resource.ModifyPlanRequest,
resp *resource.ModifyPlanResponse,
) { // nolint:gocritic // function signature required by Terraform
// skip initial empty configuration to avoid follow-up errors
if req.Config.Raw.IsNull() {
return

View file

@ -349,8 +349,8 @@ func TestAccInstanceNoEncryption(t *testing.T) {
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption"),
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.kek_key_id"),
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.kek_key_version"),
//resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.kek_key_ring_id"),
//resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.service_account"),
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.kek_key_ring_id"),
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.service_account"),
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "network.access_scope"),
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "network.acl"),
@ -450,8 +450,8 @@ func TestAccInstanceEncryption(t *testing.T) {
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption"),
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.kek_key_id"),
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.kek_key_version"),
//resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.kek_key_ring_id"),
//resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.service_account"),
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.kek_key_ring_id"),
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.service_account"),
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "network.access_scope"),
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "network.acl"),

View file

@ -20,8 +20,6 @@ import (
var _ datasource.DataSource = (*userDataSource)(nil)
const errorPrefix = "[Sqlserverflexbeta - User]"
func NewUserDataSource() datasource.DataSource {
return &userDataSource{}
}

View file

@ -20,7 +20,6 @@ import (
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pkg_gen/sqlserverflexbeta"
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/conversion"
sqlserverflexbetagen "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexbeta/user/resources_gen"
sqlserverflexbetaUtils "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexbeta/utils"
sqlserverflexbetaWait "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/wait/sqlserverflexbeta"
@ -59,7 +58,7 @@ type userResource struct {
providerData core.ProviderData
}
func (r *userResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
func (r *userResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_sqlserverflexbeta_user"
}
@ -108,23 +107,23 @@ func (r *userResource) ModifyPlan(
}
//// TODO: verify if this is needed - START
//var planRoles []string
//diags := planModel.Roles.ElementsAs(ctx, &planRoles, false)
//resp.Diagnostics.Append(diags...)
//if diags.HasError() {
// var planRoles []string
// diags := planModel.Roles.ElementsAs(ctx, &planRoles, false)
// resp.Diagnostics.Append(diags...)
// if diags.HasError() {
// return
//}
//slices.Sort(planRoles)
//var roles []attr.Value
//for _, role := range planRoles {
// slices.Sort(planRoles)
// var roles []attr.Value
// for _, role := range planRoles {
// roles = append(roles, types.StringValue(string(role)))
//}
//rolesSet, diags := types.ListValue(types.StringType, roles)
//resp.Diagnostics.Append(diags...)
//if diags.HasError() {
// rolesSet, diags := types.ListValue(types.StringType, roles)
// resp.Diagnostics.Append(diags...)
// if diags.HasError() {
// return
//}
//planModel.Roles = rolesSet
// planModel.Roles = rolesSet
//// TODO: verify if this is needed - END
resp.Diagnostics.Append(resp.Plan.Set(ctx, planModel)...)
@ -138,7 +137,7 @@ var modifiersFileByte []byte
// Schema defines the schema for the resource.
func (r *userResource) Schema(ctx context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {
s := sqlserverflexbetagen.UserResourceSchema(ctx)
s := sqlserverflexbetaResGen.UserResourceSchema(ctx)
fields, err := utils.ReadModifiersConfig(modifiersFileByte)
if err != nil {
@ -435,7 +434,12 @@ func (r *userResource) Update(
resp *resource.UpdateResponse,
) { // nolint:gocritic // function signature required by Terraform
// Update shouldn't be called
core.LogAndAddError(ctx, &resp.Diagnostics, "Error updating user", "an SQL server user can not be updated, only created")
core.LogAndAddError(
ctx,
&resp.Diagnostics,
"Error updating user",
"an SQL server user can not be updated, only created",
)
}
// Delete deletes the resource and removes the Terraform state on success.
@ -489,7 +493,6 @@ func (r *userResource) Delete(
// Delete existing record set
_, err = sqlserverflexbetaWait.DeleteUserWaitHandler(ctx, r.client, projectId, region, instanceId, userId).
WaitWithContext(ctx)
// err := r.client.DeleteUserRequest(ctx, arg.projectId, arg.region, arg.instanceId, userId).Execute()
if err != nil {
core.LogAndAddError(ctx, &resp.Diagnostics, "User Delete Error", fmt.Sprintf("Calling API: %v", err))
return

View file

@ -108,7 +108,7 @@ func CreateInstanceWaitHandler(
)
if extendedTimeout < 3 {
maxWait += time.Minute * 5
extendedTimeout = extendedTimeout + 1
extendedTimeout++
if *s.Network.AccessScope == "SNA" {
ready := true
if s.Network == nil || s.Network.InstanceAddress == nil {
@ -228,7 +228,7 @@ func GetUserByIdWaitHandler(
if userId > math.MaxInt32 {
return false, nil, fmt.Errorf("userId value is too big for int32")
}
userId32 := int32(userId)
userId32 := int32(userId) //nolint:gosec // we need to convert databaseId to int32 because API expects int32
s, err := a.GetUserRequestExecute(ctx, projectId, region, instanceId, userId32)
if err != nil {
var oapiErr *oapierror.GenericOpenAPIError
@ -239,9 +239,11 @@ func GetUserByIdWaitHandler(
switch oapiErr.StatusCode {
case http.StatusBadGateway, http.StatusGatewayTimeout, http.StatusServiceUnavailable:
case http.StatusNotFound:
tflog.Warn(ctx, "api responded with status", map[string]interface{}{
"status": oapiErr.StatusCode,
})
tflog.Warn(
ctx, "api responded with status", map[string]interface{}{
"status": oapiErr.StatusCode,
},
)
return false, nil, nil
default:
return false, nil, err
@ -262,7 +264,7 @@ func GetDatabaseByIdWaitHandler(
) *wait.AsyncActionHandler[postgresflex.GetDatabaseResponse] {
handler := wait.New(
func() (waitFinished bool, response *postgresflex.GetDatabaseResponse, err error) {
dbId32 := int32(databaseId)
dbId32 := int32(databaseId) //nolint:gosec // we need to convert databaseId to int32 because API expects int32
s, err := a.GetDatabaseRequestExecute(ctx, projectId, region, instanceId, dbId32)
if err != nil {
var oapiErr *oapierror.GenericOpenAPIError
@ -272,14 +274,18 @@ func GetDatabaseByIdWaitHandler(
}
switch oapiErr.StatusCode {
case http.StatusBadGateway, http.StatusGatewayTimeout, http.StatusServiceUnavailable:
tflog.Warn(ctx, "api responded with 50[2,3,4] status", map[string]interface{}{
"status": oapiErr.StatusCode,
})
tflog.Warn(
ctx, "api responded with 50[2,3,4] status", map[string]interface{}{
"status": oapiErr.StatusCode,
},
)
return false, nil, nil
case http.StatusNotFound:
tflog.Warn(ctx, "api responded with 404 status", map[string]interface{}{
"status": oapiErr.StatusCode,
})
tflog.Warn(
ctx, "api responded with 404 status", map[string]interface{}{
"status": oapiErr.StatusCode,
},
)
return false, nil, nil
default:
return false, nil, err

View file

@ -54,7 +54,12 @@ type APIClientInterface interface {
instanceId string,
) (*sqlserverflex.ListRolesResponse, error)
ListUsersRequest(ctx context.Context, projectId string, region string, instanceId string) sqlserverflex.ApiListUsersRequestRequest
ListUsersRequest(
ctx context.Context,
projectId string,
region string,
instanceId string,
) sqlserverflex.ApiListUsersRequestRequest
ListUsersRequestExecute(
ctx context.Context,
@ -256,7 +261,10 @@ func CreateDatabaseWaitHandler(
var oapiErr *oapierror.GenericOpenAPIError
ok := errors.As(err, &oapiErr)
if !ok {
return false, nil, fmt.Errorf("get database - could not convert error to oapierror.GenericOpenAPIError: %s", err.Error())
return false, nil, fmt.Errorf(
"get database - could not convert error to oapierror.GenericOpenAPIError: %s",
err.Error(),
)
}
if oapiErr.StatusCode != http.StatusNotFound {
return false, nil, err
@ -318,7 +326,10 @@ func WaitForUserWaitHandler(
var oapiErr *oapierror.GenericOpenAPIError
ok := errors.As(err, &oapiErr)
if !ok {
return false, nil, fmt.Errorf("Wait (list users) could not convert error to oapierror.GenericOpenAPIError: %s", err.Error())
return false, nil, fmt.Errorf(
"wait (list users) could not convert error to oapierror.GenericOpenAPIError: %s",
err.Error(),
)
}
if oapiErr.StatusCode != http.StatusNotFound {
return false, nil, err

View file

@ -116,7 +116,6 @@ func (a *apiClientInstanceMocked) GetInstanceRequestExecute(
}, nil
}
func TestCreateInstanceWaitHandler(t *testing.T) {
//stateSuccess := utils.Ptr(InstanceStateSuccess)
instanceId := utils.Ptr("foo")
tests := []struct {
desc string
@ -160,7 +159,7 @@ func TestCreateInstanceWaitHandler(t *testing.T) {
// Storage: nil,
// Version: nil,
// },
//},
// },
{
desc: "create_failed",
instanceId: *instanceId,

View file

@ -54,7 +54,12 @@ type APIClientInterface interface {
instanceId string,
) (*sqlserverflex.ListRolesResponse, error)
ListUsersRequest(ctx context.Context, projectId string, region string, instanceId string) sqlserverflex.ApiListUsersRequestRequest
ListUsersRequest(
ctx context.Context,
projectId string,
region string,
instanceId string,
) sqlserverflex.ApiListUsersRequestRequest
ListUsersRequestExecute(
ctx context.Context,
@ -162,9 +167,17 @@ func CreateInstanceWaitHandler(
}
return true, s, nil
case strings.ToLower(InstanceStateUnknown):
return true, nil, fmt.Errorf("create failed for instance %s with status %s", instanceId, InstanceStateUnknown)
return true, nil, fmt.Errorf(
"create failed for instance %s with status %s",
instanceId,
InstanceStateUnknown,
)
case strings.ToLower(InstanceStateFailed):
return true, nil, fmt.Errorf("create failed for instance %s with status %s", instanceId, InstanceStateFailed)
return true, nil, fmt.Errorf(
"create failed for instance %s with status %s",
instanceId,
InstanceStateFailed,
)
case strings.ToLower(InstanceStatePending), strings.ToLower(InstanceStateProcessing):
tflog.Info(
ctx, "request is being handled", map[string]interface{}{
@ -268,7 +281,10 @@ func CreateDatabaseWaitHandler(
var oapiErr *oapierror.GenericOpenAPIError
ok := errors.As(err, &oapiErr)
if !ok {
return false, nil, fmt.Errorf("get database - could not convert error to oapierror.GenericOpenAPIError: %s", err.Error())
return false, nil, fmt.Errorf(
"get database - could not convert error to oapierror.GenericOpenAPIError: %s",
err.Error(),
)
}
if oapiErr.StatusCode != http.StatusNotFound {
return false, nil, err
@ -330,7 +346,10 @@ func WaitForUserWaitHandler(
var oapiErr *oapierror.GenericOpenAPIError
ok := errors.As(err, &oapiErr)
if !ok {
return false, nil, fmt.Errorf("Wait (list users) could not convert error to oapierror.GenericOpenAPIError: %s", err.Error())
return false, nil, fmt.Errorf(
"wait (list users) could not convert error to oapierror.GenericOpenAPIError: %s",
err.Error(),
)
}
if oapiErr.StatusCode != http.StatusNotFound {
return false, nil, err

View file

@ -116,7 +116,6 @@ func (a *apiClientInstanceMocked) GetInstanceRequestExecute(
}, nil
}
func TestCreateInstanceWaitHandler(t *testing.T) {
//stateSuccess := utils.Ptr(InstanceStateSuccess)
instanceId := utils.Ptr("foo")
tests := []struct {
desc string
@ -160,7 +159,7 @@ func TestCreateInstanceWaitHandler(t *testing.T) {
// Storage: nil,
// Version: nil,
// },
//},
// },
{
desc: "create_failed",
instanceId: *instanceId,

View file

@ -46,6 +46,7 @@ var (
_ provider.Provider = &Provider{}
)
//nolint:unused // These constants are defined for future use in retry logic for HTTP requests, which is not yet implemented.
const (
// maxRetries is the maximum number of retries for a failed HTTP request.
maxRetries = 3
@ -123,6 +124,7 @@ type providerModel struct {
// Schema defines the provider-level schema for configuration data.
func (p *Provider) Schema(_ context.Context, _ provider.SchemaRequest, resp *provider.SchemaResponse) {
//nolint:gosec // These are just descriptions, not actual credentials or sensitive information.
descriptions := map[string]string{
"credentials_path": "Path of JSON from where the credentials are read. Takes precedence over the env var `STACKIT_CREDENTIALS_PATH`. Default value is `~/.stackit/credentials.json`.",
"service_account_token": "Token used for authentication. If set, the token flow will be used to authenticate all operations.",
@ -489,7 +491,8 @@ func (p *Provider) Configure(ctx context.Context, req provider.ConfigureRequest,
return
}
//roundTripper := core.NewRetryRoundTripper(
//nolint:gocritic // maybe later in the code
// roundTripper := core.NewRetryRoundTripper(
// baseRoundTripper,
// maxRetries,
// initialDelay,

View file

@ -12,11 +12,12 @@ import (
"time"
"github.com/golang-jwt/jwt/v5"
test "github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/google/go-cmp/cmp"
test "github.com/hashicorp/terraform-plugin-testing/helper/resource" //nolint:staticcheck // used for acceptance testing
"github.com/jarcoal/httpmock"
"github.com/stackitcloud/stackit-sdk-go/core/clients"
"github.com/stackitcloud/stackit-sdk-go/core/utils"
"github.com/stretchr/testify/require"
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pkg_gen/postgresflexalpha"
postgresFlexAlphaFlavor "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/postgresflexalpha/flavor"
@ -40,7 +41,7 @@ import (
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/internal/testutils"
"github.com/hashicorp/terraform-plugin-testing/config"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/hashicorp/terraform-plugin-testing/helper/resource" //nolint:staticcheck // used for acceptance testing
)
//go:embed testdata/provider-credentials.tf
@ -67,12 +68,15 @@ func TestMshTest(t *testing.T) {
testutils.ActivateEnvironmentHttpMocks()
httpmock.RegisterResponder("POST", `https://service-account.api.stackit.cloud/token`,
func(req *http.Request) (*http.Response, error) {
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"foo": "bar",
"nbf": time.Date(2015, 10, 10, 12, 0, 0, 0, time.UTC).Unix(),
})
httpmock.RegisterResponder(
"POST", `https://service-account.api.stackit.cloud/token`,
func(_ *http.Request) (*http.Response, error) {
token := jwt.NewWithClaims(
jwt.SigningMethodHS256, jwt.MapClaims{
"foo": "bar",
"nbf": time.Date(2015, 10, 10, 12, 0, 0, 0, time.UTC).Unix(),
},
)
// Sign and get the complete encoded token as a string using the secret
tokenString, err := token.SignedString([]byte("mySecret"))
if err != nil {
@ -88,10 +92,13 @@ func TestMshTest(t *testing.T) {
}
return httpmock.NewJsonResponse(http.StatusOK, tR)
})
},
)
httpmock.RegisterResponder("GET", `https://postgres-flex-service.api.eu01.stackit.cloud/v3alpha1/projects/xyz-project-id/regions/eu01/flavors?page=1&size=25&sort=id.asc`,
func(req *http.Request) (*http.Response, error) {
httpmock.RegisterResponder(
"GET",
`https://postgres-flex-service.api.eu01.stackit.cloud/v3alpha1/projects/xyz-project-id/regions/eu01/flavors?page=1&size=25&sort=id.asc`,
func(_ *http.Request) (*http.Response, error) {
res := postgresflexalpha.GetFlavorsResponse{
Flavors: &[]postgresflexalpha.ListFlavors{
{
@ -120,15 +127,17 @@ func TestMshTest(t *testing.T) {
},
)
test.Test(t, test.TestCase{
IsUnitTest: true,
ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories,
Steps: []test.TestStep{
{
ConfigVariables: map[string]config.Variable{
"project_id": config.StringVariable("xyz-project-id"),
},
Config: fmt.Sprintf(`
test.Test(
t, test.TestCase{
IsUnitTest: true,
ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories,
Steps: []test.TestStep{
{
ConfigVariables: map[string]config.Variable{
"project_id": config.StringVariable("xyz-project-id"),
},
Config: fmt.Sprintf(
`
provider "stackitprivatepreview" {
default_region = "%[1]s"
service_account_key_path = "%[2]s"
@ -144,12 +153,13 @@ func TestMshTest(t *testing.T) {
node_type = "Single"
storage_class = "premium-perf2-stackit"
}`,
os.Getenv("TF_ACC_REGION"),
os.Getenv("TF_ACC_SERVICE_ACCOUNT_FILE"),
),
os.Getenv("TF_ACC_REGION"),
os.Getenv("TF_ACC_SERVICE_ACCOUNT_FILE"),
),
},
},
},
})
)
}
func TestUnitProviderHasChildDataSources_Basic(t *testing.T) {
@ -171,12 +181,24 @@ func TestUnitProviderHasChildDataSources_Basic(t *testing.T) {
sqlserverFlexBetaUser.NewUserDataSource(),
sqlserverFlexBetaFlavor.NewFlavorDataSource(),
}
datasources := stackit.New("testing")().(*stackit.Provider).DataSources(context.Background())
provider, ok := stackit.New("testing")().(*stackit.Provider)
if !ok {
t.Fatal("could not assert provider type")
}
datasources := provider.DataSources(context.Background())
if !reflect.DeepEqual(len(expectedDataSources), len(datasources)) {
for _, d := range datasources {
require.Containsf(t, expectedDataSources, d(), "Data source %+v was not expected", reflect.TypeOf(d()))
}
expectedMap := map[string]struct{}{}
for _, d := range expectedDataSources {
expectedMap[reflect.TypeOf(d).String()] = struct{}{}
}
actualMap := map[string]struct{}{}
for _, d := range datasources {
actualMap[reflect.TypeOf(d()).String()] = struct{}{}
}
if diff := cmp.Diff(expectedMap, actualMap); diff != "" {
t.Errorf("DataSources mismatch (-expected +actual):\n%s", diff)
}
}
@ -194,12 +216,24 @@ func TestUnitProviderHasChildResources_Basic(t *testing.T) {
sqlserverFlexBetaUser.NewUserResource(),
sqlserverflexBetaDatabase.NewDatabaseResource(),
}
resources := stackit.New("testing")().(*stackit.Provider).Resources(context.Background())
provider, ok := stackit.New("testing")().(*stackit.Provider)
if !ok {
t.Fatal("could not assert provider type")
}
resources := provider.Resources(context.Background())
if !reflect.DeepEqual(len(expectedResources), len(resources)) {
for _, d := range resources {
require.Containsf(t, expectedResources, d(), "Resource %+v was not expected", reflect.TypeOf(d()))
}
expectedMap := map[string]struct{}{}
for _, r := range expectedResources {
expectedMap[reflect.TypeOf(r).String()] = struct{}{}
}
actualMap := map[string]struct{}{}
for _, r := range resources {
actualMap[reflect.TypeOf(r()).String()] = struct{}{}
}
if diff := cmp.Diff(expectedMap, actualMap); diff != "" {
t.Errorf("Resources mismatch (-expected +actual):\n%s", diff)
}
}
@ -209,23 +243,25 @@ func TestAccEnvVarServiceAccountPathValid(t *testing.T) {
if v := os.Getenv(resource.EnvTfAcc); v == "" {
t.Skipf(
"Acceptance tests skipped unless env '%s' set",
resource.EnvTfAcc)
resource.EnvTfAcc,
)
return
}
// t.Setenv("STACKIT_CREDENTIALS_PATH", "")
tempHomeFolder := testutils.CreateTemporaryHome(true, t)
defer testutils.CleanupTemporaryHome(tempHomeFolder, t)
resource.Test(t, resource.TestCase{
ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
PreConfig: func() { testutils.SetTemporaryHome(tempHomeFolder) },
ConfigVariables: testConfigProviderCredentials,
Config: providerCredentialConfig,
resource.Test(
t, resource.TestCase{
ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
PreConfig: func() { testutils.SetTemporaryHome(tempHomeFolder) },
ConfigVariables: testConfigProviderCredentials,
Config: providerCredentialConfig,
},
},
},
})
)
}
func TestAccEnvVarServiceAccountPathInvalid(t *testing.T) {
@ -233,17 +269,19 @@ func TestAccEnvVarServiceAccountPathInvalid(t *testing.T) {
t.Setenv("STACKIT_CREDENTIALS_PATH", "")
tempHomeFolder := testutils.CreateTemporaryHome(false, t)
defer testutils.CleanupTemporaryHome(tempHomeFolder, t)
resource.Test(t, resource.TestCase{
ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
PreConfig: func() { testutils.SetTemporaryHome(tempHomeFolder) },
ConfigVariables: testConfigProviderCredentials,
Config: providerCredentialConfig,
ExpectError: regexp.MustCompile(`undefined response type, status code 401`),
resource.Test(
t, resource.TestCase{
ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
PreConfig: func() { testutils.SetTemporaryHome(tempHomeFolder) },
ConfigVariables: testConfigProviderCredentials,
Config: providerCredentialConfig,
ExpectError: regexp.MustCompile(`undefined response type, status code 401`),
},
},
},
})
)
}
func TestAccCredentialsFileValid(t *testing.T) {
@ -251,16 +289,18 @@ func TestAccCredentialsFileValid(t *testing.T) {
t.Setenv("STACKIT_CREDENTIALS_PATH", "")
tempHomeFolder := testutils.CreateTemporaryHome(true, t)
defer testutils.CleanupTemporaryHome(tempHomeFolder, t)
resource.Test(t, resource.TestCase{
ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
PreConfig: func() { testutils.SetTemporaryHome(tempHomeFolder) },
ConfigVariables: testConfigProviderCredentials,
Config: providerCredentialConfig,
resource.Test(
t, resource.TestCase{
ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
PreConfig: func() { testutils.SetTemporaryHome(tempHomeFolder) },
ConfigVariables: testConfigProviderCredentials,
Config: providerCredentialConfig,
},
},
},
})
)
}
func TestAccCredentialsFileInvalid(t *testing.T) {
@ -268,17 +308,19 @@ func TestAccCredentialsFileInvalid(t *testing.T) {
t.Setenv("STACKIT_CREDENTIALS_PATH", "")
tempHomeFolder := testutils.CreateTemporaryHome(false, t)
defer testutils.CleanupTemporaryHome(tempHomeFolder, t)
resource.Test(t, resource.TestCase{
ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
PreConfig: func() { testutils.SetTemporaryHome(tempHomeFolder) },
ConfigVariables: testConfigProviderCredentials,
Config: providerCredentialConfig,
ExpectError: regexp.MustCompile(`Jwt is not in(\r\n|\r|\n)the form of Header.Payload.Signature`),
resource.Test(
t, resource.TestCase{
ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
PreConfig: func() { testutils.SetTemporaryHome(tempHomeFolder) },
ConfigVariables: testConfigProviderCredentials,
Config: providerCredentialConfig,
ExpectError: regexp.MustCompile(`Jwt is not in(\r\n|\r|\n)the form of Header.Payload.Signature`),
},
},
},
})
)
}
func TestAccProviderConfigureValidValues(t *testing.T) {
@ -287,21 +329,25 @@ func TestAccProviderConfigureValidValues(t *testing.T) {
if v := os.Getenv(resource.EnvTfAcc); v == "" {
t.Skipf(
"Acceptance tests skipped unless env '%s' set",
resource.EnvTfAcc)
resource.EnvTfAcc,
)
return
}
t.Setenv("STACKIT_CREDENTIALS_PATH", "")
tempHomeFolder := testutils.CreateTemporaryHome(true, t)
defer testutils.CleanupTemporaryHome(tempHomeFolder, t)
resource.Test(t, resource.TestCase{
ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{ // valid provider attributes
ConfigVariables: testConfigProviderCredentials,
Config: providerValidAttributes,
resource.Test(
t, resource.TestCase{
ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
// valid provider attributes
ConfigVariables: testConfigProviderCredentials,
Config: providerValidAttributes,
},
},
},
})
)
}
func TestAccProviderConfigureAnInvalidValue(t *testing.T) {
@ -310,21 +356,25 @@ func TestAccProviderConfigureAnInvalidValue(t *testing.T) {
if v := os.Getenv(resource.EnvTfAcc); v == "" {
t.Skipf(
"Acceptance tests skipped unless env '%s' set",
resource.EnvTfAcc)
resource.EnvTfAcc,
)
return
}
t.Setenv("STACKIT_CREDENTIALS_PATH", "")
tempHomeFolder := testutils.CreateTemporaryHome(true, t)
defer testutils.CleanupTemporaryHome(tempHomeFolder, t)
resource.Test(t, resource.TestCase{
ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{ // invalid test attribute should throw an error
ConfigVariables: testConfigProviderCredentials,
Config: providerInvalidAttribute,
ExpectError: regexp.MustCompile(`An argument named "test" is not expected here\.`),
resource.Test(
t, resource.TestCase{
ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
// invalid test attribute should throw an error
ConfigVariables: testConfigProviderCredentials,
Config: providerInvalidAttribute,
ExpectError: regexp.MustCompile(`An argument named "test" is not expected here\.`),
},
},
},
})
)
}