Extend Redis and RabbitMQ instance parameters (#431)

* Extend RabbitMQ instance parameters (#409)

* Extend Schema

* initial parameter integration in resource

* datasource, resource and acceptance testing

* add docs, fix map fields edge case

* improve testing

* rename tls_protocols to singular

* revert renaming

* Extend Redis instance parameters (#410)

* Extend Schema

* initial parameter integration in resource

* datasource, resource and acceptance testing

* add docs, fix map fields edge case

* improve testing

* rename tls_protocols to singular

* revert renaming

* initial schema

* resource and datasource

* acceptance testing

* fix linting and testing, generate docs

* improve acceptance testing

---------

Co-authored-by: Diogo Ferrão <diogo.ferrao@freiheit.com>
This commit is contained in:
João Palet 2024-06-25 16:03:59 +01:00 committed by GitHub
parent 923764172d
commit 9f82c3262b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 1009 additions and 244 deletions

View file

@ -7,6 +7,7 @@ import (
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-log/tflog"
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/core"
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/validate"
@ -130,6 +131,71 @@ func (r *instanceDataSource) Schema(_ context.Context, _ datasource.SchemaReques
"sgw_acl": schema.StringAttribute{
Computed: true,
},
"down_after_milliseconds": schema.Int64Attribute{
Computed: true,
},
"enable_monitoring": schema.BoolAttribute{
Computed: true,
},
"failover_timeout": schema.Int64Attribute{
Computed: true,
},
"graphite": schema.StringAttribute{
Computed: true,
},
"lazyfree_lazy_eviction": schema.StringAttribute{
Computed: true,
},
"lazyfree_lazy_expire": schema.StringAttribute{
Computed: true,
},
"lua_time_limit": schema.Int64Attribute{
Computed: true,
},
"max_disk_threshold": schema.Int64Attribute{
Computed: true,
},
"maxclients": schema.Int64Attribute{
Computed: true,
},
"maxmemory_policy": schema.StringAttribute{
Computed: true,
},
"maxmemory_samples": schema.Int64Attribute{
Computed: true,
},
"metrics_frequency": schema.Int64Attribute{
Computed: true,
},
"metrics_prefix": schema.StringAttribute{
Computed: true,
},
"min_replicas_max_lag": schema.Int64Attribute{
Computed: true,
},
"monitoring_instance_id": schema.StringAttribute{
Computed: true,
},
"notify_keyspace_events": schema.StringAttribute{
Computed: true,
},
"snapshot": schema.StringAttribute{
Computed: true,
},
"syslog": schema.ListAttribute{
ElementType: types.StringType,
Computed: true,
},
"tls_ciphers": schema.ListAttribute{
ElementType: types.StringType,
Computed: true,
},
"tls_ciphersuites": schema.StringAttribute{
Computed: true,
},
"tls_protocols": schema.StringAttribute{
Computed: true,
},
},
Computed: true,
},

View file

@ -4,6 +4,7 @@ import (
"context"
"fmt"
"net/http"
"slices"
"strings"
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
@ -52,12 +53,54 @@ type Model struct {
// Struct corresponding to DataSourceModel.Parameters
type parametersModel struct {
SgwAcl types.String `tfsdk:"sgw_acl"`
SgwAcl types.String `tfsdk:"sgw_acl"`
DownAfterMilliseconds types.Int64 `tfsdk:"down_after_milliseconds"`
EnableMonitoring types.Bool `tfsdk:"enable_monitoring"`
FailoverTimeout types.Int64 `tfsdk:"failover_timeout"`
Graphite types.String `tfsdk:"graphite"`
LazyfreeLazyEviction types.String `tfsdk:"lazyfree_lazy_eviction"`
LazyfreeLazyExpire types.String `tfsdk:"lazyfree_lazy_expire"`
LuaTimeLimit types.Int64 `tfsdk:"lua_time_limit"`
MaxDiskThreshold types.Int64 `tfsdk:"max_disk_threshold"`
Maxclients types.Int64 `tfsdk:"maxclients"`
MaxmemoryPolicy types.String `tfsdk:"maxmemory_policy"`
MaxmemorySamples types.Int64 `tfsdk:"maxmemory_samples"`
MetricsFrequency types.Int64 `tfsdk:"metrics_frequency"`
MetricsPrefix types.String `tfsdk:"metrics_prefix"`
MinReplicasMaxLag types.Int64 `tfsdk:"min_replicas_max_lag"`
MonitoringInstanceId types.String `tfsdk:"monitoring_instance_id"`
NotifyKeyspaceEvents types.String `tfsdk:"notify_keyspace_events"`
Snapshot types.String `tfsdk:"snapshot"`
Syslog types.List `tfsdk:"syslog"`
TlsCiphers types.List `tfsdk:"tls_ciphers"`
TlsCiphersuites types.String `tfsdk:"tls_ciphersuites"`
TlsProtocols types.String `tfsdk:"tls_protocols"`
}
// Types corresponding to parametersModel
var parametersTypes = map[string]attr.Type{
"sgw_acl": basetypes.StringType{},
"sgw_acl": basetypes.StringType{},
"down_after_milliseconds": basetypes.Int64Type{},
"enable_monitoring": basetypes.BoolType{},
"failover_timeout": basetypes.Int64Type{},
"graphite": basetypes.StringType{},
"lazyfree_lazy_eviction": basetypes.StringType{},
"lazyfree_lazy_expire": basetypes.StringType{},
"lua_time_limit": basetypes.Int64Type{},
"max_disk_threshold": basetypes.Int64Type{},
"maxclients": basetypes.Int64Type{},
"maxmemory_policy": basetypes.StringType{},
"maxmemory_samples": basetypes.Int64Type{},
"metrics_frequency": basetypes.Int64Type{},
"metrics_prefix": basetypes.StringType{},
"min_replicas_max_lag": basetypes.Int64Type{},
"monitoring_instance_id": basetypes.StringType{},
"notify_keyspace_events": basetypes.StringType{},
"snapshot": basetypes.StringType{},
"syslog": basetypes.ListType{ElemType: types.StringType},
"tls_ciphers": basetypes.ListType{ElemType: types.StringType},
"tls_ciphersuites": basetypes.StringType{},
"tls_protocols": basetypes.StringType{},
}
// NewInstanceResource is a helper function to simplify the provider implementation.
@ -124,6 +167,31 @@ func (r *instanceResource) Schema(_ context.Context, _ resource.SchemaRequest, r
"plan_id": "The selected plan ID.",
}
parametersDescriptions := map[string]string{
"sgw_acl": "Comma separated list of IP networks in CIDR notation which are allowed to access this instance.",
"down_after_milliseconds": "The number of milliseconds after which the instance is considered down.",
"enable_monitoring": "Enable monitoring.",
"failover_timeout": "The failover timeout in milliseconds.",
"graphite": "Graphite server URL (host and port). If set, monitoring with Graphite will be enabled.",
"lazyfree_lazy_eviction": "The lazy eviction enablement (yes or no).",
"lazyfree_lazy_expire": "The lazy expire enablement (yes or no).",
"lua_time_limit": "The Lua time limit.",
"max_disk_threshold": "The maximum disk threshold in MB. If the disk usage exceeds this threshold, the instance will be stopped.",
"maxclients": "The maximum number of clients.",
"maxmemory_policy": "The policy to handle the maximum memory (volatile-lru, noeviction, etc).",
"maxmemory_samples": "The maximum memory samples.",
"metrics_frequency": "The frequency in seconds at which metrics are emitted.",
"metrics_prefix": "The prefix for the metrics. Could be useful when using Graphite monitoring to prefix the metrics with a certain value, like an API key",
"min_replicas_max_lag": "The minimum replicas maximum lag.",
"monitoring_instance_id": "The monitoring instance ID.",
"notify_keyspace_events": "The notify keyspace events.",
"snapshot": "The snapshot configuration.",
"syslog": "List of syslog servers to send logs to.",
"tls_ciphers": "List of TLS ciphers to use.",
"tls_ciphersuites": "TLS cipher suites to use.",
"tls_protocols": "TLS protocol to use.",
}
resp.Schema = schema.Schema{
Description: descriptions["main"],
Attributes: map[string]schema.Attribute{
@ -183,8 +251,116 @@ func (r *instanceResource) Schema(_ context.Context, _ resource.SchemaRequest, r
"parameters": schema.SingleNestedAttribute{
Attributes: map[string]schema.Attribute{
"sgw_acl": schema.StringAttribute{
Optional: true,
Computed: true,
Description: parametersDescriptions["sgw_acl"],
Optional: true,
Computed: true,
},
"down_after_milliseconds": schema.Int64Attribute{
Description: parametersDescriptions["down_after_milliseconds"],
Optional: true,
Computed: true,
},
"enable_monitoring": schema.BoolAttribute{
Description: parametersDescriptions["enable_monitoring"],
Optional: true,
Computed: true,
},
"failover_timeout": schema.Int64Attribute{
Description: parametersDescriptions["failover_timeout"],
Optional: true,
Computed: true,
},
"graphite": schema.StringAttribute{
Description: parametersDescriptions["graphite"],
Optional: true,
Computed: true,
},
"lazyfree_lazy_eviction": schema.StringAttribute{
Description: parametersDescriptions["lazyfree_lazy_eviction"],
Optional: true,
Computed: true,
},
"lazyfree_lazy_expire": schema.StringAttribute{
Description: parametersDescriptions["lazyfree_lazy_expire"],
Optional: true,
Computed: true,
},
"lua_time_limit": schema.Int64Attribute{
Description: parametersDescriptions["lua_time_limit"],
Optional: true,
Computed: true,
},
"max_disk_threshold": schema.Int64Attribute{
Description: parametersDescriptions["max_disk_threshold"],
Optional: true,
Computed: true,
},
"maxclients": schema.Int64Attribute{
Description: parametersDescriptions["maxclients"],
Optional: true,
Computed: true,
},
"maxmemory_policy": schema.StringAttribute{
Description: parametersDescriptions["maxmemory_policy"],
Optional: true,
Computed: true,
},
"maxmemory_samples": schema.Int64Attribute{
Description: parametersDescriptions["maxmemory_samples"],
Optional: true,
Computed: true,
},
"metrics_frequency": schema.Int64Attribute{
Description: parametersDescriptions["metrics_frequency"],
Optional: true,
Computed: true,
},
"metrics_prefix": schema.StringAttribute{
Description: parametersDescriptions["metrics_prefix"],
Optional: true,
Computed: true,
},
"min_replicas_max_lag": schema.Int64Attribute{
Description: parametersDescriptions["min_replicas_max_lag"],
Optional: true,
Computed: true,
},
"monitoring_instance_id": schema.StringAttribute{
Description: parametersDescriptions["monitoring_instance_id"],
Optional: true,
Computed: true,
},
"notify_keyspace_events": schema.StringAttribute{
Description: parametersDescriptions["notify_keyspace_events"],
Optional: true,
Computed: true,
},
"snapshot": schema.StringAttribute{
Description: parametersDescriptions["snapshot"],
Optional: true,
Computed: true,
},
"syslog": schema.ListAttribute{
Description: parametersDescriptions["syslog"],
ElementType: types.StringType,
Optional: true,
Computed: true,
},
"tls_ciphers": schema.ListAttribute{
Description: parametersDescriptions["tls_ciphers"],
ElementType: types.StringType,
Optional: true,
Computed: true,
},
"tls_ciphersuites": schema.StringAttribute{
Description: parametersDescriptions["tls_ciphersuites"],
Optional: true,
Computed: true,
},
"tls_protocols": schema.StringAttribute{
Description: parametersDescriptions["tls_protocols"],
Optional: true,
Computed: true,
},
},
Optional: true,
@ -488,7 +664,31 @@ func mapFields(instance *redis.Instance, model *Model) error {
func mapParameters(params map[string]interface{}) (types.Object, error) {
attributes := map[string]attr.Value{}
for attribute := range parametersTypes {
valueInterface, ok := params[attribute]
var valueInterface interface{}
var ok bool
// This replacement is necessary because Terraform does not allow hyphens in attribute names
// And the API uses hyphens in some of the attribute names, which would cause a mismatch
// The following attributes have hyphens in the API but underscores in the schema
hyphenAttributes := []string{
"down_after_milliseconds",
"failover_timeout",
"lazyfree_lazy_eviction",
"lazyfree_lazy_expire",
"lua_time_limit",
"maxmemory_policy",
"maxmemory_samples",
"notify_keyspace_events",
"tls_ciphers",
"tls_ciphersuites",
"tls_protocols",
}
if slices.Contains(hyphenAttributes, attribute) {
alteredAttribute := strings.ReplaceAll(attribute, "_", "-")
valueInterface, ok = params[alteredAttribute]
} else {
valueInterface, ok = params[attribute]
}
if !ok {
// All fields are optional, so this is ok
// Set the value as nil, will be handled accordingly
@ -584,16 +784,12 @@ func toCreatePayload(model *Model, parameters *parametersModel) (*redis.CreateIn
if model == nil {
return nil, fmt.Errorf("nil model")
}
if parameters == nil {
return &redis.CreateInstancePayload{
InstanceName: conversion.StringValueToPointer(model.Name),
PlanId: conversion.StringValueToPointer(model.PlanId),
}, nil
}
payloadParams := &redis.InstanceParameters{}
if parameters.SgwAcl.ValueString() != "" {
payloadParams.SgwAcl = conversion.StringValueToPointer(parameters.SgwAcl)
payloadParams, err := toInstanceParams(parameters)
if err != nil {
return nil, fmt.Errorf("converting parameters: %w", err)
}
return &redis.CreateInstancePayload{
InstanceName: conversion.StringValueToPointer(model.Name),
Parameters: payloadParams,
@ -606,19 +802,58 @@ func toUpdatePayload(model *Model, parameters *parametersModel) (*redis.PartialU
return nil, fmt.Errorf("nil model")
}
if parameters == nil {
return &redis.PartialUpdateInstancePayload{
PlanId: conversion.StringValueToPointer(model.PlanId),
}, nil
payloadParams, err := toInstanceParams(parameters)
if err != nil {
return nil, fmt.Errorf("converting parameters: %w", err)
}
return &redis.PartialUpdateInstancePayload{
Parameters: &redis.InstanceParameters{
SgwAcl: conversion.StringValueToPointer(parameters.SgwAcl),
},
PlanId: conversion.StringValueToPointer(model.PlanId),
Parameters: payloadParams,
PlanId: conversion.StringValueToPointer(model.PlanId),
}, nil
}
func toInstanceParams(parameters *parametersModel) (*redis.InstanceParameters, error) {
if parameters == nil {
return nil, nil
}
payloadParams := &redis.InstanceParameters{}
payloadParams.SgwAcl = conversion.StringValueToPointer(parameters.SgwAcl)
payloadParams.DownAfterMilliseconds = conversion.Int64ValueToPointer(parameters.DownAfterMilliseconds)
payloadParams.EnableMonitoring = conversion.BoolValueToPointer(parameters.EnableMonitoring)
payloadParams.FailoverTimeout = conversion.Int64ValueToPointer(parameters.FailoverTimeout)
payloadParams.Graphite = conversion.StringValueToPointer(parameters.Graphite)
payloadParams.LazyfreeLazyEviction = conversion.StringValueToPointer(parameters.LazyfreeLazyEviction)
payloadParams.LazyfreeLazyExpire = conversion.StringValueToPointer(parameters.LazyfreeLazyExpire)
payloadParams.LuaTimeLimit = conversion.Int64ValueToPointer(parameters.LuaTimeLimit)
payloadParams.MaxDiskThreshold = conversion.Int64ValueToPointer(parameters.MaxDiskThreshold)
payloadParams.Maxclients = conversion.Int64ValueToPointer(parameters.Maxclients)
payloadParams.MaxmemoryPolicy = conversion.StringValueToPointer(parameters.MaxmemoryPolicy)
payloadParams.MaxmemorySamples = conversion.Int64ValueToPointer(parameters.MaxmemorySamples)
payloadParams.MetricsFrequency = conversion.Int64ValueToPointer(parameters.MetricsFrequency)
payloadParams.MetricsPrefix = conversion.StringValueToPointer(parameters.MetricsPrefix)
payloadParams.MinReplicasMaxLag = conversion.Int64ValueToPointer(parameters.MinReplicasMaxLag)
payloadParams.MonitoringInstanceId = conversion.StringValueToPointer(parameters.MonitoringInstanceId)
payloadParams.NotifyKeyspaceEvents = conversion.StringValueToPointer(parameters.NotifyKeyspaceEvents)
payloadParams.Snapshot = conversion.StringValueToPointer(parameters.Snapshot)
payloadParams.TlsCiphersuites = conversion.StringValueToPointer(parameters.TlsCiphersuites)
payloadParams.TlsProtocols = conversion.StringValueToPointer(parameters.TlsProtocols)
var err error
payloadParams.Syslog, err = conversion.StringListToPointer(parameters.Syslog)
if err != nil {
return nil, fmt.Errorf("converting syslog: %w", err)
}
payloadParams.TlsCiphers, err = conversion.StringListToPointer(parameters.TlsCiphers)
if err != nil {
return nil, fmt.Errorf("converting tls_ciphers: %w", err)
}
return payloadParams, nil
}
func (r *instanceResource) loadPlanId(ctx context.Context, model *Model) error {
projectId := model.ProjectId.ValueString()
res, err := r.client.ListOfferings(ctx, projectId).Execute()

View file

@ -1,15 +1,73 @@
package redis
import (
"context"
"testing"
"github.com/google/go-cmp/cmp"
"github.com/hashicorp/terraform-plugin-framework/attr"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
"github.com/stackitcloud/stackit-sdk-go/core/utils"
"github.com/stackitcloud/stackit-sdk-go/services/redis"
)
var fixtureModelParameters = types.ObjectValueMust(parametersTypes, map[string]attr.Value{
"sgw_acl": types.StringValue("acl"),
"down_after_milliseconds": types.Int64Value(10),
"enable_monitoring": types.BoolValue(true),
"failover_timeout": types.Int64Value(10),
"graphite": types.StringValue("1.1.1.1:91"),
"lazyfree_lazy_eviction": types.StringValue("lazy_eviction"),
"lazyfree_lazy_expire": types.StringValue("lazy_expire"),
"lua_time_limit": types.Int64Value(10),
"max_disk_threshold": types.Int64Value(100),
"maxclients": types.Int64Value(10),
"maxmemory_policy": types.StringValue("policy"),
"maxmemory_samples": types.Int64Value(10),
"metrics_frequency": types.Int64Value(10),
"metrics_prefix": types.StringValue("prefix"),
"min_replicas_max_lag": types.Int64Value(10),
"monitoring_instance_id": types.StringValue("mid"),
"notify_keyspace_events": types.StringValue("events"),
"snapshot": types.StringValue("snapshot"),
"syslog": types.ListValueMust(types.StringType, []attr.Value{
types.StringValue("syslog"),
types.StringValue("syslog2"),
}),
"tls_ciphers": types.ListValueMust(types.StringType, []attr.Value{
types.StringValue("ciphers1"),
types.StringValue("ciphers2"),
}),
"tls_ciphersuites": types.StringValue("ciphersuites"),
"tls_protocols": types.StringValue("protocol1"),
})
var fixtureInstanceParameters = redis.InstanceParameters{
SgwAcl: utils.Ptr("acl"),
DownAfterMilliseconds: utils.Ptr(int64(10)),
EnableMonitoring: utils.Ptr(true),
FailoverTimeout: utils.Ptr(int64(10)),
Graphite: utils.Ptr("1.1.1.1:91"),
LazyfreeLazyEviction: utils.Ptr("lazy_eviction"),
LazyfreeLazyExpire: utils.Ptr("lazy_expire"),
LuaTimeLimit: utils.Ptr(int64(10)),
MaxDiskThreshold: utils.Ptr(int64(100)),
Maxclients: utils.Ptr(int64(10)),
MaxmemoryPolicy: utils.Ptr("policy"),
MaxmemorySamples: utils.Ptr(int64(10)),
MetricsFrequency: utils.Ptr(int64(10)),
MetricsPrefix: utils.Ptr("prefix"),
MinReplicasMaxLag: utils.Ptr(int64(10)),
MonitoringInstanceId: utils.Ptr("mid"),
NotifyKeyspaceEvents: utils.Ptr("events"),
Snapshot: utils.Ptr("snapshot"),
Syslog: &[]string{"syslog", "syslog2"},
TlsCiphers: &[]string{"ciphers1", "ciphers2"},
TlsCiphersuites: utils.Ptr("ciphersuites"),
TlsProtocols: utils.Ptr("protocol1"),
}
func TestMapFields(t *testing.T) {
tests := []struct {
description string
@ -47,7 +105,28 @@ func TestMapFields(t *testing.T) {
Name: utils.Ptr("name"),
CfOrganizationGuid: utils.Ptr("org"),
Parameters: &map[string]interface{}{
"sgw_acl": "acl",
"sgw_acl": "acl",
"down-after-milliseconds": int64(10),
"enable_monitoring": true,
"failover-timeout": int64(10),
"graphite": "1.1.1.1:91",
"lazyfree-lazy-eviction": "lazy_eviction",
"lazyfree-lazy-expire": "lazy_expire",
"lua-time-limit": int64(10),
"max_disk_threshold": int64(100),
"maxclients": int64(10),
"maxmemory-policy": "policy",
"maxmemory-samples": int64(10),
"metrics_frequency": int64(10),
"metrics_prefix": "prefix",
"min_replicas_max_lag": int64(10),
"monitoring_instance_id": "mid",
"notify-keyspace-events": "events",
"snapshot": "snapshot",
"syslog": []string{"syslog", "syslog2"},
"tls-ciphers": []string{"ciphers1", "ciphers2"},
"tls-ciphersuites": "ciphersuites",
"tls-protocols": "protocol1",
},
},
Model{
@ -61,9 +140,7 @@ func TestMapFields(t *testing.T) {
DashboardUrl: types.StringValue("dashboard"),
ImageUrl: types.StringValue("image"),
CfOrganizationGuid: types.StringValue("org"),
Parameters: types.ObjectValueMust(parametersTypes, map[string]attr.Value{
"sgw_acl": types.StringValue("acl"),
}),
Parameters: fixtureModelParameters,
},
true,
},
@ -125,16 +202,14 @@ func TestMapFields(t *testing.T) {
func TestToCreatePayload(t *testing.T) {
tests := []struct {
description string
input *Model
inputParameters *parametersModel
expected *redis.CreateInstancePayload
isValid bool
description string
input *Model
expected *redis.CreateInstancePayload
isValid bool
}{
{
"default_values",
&Model{},
&parametersModel{},
&redis.CreateInstancePayload{
Parameters: &redis.InstanceParameters{},
},
@ -143,43 +218,34 @@ func TestToCreatePayload(t *testing.T) {
{
"simple_values",
&Model{
Name: types.StringValue("name"),
PlanId: types.StringValue("plan"),
},
&parametersModel{
SgwAcl: types.StringValue("sgw"),
Name: types.StringValue("name"),
PlanId: types.StringValue("plan"),
Parameters: fixtureModelParameters,
},
&redis.CreateInstancePayload{
InstanceName: utils.Ptr("name"),
Parameters: &redis.InstanceParameters{
SgwAcl: utils.Ptr("sgw"),
},
PlanId: utils.Ptr("plan"),
Parameters: &fixtureInstanceParameters,
PlanId: utils.Ptr("plan"),
},
true,
},
{
"null_fields_and_int_conversions",
&Model{
Name: types.StringValue(""),
PlanId: types.StringValue(""),
},
&parametersModel{
SgwAcl: types.StringNull(),
Name: types.StringValue(""),
PlanId: types.StringValue(""),
Parameters: fixtureModelParameters,
},
&redis.CreateInstancePayload{
InstanceName: utils.Ptr(""),
Parameters: &redis.InstanceParameters{
SgwAcl: nil,
},
PlanId: utils.Ptr(""),
Parameters: &fixtureInstanceParameters,
PlanId: utils.Ptr(""),
},
true,
},
{
"nil_model",
nil,
&parametersModel{},
nil,
false,
},
@ -189,17 +255,26 @@ func TestToCreatePayload(t *testing.T) {
Name: types.StringValue("name"),
PlanId: types.StringValue("plan"),
},
nil,
&redis.CreateInstancePayload{
InstanceName: utils.Ptr("name"),
PlanId: utils.Ptr("plan"),
Parameters: &redis.InstanceParameters{},
},
true,
},
}
for _, tt := range tests {
t.Run(tt.description, func(t *testing.T) {
output, err := toCreatePayload(tt.input, tt.inputParameters)
var parameters = &parametersModel{}
if tt.input != nil {
if !(tt.input.Parameters.IsNull() || tt.input.Parameters.IsUnknown()) {
diags := tt.input.Parameters.As(context.Background(), parameters, basetypes.ObjectAsOptions{})
if diags.HasError() {
t.Fatalf("Error converting parameters: %v", diags.Errors())
}
}
}
output, err := toCreatePayload(tt.input, parameters)
if !tt.isValid && err == nil {
t.Fatalf("Should have failed")
}
@ -218,16 +293,14 @@ func TestToCreatePayload(t *testing.T) {
func TestToUpdatePayload(t *testing.T) {
tests := []struct {
description string
input *Model
inputParameters *parametersModel
expected *redis.PartialUpdateInstancePayload
isValid bool
description string
input *Model
expected *redis.PartialUpdateInstancePayload
isValid bool
}{
{
"default_values",
&Model{},
&parametersModel{},
&redis.PartialUpdateInstancePayload{
Parameters: &redis.InstanceParameters{},
},
@ -236,39 +309,30 @@ func TestToUpdatePayload(t *testing.T) {
{
"simple_values",
&Model{
PlanId: types.StringValue("plan"),
},
&parametersModel{
SgwAcl: types.StringValue("sgw"),
PlanId: types.StringValue("plan"),
Parameters: fixtureModelParameters,
},
&redis.PartialUpdateInstancePayload{
Parameters: &redis.InstanceParameters{
SgwAcl: utils.Ptr("sgw"),
},
PlanId: utils.Ptr("plan"),
Parameters: &fixtureInstanceParameters,
PlanId: utils.Ptr("plan"),
},
true,
},
{
"null_fields_and_int_conversions",
&Model{
PlanId: types.StringValue(""),
},
&parametersModel{
SgwAcl: types.StringNull(),
PlanId: types.StringValue(""),
Parameters: fixtureModelParameters,
},
&redis.PartialUpdateInstancePayload{
Parameters: &redis.InstanceParameters{
SgwAcl: nil,
},
PlanId: utils.Ptr(""),
Parameters: &fixtureInstanceParameters,
PlanId: utils.Ptr(""),
},
true,
},
{
"nil_model",
nil,
&parametersModel{},
nil,
false,
},
@ -277,16 +341,25 @@ func TestToUpdatePayload(t *testing.T) {
&Model{
PlanId: types.StringValue("plan"),
},
nil,
&redis.PartialUpdateInstancePayload{
PlanId: utils.Ptr("plan"),
PlanId: utils.Ptr("plan"),
Parameters: &redis.InstanceParameters{},
},
true,
},
}
for _, tt := range tests {
t.Run(tt.description, func(t *testing.T) {
output, err := toUpdatePayload(tt.input, tt.inputParameters)
var parameters = &parametersModel{}
if tt.input != nil {
if !(tt.input.Parameters.IsNull() || tt.input.Parameters.IsUnknown()) {
diags := tt.input.Parameters.As(context.Background(), parameters, basetypes.ObjectAsOptions{})
if diags.HasError() {
t.Fatalf("Error converting parameters: %v", diags.Errors())
}
}
}
output, err := toUpdatePayload(tt.input, parameters)
if !tt.isValid && err == nil {
t.Fatalf("Should have failed")
}