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:
parent
923764172d
commit
9f82c3262b
15 changed files with 1009 additions and 244 deletions
|
|
@ -46,4 +46,16 @@ data "stackit_rabbitmq_instance" "example" {
|
|||
|
||||
Read-Only:
|
||||
|
||||
- `consumer_timeout` (Number)
|
||||
- `enable_monitoring` (Boolean)
|
||||
- `graphite` (String)
|
||||
- `max_disk_threshold` (Number)
|
||||
- `metrics_frequency` (Number)
|
||||
- `metrics_prefix` (String)
|
||||
- `monitoring_instance_id` (String)
|
||||
- `plugins` (List of String)
|
||||
- `roles` (List of String)
|
||||
- `sgw_acl` (String)
|
||||
- `syslog` (List of String)
|
||||
- `tls_ciphers` (List of String)
|
||||
- `tls_protocols` (String)
|
||||
|
|
|
|||
|
|
@ -46,4 +46,25 @@ data "stackit_redis_instance" "example" {
|
|||
|
||||
Read-Only:
|
||||
|
||||
- `down_after_milliseconds` (Number)
|
||||
- `enable_monitoring` (Boolean)
|
||||
- `failover_timeout` (Number)
|
||||
- `graphite` (String)
|
||||
- `lazyfree_lazy_eviction` (String)
|
||||
- `lazyfree_lazy_expire` (String)
|
||||
- `lua_time_limit` (Number)
|
||||
- `max_disk_threshold` (Number)
|
||||
- `maxclients` (Number)
|
||||
- `maxmemory_policy` (String)
|
||||
- `maxmemory_samples` (Number)
|
||||
- `metrics_frequency` (Number)
|
||||
- `metrics_prefix` (String)
|
||||
- `min_replicas_max_lag` (Number)
|
||||
- `monitoring_instance_id` (String)
|
||||
- `notify_keyspace_events` (String)
|
||||
- `sgw_acl` (String)
|
||||
- `snapshot` (String)
|
||||
- `syslog` (List of String)
|
||||
- `tls_ciphers` (List of String)
|
||||
- `tls_ciphersuites` (String)
|
||||
- `tls_protocols` (String)
|
||||
|
|
|
|||
|
|
@ -19,7 +19,10 @@ resource "stackit_rabbitmq_instance" "example" {
|
|||
version = "10"
|
||||
plan_name = "example-plan-name"
|
||||
parameters = {
|
||||
sgw_acl = "x.x.x.x/x,y.y.y.y/y"
|
||||
sgw_acl = "x.x.x.x/x,y.y.y.y/y"
|
||||
consumer_timeout = 18000000
|
||||
enable_monitoring = false
|
||||
plugins = ["example-plugin1", "example-plugin2"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
|
@ -54,4 +57,16 @@ resource "stackit_rabbitmq_instance" "example" {
|
|||
|
||||
Optional:
|
||||
|
||||
- `sgw_acl` (String)
|
||||
- `consumer_timeout` (Number) The timeout in milliseconds for the consumer.
|
||||
- `enable_monitoring` (Boolean) Enable monitoring.
|
||||
- `graphite` (String) Graphite server URL (host and port). If set, monitoring with Graphite will be enabled.
|
||||
- `max_disk_threshold` (Number) The maximum disk threshold in MB. If the disk usage exceeds this threshold, the instance will be stopped.
|
||||
- `metrics_frequency` (Number) The frequency in seconds at which metrics are emitted.
|
||||
- `metrics_prefix` (String) The prefix for the metrics. Could be useful when using Graphite monitoring to prefix the metrics with a certain value, like an API key
|
||||
- `monitoring_instance_id` (String) The monitoring instance ID.
|
||||
- `plugins` (List of String) List of plugins to install. Must be a supported plugin name.
|
||||
- `roles` (List of String) List of roles to assign to the instance.
|
||||
- `sgw_acl` (String) Comma separated list of IP networks in CIDR notation which are allowed to access this instance.
|
||||
- `syslog` (List of String) List of syslog servers to send logs to.
|
||||
- `tls_ciphers` (List of String) List of TLS ciphers to use.
|
||||
- `tls_protocols` (String) TLS protocol to use.
|
||||
|
|
|
|||
|
|
@ -19,7 +19,10 @@ resource "stackit_redis_instance" "example" {
|
|||
version = "10"
|
||||
plan_name = "example-plan-name"
|
||||
parameters = {
|
||||
sgw_acl = "x.x.x.x/x,y.y.y.y/y"
|
||||
sgw_acl = "x.x.x.x/x,y.y.y.y/y"
|
||||
enable_monitoring = false
|
||||
down_after_milliseconds = 30000
|
||||
syslog = ["syslog.example.com:514"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
|
@ -54,4 +57,25 @@ resource "stackit_redis_instance" "example" {
|
|||
|
||||
Optional:
|
||||
|
||||
- `sgw_acl` (String)
|
||||
- `down_after_milliseconds` (Number) The number of milliseconds after which the instance is considered down.
|
||||
- `enable_monitoring` (Boolean) Enable monitoring.
|
||||
- `failover_timeout` (Number) The failover timeout in milliseconds.
|
||||
- `graphite` (String) Graphite server URL (host and port). If set, monitoring with Graphite will be enabled.
|
||||
- `lazyfree_lazy_eviction` (String) The lazy eviction enablement (yes or no).
|
||||
- `lazyfree_lazy_expire` (String) The lazy expire enablement (yes or no).
|
||||
- `lua_time_limit` (Number) The Lua time limit.
|
||||
- `max_disk_threshold` (Number) The maximum disk threshold in MB. If the disk usage exceeds this threshold, the instance will be stopped.
|
||||
- `maxclients` (Number) The maximum number of clients.
|
||||
- `maxmemory_policy` (String) The policy to handle the maximum memory (volatile-lru, noeviction, etc).
|
||||
- `maxmemory_samples` (Number) The maximum memory samples.
|
||||
- `metrics_frequency` (Number) The frequency in seconds at which metrics are emitted.
|
||||
- `metrics_prefix` (String) 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` (Number) The minimum replicas maximum lag.
|
||||
- `monitoring_instance_id` (String) The monitoring instance ID.
|
||||
- `notify_keyspace_events` (String) The notify keyspace events.
|
||||
- `sgw_acl` (String) Comma separated list of IP networks in CIDR notation which are allowed to access this instance.
|
||||
- `snapshot` (String) The snapshot configuration.
|
||||
- `syslog` (List of String) List of syslog servers to send logs to.
|
||||
- `tls_ciphers` (List of String) List of TLS ciphers to use.
|
||||
- `tls_ciphersuites` (String) TLS cipher suites to use.
|
||||
- `tls_protocols` (String) TLS protocol to use.
|
||||
|
|
|
|||
|
|
@ -4,6 +4,9 @@ resource "stackit_rabbitmq_instance" "example" {
|
|||
version = "10"
|
||||
plan_name = "example-plan-name"
|
||||
parameters = {
|
||||
sgw_acl = "x.x.x.x/x,y.y.y.y/y"
|
||||
sgw_acl = "x.x.x.x/x,y.y.y.y/y"
|
||||
consumer_timeout = 18000000
|
||||
enable_monitoring = false
|
||||
plugins = ["example-plugin1", "example-plugin2"]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,9 @@ resource "stackit_redis_instance" "example" {
|
|||
version = "10"
|
||||
plan_name = "example-plan-name"
|
||||
parameters = {
|
||||
sgw_acl = "x.x.x.x/x,y.y.y.y/y"
|
||||
sgw_acl = "x.x.x.x/x,y.y.y.y/y"
|
||||
enable_monitoring = false
|
||||
down_after_milliseconds = 30000
|
||||
syslog = ["syslog.example.com:514"]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,3 +87,22 @@ func BoolValueToPointer(s basetypes.BoolValue) *bool {
|
|||
value := s.ValueBool()
|
||||
return &value
|
||||
}
|
||||
|
||||
// StringListToPointer converts basetypes.ListValue to a pointer to a list of strings.
|
||||
// It returns nil if the value is null or unknown.
|
||||
func StringListToPointer(list basetypes.ListValue) (*[]string, error) {
|
||||
if list.IsNull() || list.IsUnknown() {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
listStr := []string{}
|
||||
for i, el := range list.Elements() {
|
||||
elStr, ok := el.(types.String)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("element %d is not a string", i)
|
||||
}
|
||||
listStr = append(listStr, elStr.ValueString())
|
||||
}
|
||||
|
||||
return &listStr, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,46 @@ func (r *instanceDataSource) Schema(_ context.Context, _ datasource.SchemaReques
|
|||
"sgw_acl": schema.StringAttribute{
|
||||
Computed: true,
|
||||
},
|
||||
"consumer_timeout": schema.Int64Attribute{
|
||||
Computed: true,
|
||||
},
|
||||
"enable_monitoring": schema.BoolAttribute{
|
||||
Computed: true,
|
||||
},
|
||||
"graphite": schema.StringAttribute{
|
||||
Computed: true,
|
||||
},
|
||||
"max_disk_threshold": schema.Int64Attribute{
|
||||
Computed: true,
|
||||
},
|
||||
"metrics_frequency": schema.Int64Attribute{
|
||||
Computed: true,
|
||||
},
|
||||
"metrics_prefix": schema.StringAttribute{
|
||||
Computed: true,
|
||||
},
|
||||
"monitoring_instance_id": schema.StringAttribute{
|
||||
Computed: true,
|
||||
},
|
||||
"plugins": schema.ListAttribute{
|
||||
ElementType: types.StringType,
|
||||
Computed: true,
|
||||
},
|
||||
"roles": schema.ListAttribute{
|
||||
ElementType: types.StringType,
|
||||
Computed: true,
|
||||
},
|
||||
"syslog": schema.ListAttribute{
|
||||
ElementType: types.StringType,
|
||||
Computed: true,
|
||||
},
|
||||
"tls_ciphers": schema.ListAttribute{
|
||||
ElementType: types.StringType,
|
||||
Computed: true,
|
||||
},
|
||||
"tls_protocols": schema.StringAttribute{
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
Computed: true,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -52,12 +52,36 @@ type Model struct {
|
|||
|
||||
// Struct corresponding to DataSourceModel.Parameters
|
||||
type parametersModel struct {
|
||||
SgwAcl types.String `tfsdk:"sgw_acl"`
|
||||
SgwAcl types.String `tfsdk:"sgw_acl"`
|
||||
ConsumerTimeout types.Int64 `tfsdk:"consumer_timeout"`
|
||||
EnableMonitoring types.Bool `tfsdk:"enable_monitoring"`
|
||||
Graphite types.String `tfsdk:"graphite"`
|
||||
MaxDiskThreshold types.Int64 `tfsdk:"max_disk_threshold"`
|
||||
MetricsFrequency types.Int64 `tfsdk:"metrics_frequency"`
|
||||
MetricsPrefix types.String `tfsdk:"metrics_prefix"`
|
||||
MonitoringInstanceId types.String `tfsdk:"monitoring_instance_id"`
|
||||
Plugins types.List `tfsdk:"plugins"`
|
||||
Roles types.List `tfsdk:"roles"`
|
||||
Syslog types.List `tfsdk:"syslog"`
|
||||
TlsCiphers types.List `tfsdk:"tls_ciphers"`
|
||||
TlsProtocols types.String `tfsdk:"tls_protocols"`
|
||||
}
|
||||
|
||||
// Types corresponding to parametersModel
|
||||
var parametersTypes = map[string]attr.Type{
|
||||
"sgw_acl": basetypes.StringType{},
|
||||
"sgw_acl": basetypes.StringType{},
|
||||
"consumer_timeout": basetypes.Int64Type{},
|
||||
"enable_monitoring": basetypes.BoolType{},
|
||||
"graphite": basetypes.StringType{},
|
||||
"max_disk_threshold": basetypes.Int64Type{},
|
||||
"metrics_frequency": basetypes.Int64Type{},
|
||||
"metrics_prefix": basetypes.StringType{},
|
||||
"monitoring_instance_id": basetypes.StringType{},
|
||||
"plugins": basetypes.ListType{ElemType: types.StringType},
|
||||
"roles": basetypes.ListType{ElemType: types.StringType},
|
||||
"syslog": basetypes.ListType{ElemType: types.StringType},
|
||||
"tls_ciphers": basetypes.ListType{ElemType: types.StringType},
|
||||
"tls_protocols": basetypes.StringType{},
|
||||
}
|
||||
|
||||
// NewInstanceResource is a helper function to simplify the provider implementation.
|
||||
|
|
@ -124,6 +148,22 @@ 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.",
|
||||
"consumer_timeout": "The timeout in milliseconds for the consumer.",
|
||||
"enable_monitoring": "Enable monitoring.",
|
||||
"graphite": "Graphite server URL (host and port). If set, monitoring with Graphite will be enabled.",
|
||||
"max_disk_threshold": "The maximum disk threshold in MB. If the disk usage exceeds this threshold, the instance will be stopped.",
|
||||
"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",
|
||||
"monitoring_instance_id": "The monitoring instance ID.",
|
||||
"plugins": "List of plugins to install. Must be a supported plugin name.",
|
||||
"roles": "List of roles to assign to the instance.",
|
||||
"syslog": "List of syslog servers to send logs to.",
|
||||
"tls_ciphers": "List of TLS ciphers to use.",
|
||||
"tls_protocols": "TLS protocol to use.",
|
||||
}
|
||||
|
||||
resp.Schema = schema.Schema{
|
||||
Description: descriptions["main"],
|
||||
Attributes: map[string]schema.Attribute{
|
||||
|
|
@ -183,8 +223,73 @@ 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,
|
||||
},
|
||||
"consumer_timeout": schema.Int64Attribute{
|
||||
Description: parametersDescriptions["consumer_timeout"],
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
"enable_monitoring": schema.BoolAttribute{
|
||||
Description: parametersDescriptions["enable_monitoring"],
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
"graphite": schema.StringAttribute{
|
||||
Description: parametersDescriptions["graphite"],
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
"max_disk_threshold": schema.Int64Attribute{
|
||||
Description: parametersDescriptions["max_disk_threshold"],
|
||||
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,
|
||||
},
|
||||
"monitoring_instance_id": schema.StringAttribute{
|
||||
Description: parametersDescriptions["monitoring_instance_id"],
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
"plugins": schema.ListAttribute{
|
||||
Description: parametersDescriptions["plugins"],
|
||||
ElementType: types.StringType,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
"roles": schema.ListAttribute{
|
||||
Description: parametersDescriptions["roles"],
|
||||
ElementType: types.StringType,
|
||||
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_protocols": schema.StringAttribute{
|
||||
Description: parametersDescriptions["tls_protocols"],
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
Optional: true,
|
||||
|
|
@ -488,7 +593,17 @@ func mapFields(instance *rabbitmq.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 the attribute names (tls-ciphers, tls-protocols)
|
||||
if attribute == "tls_ciphers" || attribute == "tls_protocols" {
|
||||
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 +699,12 @@ func toCreatePayload(model *Model, parameters *parametersModel) (*rabbitmq.Creat
|
|||
if model == nil {
|
||||
return nil, fmt.Errorf("nil model")
|
||||
}
|
||||
if parameters == nil {
|
||||
return &rabbitmq.CreateInstancePayload{
|
||||
InstanceName: conversion.StringValueToPointer(model.Name),
|
||||
PlanId: conversion.StringValueToPointer(model.PlanId),
|
||||
}, nil
|
||||
}
|
||||
payloadParams := &rabbitmq.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 &rabbitmq.CreateInstancePayload{
|
||||
InstanceName: conversion.StringValueToPointer(model.Name),
|
||||
Parameters: payloadParams,
|
||||
|
|
@ -606,19 +717,57 @@ func toUpdatePayload(model *Model, parameters *parametersModel) (*rabbitmq.Parti
|
|||
return nil, fmt.Errorf("nil model")
|
||||
}
|
||||
|
||||
if parameters == nil {
|
||||
return &rabbitmq.PartialUpdateInstancePayload{
|
||||
PlanId: conversion.StringValueToPointer(model.PlanId),
|
||||
}, nil
|
||||
payloadParams, err := toInstanceParams(parameters)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("converting parameters: %w", err)
|
||||
}
|
||||
|
||||
return &rabbitmq.PartialUpdateInstancePayload{
|
||||
Parameters: &rabbitmq.InstanceParameters{
|
||||
SgwAcl: conversion.StringValueToPointer(parameters.SgwAcl),
|
||||
},
|
||||
PlanId: conversion.StringValueToPointer(model.PlanId),
|
||||
Parameters: payloadParams,
|
||||
PlanId: conversion.StringValueToPointer(model.PlanId),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func toInstanceParams(parameters *parametersModel) (*rabbitmq.InstanceParameters, error) {
|
||||
if parameters == nil {
|
||||
return nil, nil
|
||||
}
|
||||
payloadParams := &rabbitmq.InstanceParameters{}
|
||||
|
||||
payloadParams.SgwAcl = conversion.StringValueToPointer(parameters.SgwAcl)
|
||||
payloadParams.ConsumerTimeout = conversion.Int64ValueToPointer(parameters.ConsumerTimeout)
|
||||
payloadParams.EnableMonitoring = conversion.BoolValueToPointer(parameters.EnableMonitoring)
|
||||
payloadParams.Graphite = conversion.StringValueToPointer(parameters.Graphite)
|
||||
payloadParams.MaxDiskThreshold = conversion.Int64ValueToPointer(parameters.MaxDiskThreshold)
|
||||
payloadParams.MetricsFrequency = conversion.Int64ValueToPointer(parameters.MetricsFrequency)
|
||||
payloadParams.MetricsPrefix = conversion.StringValueToPointer(parameters.MetricsPrefix)
|
||||
payloadParams.MonitoringInstanceId = conversion.StringValueToPointer(parameters.MonitoringInstanceId)
|
||||
payloadParams.TlsProtocols = conversion.StringValueToPointer(parameters.TlsProtocols)
|
||||
|
||||
var err error
|
||||
payloadParams.Plugins, err = conversion.StringListToPointer(parameters.Plugins)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("converting plugins: %w", err)
|
||||
}
|
||||
|
||||
payloadParams.Roles, err = conversion.StringListToPointer(parameters.Roles)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("converting roles: %w", err)
|
||||
}
|
||||
|
||||
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()
|
||||
|
|
|
|||
|
|
@ -1,15 +1,61 @@
|
|||
package rabbitmq
|
||||
|
||||
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/rabbitmq"
|
||||
)
|
||||
|
||||
var fixtureModelParameters = types.ObjectValueMust(parametersTypes, map[string]attr.Value{
|
||||
"sgw_acl": types.StringValue("acl"),
|
||||
"consumer_timeout": types.Int64Value(10),
|
||||
"enable_monitoring": types.BoolValue(true),
|
||||
"graphite": types.StringValue("1.1.1.1:91"),
|
||||
"max_disk_threshold": types.Int64Value(100),
|
||||
"metrics_frequency": types.Int64Value(10),
|
||||
"metrics_prefix": types.StringValue("prefix"),
|
||||
"monitoring_instance_id": types.StringValue("mid"),
|
||||
"plugins": types.ListValueMust(types.StringType, []attr.Value{
|
||||
types.StringValue("plugin1"),
|
||||
types.StringValue("plugin2"),
|
||||
}),
|
||||
"roles": types.ListValueMust(types.StringType, []attr.Value{
|
||||
types.StringValue("role1"),
|
||||
types.StringValue("role2"),
|
||||
}),
|
||||
"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_protocols": types.StringValue("protocol1"),
|
||||
})
|
||||
|
||||
var fixtureInstanceParameters = rabbitmq.InstanceParameters{
|
||||
SgwAcl: utils.Ptr("acl"),
|
||||
ConsumerTimeout: utils.Ptr(int64(10)),
|
||||
EnableMonitoring: utils.Ptr(true),
|
||||
Graphite: utils.Ptr("1.1.1.1:91"),
|
||||
MaxDiskThreshold: utils.Ptr(int64(100)),
|
||||
MetricsFrequency: utils.Ptr(int64(10)),
|
||||
MetricsPrefix: utils.Ptr("prefix"),
|
||||
MonitoringInstanceId: utils.Ptr("mid"),
|
||||
Plugins: &[]string{"plugin1", "plugin2"},
|
||||
Roles: &[]string{"role1", "role2"},
|
||||
Syslog: &[]string{"syslog", "syslog2"},
|
||||
TlsCiphers: &[]string{"ciphers1", "ciphers2"},
|
||||
TlsProtocols: utils.Ptr("protocol1"),
|
||||
}
|
||||
|
||||
func TestMapFields(t *testing.T) {
|
||||
tests := []struct {
|
||||
description string
|
||||
|
|
@ -47,7 +93,19 @@ func TestMapFields(t *testing.T) {
|
|||
Name: utils.Ptr("name"),
|
||||
CfOrganizationGuid: utils.Ptr("org"),
|
||||
Parameters: &map[string]interface{}{
|
||||
"sgw_acl": "acl",
|
||||
"sgw_acl": "acl",
|
||||
"consumer_timeout": 10,
|
||||
"enable_monitoring": true,
|
||||
"graphite": "1.1.1.1:91",
|
||||
"max_disk_threshold": 100,
|
||||
"metrics_frequency": 10,
|
||||
"metrics_prefix": "prefix",
|
||||
"monitoring_instance_id": "mid",
|
||||
"plugins": []string{"plugin1", "plugin2"},
|
||||
"roles": []string{"role1", "role2"},
|
||||
"syslog": []string{"syslog", "syslog2"},
|
||||
"tls-ciphers": []string{"ciphers1", "ciphers2"},
|
||||
"tls-protocols": "protocol1",
|
||||
},
|
||||
},
|
||||
Model{
|
||||
|
|
@ -61,12 +119,11 @@ 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,
|
||||
},
|
||||
|
||||
{
|
||||
"nil_response",
|
||||
nil,
|
||||
|
|
@ -125,16 +182,14 @@ func TestMapFields(t *testing.T) {
|
|||
|
||||
func TestToCreatePayload(t *testing.T) {
|
||||
tests := []struct {
|
||||
description string
|
||||
input *Model
|
||||
inputParameters *parametersModel
|
||||
expected *rabbitmq.CreateInstancePayload
|
||||
isValid bool
|
||||
description string
|
||||
input *Model
|
||||
expected *rabbitmq.CreateInstancePayload
|
||||
isValid bool
|
||||
}{
|
||||
{
|
||||
"default_values",
|
||||
&Model{},
|
||||
¶metersModel{},
|
||||
&rabbitmq.CreateInstancePayload{
|
||||
Parameters: &rabbitmq.InstanceParameters{},
|
||||
},
|
||||
|
|
@ -143,43 +198,34 @@ func TestToCreatePayload(t *testing.T) {
|
|||
{
|
||||
"simple_values",
|
||||
&Model{
|
||||
Name: types.StringValue("name"),
|
||||
PlanId: types.StringValue("plan"),
|
||||
},
|
||||
¶metersModel{
|
||||
SgwAcl: types.StringValue("sgw"),
|
||||
Name: types.StringValue("name"),
|
||||
PlanId: types.StringValue("plan"),
|
||||
Parameters: fixtureModelParameters,
|
||||
},
|
||||
&rabbitmq.CreateInstancePayload{
|
||||
InstanceName: utils.Ptr("name"),
|
||||
Parameters: &rabbitmq.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(""),
|
||||
},
|
||||
¶metersModel{
|
||||
SgwAcl: types.StringNull(),
|
||||
Name: types.StringValue(""),
|
||||
PlanId: types.StringValue(""),
|
||||
Parameters: fixtureModelParameters,
|
||||
},
|
||||
&rabbitmq.CreateInstancePayload{
|
||||
InstanceName: utils.Ptr(""),
|
||||
Parameters: &rabbitmq.InstanceParameters{
|
||||
SgwAcl: nil,
|
||||
},
|
||||
PlanId: utils.Ptr(""),
|
||||
PlanId: utils.Ptr(""),
|
||||
Parameters: &fixtureInstanceParameters,
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"nil_model",
|
||||
nil,
|
||||
¶metersModel{},
|
||||
nil,
|
||||
false,
|
||||
},
|
||||
|
|
@ -189,17 +235,26 @@ func TestToCreatePayload(t *testing.T) {
|
|||
Name: types.StringValue("name"),
|
||||
PlanId: types.StringValue("plan"),
|
||||
},
|
||||
nil,
|
||||
&rabbitmq.CreateInstancePayload{
|
||||
InstanceName: utils.Ptr("name"),
|
||||
PlanId: utils.Ptr("plan"),
|
||||
Parameters: &rabbitmq.InstanceParameters{},
|
||||
},
|
||||
true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.description, func(t *testing.T) {
|
||||
output, err := toCreatePayload(tt.input, tt.inputParameters)
|
||||
var parameters = ¶metersModel{}
|
||||
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 +273,14 @@ func TestToCreatePayload(t *testing.T) {
|
|||
|
||||
func TestToUpdatePayload(t *testing.T) {
|
||||
tests := []struct {
|
||||
description string
|
||||
input *Model
|
||||
inputParameters *parametersModel
|
||||
expected *rabbitmq.PartialUpdateInstancePayload
|
||||
isValid bool
|
||||
description string
|
||||
input *Model
|
||||
expected *rabbitmq.PartialUpdateInstancePayload
|
||||
isValid bool
|
||||
}{
|
||||
{
|
||||
"default_values",
|
||||
&Model{},
|
||||
¶metersModel{},
|
||||
&rabbitmq.PartialUpdateInstancePayload{
|
||||
Parameters: &rabbitmq.InstanceParameters{},
|
||||
},
|
||||
|
|
@ -236,39 +289,31 @@ func TestToUpdatePayload(t *testing.T) {
|
|||
{
|
||||
"simple_values",
|
||||
&Model{
|
||||
PlanId: types.StringValue("plan"),
|
||||
},
|
||||
¶metersModel{
|
||||
SgwAcl: types.StringValue("sgw"),
|
||||
Name: types.StringValue("name"),
|
||||
PlanId: types.StringValue("plan"),
|
||||
Parameters: fixtureModelParameters,
|
||||
},
|
||||
&rabbitmq.PartialUpdateInstancePayload{
|
||||
Parameters: &rabbitmq.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(""),
|
||||
},
|
||||
¶metersModel{
|
||||
SgwAcl: types.StringNull(),
|
||||
PlanId: types.StringValue(""),
|
||||
Parameters: fixtureModelParameters,
|
||||
},
|
||||
&rabbitmq.PartialUpdateInstancePayload{
|
||||
Parameters: &rabbitmq.InstanceParameters{
|
||||
SgwAcl: nil,
|
||||
},
|
||||
PlanId: utils.Ptr(""),
|
||||
Parameters: &fixtureInstanceParameters,
|
||||
PlanId: utils.Ptr(""),
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"nil_model",
|
||||
nil,
|
||||
¶metersModel{},
|
||||
nil,
|
||||
false,
|
||||
},
|
||||
|
|
@ -277,16 +322,25 @@ func TestToUpdatePayload(t *testing.T) {
|
|||
&Model{
|
||||
PlanId: types.StringValue("plan"),
|
||||
},
|
||||
nil,
|
||||
&rabbitmq.PartialUpdateInstancePayload{
|
||||
PlanId: utils.Ptr("plan"),
|
||||
PlanId: utils.Ptr("plan"),
|
||||
Parameters: &rabbitmq.InstanceParameters{},
|
||||
},
|
||||
true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.description, func(t *testing.T) {
|
||||
output, err := toUpdatePayload(tt.input, tt.inputParameters)
|
||||
var parameters = ¶metersModel{}
|
||||
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")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,11 +28,30 @@ var instanceResource = map[string]string{
|
|||
"sgw_acl_valid": "192.168.0.0/16",
|
||||
}
|
||||
|
||||
func resourceConfig(acls *string) string {
|
||||
aclsLine := ""
|
||||
if acls != nil {
|
||||
aclsLine = fmt.Sprintf(`sgw_acl = %q`, *acls)
|
||||
func parametersConfig(params map[string]string) string {
|
||||
nonStringParams := []string{
|
||||
"consumer_timeout",
|
||||
"enable_monitoring",
|
||||
"max_disk_threshold",
|
||||
"metrics_frequency",
|
||||
"plugins",
|
||||
"roles",
|
||||
"syslog",
|
||||
"tls_ciphers",
|
||||
}
|
||||
parameters := "parameters = {"
|
||||
for k, v := range params {
|
||||
if utils.Contains(nonStringParams, k) {
|
||||
parameters += fmt.Sprintf("%s = %s\n", k, v)
|
||||
} else {
|
||||
parameters += fmt.Sprintf("%s = %q\n", k, v)
|
||||
}
|
||||
}
|
||||
parameters += "\n}"
|
||||
return parameters
|
||||
}
|
||||
|
||||
func resourceConfig(params map[string]string) string {
|
||||
return fmt.Sprintf(`
|
||||
%s
|
||||
|
||||
|
|
@ -41,10 +60,7 @@ func resourceConfig(acls *string) string {
|
|||
name = "%s"
|
||||
plan_name = "%s"
|
||||
version = "%s"
|
||||
parameters = {
|
||||
%s
|
||||
metrics_frequency = "%s"
|
||||
}
|
||||
%s
|
||||
}
|
||||
|
||||
%s
|
||||
|
|
@ -54,34 +70,7 @@ func resourceConfig(acls *string) string {
|
|||
instanceResource["name"],
|
||||
instanceResource["plan_name"],
|
||||
instanceResource["version"],
|
||||
aclsLine,
|
||||
instanceResource["metrics_frequency"],
|
||||
resourceConfigCredential(),
|
||||
)
|
||||
}
|
||||
|
||||
func resourceConfigWithUpdate() string {
|
||||
return fmt.Sprintf(`
|
||||
%s
|
||||
|
||||
resource "stackit_rabbitmq_instance" "instance" {
|
||||
project_id = "%s"
|
||||
name = "%s"
|
||||
plan_name = "%s"
|
||||
version = "%s"
|
||||
parameters = {
|
||||
sgw_acl = "%s"
|
||||
}
|
||||
}
|
||||
|
||||
%s
|
||||
`,
|
||||
testutil.RabbitMQProviderConfig(),
|
||||
instanceResource["project_id"],
|
||||
instanceResource["name"],
|
||||
instanceResource["plan_name"],
|
||||
instanceResource["version"],
|
||||
instanceResource["sgw_acl_valid"],
|
||||
parametersConfig(params),
|
||||
resourceConfigCredential(),
|
||||
)
|
||||
}
|
||||
|
|
@ -103,12 +92,24 @@ func TestAccRabbitMQResource(t *testing.T) {
|
|||
Steps: []resource.TestStep{
|
||||
// Creation fail
|
||||
{
|
||||
Config: resourceConfig(&acls),
|
||||
Config: resourceConfig(map[string]string{"sgw_acl": acls}),
|
||||
ExpectError: regexp.MustCompile(`.*sgw_acl is invalid.*`),
|
||||
},
|
||||
// Creation
|
||||
{
|
||||
Config: resourceConfig(nil),
|
||||
Config: resourceConfig(map[string]string{
|
||||
"sgw_acl": instanceResource["sgw_acl_valid"],
|
||||
"consumer_timeout": "1800000",
|
||||
"enable_monitoring": "true",
|
||||
"graphite": "graphite.example.com:2003",
|
||||
"max_disk_threshold": "80",
|
||||
"metrics_frequency": "60",
|
||||
"metrics_prefix": "rabbitmq",
|
||||
"plugins": `["rabbitmq_federation"]`,
|
||||
"roles": `["administrator"]`,
|
||||
"syslog": `["syslog.example.com:514"]`,
|
||||
"tls_ciphers": `["TLS_AES_128_GCM_SHA256"]`,
|
||||
}),
|
||||
Check: resource.ComposeAggregateTestCheckFunc(
|
||||
// Instance data
|
||||
resource.TestCheckResourceAttr("stackit_rabbitmq_instance.instance", "project_id", instanceResource["project_id"]),
|
||||
|
|
@ -117,7 +118,23 @@ func TestAccRabbitMQResource(t *testing.T) {
|
|||
resource.TestCheckResourceAttr("stackit_rabbitmq_instance.instance", "plan_name", instanceResource["plan_name"]),
|
||||
resource.TestCheckResourceAttr("stackit_rabbitmq_instance.instance", "version", instanceResource["version"]),
|
||||
resource.TestCheckResourceAttr("stackit_rabbitmq_instance.instance", "name", instanceResource["name"]),
|
||||
resource.TestCheckResourceAttrSet("stackit_rabbitmq_instance.instance", "parameters.sgw_acl"),
|
||||
|
||||
// Instance params data
|
||||
resource.TestCheckResourceAttr("stackit_rabbitmq_instance.instance", "parameters.sgw_acl", instanceResource["sgw_acl_valid"]),
|
||||
resource.TestCheckResourceAttr("stackit_rabbitmq_instance.instance", "parameters.consumer_timeout", "1800000"),
|
||||
resource.TestCheckResourceAttr("stackit_rabbitmq_instance.instance", "parameters.enable_monitoring", "true"),
|
||||
resource.TestCheckResourceAttr("stackit_rabbitmq_instance.instance", "parameters.graphite", "graphite.example.com:2003"),
|
||||
resource.TestCheckResourceAttr("stackit_rabbitmq_instance.instance", "parameters.max_disk_threshold", "80"),
|
||||
resource.TestCheckResourceAttr("stackit_rabbitmq_instance.instance", "parameters.metrics_frequency", "60"),
|
||||
resource.TestCheckResourceAttr("stackit_rabbitmq_instance.instance", "parameters.metrics_prefix", "rabbitmq"),
|
||||
resource.TestCheckResourceAttr("stackit_rabbitmq_instance.instance", "parameters.plugins.#", "1"),
|
||||
resource.TestCheckResourceAttr("stackit_rabbitmq_instance.instance", "parameters.plugins.0", "rabbitmq_federation"),
|
||||
resource.TestCheckResourceAttr("stackit_rabbitmq_instance.instance", "parameters.roles.#", "1"),
|
||||
resource.TestCheckResourceAttr("stackit_rabbitmq_instance.instance", "parameters.roles.0", "administrator"),
|
||||
resource.TestCheckResourceAttr("stackit_rabbitmq_instance.instance", "parameters.syslog.#", "1"),
|
||||
resource.TestCheckResourceAttr("stackit_rabbitmq_instance.instance", "parameters.syslog.0", "syslog.example.com:514"),
|
||||
resource.TestCheckResourceAttr("stackit_rabbitmq_instance.instance", "parameters.tls_ciphers.#", "1"),
|
||||
resource.TestCheckResourceAttr("stackit_rabbitmq_instance.instance", "parameters.tls_ciphers.0", "TLS_AES_128_GCM_SHA256"),
|
||||
|
||||
// Credential data
|
||||
resource.TestCheckResourceAttrPair(
|
||||
|
|
@ -209,7 +226,7 @@ func TestAccRabbitMQResource(t *testing.T) {
|
|||
},
|
||||
// Update
|
||||
{
|
||||
Config: resourceConfigWithUpdate(),
|
||||
Config: resourceConfig(map[string]string{"sgw_acl": instanceResource["sgw_acl_valid"]}),
|
||||
Check: resource.ComposeAggregateTestCheckFunc(
|
||||
// Instance data
|
||||
resource.TestCheckResourceAttr("stackit_rabbitmq_instance.instance", "project_id", instanceResource["project_id"]),
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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{},
|
||||
¶metersModel{},
|
||||
&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"),
|
||||
},
|
||||
¶metersModel{
|
||||
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(""),
|
||||
},
|
||||
¶metersModel{
|
||||
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,
|
||||
¶metersModel{},
|
||||
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 = ¶metersModel{}
|
||||
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{},
|
||||
¶metersModel{},
|
||||
&redis.PartialUpdateInstancePayload{
|
||||
Parameters: &redis.InstanceParameters{},
|
||||
},
|
||||
|
|
@ -236,39 +309,30 @@ func TestToUpdatePayload(t *testing.T) {
|
|||
{
|
||||
"simple_values",
|
||||
&Model{
|
||||
PlanId: types.StringValue("plan"),
|
||||
},
|
||||
¶metersModel{
|
||||
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(""),
|
||||
},
|
||||
¶metersModel{
|
||||
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,
|
||||
¶metersModel{},
|
||||
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 = ¶metersModel{}
|
||||
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")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,41 +26,36 @@ var instanceResource = map[string]string{
|
|||
"version": "6",
|
||||
"sgw_acl_invalid": "1.2.3.4/4",
|
||||
"sgw_acl_valid": "192.168.0.0/16",
|
||||
"sgw_acl_valid2": "10.10.10.0/24",
|
||||
}
|
||||
|
||||
func resourceConfig(acls *string) string {
|
||||
aclsLine := ""
|
||||
if acls != nil {
|
||||
aclsLine = fmt.Sprintf(`sgw_acl = %q`, *acls)
|
||||
func parametersConfig(params map[string]string) string {
|
||||
nonStringParams := []string{
|
||||
"down_after_milliseconds",
|
||||
"enable_monitoring",
|
||||
"failover_timeout",
|
||||
"lua_time_limit",
|
||||
"max_disk_threshold",
|
||||
"maxclients",
|
||||
"maxmemory_samples",
|
||||
"metrics_frequency",
|
||||
"min_replicas_max_lag",
|
||||
"syslog",
|
||||
"tls_ciphers",
|
||||
}
|
||||
return fmt.Sprintf(`
|
||||
%s
|
||||
|
||||
resource "stackit_redis_instance" "instance" {
|
||||
project_id = "%s"
|
||||
name = "%s"
|
||||
plan_name = "%s"
|
||||
version = "%s"
|
||||
parameters = {
|
||||
%s
|
||||
metrics_frequency = "%s"
|
||||
}
|
||||
}
|
||||
|
||||
%s
|
||||
`,
|
||||
testutil.RedisProviderConfig(),
|
||||
instanceResource["project_id"],
|
||||
instanceResource["name"],
|
||||
instanceResource["plan_name"],
|
||||
instanceResource["version"],
|
||||
aclsLine,
|
||||
instanceResource["metrics_frequency"],
|
||||
resourceConfigCredential(),
|
||||
)
|
||||
parameters := "parameters = {"
|
||||
for k, v := range params {
|
||||
if utils.Contains(nonStringParams, k) {
|
||||
parameters += fmt.Sprintf("%s = %s\n", k, v)
|
||||
} else {
|
||||
parameters += fmt.Sprintf("%s = %q\n", k, v)
|
||||
}
|
||||
}
|
||||
parameters += "\n}"
|
||||
return parameters
|
||||
}
|
||||
|
||||
func resourceConfigWithUpdate() string {
|
||||
func resourceConfig(params map[string]string) string {
|
||||
return fmt.Sprintf(`
|
||||
%s
|
||||
|
||||
|
|
@ -69,9 +64,7 @@ func resourceConfigWithUpdate() string {
|
|||
name = "%s"
|
||||
plan_name = "%s"
|
||||
version = "%s"
|
||||
parameters = {
|
||||
sgw_acl = "%s"
|
||||
}
|
||||
%s
|
||||
}
|
||||
|
||||
%s
|
||||
|
|
@ -81,7 +74,7 @@ func resourceConfigWithUpdate() string {
|
|||
instanceResource["name"],
|
||||
instanceResource["plan_name"],
|
||||
instanceResource["version"],
|
||||
instanceResource["sgw_acl_valid"],
|
||||
parametersConfig(params),
|
||||
resourceConfigCredential(),
|
||||
)
|
||||
}
|
||||
|
|
@ -96,19 +89,38 @@ func resourceConfigCredential() string {
|
|||
}
|
||||
|
||||
func TestAccRedisResource(t *testing.T) {
|
||||
acls := instanceResource["sgw_acl_invalid"]
|
||||
resource.Test(t, resource.TestCase{
|
||||
ProtoV6ProviderFactories: testutil.TestAccProtoV6ProviderFactories,
|
||||
CheckDestroy: testAccCheckRedisDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
// Creation fail
|
||||
{
|
||||
Config: resourceConfig(&acls),
|
||||
Config: resourceConfig(map[string]string{"sgw_acl": instanceResource["sgw_acl_invalid"]}),
|
||||
ExpectError: regexp.MustCompile(`.*sgw_acl is invalid.*`),
|
||||
},
|
||||
// Creation
|
||||
{
|
||||
Config: resourceConfig(nil),
|
||||
Config: resourceConfig(map[string]string{
|
||||
"sgw_acl": instanceResource["sgw_acl_valid"],
|
||||
"down_after_milliseconds": "10000",
|
||||
"enable_monitoring": "false",
|
||||
"failover_timeout": "30000",
|
||||
"graphite": "graphite.example.com:2003",
|
||||
"lazyfree_lazy_eviction": "no",
|
||||
"lazyfree_lazy_expire": "no",
|
||||
"lua_time_limit": "5000",
|
||||
"max_disk_threshold": "80",
|
||||
"maxclients": "10000",
|
||||
"maxmemory_policy": "volatile-lru",
|
||||
"maxmemory_samples": "5",
|
||||
"metrics_frequency": "10",
|
||||
"metrics_prefix": "prefix",
|
||||
"min_replicas_max_lag": "15",
|
||||
"monitoring_instance_id": "mid",
|
||||
"notify_keyspace_events": "Ex",
|
||||
"syslog": `["syslog.example.com:123"]`,
|
||||
"tls_protocols": "TLSv1.2",
|
||||
}),
|
||||
Check: resource.ComposeAggregateTestCheckFunc(
|
||||
// Instance data
|
||||
resource.TestCheckResourceAttr("stackit_redis_instance.instance", "project_id", instanceResource["project_id"]),
|
||||
|
|
@ -117,7 +129,28 @@ func TestAccRedisResource(t *testing.T) {
|
|||
resource.TestCheckResourceAttr("stackit_redis_instance.instance", "plan_name", instanceResource["plan_name"]),
|
||||
resource.TestCheckResourceAttr("stackit_redis_instance.instance", "version", instanceResource["version"]),
|
||||
resource.TestCheckResourceAttr("stackit_redis_instance.instance", "name", instanceResource["name"]),
|
||||
resource.TestCheckResourceAttrSet("stackit_redis_instance.instance", "parameters.sgw_acl"),
|
||||
|
||||
// Instance Params data
|
||||
resource.TestCheckResourceAttr("stackit_redis_instance.instance", "parameters.sgw_acl", instanceResource["sgw_acl_valid"]),
|
||||
resource.TestCheckResourceAttr("stackit_redis_instance.instance", "parameters.down_after_milliseconds", "10000"),
|
||||
resource.TestCheckResourceAttr("stackit_redis_instance.instance", "parameters.enable_monitoring", "false"),
|
||||
resource.TestCheckResourceAttr("stackit_redis_instance.instance", "parameters.failover_timeout", "30000"),
|
||||
resource.TestCheckResourceAttr("stackit_redis_instance.instance", "parameters.graphite", "graphite.example.com:2003"),
|
||||
resource.TestCheckResourceAttr("stackit_redis_instance.instance", "parameters.lazyfree_lazy_eviction", "no"),
|
||||
resource.TestCheckResourceAttr("stackit_redis_instance.instance", "parameters.lazyfree_lazy_expire", "no"),
|
||||
resource.TestCheckResourceAttr("stackit_redis_instance.instance", "parameters.lua_time_limit", "5000"),
|
||||
resource.TestCheckResourceAttr("stackit_redis_instance.instance", "parameters.max_disk_threshold", "80"),
|
||||
resource.TestCheckResourceAttr("stackit_redis_instance.instance", "parameters.maxclients", "10000"),
|
||||
resource.TestCheckResourceAttr("stackit_redis_instance.instance", "parameters.maxmemory_policy", "volatile-lru"),
|
||||
resource.TestCheckResourceAttr("stackit_redis_instance.instance", "parameters.maxmemory_samples", "5"),
|
||||
resource.TestCheckResourceAttr("stackit_redis_instance.instance", "parameters.metrics_frequency", "10"),
|
||||
resource.TestCheckResourceAttr("stackit_redis_instance.instance", "parameters.metrics_prefix", "prefix"),
|
||||
resource.TestCheckResourceAttr("stackit_redis_instance.instance", "parameters.min_replicas_max_lag", "15"),
|
||||
resource.TestCheckResourceAttr("stackit_redis_instance.instance", "parameters.monitoring_instance_id", "mid"),
|
||||
resource.TestCheckResourceAttr("stackit_redis_instance.instance", "parameters.notify_keyspace_events", "Ex"),
|
||||
resource.TestCheckResourceAttr("stackit_redis_instance.instance", "parameters.syslog.#", "1"),
|
||||
resource.TestCheckResourceAttr("stackit_redis_instance.instance", "parameters.syslog.0", "syslog.example.com:123"),
|
||||
resource.TestCheckResourceAttr("stackit_redis_instance.instance", "parameters.tls_protocols", "TLSv1.2"),
|
||||
|
||||
// Credential data
|
||||
resource.TestCheckResourceAttrPair(
|
||||
|
|
@ -208,7 +241,7 @@ func TestAccRedisResource(t *testing.T) {
|
|||
},
|
||||
// Update
|
||||
{
|
||||
Config: resourceConfigWithUpdate(),
|
||||
Config: resourceConfig(map[string]string{"sgw_acl": instanceResource["sgw_acl_valid2"]}),
|
||||
Check: resource.ComposeAggregateTestCheckFunc(
|
||||
// Instance data
|
||||
resource.TestCheckResourceAttr("stackit_redis_instance.instance", "project_id", instanceResource["project_id"]),
|
||||
|
|
@ -217,7 +250,7 @@ func TestAccRedisResource(t *testing.T) {
|
|||
resource.TestCheckResourceAttr("stackit_redis_instance.instance", "plan_name", instanceResource["plan_name"]),
|
||||
resource.TestCheckResourceAttr("stackit_redis_instance.instance", "version", instanceResource["version"]),
|
||||
resource.TestCheckResourceAttr("stackit_redis_instance.instance", "name", instanceResource["name"]),
|
||||
resource.TestCheckResourceAttr("stackit_redis_instance.instance", "parameters.sgw_acl", instanceResource["sgw_acl_valid"]),
|
||||
resource.TestCheckResourceAttr("stackit_redis_instance.instance", "parameters.sgw_acl", instanceResource["sgw_acl_valid2"]),
|
||||
),
|
||||
},
|
||||
// Deletion is done by the framework implicitly
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue