From c4891b770d58412770d53eee84cfe4c46bf73ae6 Mon Sep 17 00:00:00 2001 From: Andre Harms Date: Fri, 6 Feb 2026 13:14:35 +0100 Subject: [PATCH] feat: add database data source schema and model with required attributes --- .../database_data_source_fix.go | 532 ++++++++++++++++++ 1 file changed, 532 insertions(+) create mode 100644 stackit/internal/services/postgresflexalpha/database/datasources_gen/database_data_source_fix.go diff --git a/stackit/internal/services/postgresflexalpha/database/datasources_gen/database_data_source_fix.go b/stackit/internal/services/postgresflexalpha/database/datasources_gen/database_data_source_fix.go new file mode 100644 index 00000000..b2d62433 --- /dev/null +++ b/stackit/internal/services/postgresflexalpha/database/datasources_gen/database_data_source_fix.go @@ -0,0 +1,532 @@ +// Code generated by terraform-plugin-framework-generator DO NOT EDIT. + +package postgresflexalpha + +import ( + "context" + "fmt" + "strings" + + "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" +) + +func DatabaseDataSourceSchema(ctx context.Context) schema.Schema { + return schema.Schema{ + Attributes: map[string]schema.Attribute{ + "id": schema.Int64Attribute{ + Computed: true, + Description: "The id of the database.", + MarkdownDescription: "The id of the database.", + }, + "name": schema.StringAttribute{ + Computed: true, + Description: "The name of the database.", + MarkdownDescription: "The name of the database.", + }, + "owner": schema.StringAttribute{ + Computed: true, + Description: "The owner of the database.", + MarkdownDescription: "The owner of the database.", + }, + "database_id": schema.Int64Attribute{ + Required: true, + Description: "The ID of the database.", + MarkdownDescription: "The ID of the database.", + }, + "instance_id": schema.StringAttribute{ + Required: true, + Description: "The ID of the instance.", + MarkdownDescription: "The ID of the instance.", + }, + "project_id": schema.StringAttribute{ + Required: true, + Description: "The STACKIT project ID.", + MarkdownDescription: "The STACKIT project ID.", + }, + "region": schema.StringAttribute{ + Required: true, + Description: "The region which should be addressed", + MarkdownDescription: "The region which should be addressed", + Validators: []validator.String{ + stringvalidator.OneOf( + "eu01", + ), + }, + }, + }, + } +} + +type DatabaseModel struct { + Id types.Int64 `tfsdk:"tf_original_api_id"` + Name types.String `tfsdk:"name"` + Owner types.String `tfsdk:"owner"` + DatabaseId types.Int64 `tfsdk:"database_id"` + InstanceId types.String `tfsdk:"instance_id"` + ProjectId types.String `tfsdk:"project_id"` + Region types.String `tfsdk:"region"` +} + +var _ basetypes.ObjectTypable = DatabaseType{} + +type DatabaseType struct { + basetypes.ObjectType +} + +func (t DatabaseType) Equal(o attr.Type) bool { + other, ok := o.(DatabaseType) + + if !ok { + return false + } + + return t.ObjectType.Equal(other.ObjectType) +} + +func (t DatabaseType) String() string { + return "DatabaseType" +} + +func (t DatabaseType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) ( + basetypes.ObjectValuable, + diag.Diagnostics, +) { + var diags diag.Diagnostics + + attributes := in.Attributes() + + idAttribute, ok := attributes["id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `id is missing from object`, + ) + + return nil, diags + } + + idVal, ok := idAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`id expected to be basetypes.Int64Value, was: %T`, idAttribute), + ) + } + + nameAttribute, ok := attributes["name"] + + if !ok { + diags.AddError( + "Attribute Missing", + `name is missing from object`, + ) + + return nil, diags + } + + nameVal, ok := nameAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`name expected to be basetypes.StringValue, was: %T`, nameAttribute), + ) + } + + ownerAttribute, ok := attributes["owner"] + + if !ok { + diags.AddError( + "Attribute Missing", + `owner is missing from object`, + ) + + return nil, diags + } + + ownerVal, ok := ownerAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`owner expected to be basetypes.StringValue, was: %T`, ownerAttribute), + ) + } + + if diags.HasError() { + return nil, diags + } + + return DatabaseValue{ + Id: idVal, + Name: nameVal, + Owner: ownerVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewDatabaseValueNull() DatabaseValue { + return DatabaseValue{ + state: attr.ValueStateNull, + } +} + +func NewDatabaseValueUnknown() DatabaseValue { + return DatabaseValue{ + state: attr.ValueStateUnknown, + } +} + +func NewDatabaseValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) ( + DatabaseValue, + 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 DatabaseValue Attribute Value", + "While creating a DatabaseValue value, a missing attribute value was detected. "+ + "A DatabaseValue 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("DatabaseValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()), + ) + + continue + } + + if !attributeType.Equal(attribute.Type(ctx)) { + diags.AddError( + "Invalid DatabaseValue Attribute Type", + "While creating a DatabaseValue value, an invalid attribute value was detected. "+ + "A DatabaseValue 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("DatabaseValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ + fmt.Sprintf("DatabaseValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), + ) + } + } + + for name := range attributes { + _, ok := attributeTypes[name] + + if !ok { + diags.AddError( + "Extra DatabaseValue Attribute Value", + "While creating a DatabaseValue value, an extra attribute value was detected. "+ + "A DatabaseValue 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 DatabaseValue Attribute Name: %s", name), + ) + } + } + + if diags.HasError() { + return NewDatabaseValueUnknown(), diags + } + + idAttribute, ok := attributes["id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `id is missing from object`, + ) + + return NewDatabaseValueUnknown(), diags + } + + idVal, ok := idAttribute.(basetypes.Int64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`id expected to be basetypes.Int64Value, was: %T`, idAttribute), + ) + } + + nameAttribute, ok := attributes["name"] + + if !ok { + diags.AddError( + "Attribute Missing", + `name is missing from object`, + ) + + return NewDatabaseValueUnknown(), diags + } + + nameVal, ok := nameAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`name expected to be basetypes.StringValue, was: %T`, nameAttribute), + ) + } + + ownerAttribute, ok := attributes["owner"] + + if !ok { + diags.AddError( + "Attribute Missing", + `owner is missing from object`, + ) + + return NewDatabaseValueUnknown(), diags + } + + ownerVal, ok := ownerAttribute.(basetypes.StringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`owner expected to be basetypes.StringValue, was: %T`, ownerAttribute), + ) + } + + if diags.HasError() { + return NewDatabaseValueUnknown(), diags + } + + return DatabaseValue{ + Id: idVal, + Name: nameVal, + Owner: ownerVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewDatabaseValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) DatabaseValue { + object, diags := NewDatabaseValue(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("NewDatabaseValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return object +} + +func (t DatabaseType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewDatabaseValueNull(), 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 NewDatabaseValueUnknown(), nil + } + + if in.IsNull() { + return NewDatabaseValueNull(), 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 NewDatabaseValueMust(DatabaseValue{}.AttributeTypes(ctx), attributes), nil +} + +func (t DatabaseType) ValueType(ctx context.Context) attr.Value { + return DatabaseValue{} +} + +var _ basetypes.ObjectValuable = DatabaseValue{} + +type DatabaseValue struct { + Id basetypes.Int64Value `tfsdk:"id"` + Name basetypes.StringValue `tfsdk:"name"` + Owner basetypes.StringValue `tfsdk:"owner"` + state attr.ValueState +} + +func (v DatabaseValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + attrTypes := make(map[string]tftypes.Type, 3) + + var val tftypes.Value + var err error + + attrTypes["id"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["name"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["owner"] = basetypes.StringType{}.TerraformType(ctx) + + objectType := tftypes.Object{AttributeTypes: attrTypes} + + switch v.state { + case attr.ValueStateKnown: + vals := make(map[string]tftypes.Value, 3) + + val, err = v.Id.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["id"] = val + + val, err = v.Name.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["name"] = val + + val, err = v.Owner.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["owner"] = 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 DatabaseValue) IsNull() bool { + return v.state == attr.ValueStateNull +} + +func (v DatabaseValue) IsUnknown() bool { + return v.state == attr.ValueStateUnknown +} + +func (v DatabaseValue) String() string { + return "DatabaseValue" +} + +func (v DatabaseValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) { + var diags diag.Diagnostics + + attributeTypes := map[string]attr.Type{ + "id": basetypes.Int64Type{}, + "name": basetypes.StringType{}, + "owner": basetypes.StringType{}, + } + + 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{ + "id": v.Id, + "name": v.Name, + "owner": v.Owner, + }, + ) + + return objVal, diags +} + +func (v DatabaseValue) Equal(o attr.Value) bool { + other, ok := o.(DatabaseValue) + + if !ok { + return false + } + + if v.state != other.state { + return false + } + + if v.state != attr.ValueStateKnown { + return true + } + + if !v.Id.Equal(other.Id) { + return false + } + + if !v.Name.Equal(other.Name) { + return false + } + + if !v.Owner.Equal(other.Owner) { + return false + } + + return true +} + +func (v DatabaseValue) Type(ctx context.Context) attr.Type { + return DatabaseType{ + basetypes.ObjectType{ + AttrTypes: v.AttributeTypes(ctx), + }, + } +} + +func (v DatabaseValue) AttributeTypes(ctx context.Context) map[string]attr.Type { + return map[string]attr.Type{ + "id": basetypes.Int64Type{}, + "name": basetypes.StringType{}, + "owner": basetypes.StringType{}, + } +}