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

@ -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{},