fix: add missing functions
This commit is contained in:
parent
b08b32ef1d
commit
76b61859da
11 changed files with 940 additions and 214 deletions
|
|
@ -193,7 +193,7 @@ type DefaultApi interface {
|
||||||
@param region The region which should be addressed
|
@param region The region which should be addressed
|
||||||
@return ApiGetFlavorsRequestRequest
|
@return ApiGetFlavorsRequestRequest
|
||||||
*/
|
*/
|
||||||
GetFlavorsRequest(ctx context.Context, projectId string, region string) ApiGetFlavorsRequestRequest
|
GetFlavorsRequest(ctx context.Context, projectId string, region string, page, size *int64, sort *FlavorSort) ApiGetFlavorsRequestRequest
|
||||||
/*
|
/*
|
||||||
GetFlavorsRequestExecute executes the request
|
GetFlavorsRequestExecute executes the request
|
||||||
|
|
||||||
|
|
@ -203,7 +203,7 @@ type DefaultApi interface {
|
||||||
@return GetFlavorsResponse
|
@return GetFlavorsResponse
|
||||||
|
|
||||||
*/
|
*/
|
||||||
GetFlavorsRequestExecute(ctx context.Context, projectId string, region string) (*GetFlavorsResponse, error)
|
GetFlavorsRequestExecute(ctx context.Context, projectId string, region string, page, size *int64, sort *FlavorSort) (*GetFlavorsResponse, error)
|
||||||
/*
|
/*
|
||||||
GetInstanceRequest Get Specific Instance
|
GetInstanceRequest Get Specific Instance
|
||||||
Get information about a specific available instance
|
Get information about a specific available instance
|
||||||
|
|
@ -2520,7 +2520,7 @@ Get all available flavors for a project.
|
||||||
@param region The region which should be addressed
|
@param region The region which should be addressed
|
||||||
@return ApiGetFlavorsRequestRequest
|
@return ApiGetFlavorsRequestRequest
|
||||||
*/
|
*/
|
||||||
func (a *APIClient) GetFlavorsRequest(ctx context.Context, projectId string, region string) ApiGetFlavorsRequestRequest {
|
func (a *APIClient) GetFlavorsRequest(ctx context.Context, projectId string, region string, page, size *int64, sort *FlavorSort) ApiGetFlavorsRequestRequest {
|
||||||
return GetFlavorsRequestRequest{
|
return GetFlavorsRequestRequest{
|
||||||
apiService: a.defaultApi,
|
apiService: a.defaultApi,
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
|
|
@ -2529,7 +2529,7 @@ func (a *APIClient) GetFlavorsRequest(ctx context.Context, projectId string, reg
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *APIClient) GetFlavorsRequestExecute(ctx context.Context, projectId string, region string) (*GetFlavorsResponse, error) {
|
func (a *APIClient) GetFlavorsRequestExecute(ctx context.Context, projectId string, region string, page, size *int64, sort *FlavorSort) (*GetFlavorsResponse, error) {
|
||||||
r := GetFlavorsRequestRequest{
|
r := GetFlavorsRequestRequest{
|
||||||
apiService: a.defaultApi,
|
apiService: a.defaultApi,
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
|
|
|
||||||
|
|
@ -221,6 +221,26 @@ func setGetInstanceResponseGetStorageAttributeType(arg *GetInstanceResponseGetSt
|
||||||
*arg = &val
|
*arg = &val
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
types and functions for encryption
|
||||||
|
*/
|
||||||
|
|
||||||
|
// isModel
|
||||||
|
type GetInstanceResponseGetEncryptionAttributeType = *InstanceEncryption
|
||||||
|
type GetInstanceResponseGetEncryptionArgType = InstanceEncryption
|
||||||
|
type GetInstanceResponseGetEncryptionRetType = InstanceEncryption
|
||||||
|
|
||||||
|
func getGetInstanceResponseGetEncryptionAttributeTypeOk(arg GetInstanceResponseGetEncryptionAttributeType) (ret GetInstanceResponseGetEncryptionRetType, ok bool) {
|
||||||
|
if arg == nil {
|
||||||
|
return ret, false
|
||||||
|
}
|
||||||
|
return *arg, true
|
||||||
|
}
|
||||||
|
|
||||||
|
func setGetInstanceResponseGetEncryptionAttributeType(arg *GetInstanceResponseGetEncryptionAttributeType, val GetInstanceResponseGetEncryptionRetType) {
|
||||||
|
*arg = &val
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
types and functions for version
|
types and functions for version
|
||||||
*/
|
*/
|
||||||
|
|
@ -256,6 +276,7 @@ type GetInstanceResponse struct {
|
||||||
// Whether the instance can be deleted or not.
|
// Whether the instance can be deleted or not.
|
||||||
// REQUIRED
|
// REQUIRED
|
||||||
IsDeletable GetInstanceResponsegetIsDeletableAttributeType `json:"isDeletable" required:"true"`
|
IsDeletable GetInstanceResponsegetIsDeletableAttributeType `json:"isDeletable" required:"true"`
|
||||||
|
Encryption GetInstanceResponseGetEncryptionAttributeType `json:"encryption,omitempty"`
|
||||||
// The name of the instance.
|
// The name of the instance.
|
||||||
// REQUIRED
|
// REQUIRED
|
||||||
Name GetInstanceResponseGetNameAttributeType `json:"name" required:"true"`
|
Name GetInstanceResponseGetNameAttributeType `json:"name" required:"true"`
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ package wait
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"math"
|
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
|
@ -144,16 +143,15 @@ func TestCreateInstanceWaitHandler(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(
|
t.Run(tt.desc, func(t *testing.T) {
|
||||||
tt.desc, func(t *testing.T) {
|
instanceId := "foo-bar"
|
||||||
instanceId := "foo-bar"
|
|
||||||
|
|
||||||
apiClient := &apiClientInstanceMocked{
|
apiClient := &apiClientInstanceMocked{
|
||||||
instanceId: instanceId,
|
instanceId: instanceId,
|
||||||
instanceState: tt.instanceState,
|
instanceState: tt.instanceState,
|
||||||
instanceGetFails: tt.instanceGetFails,
|
instanceGetFails: tt.instanceGetFails,
|
||||||
usersGetErrorStatus: tt.usersGetErrorStatus,
|
usersGetErrorStatus: tt.usersGetErrorStatus,
|
||||||
}
|
}
|
||||||
|
|
||||||
var wantRes *postgresflex.GetInstanceResponse
|
var wantRes *postgresflex.GetInstanceResponse
|
||||||
if tt.wantResp {
|
if tt.wantResp {
|
||||||
|
|
@ -172,8 +170,8 @@ func TestCreateInstanceWaitHandler(t *testing.T) {
|
||||||
if !cmp.Equal(gotRes, wantRes) {
|
if !cmp.Equal(gotRes, wantRes) {
|
||||||
t.Fatalf("handler gotRes = %v, want %v", gotRes, wantRes)
|
t.Fatalf("handler gotRes = %v, want %v", gotRes, wantRes)
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
)
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -221,15 +219,14 @@ func TestUpdateInstanceWaitHandler(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(
|
t.Run(tt.desc, func(t *testing.T) {
|
||||||
tt.desc, func(t *testing.T) {
|
instanceId := "foo-bar"
|
||||||
instanceId := "foo-bar"
|
|
||||||
|
|
||||||
apiClient := &apiClientInstanceMocked{
|
apiClient := &apiClientInstanceMocked{
|
||||||
instanceId: instanceId,
|
instanceId: instanceId,
|
||||||
instanceState: tt.instanceState,
|
instanceState: tt.instanceState,
|
||||||
instanceGetFails: tt.instanceGetFails,
|
instanceGetFails: tt.instanceGetFails,
|
||||||
}
|
}
|
||||||
|
|
||||||
var wantRes *postgresflex.GetInstanceResponse
|
var wantRes *postgresflex.GetInstanceResponse
|
||||||
if tt.wantResp {
|
if tt.wantResp {
|
||||||
|
|
@ -248,8 +245,8 @@ func TestUpdateInstanceWaitHandler(t *testing.T) {
|
||||||
if !cmp.Equal(gotRes, wantRes) {
|
if !cmp.Equal(gotRes, wantRes) {
|
||||||
t.Fatalf("handler gotRes = %v, want %v", gotRes, wantRes)
|
t.Fatalf("handler gotRes = %v, want %v", gotRes, wantRes)
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
)
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -378,22 +375,22 @@ func TestDeleteUserWaitHandler(t *testing.T) {
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.desc, func(t *testing.T) {
|
t.Run(tt.desc, func(t *testing.T) {
|
||||||
userId := "foo-bar"
|
userId := int64(1001)
|
||||||
|
|
||||||
apiClient := &apiClientUserMocked{
|
apiClient := &apiClientUserMocked{
|
||||||
getFails: tt.getFails,
|
getFails: tt.getFails,
|
||||||
userId: userId,
|
userId: userId,
|
||||||
isUserDeleted: !tt.deleteFails,
|
isUserDeleted: !tt.deleteFails,
|
||||||
}
|
}
|
||||||
|
|
||||||
handler := DeleteUserWaitHandler(context.Background(), apiClient, "", "", "", userId)
|
handler := DeleteUserWaitHandler(context.Background(), apiClient, "", "", "", userId)
|
||||||
|
|
||||||
_, err := handler.SetTimeout(10 * time.Millisecond).WaitWithContext(context.Background())
|
_, err := handler.SetTimeout(10 * time.Millisecond).WaitWithContext(context.Background())
|
||||||
|
|
||||||
if (err != nil) != tt.wantErr {
|
if (err != nil) != tt.wantErr {
|
||||||
t.Fatalf("handler error = %v, wantErr %v", err, tt.wantErr)
|
t.Fatalf("handler error = %v, wantErr %v", err, tt.wantErr)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
resource "stackitprivatepreview_postgresflexalpha_instance" "ptlsdbsrv" {
|
resource "stackitprivatepreview_postgresflexalpha_instance" "ptlsdbsrv" {
|
||||||
project_id = var.project_id
|
project_id = var.project_id
|
||||||
name = "pgsql-example-instance"
|
name = "pgsql-example-instance"
|
||||||
acl = ["0.0.0.0/0"]
|
|
||||||
backup_schedule = "0 0 * * *"
|
backup_schedule = "0 0 * * *"
|
||||||
flavor = {
|
flavor = {
|
||||||
cpu = 2
|
cpu = 2
|
||||||
|
|
@ -29,7 +28,7 @@ resource "stackitprivatepreview_postgresflexalpha_instance" "ptlsdbsrv" {
|
||||||
|
|
||||||
data "stackitprivatepreview_postgresflexalpha_instance" "datapsql" {
|
data "stackitprivatepreview_postgresflexalpha_instance" "datapsql" {
|
||||||
project_id = var.project_id
|
project_id = var.project_id
|
||||||
instance_id = "e0c028e0-a201-4b75-8ee5-50a0ad17b0d7"
|
instance_id = "fdb6573e-2dea-4e1d-a638-9157cf90c3ba"
|
||||||
region = "eu01"
|
region = "eu01"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
502
stackit/internal/services/postgresflexalpha/flavor.go
Normal file
502
stackit/internal/services/postgresflexalpha/flavor.go
Normal file
|
|
@ -0,0 +1,502 @@
|
||||||
|
package postgresflex
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/attr"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/diag"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
|
||||||
|
"github.com/hashicorp/terraform-plugin-go/tftypes"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ basetypes.ObjectTypable = FlavorType{}
|
||||||
|
|
||||||
|
type FlavorType struct {
|
||||||
|
basetypes.ObjectType
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t FlavorType) Equal(o attr.Type) bool {
|
||||||
|
other, ok := o.(FlavorType)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return t.ObjectType.Equal(other.ObjectType)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t FlavorType) String() string {
|
||||||
|
return "FlavorType"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t FlavorType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) {
|
||||||
|
var diags diag.Diagnostics
|
||||||
|
|
||||||
|
attributes := in.Attributes()
|
||||||
|
|
||||||
|
cpuAttribute, ok := attributes["cpu"]
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
diags.AddError(
|
||||||
|
"Attribute Missing",
|
||||||
|
`cpu is missing from object`)
|
||||||
|
|
||||||
|
return nil, diags
|
||||||
|
}
|
||||||
|
|
||||||
|
cpuVal, ok := cpuAttribute.(basetypes.Int64Value)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
diags.AddError(
|
||||||
|
"Attribute Wrong Type",
|
||||||
|
fmt.Sprintf(`cpu expected to be basetypes.Int64Value, was: %T`, cpuAttribute))
|
||||||
|
}
|
||||||
|
|
||||||
|
descriptionAttribute, ok := attributes["description"]
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
diags.AddError(
|
||||||
|
"Attribute Missing",
|
||||||
|
`description is missing from object`)
|
||||||
|
|
||||||
|
return nil, diags
|
||||||
|
}
|
||||||
|
|
||||||
|
descriptionVal, ok := descriptionAttribute.(basetypes.StringValue)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
diags.AddError(
|
||||||
|
"Attribute Wrong Type",
|
||||||
|
fmt.Sprintf(`description expected to be basetypes.StringValue, was: %T`, descriptionAttribute))
|
||||||
|
}
|
||||||
|
|
||||||
|
idAttribute, ok := attributes["id"]
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
diags.AddError(
|
||||||
|
"Attribute Missing",
|
||||||
|
`id is missing from object`)
|
||||||
|
|
||||||
|
return nil, diags
|
||||||
|
}
|
||||||
|
|
||||||
|
idVal, ok := idAttribute.(basetypes.StringValue)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
diags.AddError(
|
||||||
|
"Attribute Wrong Type",
|
||||||
|
fmt.Sprintf(`id expected to be basetypes.StringValue, was: %T`, idAttribute))
|
||||||
|
}
|
||||||
|
|
||||||
|
memoryAttribute, ok := attributes["memory"]
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
diags.AddError(
|
||||||
|
"Attribute Missing",
|
||||||
|
`memory is missing from object`)
|
||||||
|
|
||||||
|
return nil, diags
|
||||||
|
}
|
||||||
|
|
||||||
|
ramVal, ok := memoryAttribute.(basetypes.Int64Value)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
diags.AddError(
|
||||||
|
"Attribute Wrong Type",
|
||||||
|
fmt.Sprintf(`memory expected to be basetypes.Int64Value, was: %T`, memoryAttribute))
|
||||||
|
}
|
||||||
|
|
||||||
|
if diags.HasError() {
|
||||||
|
return nil, diags
|
||||||
|
}
|
||||||
|
|
||||||
|
return FlavorValue{
|
||||||
|
Cpu: cpuVal,
|
||||||
|
Description: descriptionVal,
|
||||||
|
Id: idVal,
|
||||||
|
Ram: ramVal,
|
||||||
|
state: attr.ValueStateKnown,
|
||||||
|
}, diags
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewFlavorValueNull() FlavorValue {
|
||||||
|
return FlavorValue{
|
||||||
|
state: attr.ValueStateNull,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewFlavorValueUnknown() FlavorValue {
|
||||||
|
return FlavorValue{
|
||||||
|
state: attr.ValueStateUnknown,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewFlavorValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (FlavorValue, 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 FlavorValue Attribute Value",
|
||||||
|
"While creating a FlavorValue value, a missing attribute value was detected. "+
|
||||||
|
"A FlavorValue 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("FlavorValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()),
|
||||||
|
)
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if !attributeType.Equal(attribute.Type(ctx)) {
|
||||||
|
diags.AddError(
|
||||||
|
"Invalid FlavorValue Attribute Type",
|
||||||
|
"While creating a FlavorValue value, an invalid attribute value was detected. "+
|
||||||
|
"A FlavorValue 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("FlavorValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+
|
||||||
|
fmt.Sprintf("FlavorValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for name := range attributes {
|
||||||
|
_, ok := attributeTypes[name]
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
diags.AddError(
|
||||||
|
"Extra FlavorValue Attribute Value",
|
||||||
|
"While creating a FlavorValue value, an extra attribute value was detected. "+
|
||||||
|
"A FlavorValue 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 FlavorValue Attribute Name: %s", name),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if diags.HasError() {
|
||||||
|
return NewFlavorValueUnknown(), diags
|
||||||
|
}
|
||||||
|
|
||||||
|
cpuAttribute, ok := attributes["cpu"]
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
diags.AddError(
|
||||||
|
"Attribute Missing",
|
||||||
|
`cpu is missing from object`)
|
||||||
|
|
||||||
|
return NewFlavorValueUnknown(), diags
|
||||||
|
}
|
||||||
|
|
||||||
|
cpuVal, ok := cpuAttribute.(basetypes.Int64Value)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
diags.AddError(
|
||||||
|
"Attribute Wrong Type",
|
||||||
|
fmt.Sprintf(`cpu expected to be basetypes.Int64Value, was: %T`, cpuAttribute))
|
||||||
|
}
|
||||||
|
|
||||||
|
descriptionAttribute, ok := attributes["description"]
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
diags.AddError(
|
||||||
|
"Attribute Missing",
|
||||||
|
`description is missing from object`)
|
||||||
|
|
||||||
|
return NewFlavorValueUnknown(), diags
|
||||||
|
}
|
||||||
|
|
||||||
|
descriptionVal, ok := descriptionAttribute.(basetypes.StringValue)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
diags.AddError(
|
||||||
|
"Attribute Wrong Type",
|
||||||
|
fmt.Sprintf(`description expected to be basetypes.StringValue, was: %T`, descriptionAttribute))
|
||||||
|
}
|
||||||
|
|
||||||
|
idAttribute, ok := attributes["id"]
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
diags.AddError(
|
||||||
|
"Attribute Missing",
|
||||||
|
`id is missing from object`)
|
||||||
|
|
||||||
|
return NewFlavorValueUnknown(), diags
|
||||||
|
}
|
||||||
|
|
||||||
|
idVal, ok := idAttribute.(basetypes.StringValue)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
diags.AddError(
|
||||||
|
"Attribute Wrong Type",
|
||||||
|
fmt.Sprintf(`id expected to be basetypes.StringValue, was: %T`, idAttribute))
|
||||||
|
}
|
||||||
|
|
||||||
|
memoryAttribute, ok := attributes["memory"]
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
diags.AddError(
|
||||||
|
"Attribute Missing",
|
||||||
|
`memory is missing from object`)
|
||||||
|
|
||||||
|
return NewFlavorValueUnknown(), diags
|
||||||
|
}
|
||||||
|
|
||||||
|
memoryVal, ok := memoryAttribute.(basetypes.Int64Value)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
diags.AddError(
|
||||||
|
"Attribute Wrong Type",
|
||||||
|
fmt.Sprintf(`memory expected to be basetypes.Int64Value, was: %T`, memoryAttribute))
|
||||||
|
}
|
||||||
|
|
||||||
|
if diags.HasError() {
|
||||||
|
return NewFlavorValueUnknown(), diags
|
||||||
|
}
|
||||||
|
|
||||||
|
return FlavorValue{
|
||||||
|
Cpu: cpuVal,
|
||||||
|
Description: descriptionVal,
|
||||||
|
Id: idVal,
|
||||||
|
Ram: memoryVal,
|
||||||
|
state: attr.ValueStateKnown,
|
||||||
|
}, diags
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewFlavorValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) FlavorValue {
|
||||||
|
object, diags := NewFlavorValue(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("NewFlavorValueMust received error(s): " + strings.Join(diagsStrings, "\n"))
|
||||||
|
}
|
||||||
|
|
||||||
|
return object
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t FlavorType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) {
|
||||||
|
if in.Type() == nil {
|
||||||
|
return NewFlavorValueNull(), 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 NewFlavorValueUnknown(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if in.IsNull() {
|
||||||
|
return NewFlavorValueNull(), 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 NewFlavorValueMust(FlavorValue{}.AttributeTypes(ctx), attributes), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t FlavorType) ValueType(ctx context.Context) attr.Value {
|
||||||
|
return FlavorValue{}
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ basetypes.ObjectValuable = FlavorValue{}
|
||||||
|
|
||||||
|
type FlavorValue struct {
|
||||||
|
Cpu basetypes.Int64Value `tfsdk:"cpu"`
|
||||||
|
Description basetypes.StringValue `tfsdk:"description"`
|
||||||
|
Id basetypes.StringValue `tfsdk:"id"`
|
||||||
|
Ram basetypes.Int64Value `tfsdk:"ram"`
|
||||||
|
state attr.ValueState
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v FlavorValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) {
|
||||||
|
attrTypes := make(map[string]tftypes.Type, 4)
|
||||||
|
|
||||||
|
var val tftypes.Value
|
||||||
|
var err error
|
||||||
|
|
||||||
|
attrTypes["cpu"] = basetypes.Int64Type{}.TerraformType(ctx)
|
||||||
|
attrTypes["description"] = basetypes.StringType{}.TerraformType(ctx)
|
||||||
|
attrTypes["id"] = basetypes.StringType{}.TerraformType(ctx)
|
||||||
|
attrTypes["memory"] = basetypes.Int64Type{}.TerraformType(ctx)
|
||||||
|
|
||||||
|
objectType := tftypes.Object{AttributeTypes: attrTypes}
|
||||||
|
|
||||||
|
switch v.state {
|
||||||
|
case attr.ValueStateKnown:
|
||||||
|
vals := make(map[string]tftypes.Value, 4)
|
||||||
|
|
||||||
|
val, err = v.Cpu.ToTerraformValue(ctx)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return tftypes.NewValue(objectType, tftypes.UnknownValue), err
|
||||||
|
}
|
||||||
|
|
||||||
|
vals["cpu"] = val
|
||||||
|
|
||||||
|
val, err = v.Description.ToTerraformValue(ctx)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return tftypes.NewValue(objectType, tftypes.UnknownValue), err
|
||||||
|
}
|
||||||
|
|
||||||
|
vals["description"] = val
|
||||||
|
|
||||||
|
val, err = v.Id.ToTerraformValue(ctx)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return tftypes.NewValue(objectType, tftypes.UnknownValue), err
|
||||||
|
}
|
||||||
|
|
||||||
|
vals["id"] = val
|
||||||
|
|
||||||
|
val, err = v.Ram.ToTerraformValue(ctx)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return tftypes.NewValue(objectType, tftypes.UnknownValue), err
|
||||||
|
}
|
||||||
|
|
||||||
|
vals["memory"] = 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 FlavorValue) IsNull() bool {
|
||||||
|
return v.state == attr.ValueStateNull
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v FlavorValue) IsUnknown() bool {
|
||||||
|
return v.state == attr.ValueStateUnknown
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v FlavorValue) String() string {
|
||||||
|
return "FlavorValue"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v FlavorValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) {
|
||||||
|
var diags diag.Diagnostics
|
||||||
|
|
||||||
|
attributeTypes := map[string]attr.Type{
|
||||||
|
"cpu": basetypes.Int64Type{},
|
||||||
|
"description": basetypes.StringType{},
|
||||||
|
"id": basetypes.StringType{},
|
||||||
|
"memory": basetypes.Int64Type{},
|
||||||
|
}
|
||||||
|
|
||||||
|
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{
|
||||||
|
"cpu": v.Cpu,
|
||||||
|
"description": v.Description,
|
||||||
|
"id": v.Id,
|
||||||
|
"memory": v.Ram,
|
||||||
|
})
|
||||||
|
|
||||||
|
return objVal, diags
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v FlavorValue) Equal(o attr.Value) bool {
|
||||||
|
other, ok := o.(FlavorValue)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if v.state != other.state {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if v.state != attr.ValueStateKnown {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if !v.Cpu.Equal(other.Cpu) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if !v.Description.Equal(other.Description) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if !v.Id.Equal(other.Id) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if !v.Ram.Equal(other.Ram) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v FlavorValue) Type(ctx context.Context) attr.Type {
|
||||||
|
return FlavorType{
|
||||||
|
basetypes.ObjectType{
|
||||||
|
AttrTypes: v.AttributeTypes(ctx),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v FlavorValue) AttributeTypes(ctx context.Context) map[string]attr.Type {
|
||||||
|
return map[string]attr.Type{
|
||||||
|
"cpu": basetypes.Int64Type{},
|
||||||
|
"description": basetypes.StringType{},
|
||||||
|
"id": basetypes.StringType{},
|
||||||
|
"memory": basetypes.Int64Type{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -60,7 +60,7 @@ func (r *instanceDataSource) Configure(ctx context.Context, req datasource.Confi
|
||||||
}
|
}
|
||||||
|
|
||||||
// Schema defines the schema for the data source.
|
// Schema defines the schema for the data source.
|
||||||
func (r *instanceDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
|
func (r *instanceDataSource) Schema(ctx context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
|
||||||
descriptions := map[string]string{
|
descriptions := map[string]string{
|
||||||
"main": "Postgres Flex instance data source schema. Must have a `region` specified in the provider configuration.",
|
"main": "Postgres Flex instance data source schema. Must have a `region` specified in the provider configuration.",
|
||||||
"id": "Terraform's internal data source. ID. It is structured as \"`project_id`,`region`,`instance_id`\".",
|
"id": "Terraform's internal data source. ID. It is structured as \"`project_id`,`region`,`instance_id`\".",
|
||||||
|
|
@ -98,11 +98,6 @@ func (r *instanceDataSource) Schema(_ context.Context, _ datasource.SchemaReques
|
||||||
Description: descriptions["name"],
|
Description: descriptions["name"],
|
||||||
Computed: true,
|
Computed: true,
|
||||||
},
|
},
|
||||||
"acl": schema.ListAttribute{
|
|
||||||
Description: descriptions["acl"],
|
|
||||||
ElementType: types.StringType,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"backup_schedule": schema.StringAttribute{
|
"backup_schedule": schema.StringAttribute{
|
||||||
Computed: true,
|
Computed: true,
|
||||||
},
|
},
|
||||||
|
|
@ -121,7 +116,15 @@ func (r *instanceDataSource) Schema(_ context.Context, _ datasource.SchemaReques
|
||||||
"ram": schema.Int64Attribute{
|
"ram": schema.Int64Attribute{
|
||||||
Computed: true,
|
Computed: true,
|
||||||
},
|
},
|
||||||
|
"node_type": schema.StringAttribute{
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
//CustomType: postgresflex.FlavorType{
|
||||||
|
// ObjectType: types.ObjectType{
|
||||||
|
// AttrTypes: postgresflex.FlavorValue{}.AttributeTypes(ctx),
|
||||||
|
// },
|
||||||
|
//},
|
||||||
},
|
},
|
||||||
"replicas": schema.Int64Attribute{
|
"replicas": schema.Int64Attribute{
|
||||||
Computed: true,
|
Computed: true,
|
||||||
|
|
@ -146,7 +149,7 @@ func (r *instanceDataSource) Schema(_ context.Context, _ datasource.SchemaReques
|
||||||
Description: descriptions["region"],
|
Description: descriptions["region"],
|
||||||
},
|
},
|
||||||
"encryption": schema.SingleNestedAttribute{
|
"encryption": schema.SingleNestedAttribute{
|
||||||
Required: true,
|
Computed: true,
|
||||||
Attributes: map[string]schema.Attribute{
|
Attributes: map[string]schema.Attribute{
|
||||||
"key_id": schema.StringAttribute{
|
"key_id": schema.StringAttribute{
|
||||||
Description: descriptions["key_id"],
|
Description: descriptions["key_id"],
|
||||||
|
|
@ -236,13 +239,30 @@ func (r *instanceDataSource) Read(ctx context.Context, req datasource.ReadReques
|
||||||
}
|
}
|
||||||
|
|
||||||
var flavor = &flavorModel{}
|
var flavor = &flavorModel{}
|
||||||
|
if instanceResp != nil && instanceResp.FlavorId != nil {
|
||||||
|
flavor.Id = types.StringValue(*instanceResp.FlavorId)
|
||||||
|
}
|
||||||
|
|
||||||
if !(model.Flavor.IsNull() || model.Flavor.IsUnknown()) {
|
if !(model.Flavor.IsNull() || model.Flavor.IsUnknown()) {
|
||||||
diags = model.Flavor.As(ctx, flavor, basetypes.ObjectAsOptions{})
|
diags = model.Flavor.As(ctx, flavor, basetypes.ObjectAsOptions{})
|
||||||
resp.Diagnostics.Append(diags...)
|
resp.Diagnostics.Append(diags...)
|
||||||
if resp.Diagnostics.HasError() {
|
if resp.Diagnostics.HasError() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err := getFlavorModelById(ctx, r.client, &model, flavor)
|
||||||
|
if err != nil {
|
||||||
|
resp.Diagnostics.AddError(err.Error(), err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
diags = model.Flavor.As(ctx, flavor, basetypes.ObjectAsOptions{})
|
||||||
|
resp.Diagnostics.Append(diags...)
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var storage = &storageModel{}
|
var storage = &storageModel{}
|
||||||
if !(model.Storage.IsNull() || model.Storage.IsUnknown()) {
|
if !(model.Storage.IsNull() || model.Storage.IsUnknown()) {
|
||||||
diags = model.Storage.As(ctx, storage, basetypes.ObjectAsOptions{})
|
diags = model.Storage.As(ctx, storage, basetypes.ObjectAsOptions{})
|
||||||
|
|
@ -261,7 +281,16 @@ func (r *instanceDataSource) Read(ctx context.Context, req datasource.ReadReques
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = mapFields(ctx, instanceResp, &model, flavor, storage, network, region)
|
var encryption = &encryptionModel{}
|
||||||
|
if !(model.Encryption.IsNull() || model.Encryption.IsUnknown()) {
|
||||||
|
diags = model.Encryption.As(ctx, encryption, basetypes.ObjectAsOptions{})
|
||||||
|
resp.Diagnostics.Append(diags...)
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = mapFields(ctx, instanceResp, &model, flavor, storage, encryption, network, region)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading instance", fmt.Sprintf("Processing API payload: %v", err))
|
core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading instance", fmt.Sprintf("Processing API payload: %v", err))
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package postgresflexalpha
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-framework/attr"
|
"github.com/hashicorp/terraform-plugin-framework/attr"
|
||||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||||
|
|
@ -13,10 +14,19 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type postgresflexClient interface {
|
type postgresflexClient interface {
|
||||||
GetFlavorsRequestExecute(ctx context.Context, projectId string, region string) (*postgresflex.GetFlavorsResponse, error)
|
GetFlavorsRequestExecute(ctx context.Context, projectId string, region string, page, size *int64, sort *postgresflex.FlavorSort) (*postgresflex.GetFlavorsResponse, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func mapFields(ctx context.Context, resp *postgresflex.GetInstanceResponse, model *Model, flavor *flavorModel, storage *storageModel, network *networkModel, region string) error {
|
func mapFields(
|
||||||
|
ctx context.Context,
|
||||||
|
resp *postgresflex.GetInstanceResponse,
|
||||||
|
model *Model,
|
||||||
|
flavor *flavorModel,
|
||||||
|
storage *storageModel,
|
||||||
|
encryption *encryptionModel,
|
||||||
|
network *networkModel,
|
||||||
|
region string,
|
||||||
|
) error {
|
||||||
if resp == nil {
|
if resp == nil {
|
||||||
return fmt.Errorf("response input is nil")
|
return fmt.Errorf("response input is nil")
|
||||||
}
|
}
|
||||||
|
|
@ -34,28 +44,26 @@ func mapFields(ctx context.Context, resp *postgresflex.GetInstanceResponse, mode
|
||||||
return fmt.Errorf("instance id not present")
|
return fmt.Errorf("instance id not present")
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
var encryptionValues map[string]attr.Value
|
||||||
|
if instance.Encryption == nil {
|
||||||
var aclList basetypes.ListValue
|
encryptionValues = map[string]attr.Value{
|
||||||
var diags diag.Diagnostics
|
"keyring_id": encryption.KeyRingId,
|
||||||
if instance.Acl == nil {
|
"key_id": encryption.KeyId,
|
||||||
aclList = types.ListNull(types.StringType)
|
"key_version": encryption.KeyVersion,
|
||||||
} else {
|
"service_account": encryption.ServiceAccount,
|
||||||
respACL := *instance.Acl
|
|
||||||
modelACL, err := utils.ListValuetoStringSlice(model.ACL)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
reconciledACL := utils.ReconcileStringSlices(modelACL, respACL)
|
|
||||||
|
|
||||||
aclList, diags = types.ListValueFrom(ctx, types.StringType, reconciledACL)
|
|
||||||
if diags.HasError() {
|
|
||||||
return fmt.Errorf("mapping ACL: %w", core.DiagsToError(diags))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
*/
|
encryptionValues = map[string]attr.Value{
|
||||||
|
"keyring_id": types.StringValue(*instance.Encryption.KekKeyRingId),
|
||||||
|
"key_id": types.StringValue(*instance.Encryption.KekKeyId),
|
||||||
|
"key_version": types.StringValue(*instance.Encryption.KekKeyVersion),
|
||||||
|
"service_account": types.StringValue(*instance.Encryption.ServiceAccount),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
encryptionObject, diags := types.ObjectValue(encryptionTypes, encryptionValues)
|
||||||
|
if diags.HasError() {
|
||||||
|
return fmt.Errorf("creating encryption: %w", core.DiagsToError(diags))
|
||||||
|
}
|
||||||
|
|
||||||
var networkValues map[string]attr.Value
|
var networkValues map[string]attr.Value
|
||||||
if instance.Network == nil {
|
if instance.Network == nil {
|
||||||
|
|
@ -93,21 +101,25 @@ func mapFields(ctx context.Context, resp *postgresflex.GetInstanceResponse, mode
|
||||||
|
|
||||||
var flavorValues map[string]attr.Value
|
var flavorValues map[string]attr.Value
|
||||||
if instance.FlavorId == nil {
|
if instance.FlavorId == nil {
|
||||||
|
return fmt.Errorf("instance has no flavor id")
|
||||||
|
}
|
||||||
|
if !flavor.Id.IsUnknown() && !flavor.Id.IsNull() {
|
||||||
|
if *instance.FlavorId != flavor.Id.ValueString() {
|
||||||
|
return fmt.Errorf("instance has different flavor id %s - %s", *instance.FlavorId, flavor.Id.ValueString())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if model.Flavor.IsNull() || model.Flavor.IsUnknown() {
|
||||||
flavorValues = map[string]attr.Value{
|
flavorValues = map[string]attr.Value{
|
||||||
"id": flavor.Id,
|
"id": flavor.Id,
|
||||||
"description": flavor.Description,
|
"description": flavor.Description,
|
||||||
"cpu": flavor.CPU,
|
"cpu": flavor.CPU,
|
||||||
"ram": flavor.RAM,
|
"ram": flavor.RAM,
|
||||||
|
"node_type": flavor.NodeType,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// TODO @mhenselin
|
flavorValues = model.Flavor.Attributes()
|
||||||
// flavorValues = map[string]attr.Value{
|
|
||||||
// "id": types.StringValue(*instance.FlavorId),
|
|
||||||
// "description": types.StringValue(*instance.FlavorId.Description),
|
|
||||||
// "cpu": types.Int64PointerValue(instance.FlavorId.Cpu),
|
|
||||||
// "ram": types.Int64PointerValue(instance.FlavorId.Memory),
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
flavorObject, diags := types.ObjectValue(flavorTypes, flavorValues)
|
flavorObject, diags := types.ObjectValue(flavorTypes, flavorValues)
|
||||||
if diags.HasError() {
|
if diags.HasError() {
|
||||||
return fmt.Errorf("creating flavor: %w", core.DiagsToError(diags))
|
return fmt.Errorf("creating flavor: %w", core.DiagsToError(diags))
|
||||||
|
|
@ -133,7 +145,6 @@ func mapFields(ctx context.Context, resp *postgresflex.GetInstanceResponse, mode
|
||||||
model.Id = utils.BuildInternalTerraformId(model.ProjectId.ValueString(), region, instanceId)
|
model.Id = utils.BuildInternalTerraformId(model.ProjectId.ValueString(), region, instanceId)
|
||||||
model.InstanceId = types.StringValue(instanceId)
|
model.InstanceId = types.StringValue(instanceId)
|
||||||
model.Name = types.StringPointerValue(instance.Name)
|
model.Name = types.StringPointerValue(instance.Name)
|
||||||
// model.ACL = aclList
|
|
||||||
model.Network = networkObject
|
model.Network = networkObject
|
||||||
model.BackupSchedule = types.StringPointerValue(instance.BackupSchedule)
|
model.BackupSchedule = types.StringPointerValue(instance.BackupSchedule)
|
||||||
model.Flavor = flavorObject
|
model.Flavor = flavorObject
|
||||||
|
|
@ -142,18 +153,15 @@ func mapFields(ctx context.Context, resp *postgresflex.GetInstanceResponse, mode
|
||||||
model.Storage = storageObject
|
model.Storage = storageObject
|
||||||
model.Version = types.StringPointerValue(instance.Version)
|
model.Version = types.StringPointerValue(instance.Version)
|
||||||
model.Region = types.StringValue(region)
|
model.Region = types.StringValue(region)
|
||||||
//model.Encryption = types.ObjectValue()
|
model.Encryption = encryptionObject
|
||||||
//model.Network = networkModel
|
model.Network = networkObject
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func toCreatePayload(model *Model, acl []string, flavor *flavorModel, storage *storageModel, enc *encryptionModel, net *networkModel) (*postgresflex.CreateInstanceRequestPayload, error) {
|
func toCreatePayload(model *Model, flavor *flavorModel, storage *storageModel, enc *encryptionModel, net *networkModel) (*postgresflex.CreateInstanceRequestPayload, error) {
|
||||||
if model == nil {
|
if model == nil {
|
||||||
return nil, fmt.Errorf("nil model")
|
return nil, fmt.Errorf("nil model")
|
||||||
}
|
}
|
||||||
if acl == nil {
|
|
||||||
return nil, fmt.Errorf("nil acl")
|
|
||||||
}
|
|
||||||
if flavor == nil {
|
if flavor == nil {
|
||||||
return nil, fmt.Errorf("nil flavor")
|
return nil, fmt.Errorf("nil flavor")
|
||||||
}
|
}
|
||||||
|
|
@ -162,46 +170,57 @@ func toCreatePayload(model *Model, acl []string, flavor *flavorModel, storage *s
|
||||||
}
|
}
|
||||||
|
|
||||||
replVal := int32(model.Replicas.ValueInt64())
|
replVal := int32(model.Replicas.ValueInt64())
|
||||||
|
|
||||||
|
storagePayload := &postgresflex.CreateInstanceRequestPayloadGetStorageArgType{
|
||||||
|
PerformanceClass: conversion.StringValueToPointer(storage.Class),
|
||||||
|
Size: conversion.Int64ValueToPointer(storage.Size),
|
||||||
|
}
|
||||||
|
|
||||||
|
encryptionPayload := &postgresflex.CreateInstanceRequestPayloadGetEncryptionArgType{}
|
||||||
|
if enc != nil {
|
||||||
|
encryptionPayload.KekKeyId = conversion.StringValueToPointer(enc.KeyId)
|
||||||
|
encryptionPayload.KekKeyVersion = conversion.StringValueToPointer(enc.KeyVersion)
|
||||||
|
encryptionPayload.KekKeyRingId = conversion.StringValueToPointer(enc.KeyRingId)
|
||||||
|
encryptionPayload.ServiceAccount = conversion.StringValueToPointer(enc.ServiceAccount)
|
||||||
|
}
|
||||||
|
|
||||||
|
var aclElements []string
|
||||||
|
if net != nil && !(net.ACL.IsNull() || net.ACL.IsUnknown()) {
|
||||||
|
aclElements = make([]string, 0, len(net.ACL.Elements()))
|
||||||
|
diags := net.ACL.ElementsAs(context.TODO(), &aclElements, false)
|
||||||
|
if diags.HasError() {
|
||||||
|
return nil, fmt.Errorf("creating network: %w", core.DiagsToError(diags))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
networkPayload := &postgresflex.CreateInstanceRequestPayloadGetNetworkArgType{}
|
||||||
|
if net != nil {
|
||||||
|
networkPayload = &postgresflex.CreateInstanceRequestPayloadGetNetworkArgType{
|
||||||
|
AccessScope: postgresflex.InstanceNetworkGetAccessScopeAttributeType(conversion.StringValueToPointer(net.AccessScope)),
|
||||||
|
Acl: &aclElements,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return &postgresflex.CreateInstanceRequestPayload{
|
return &postgresflex.CreateInstanceRequestPayload{
|
||||||
// TODO - verify working
|
|
||||||
//Acl: &[]string{
|
|
||||||
// strings.Join(acl, ","),
|
|
||||||
//},
|
|
||||||
BackupSchedule: conversion.StringValueToPointer(model.BackupSchedule),
|
BackupSchedule: conversion.StringValueToPointer(model.BackupSchedule),
|
||||||
FlavorId: conversion.StringValueToPointer(flavor.Id),
|
FlavorId: conversion.StringValueToPointer(flavor.Id),
|
||||||
Name: conversion.StringValueToPointer(model.Name),
|
Name: conversion.StringValueToPointer(model.Name),
|
||||||
// TODO - verify working
|
// TODO - verify working
|
||||||
Replicas: postgresflex.CreateInstanceRequestPayloadGetReplicasAttributeType(&replVal),
|
Replicas: postgresflex.CreateInstanceRequestPayloadGetReplicasAttributeType(&replVal),
|
||||||
// TODO - verify working
|
Storage: storagePayload,
|
||||||
Storage: postgresflex.CreateInstanceRequestPayloadGetStorageAttributeType(&postgresflex.Storage{
|
Version: conversion.StringValueToPointer(model.Version),
|
||||||
PerformanceClass: conversion.StringValueToPointer(storage.Class),
|
Encryption: encryptionPayload,
|
||||||
Size: conversion.Int64ValueToPointer(storage.Size),
|
Network: networkPayload,
|
||||||
}),
|
|
||||||
Version: conversion.StringValueToPointer(model.Version),
|
|
||||||
// TODO - verify working
|
|
||||||
Encryption: postgresflex.CreateInstanceRequestPayloadGetEncryptionAttributeType(
|
|
||||||
&postgresflex.InstanceEncryption{
|
|
||||||
KekKeyId: conversion.StringValueToPointer(enc.KeyId), // model.Encryption.Attributes(),
|
|
||||||
KekKeyRingId: conversion.StringValueToPointer(enc.KeyRingId),
|
|
||||||
KekKeyVersion: conversion.StringValueToPointer(enc.KeyVersion),
|
|
||||||
ServiceAccount: conversion.StringValueToPointer(enc.ServiceAccount),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
Network: &postgresflex.InstanceNetwork{
|
|
||||||
AccessScope: postgresflex.InstanceNetworkGetAccessScopeAttributeType(
|
|
||||||
conversion.StringValueToPointer(net.AccessScope),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func toUpdatePayload(model *Model, acl []string, flavor *flavorModel, storage *storageModel) (*postgresflex.UpdateInstancePartiallyRequestPayload, error) {
|
func toUpdatePayload(model *Model, flavor *flavorModel, storage *storageModel, network *networkModel) (*postgresflex.UpdateInstancePartiallyRequestPayload, error) {
|
||||||
if model == nil {
|
if model == nil {
|
||||||
return nil, fmt.Errorf("nil model")
|
return nil, fmt.Errorf("nil model")
|
||||||
}
|
}
|
||||||
if acl == nil {
|
// if acl == nil {
|
||||||
return nil, fmt.Errorf("nil acl")
|
// return nil, fmt.Errorf("nil acl")
|
||||||
}
|
// }
|
||||||
if flavor == nil {
|
if flavor == nil {
|
||||||
return nil, fmt.Errorf("nil flavor")
|
return nil, fmt.Errorf("nil flavor")
|
||||||
}
|
}
|
||||||
|
|
@ -224,7 +243,7 @@ func toUpdatePayload(model *Model, acl []string, flavor *flavorModel, storage *s
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadFlavorId(ctx context.Context, client postgresflexClient, model *Model, flavor *flavorModel) error {
|
func loadFlavorId(ctx context.Context, client postgresflexClient, model *Model, flavor *flavorModel, storage *storageModel) error {
|
||||||
if model == nil {
|
if model == nil {
|
||||||
return fmt.Errorf("nil model")
|
return fmt.Errorf("nil model")
|
||||||
}
|
}
|
||||||
|
|
@ -239,28 +258,61 @@ func loadFlavorId(ctx context.Context, client postgresflexClient, model *Model,
|
||||||
if ram == nil {
|
if ram == nil {
|
||||||
return fmt.Errorf("nil RAM")
|
return fmt.Errorf("nil RAM")
|
||||||
}
|
}
|
||||||
|
nodeType := conversion.StringValueToPointer(flavor.NodeType)
|
||||||
|
if nodeType == nil {
|
||||||
|
return fmt.Errorf("nil NodeType")
|
||||||
|
}
|
||||||
|
storageClass := conversion.StringValueToPointer(storage.Class)
|
||||||
|
if storageClass == nil {
|
||||||
|
return fmt.Errorf("nil StorageClass")
|
||||||
|
}
|
||||||
|
storageSize := conversion.Int64ValueToPointer(storage.Size)
|
||||||
|
if storageSize == nil {
|
||||||
|
return fmt.Errorf("nil StorageSize")
|
||||||
|
}
|
||||||
|
|
||||||
projectId := model.ProjectId.ValueString()
|
projectId := model.ProjectId.ValueString()
|
||||||
region := model.Region.ValueString()
|
region := model.Region.ValueString()
|
||||||
res, err := client.GetFlavorsRequestExecute(ctx, projectId, region)
|
|
||||||
|
flavorList, err := getAllFlavors(ctx, client, projectId, region)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("listing postgresflex flavors: %w", err)
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
avl := ""
|
avl := ""
|
||||||
if res.Flavors == nil {
|
foundFlavorCount := 0
|
||||||
return fmt.Errorf("finding flavors for project %s", projectId)
|
for _, f := range flavorList {
|
||||||
}
|
|
||||||
for _, f := range *res.Flavors {
|
|
||||||
if f.Id == nil || f.Cpu == nil || f.Memory == nil {
|
if f.Id == nil || f.Cpu == nil || f.Memory == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if !strings.EqualFold(*f.NodeType, *nodeType) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
if *f.Cpu == *cpu && *f.Memory == *ram {
|
if *f.Cpu == *cpu && *f.Memory == *ram {
|
||||||
|
var useSc *postgresflex.FlavorStorageClassesStorageClass
|
||||||
|
for _, sc := range *f.StorageClasses {
|
||||||
|
if *sc.Class != *storageClass {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if *storageSize < *f.MinGB || *storageSize > *f.MaxGB {
|
||||||
|
return fmt.Errorf("storage size %d out of bounds (min: %d - max: %d)", *storageSize, *f.MinGB, *f.MaxGB)
|
||||||
|
}
|
||||||
|
useSc = &sc
|
||||||
|
}
|
||||||
|
if useSc == nil {
|
||||||
|
return fmt.Errorf("no storage class found for %s", *storageClass)
|
||||||
|
}
|
||||||
|
|
||||||
flavor.Id = types.StringValue(*f.Id)
|
flavor.Id = types.StringValue(*f.Id)
|
||||||
flavor.Description = types.StringValue(*f.Description)
|
flavor.Description = types.StringValue(*f.Description)
|
||||||
break
|
foundFlavorCount++
|
||||||
}
|
}
|
||||||
avl = fmt.Sprintf("%s\n- %d CPU, %d GB RAM", avl, *f.Cpu, *f.Memory)
|
for _, cls := range *f.StorageClasses {
|
||||||
|
avl = fmt.Sprintf("%s\n- %d CPU, %d GB RAM, storage %s (min: %d - max: %d)", avl, *f.Cpu, *f.Memory, *cls.Class, *f.MinGB, *f.MaxGB)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if foundFlavorCount > 1 {
|
||||||
|
return fmt.Errorf("multiple flavors found: %d flavors", foundFlavorCount)
|
||||||
}
|
}
|
||||||
if flavor.Id.ValueString() == "" {
|
if flavor.Id.ValueString() == "" {
|
||||||
return fmt.Errorf("couldn't find flavor, available specs are:%s", avl)
|
return fmt.Errorf("couldn't find flavor, available specs are:%s", avl)
|
||||||
|
|
@ -268,3 +320,75 @@ func loadFlavorId(ctx context.Context, client postgresflexClient, model *Model,
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getAllFlavors(ctx context.Context, client postgresflexClient, projectId, region string) ([]postgresflex.ListFlavors, error) {
|
||||||
|
if projectId == "" || region == "" {
|
||||||
|
return nil, fmt.Errorf("listing postgresflex flavors: projectId and region are required")
|
||||||
|
}
|
||||||
|
var flavorList []postgresflex.ListFlavors
|
||||||
|
|
||||||
|
page := int64(1)
|
||||||
|
size := int64(10)
|
||||||
|
for {
|
||||||
|
sort := postgresflex.FLAVORSORT_INDEX_ASC
|
||||||
|
res, err := client.GetFlavorsRequestExecute(ctx, projectId, region, &page, &size, &sort)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("listing postgresflex flavors: %w", err)
|
||||||
|
}
|
||||||
|
if res.Flavors == nil {
|
||||||
|
return nil, fmt.Errorf("finding flavors for project %s", projectId)
|
||||||
|
}
|
||||||
|
pagination := res.GetPagination()
|
||||||
|
flavorList = append(flavorList, *res.Flavors...)
|
||||||
|
|
||||||
|
if *pagination.TotalRows == int64(len(flavorList)) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
page++
|
||||||
|
}
|
||||||
|
return flavorList, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getFlavorModelById(ctx context.Context, client postgresflexClient, model *Model, flavor *flavorModel) error {
|
||||||
|
if model == nil {
|
||||||
|
return fmt.Errorf("nil model")
|
||||||
|
}
|
||||||
|
if flavor == nil {
|
||||||
|
return fmt.Errorf("nil flavor")
|
||||||
|
}
|
||||||
|
id := conversion.StringValueToPointer(flavor.Id)
|
||||||
|
if id == nil {
|
||||||
|
return fmt.Errorf("nil flavor ID")
|
||||||
|
}
|
||||||
|
|
||||||
|
flavor.Id = types.StringValue("")
|
||||||
|
|
||||||
|
projectId := model.ProjectId.ValueString()
|
||||||
|
region := model.Region.ValueString()
|
||||||
|
|
||||||
|
flavorList, err := getAllFlavors(ctx, client, projectId, region)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
avl := ""
|
||||||
|
for _, f := range flavorList {
|
||||||
|
if f.Id == nil || f.Cpu == nil || f.Memory == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if *f.Id == *id {
|
||||||
|
flavor.Id = types.StringValue(*f.Id)
|
||||||
|
flavor.Description = types.StringValue(*f.Description)
|
||||||
|
flavor.CPU = types.Int64Value(*f.Cpu)
|
||||||
|
flavor.RAM = types.Int64Value(*f.Memory)
|
||||||
|
flavor.NodeType = types.StringValue(*f.NodeType)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
avl = fmt.Sprintf("%s\n- %d CPU, %d GB RAM", avl, *f.Cpu, *f.Memory)
|
||||||
|
}
|
||||||
|
if flavor.Id.ValueString() == "" {
|
||||||
|
return fmt.Errorf("couldn't find flavor, available specs are: %s", avl)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,14 +8,14 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-framework/resource/schema/listplanmodifier"
|
|
||||||
//postgresflex "github.com/mhenselin/terraform-provider-stackitprivatepreview/pkg/postgresflexalpha"
|
|
||||||
postgresflex "github.com/mhenselin/terraform-provider-stackitprivatepreview/pkg/postgresflexalpha"
|
postgresflex "github.com/mhenselin/terraform-provider-stackitprivatepreview/pkg/postgresflexalpha"
|
||||||
"github.com/mhenselin/terraform-provider-stackitprivatepreview/pkg/postgresflexalpha/wait"
|
"github.com/mhenselin/terraform-provider-stackitprivatepreview/pkg/postgresflexalpha/wait"
|
||||||
postgresflexUtils "github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit/internal/services/postgresflexalpha/utils"
|
postgresflexUtils "github.com/mhenselin/terraform-provider-stackitprivatepreview/stackit/internal/services/postgresflexalpha/utils"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
|
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
|
||||||
"github.com/hashicorp/terraform-plugin-framework/attr"
|
"github.com/hashicorp/terraform-plugin-framework/attr"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/resource/schema/listplanmodifier"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault"
|
||||||
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
||||||
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
|
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
|
||||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||||
|
|
@ -46,7 +46,6 @@ type Model struct {
|
||||||
InstanceId types.String `tfsdk:"instance_id"`
|
InstanceId types.String `tfsdk:"instance_id"`
|
||||||
ProjectId types.String `tfsdk:"project_id"`
|
ProjectId types.String `tfsdk:"project_id"`
|
||||||
Name types.String `tfsdk:"name"`
|
Name types.String `tfsdk:"name"`
|
||||||
ACL types.List `tfsdk:"acl"`
|
|
||||||
BackupSchedule types.String `tfsdk:"backup_schedule"`
|
BackupSchedule types.String `tfsdk:"backup_schedule"`
|
||||||
Flavor types.Object `tfsdk:"flavor"`
|
Flavor types.Object `tfsdk:"flavor"`
|
||||||
Replicas types.Int64 `tfsdk:"replicas"`
|
Replicas types.Int64 `tfsdk:"replicas"`
|
||||||
|
|
@ -91,6 +90,7 @@ type flavorModel struct {
|
||||||
Description types.String `tfsdk:"description"`
|
Description types.String `tfsdk:"description"`
|
||||||
CPU types.Int64 `tfsdk:"cpu"`
|
CPU types.Int64 `tfsdk:"cpu"`
|
||||||
RAM types.Int64 `tfsdk:"ram"`
|
RAM types.Int64 `tfsdk:"ram"`
|
||||||
|
NodeType types.String `tfsdk:"node_type"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Types corresponding to flavorModel
|
// Types corresponding to flavorModel
|
||||||
|
|
@ -99,6 +99,7 @@ var flavorTypes = map[string]attr.Type{
|
||||||
"description": basetypes.StringType{},
|
"description": basetypes.StringType{},
|
||||||
"cpu": basetypes.Int64Type{},
|
"cpu": basetypes.Int64Type{},
|
||||||
"ram": basetypes.Int64Type{},
|
"ram": basetypes.Int64Type{},
|
||||||
|
"node_type": basetypes.StringType{},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Struct corresponding to Model.Storage
|
// Struct corresponding to Model.Storage
|
||||||
|
|
@ -178,17 +179,18 @@ func (r *instanceResource) Configure(ctx context.Context, req resource.Configure
|
||||||
// Schema defines the schema for the resource.
|
// Schema defines the schema for the resource.
|
||||||
func (r *instanceResource) Schema(_ context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
|
func (r *instanceResource) Schema(_ context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
|
||||||
descriptions := map[string]string{
|
descriptions := map[string]string{
|
||||||
"main": "Postgres Flex instance resource schema. Must have a `region` specified in the provider configuration.",
|
"backup_schedule": "The schedule for on what time and how often the database backup will be created. The schedule is written as a cron schedule.",
|
||||||
"id": "Terraform's internal resource ID. It is structured as \"`project_id`,`region`,`instance_id`\".",
|
"main": "Postgres Flex instance resource schema. Must have a `region` specified in the provider configuration.",
|
||||||
"instance_id": "ID of the PostgresFlex instance.",
|
"id": "Terraform's internal resource ID. It is structured as \"`project_id`,`region`,`instance_id`\".",
|
||||||
"project_id": "STACKIT project ID to which the instance is associated.",
|
"instance_id": "ID of the PostgresFlex instance.",
|
||||||
"name": "Instance name.",
|
"project_id": "STACKIT project ID to which the instance is associated.",
|
||||||
"acl": "The Access Control List (ACL) for the PostgresFlex instance.",
|
"name": "Instance name.",
|
||||||
"region": "The resource region. If not defined, the provider region is used.",
|
"acl": "The Access Control List (ACL) for the PostgresFlex instance.",
|
||||||
"encryption": "The encryption block.",
|
"region": "The resource region. If not defined, the provider region is used.",
|
||||||
"key_id": "Key ID of the encryption key.",
|
"encryption": "The encryption block.",
|
||||||
// TODO @mhenselin - do the rest
|
"key_id": "Key ID of the encryption key.",
|
||||||
}
|
}
|
||||||
|
// TODO @mhenselin - do the rest
|
||||||
|
|
||||||
resp.Schema = schema.Schema{
|
resp.Schema = schema.Schema{
|
||||||
Description: descriptions["main"],
|
Description: descriptions["main"],
|
||||||
|
|
@ -234,11 +236,6 @@ func (r *instanceResource) Schema(_ context.Context, req resource.SchemaRequest,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"acl": schema.ListAttribute{
|
|
||||||
Description: descriptions["acl"],
|
|
||||||
ElementType: types.StringType,
|
|
||||||
Required: true,
|
|
||||||
},
|
|
||||||
"backup_schedule": schema.StringAttribute{
|
"backup_schedule": schema.StringAttribute{
|
||||||
Required: true,
|
Required: true,
|
||||||
},
|
},
|
||||||
|
|
@ -247,8 +244,10 @@ func (r *instanceResource) Schema(_ context.Context, req resource.SchemaRequest,
|
||||||
Attributes: map[string]schema.Attribute{
|
Attributes: map[string]schema.Attribute{
|
||||||
"id": schema.StringAttribute{
|
"id": schema.StringAttribute{
|
||||||
Computed: true,
|
Computed: true,
|
||||||
|
Optional: true,
|
||||||
PlanModifiers: []planmodifier.String{
|
PlanModifiers: []planmodifier.String{
|
||||||
UseStateForUnknownIfFlavorUnchanged(req),
|
UseStateForUnknownIfFlavorUnchanged(req),
|
||||||
|
stringplanmodifier.RequiresReplace(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"description": schema.StringAttribute{
|
"description": schema.StringAttribute{
|
||||||
|
|
@ -350,14 +349,19 @@ func (r *instanceResource) Schema(_ context.Context, req resource.SchemaRequest,
|
||||||
Required: true,
|
Required: true,
|
||||||
Attributes: map[string]schema.Attribute{
|
Attributes: map[string]schema.Attribute{
|
||||||
"access_scope": schema.StringAttribute{
|
"access_scope": schema.StringAttribute{
|
||||||
|
Default: stringdefault.StaticString(
|
||||||
|
"PUBLIC",
|
||||||
|
),
|
||||||
Description: descriptions["access_scope"],
|
Description: descriptions["access_scope"],
|
||||||
Required: true,
|
Computed: true,
|
||||||
|
Optional: true,
|
||||||
PlanModifiers: []planmodifier.String{
|
PlanModifiers: []planmodifier.String{
|
||||||
stringplanmodifier.RequiresReplace(),
|
stringplanmodifier.RequiresReplace(),
|
||||||
stringplanmodifier.UseStateForUnknown(),
|
stringplanmodifier.UseStateForUnknown(),
|
||||||
},
|
},
|
||||||
Validators: []validator.String{
|
Validators: []validator.String{
|
||||||
validate.NoSeparator(),
|
validate.NoSeparator(),
|
||||||
|
stringvalidator.OneOf("SNA", "PUBLIC"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"acl": schema.ListAttribute{
|
"acl": schema.ListAttribute{
|
||||||
|
|
@ -371,6 +375,7 @@ func (r *instanceResource) Schema(_ context.Context, req resource.SchemaRequest,
|
||||||
"instance_address": schema.StringAttribute{
|
"instance_address": schema.StringAttribute{
|
||||||
Description: descriptions["instance_address"],
|
Description: descriptions["instance_address"],
|
||||||
Computed: true,
|
Computed: true,
|
||||||
|
Optional: true,
|
||||||
PlanModifiers: []planmodifier.String{
|
PlanModifiers: []planmodifier.String{
|
||||||
stringplanmodifier.UseStateForUnknown(),
|
stringplanmodifier.UseStateForUnknown(),
|
||||||
},
|
},
|
||||||
|
|
@ -378,6 +383,7 @@ func (r *instanceResource) Schema(_ context.Context, req resource.SchemaRequest,
|
||||||
"router_address": schema.StringAttribute{
|
"router_address": schema.StringAttribute{
|
||||||
Description: descriptions["router_address"],
|
Description: descriptions["router_address"],
|
||||||
Computed: true,
|
Computed: true,
|
||||||
|
Optional: true,
|
||||||
PlanModifiers: []planmodifier.String{
|
PlanModifiers: []planmodifier.String{
|
||||||
stringplanmodifier.UseStateForUnknown(),
|
stringplanmodifier.UseStateForUnknown(),
|
||||||
},
|
},
|
||||||
|
|
@ -409,27 +415,6 @@ func (r *instanceResource) Create(ctx context.Context, req resource.CreateReques
|
||||||
ctx = tflog.SetField(ctx, "project_id", projectId)
|
ctx = tflog.SetField(ctx, "project_id", projectId)
|
||||||
ctx = tflog.SetField(ctx, "region", region)
|
ctx = tflog.SetField(ctx, "region", region)
|
||||||
|
|
||||||
var acl []string
|
|
||||||
if !(model.ACL.IsNull() || model.ACL.IsUnknown()) {
|
|
||||||
diags = model.ACL.ElementsAs(ctx, &acl, false)
|
|
||||||
resp.Diagnostics.Append(diags...)
|
|
||||||
if resp.Diagnostics.HasError() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var flavor = &flavorModel{}
|
|
||||||
if !(model.Flavor.IsNull() || model.Flavor.IsUnknown()) {
|
|
||||||
diags = model.Flavor.As(ctx, flavor, basetypes.ObjectAsOptions{})
|
|
||||||
resp.Diagnostics.Append(diags...)
|
|
||||||
if resp.Diagnostics.HasError() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
err := loadFlavorId(ctx, r.client, &model, flavor)
|
|
||||||
if err != nil {
|
|
||||||
core.LogAndAddError(ctx, &resp.Diagnostics, "Error creating instance", fmt.Sprintf("Loading flavor ID: %v", err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var storage = &storageModel{}
|
var storage = &storageModel{}
|
||||||
if !(model.Storage.IsNull() || model.Storage.IsUnknown()) {
|
if !(model.Storage.IsNull() || model.Storage.IsUnknown()) {
|
||||||
diags = model.Storage.As(ctx, storage, basetypes.ObjectAsOptions{})
|
diags = model.Storage.As(ctx, storage, basetypes.ObjectAsOptions{})
|
||||||
|
|
@ -439,6 +424,42 @@ func (r *instanceResource) Create(ctx context.Context, req resource.CreateReques
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var flavor = &flavorModel{}
|
||||||
|
if !(model.Flavor.IsNull() || model.Flavor.IsUnknown()) {
|
||||||
|
diags = model.Flavor.As(ctx, flavor, basetypes.ObjectAsOptions{})
|
||||||
|
resp.Diagnostics.Append(diags...)
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err := loadFlavorId(ctx, r.client, &model, flavor, storage)
|
||||||
|
if err != nil {
|
||||||
|
core.LogAndAddError(ctx, &resp.Diagnostics, "Error creating instance", fmt.Sprintf("Loading flavor ID: %v", err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if flavor.Id.IsNull() || flavor.Id.IsUnknown() {
|
||||||
|
err := loadFlavorId(ctx, r.client, &model, flavor, storage)
|
||||||
|
if err != nil {
|
||||||
|
resp.Diagnostics.AddError(err.Error(), err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
flavorValues := map[string]attr.Value{
|
||||||
|
"id": flavor.Id,
|
||||||
|
"description": flavor.Description,
|
||||||
|
"cpu": flavor.CPU,
|
||||||
|
"ram": flavor.RAM,
|
||||||
|
"node_type": flavor.NodeType,
|
||||||
|
}
|
||||||
|
var flavorObject basetypes.ObjectValue
|
||||||
|
flavorObject, diags = types.ObjectValue(flavorTypes, flavorValues)
|
||||||
|
resp.Diagnostics.Append(diags...)
|
||||||
|
if diags.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
model.Flavor = flavorObject
|
||||||
|
}
|
||||||
|
|
||||||
var encryption = &encryptionModel{}
|
var encryption = &encryptionModel{}
|
||||||
if !(model.Encryption.IsNull() || model.Encryption.IsUnknown()) {
|
if !(model.Encryption.IsNull() || model.Encryption.IsUnknown()) {
|
||||||
diags = model.Encryption.As(ctx, encryption, basetypes.ObjectAsOptions{})
|
diags = model.Encryption.As(ctx, encryption, basetypes.ObjectAsOptions{})
|
||||||
|
|
@ -457,8 +478,17 @@ func (r *instanceResource) Create(ctx context.Context, req resource.CreateReques
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var acl []string
|
||||||
|
if !(network.ACL.IsNull() || network.ACL.IsUnknown()) {
|
||||||
|
diags = network.ACL.ElementsAs(ctx, &acl, false)
|
||||||
|
resp.Diagnostics.Append(diags...)
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Generate API request body from model
|
// Generate API request body from model
|
||||||
payload, err := toCreatePayload(&model, acl, flavor, storage, encryption, network)
|
payload, err := toCreatePayload(&model, flavor, storage, encryption, network)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
core.LogAndAddError(ctx, &resp.Diagnostics, "Error creating instance", fmt.Sprintf("Creating API payload: %v", err))
|
core.LogAndAddError(ctx, &resp.Diagnostics, "Error creating instance", fmt.Sprintf("Creating API payload: %v", err))
|
||||||
return
|
return
|
||||||
|
|
@ -487,7 +517,7 @@ func (r *instanceResource) Create(ctx context.Context, req resource.CreateReques
|
||||||
}
|
}
|
||||||
|
|
||||||
// Map response body to schema
|
// Map response body to schema
|
||||||
err = mapFields(ctx, waitResp, &model, flavor, storage, network, region)
|
err = mapFields(ctx, waitResp, &model, flavor, storage, encryption, network, region)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
core.LogAndAddError(ctx, &resp.Diagnostics, "Error creating instance", fmt.Sprintf("Processing API payload: %v", err))
|
core.LogAndAddError(ctx, &resp.Diagnostics, "Error creating instance", fmt.Sprintf("Processing API payload: %v", err))
|
||||||
return
|
return
|
||||||
|
|
@ -545,6 +575,15 @@ func (r *instanceResource) Read(ctx context.Context, req resource.ReadRequest, r
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var encryption = &encryptionModel{}
|
||||||
|
if !(model.Encryption.IsNull() || model.Encryption.IsUnknown()) {
|
||||||
|
diags = model.Encryption.As(ctx, encryption, basetypes.ObjectAsOptions{})
|
||||||
|
resp.Diagnostics.Append(diags...)
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
instanceResp, err := r.client.GetInstanceRequest(ctx, projectId, region, instanceId).Execute()
|
instanceResp, err := r.client.GetInstanceRequest(ctx, projectId, region, instanceId).Execute()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
oapiErr, ok := err.(*oapierror.GenericOpenAPIError) //nolint:errorlint //complaining that error.As should be used to catch wrapped errors, but this error should not be wrapped
|
oapiErr, ok := err.(*oapierror.GenericOpenAPIError) //nolint:errorlint //complaining that error.As should be used to catch wrapped errors, but this error should not be wrapped
|
||||||
|
|
@ -564,7 +603,7 @@ func (r *instanceResource) Read(ctx context.Context, req resource.ReadRequest, r
|
||||||
}
|
}
|
||||||
|
|
||||||
// Map response body to schema
|
// Map response body to schema
|
||||||
err = mapFields(ctx, instanceResp, &model, flavor, storage, network, region)
|
err = mapFields(ctx, instanceResp, &model, flavor, storage, encryption, network, region)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading instance", fmt.Sprintf("Processing API payload: %v", err))
|
core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading instance", fmt.Sprintf("Processing API payload: %v", err))
|
||||||
return
|
return
|
||||||
|
|
@ -597,27 +636,15 @@ func (r *instanceResource) Update(ctx context.Context, req resource.UpdateReques
|
||||||
ctx = tflog.SetField(ctx, "instance_id", instanceId)
|
ctx = tflog.SetField(ctx, "instance_id", instanceId)
|
||||||
ctx = tflog.SetField(ctx, "region", region)
|
ctx = tflog.SetField(ctx, "region", region)
|
||||||
|
|
||||||
var acl []string
|
//var acl []string
|
||||||
if !(model.ACL.IsNull() || model.ACL.IsUnknown()) {
|
//if !(model.ACL.IsNull() || model.ACL.IsUnknown()) {
|
||||||
diags = model.ACL.ElementsAs(ctx, &acl, false)
|
// diags = model.ACL.ElementsAs(ctx, &acl, false)
|
||||||
resp.Diagnostics.Append(diags...)
|
// resp.Diagnostics.Append(diags...)
|
||||||
if resp.Diagnostics.HasError() {
|
// if resp.Diagnostics.HasError() {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
var flavor = &flavorModel{}
|
|
||||||
if !(model.Flavor.IsNull() || model.Flavor.IsUnknown()) {
|
|
||||||
diags = model.Flavor.As(ctx, flavor, basetypes.ObjectAsOptions{})
|
|
||||||
resp.Diagnostics.Append(diags...)
|
|
||||||
if resp.Diagnostics.HasError() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
err := loadFlavorId(ctx, r.client, &model, flavor)
|
|
||||||
if err != nil {
|
|
||||||
core.LogAndAddError(ctx, &resp.Diagnostics, "Error updating instance", fmt.Sprintf("Loading flavor ID: %v", err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var storage = &storageModel{}
|
var storage = &storageModel{}
|
||||||
if !(model.Storage.IsNull() || model.Storage.IsUnknown()) {
|
if !(model.Storage.IsNull() || model.Storage.IsUnknown()) {
|
||||||
diags = model.Storage.As(ctx, storage, basetypes.ObjectAsOptions{})
|
diags = model.Storage.As(ctx, storage, basetypes.ObjectAsOptions{})
|
||||||
|
|
@ -627,8 +654,40 @@ func (r *instanceResource) Update(ctx context.Context, req resource.UpdateReques
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var flavor = &flavorModel{}
|
||||||
|
if !(model.Flavor.IsNull() || model.Flavor.IsUnknown()) {
|
||||||
|
diags = model.Flavor.As(ctx, flavor, basetypes.ObjectAsOptions{})
|
||||||
|
resp.Diagnostics.Append(diags...)
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err := loadFlavorId(ctx, r.client, &model, flavor, storage)
|
||||||
|
if err != nil {
|
||||||
|
core.LogAndAddError(ctx, &resp.Diagnostics, "Error updating instance", fmt.Sprintf("Loading flavor ID: %v", err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var network = &networkModel{}
|
||||||
|
if !(model.Network.IsNull() || model.Network.IsUnknown()) {
|
||||||
|
diags = model.Network.As(ctx, network, basetypes.ObjectAsOptions{})
|
||||||
|
resp.Diagnostics.Append(diags...)
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var encryption = &encryptionModel{}
|
||||||
|
if !(model.Encryption.IsNull() || model.Encryption.IsUnknown()) {
|
||||||
|
diags = model.Encryption.As(ctx, encryption, basetypes.ObjectAsOptions{})
|
||||||
|
resp.Diagnostics.Append(diags...)
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Generate API request body from model
|
// Generate API request body from model
|
||||||
payload, err := toUpdatePayload(&model, acl, flavor, storage)
|
payload, err := toUpdatePayload(&model, flavor, storage, network)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
core.LogAndAddError(ctx, &resp.Diagnostics, "Error updating instance", fmt.Sprintf("Creating API payload: %v", err))
|
core.LogAndAddError(ctx, &resp.Diagnostics, "Error updating instance", fmt.Sprintf("Creating API payload: %v", err))
|
||||||
return
|
return
|
||||||
|
|
@ -648,17 +707,8 @@ func (r *instanceResource) Update(ctx context.Context, req resource.UpdateReques
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var network = &networkModel{}
|
|
||||||
if !(model.Network.IsNull() || model.Network.IsUnknown()) {
|
|
||||||
diags = model.Network.As(ctx, network, basetypes.ObjectAsOptions{})
|
|
||||||
resp.Diagnostics.Append(diags...)
|
|
||||||
if resp.Diagnostics.HasError() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Map response body to schema
|
// Map response body to schema
|
||||||
err = mapFields(ctx, waitResp, &model, flavor, storage, network, region)
|
err = mapFields(ctx, waitResp, &model, flavor, storage, encryption, network, region)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
core.LogAndAddError(ctx, &resp.Diagnostics, "Error updating instance", fmt.Sprintf("Processing API payload: %v", err))
|
core.LogAndAddError(ctx, &resp.Diagnostics, "Error updating instance", fmt.Sprintf("Processing API payload: %v", err))
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,7 @@ func TestMapFields(t *testing.T) {
|
||||||
// Cpu: utils.Ptr(int64(12)),
|
// Cpu: utils.Ptr(int64(12)),
|
||||||
// Description: utils.Ptr("description"),
|
// Description: utils.Ptr("description"),
|
||||||
// Id: utils.Ptr("flavor_id"),
|
// Id: utils.Ptr("flavor_id"),
|
||||||
// Memory: utils.Ptr(int64(34)),
|
// Ram: utils.Ptr(int64(34)),
|
||||||
//},
|
//},
|
||||||
Id: utils.Ptr("iid"),
|
Id: utils.Ptr("iid"),
|
||||||
Name: utils.Ptr("name"),
|
Name: utils.Ptr("name"),
|
||||||
|
|
@ -633,7 +633,7 @@ func TestToCreatePayload(t *testing.T) {
|
||||||
// Id: utils.Ptr("fid-1"),
|
// Id: utils.Ptr("fid-1"),
|
||||||
// Cpu: utils.Ptr(int64(2)),
|
// Cpu: utils.Ptr(int64(2)),
|
||||||
// Description: utils.Ptr("description"),
|
// Description: utils.Ptr("description"),
|
||||||
// Memory: utils.Ptr(int64(8)),
|
// Ram: utils.Ptr(int64(8)),
|
||||||
// },
|
// },
|
||||||
// },
|
// },
|
||||||
// },
|
// },
|
||||||
|
|
@ -658,13 +658,13 @@ func TestToCreatePayload(t *testing.T) {
|
||||||
// Id: utils.Ptr("fid-1"),
|
// Id: utils.Ptr("fid-1"),
|
||||||
// Cpu: utils.Ptr(int64(2)),
|
// Cpu: utils.Ptr(int64(2)),
|
||||||
// Description: utils.Ptr("description"),
|
// Description: utils.Ptr("description"),
|
||||||
// Memory: utils.Ptr(int64(8)),
|
// Ram: utils.Ptr(int64(8)),
|
||||||
// },
|
// },
|
||||||
// {
|
// {
|
||||||
// Id: utils.Ptr("fid-2"),
|
// Id: utils.Ptr("fid-2"),
|
||||||
// Cpu: utils.Ptr(int64(1)),
|
// Cpu: utils.Ptr(int64(1)),
|
||||||
// Description: utils.Ptr("description"),
|
// Description: utils.Ptr("description"),
|
||||||
// Memory: utils.Ptr(int64(4)),
|
// Ram: utils.Ptr(int64(4)),
|
||||||
// },
|
// },
|
||||||
// },
|
// },
|
||||||
// },
|
// },
|
||||||
|
|
@ -689,13 +689,13 @@ func TestToCreatePayload(t *testing.T) {
|
||||||
// Id: utils.Ptr("fid-1"),
|
// Id: utils.Ptr("fid-1"),
|
||||||
// Cpu: utils.Ptr(int64(1)),
|
// Cpu: utils.Ptr(int64(1)),
|
||||||
// Description: utils.Ptr("description"),
|
// Description: utils.Ptr("description"),
|
||||||
// Memory: utils.Ptr(int64(8)),
|
// Ram: utils.Ptr(int64(8)),
|
||||||
// },
|
// },
|
||||||
// {
|
// {
|
||||||
// Id: utils.Ptr("fid-2"),
|
// Id: utils.Ptr("fid-2"),
|
||||||
// Cpu: utils.Ptr(int64(1)),
|
// Cpu: utils.Ptr(int64(1)),
|
||||||
// Description: utils.Ptr("description"),
|
// Description: utils.Ptr("description"),
|
||||||
// Memory: utils.Ptr(int64(4)),
|
// Ram: utils.Ptr(int64(4)),
|
||||||
// },
|
// },
|
||||||
// },
|
// },
|
||||||
// },
|
// },
|
||||||
|
|
|
||||||
|
|
@ -199,17 +199,13 @@ func toCreatePayload(model *Model, storage *storageModel, encryption *encryption
|
||||||
encryptionPayload.ServiceAccount = conversion.StringValueToPointer(encryption.ServiceAccount)
|
encryptionPayload.ServiceAccount = conversion.StringValueToPointer(encryption.ServiceAccount)
|
||||||
}
|
}
|
||||||
|
|
||||||
networkPayload := &sqlserverflex.CreateInstanceRequestPayloadGetNetworkArgType{}
|
|
||||||
if network != nil {
|
|
||||||
networkPayload.AccessScope = sqlserverflex.CreateInstanceRequestPayloadNetworkGetAccessScopeAttributeType(conversion.StringValueToPointer(network.AccessScope))
|
|
||||||
}
|
|
||||||
|
|
||||||
flavorId := ""
|
flavorId := ""
|
||||||
if !(model.Flavor.IsNull() || model.Flavor.IsUnknown()) {
|
if !(model.Flavor.IsNull() || model.Flavor.IsUnknown()) {
|
||||||
modelValues := model.Flavor.Attributes()
|
modelValues := model.Flavor.Attributes()
|
||||||
if _, ok := modelValues["id"]; !ok {
|
if _, ok := modelValues["id"]; !ok {
|
||||||
return nil, fmt.Errorf("flavor has not yet been created")
|
return nil, fmt.Errorf("flavor has not yet been created")
|
||||||
}
|
}
|
||||||
|
// TODO - how to get rid of that trim?
|
||||||
flavorId = strings.Trim(modelValues["id"].String(), "\"")
|
flavorId = strings.Trim(modelValues["id"].String(), "\"")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -222,7 +218,15 @@ func toCreatePayload(model *Model, storage *storageModel, encryption *encryption
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
networkPayload := &sqlserverflex.CreateInstanceRequestPayloadGetNetworkArgType{}
|
||||||
|
if network != nil {
|
||||||
|
networkPayload.AccessScope = sqlserverflex.CreateInstanceRequestPayloadNetworkGetAccessScopeAttributeType(conversion.StringValueToPointer(network.AccessScope))
|
||||||
|
// TODO - implement as soon as exists
|
||||||
|
// networkPayload.ACL
|
||||||
|
}
|
||||||
|
|
||||||
return &sqlserverflex.CreateInstanceRequestPayload{
|
return &sqlserverflex.CreateInstanceRequestPayload{
|
||||||
|
// TODO - remove as soon as exists in network
|
||||||
Acl: &aclElements,
|
Acl: &aclElements,
|
||||||
BackupSchedule: conversion.StringValueToPointer(model.BackupSchedule),
|
BackupSchedule: conversion.StringValueToPointer(model.BackupSchedule),
|
||||||
FlavorId: &flavorId,
|
FlavorId: &flavorId,
|
||||||
|
|
|
||||||
|
|
@ -731,7 +731,7 @@ func TestMapFields(t *testing.T) {
|
||||||
// Id: utils.Ptr("fid-1"),
|
// Id: utils.Ptr("fid-1"),
|
||||||
// Cpu: utils.Ptr(int64(2)),
|
// Cpu: utils.Ptr(int64(2)),
|
||||||
// Description: utils.Ptr("description"),
|
// Description: utils.Ptr("description"),
|
||||||
// Memory: utils.Ptr(int64(8)),
|
// Ram: utils.Ptr(int64(8)),
|
||||||
// },
|
// },
|
||||||
// },
|
// },
|
||||||
// },
|
// },
|
||||||
|
|
@ -756,13 +756,13 @@ func TestMapFields(t *testing.T) {
|
||||||
// Id: utils.Ptr("fid-1"),
|
// Id: utils.Ptr("fid-1"),
|
||||||
// Cpu: utils.Ptr(int64(2)),
|
// Cpu: utils.Ptr(int64(2)),
|
||||||
// Description: utils.Ptr("description"),
|
// Description: utils.Ptr("description"),
|
||||||
// Memory: utils.Ptr(int64(8)),
|
// Ram: utils.Ptr(int64(8)),
|
||||||
// },
|
// },
|
||||||
// {
|
// {
|
||||||
// Id: utils.Ptr("fid-2"),
|
// Id: utils.Ptr("fid-2"),
|
||||||
// Cpu: utils.Ptr(int64(1)),
|
// Cpu: utils.Ptr(int64(1)),
|
||||||
// Description: utils.Ptr("description"),
|
// Description: utils.Ptr("description"),
|
||||||
// Memory: utils.Ptr(int64(4)),
|
// Ram: utils.Ptr(int64(4)),
|
||||||
// },
|
// },
|
||||||
// },
|
// },
|
||||||
// },
|
// },
|
||||||
|
|
@ -787,13 +787,13 @@ func TestMapFields(t *testing.T) {
|
||||||
// Id: utils.Ptr("fid-1"),
|
// Id: utils.Ptr("fid-1"),
|
||||||
// Cpu: utils.Ptr(int64(1)),
|
// Cpu: utils.Ptr(int64(1)),
|
||||||
// Description: utils.Ptr("description"),
|
// Description: utils.Ptr("description"),
|
||||||
// Memory: utils.Ptr(int64(8)),
|
// Ram: utils.Ptr(int64(8)),
|
||||||
// },
|
// },
|
||||||
// {
|
// {
|
||||||
// Id: utils.Ptr("fid-2"),
|
// Id: utils.Ptr("fid-2"),
|
||||||
// Cpu: utils.Ptr(int64(1)),
|
// Cpu: utils.Ptr(int64(1)),
|
||||||
// Description: utils.Ptr("description"),
|
// Description: utils.Ptr("description"),
|
||||||
// Memory: utils.Ptr(int64(4)),
|
// Ram: utils.Ptr(int64(4)),
|
||||||
// },
|
// },
|
||||||
// },
|
// },
|
||||||
// },
|
// },
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue