Compare commits
1 commit
alpha
...
feat/respo
| Author | SHA1 | Date | |
|---|---|---|---|
| 7638c4cc13 |
3 changed files with 1804 additions and 0 deletions
106
pkg/responseMapper/mapper.go
Normal file
106
pkg/responseMapper/mapper.go
Normal file
|
|
@ -0,0 +1,106 @@
|
||||||
|
package responseMapper
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ToModel(_ context.Context, resp interface{}, model any) error {
|
||||||
|
modelValue := reflect.ValueOf(model)
|
||||||
|
if modelValue.Kind() != reflect.Ptr || modelValue.IsNil() {
|
||||||
|
return fmt.Errorf("model must be a pointer and must not be nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
responseValue := reflect.ValueOf(resp)
|
||||||
|
if responseValue.Kind() == reflect.Ptr {
|
||||||
|
return fmt.Errorf("response must NOT be a pointer")
|
||||||
|
}
|
||||||
|
|
||||||
|
responseType := reflect.TypeOf(resp)
|
||||||
|
modelType := reflect.TypeOf(model).Elem()
|
||||||
|
|
||||||
|
mdl := modelValue.Elem()
|
||||||
|
|
||||||
|
for i := 0; i < modelType.NumField(); i++ {
|
||||||
|
f := modelType.Field(i)
|
||||||
|
if field, ok := responseType.FieldByName(f.Name); ok {
|
||||||
|
nameField := mdl.FieldByName(f.Name)
|
||||||
|
switch f.Type {
|
||||||
|
case reflect.TypeOf(basetypes.StringValue{}):
|
||||||
|
var s *string
|
||||||
|
if nameField.IsValid() && nameField.CanSet() && (field.Type == reflect.TypeOf(s) || field.Type.Kind() == reflect.TypeOf(s).Kind()) {
|
||||||
|
nameField.Set(
|
||||||
|
reflect.ValueOf(
|
||||||
|
types.StringValue(
|
||||||
|
responseValue.FieldByName(f.Name).Elem().String())))
|
||||||
|
} else {
|
||||||
|
fmt.Printf("[ERR] field types differ: %s vs %s\n", field.Type, reflect.TypeOf(s))
|
||||||
|
}
|
||||||
|
case reflect.TypeOf(basetypes.BoolValue{}):
|
||||||
|
var s *bool
|
||||||
|
if nameField.IsValid() && nameField.CanSet() && (field.Type == reflect.TypeOf(s) || field.Type.Kind() == reflect.TypeOf(s).Kind()) {
|
||||||
|
if !responseValue.FieldByName(f.Name).IsZero() {
|
||||||
|
nameField.Set(
|
||||||
|
reflect.ValueOf(
|
||||||
|
types.BoolValue(
|
||||||
|
responseValue.FieldByName(f.Name).Elem().Bool(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
nameField.Set(
|
||||||
|
reflect.ValueOf(
|
||||||
|
types.BoolValue(
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fmt.Printf("[ERR] field types differ: %s vs %s\n", field.Type, reflect.TypeOf(s))
|
||||||
|
}
|
||||||
|
case reflect.TypeOf(basetypes.Int32Value{}):
|
||||||
|
case reflect.TypeOf(basetypes.Int64Value{}):
|
||||||
|
var i32 *int32
|
||||||
|
var i64 *int64
|
||||||
|
if nameField.IsValid() && nameField.CanSet() && (field.Type.Kind() == reflect.TypeOf(i32).Kind() || field.Type.Kind() == reflect.TypeOf(i64).Kind()) {
|
||||||
|
if !responseValue.FieldByName(f.Name).IsZero() {
|
||||||
|
nameField.Set(
|
||||||
|
reflect.ValueOf(
|
||||||
|
types.Int64Value(
|
||||||
|
responseValue.FieldByName(f.Name).Elem().Int(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
nameField.Set(
|
||||||
|
reflect.ValueOf(
|
||||||
|
types.Int64Value(
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fmt.Printf("[ERR] field types differ: %s vs %s or %s\n", field.Type, reflect.TypeOf(i32), reflect.TypeOf(i64))
|
||||||
|
}
|
||||||
|
case reflect.TypeOf(basetypes.ObjectValue{}):
|
||||||
|
fmt.Printf("have an object: %s\n", f.Name)
|
||||||
|
resField := responseValue.FieldByName(f.Name)
|
||||||
|
if !resField.IsZero() {
|
||||||
|
for z := 0; z < field.Type.Elem().NumField(); z++ {
|
||||||
|
rF := field.Type.Elem().Field(z)
|
||||||
|
fmt.Printf("field: %s (%s)\n", rF.Name, rF.Type)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fmt.Printf("field is zero")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
101
tmp/main.go
Normal file
101
tmp/main.go
Normal file
|
|
@ -0,0 +1,101 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/attr"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
|
||||||
|
"github.com/mhenselin/terraform-provider-stackitprivatepreview/pkg/postgresflexalpha"
|
||||||
|
"github.com/mhenselin/terraform-provider-stackitprivatepreview/pkg/responseMapper"
|
||||||
|
"github.com/mhenselin/terraform-provider-stackitprivatepreview/tmp/temp"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Model struct {
|
||||||
|
Id types.String `tfsdk:"id"` // needed by TF
|
||||||
|
InstanceId types.String `tfsdk:"instance_id"`
|
||||||
|
ProjectId types.String `tfsdk:"project_id"`
|
||||||
|
Name types.String `tfsdk:"name"`
|
||||||
|
BackupSchedule types.String `tfsdk:"backup_schedule"`
|
||||||
|
FlavorId types.String `tfsdk:"flavor_id"`
|
||||||
|
Replicas types.Int64 `tfsdk:"replicas"`
|
||||||
|
RetentionDays types.Int64 `tfsdk:"retention_days"`
|
||||||
|
Storage types.Object `tfsdk:"storage"`
|
||||||
|
Version types.String `tfsdk:"version"`
|
||||||
|
Region types.String `tfsdk:"region"`
|
||||||
|
Encryption types.Object `tfsdk:"encryption"`
|
||||||
|
Network types.Object `tfsdk:"network"`
|
||||||
|
IsDeletable types.Bool `tfsdk:"is_deletable"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func Ptr[T any](val T) *T {
|
||||||
|
return &val
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
resp := postgresflexalpha.GetInstanceResponse{
|
||||||
|
BackupSchedule: Ptr("backupSchedule"),
|
||||||
|
FlavorId: Ptr("2.4"),
|
||||||
|
Id: Ptr("myId"),
|
||||||
|
IsDeletable: Ptr(true),
|
||||||
|
Encryption: &postgresflexalpha.InstanceEncryption{
|
||||||
|
KekKeyId: Ptr("myKekKeyId"),
|
||||||
|
KekKeyRingId: nil,
|
||||||
|
KekKeyVersion: nil,
|
||||||
|
ServiceAccount: nil,
|
||||||
|
},
|
||||||
|
Name: Ptr("NameFromMe"),
|
||||||
|
Network: &postgresflexalpha.InstanceNetwork{
|
||||||
|
AccessScope: postgresflexalpha.InstanceNetworkGetAccessScopeAttributeType(Ptr("PUBLIC")),
|
||||||
|
Acl: &[]string{"0.0.0.0/0"},
|
||||||
|
InstanceAddress: Ptr("10.0.0.1"),
|
||||||
|
RouterAddress: Ptr("192.168.0.1"),
|
||||||
|
},
|
||||||
|
Replicas: postgresflexalpha.GetInstanceResponseGetReplicasAttributeType(Ptr(int32(7))),
|
||||||
|
RetentionDays: Ptr(int64(42)),
|
||||||
|
Status: postgresflexalpha.GetInstanceResponseGetStatusAttributeType(Ptr("READY")),
|
||||||
|
Storage: &postgresflexalpha.Storage{
|
||||||
|
PerformanceClass: Ptr("class007"),
|
||||||
|
Size: Ptr(int64(123)),
|
||||||
|
},
|
||||||
|
Version: Ptr("11"),
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("======== TEST 1 ========")
|
||||||
|
enc, _ := basetypes.NewObjectValue(map[string]attr.Type{"id": types.StringType}, map[string]attr.Value{"id": basetypes.NewStringValue("")})
|
||||||
|
storage, _ := basetypes.NewObjectValue(map[string]attr.Type{"id": types.StringType}, map[string]attr.Value{"id": basetypes.NewStringValue("")})
|
||||||
|
net, _ := basetypes.NewObjectValue(map[string]attr.Type{"id": types.StringType}, map[string]attr.Value{"id": basetypes.NewStringValue("")})
|
||||||
|
model := Model{
|
||||||
|
Id: basetypes.NewStringValue(""),
|
||||||
|
InstanceId: basetypes.NewStringValue(""),
|
||||||
|
ProjectId: basetypes.NewStringValue(""),
|
||||||
|
Name: basetypes.NewStringValue(""),
|
||||||
|
BackupSchedule: basetypes.NewStringValue(""),
|
||||||
|
FlavorId: basetypes.NewStringValue(""),
|
||||||
|
Replicas: basetypes.NewInt64Value(0),
|
||||||
|
RetentionDays: basetypes.NewInt64Value(0),
|
||||||
|
Storage: storage,
|
||||||
|
Version: basetypes.NewStringValue(""),
|
||||||
|
Region: basetypes.NewStringValue(""),
|
||||||
|
Encryption: enc,
|
||||||
|
Network: net,
|
||||||
|
}
|
||||||
|
err := responseMapper.ToModel(ctx, resp, &model)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Printf("model: %s (%+v)\n", reflect.TypeOf(model), model)
|
||||||
|
|
||||||
|
fmt.Println("======== TEST 2 ========")
|
||||||
|
model2 := temp.InstanceModel{}
|
||||||
|
err = responseMapper.ToModel(ctx, resp, &model2)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Printf("model: %s (%+v)\n", reflect.TypeOf(model2), model2)
|
||||||
|
|
||||||
|
}
|
||||||
1597
tmp/temp/instance_resource_gen.go
Normal file
1597
tmp/temp/instance_resource_gen.go
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue