diff --git a/docs/data-sources/logme_instance.md b/docs/data-sources/logme_instance.md index 9133c239..a212045d 100644 --- a/docs/data-sources/logme_instance.md +++ b/docs/data-sources/logme_instance.md @@ -20,6 +20,7 @@ data "stackit_logme_instance" "example" { ``` + ## Schema ### Required @@ -42,6 +43,7 @@ data "stackit_logme_instance" "example" { - `version` (String) The service version. + ### Nested Schema for `parameters` Read-Only: @@ -63,7 +65,7 @@ Read-Only: - `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 (in seconds). - `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. +- `monitoring_instance_id` (String) The ID of the STACKIT monitoring instance. - `opensearch_tls_ciphers` (List of String) - `opensearch_tls_protocols` (List of String) - `sgw_acl` (String) Comma separated list of IP networks in CIDR notation which are allowed to access this instance. diff --git a/docs/data-sources/mariadb_instance.md b/docs/data-sources/mariadb_instance.md index d055e897..cb465633 100644 --- a/docs/data-sources/mariadb_instance.md +++ b/docs/data-sources/mariadb_instance.md @@ -20,6 +20,7 @@ data "stackit_mariadb_instance" "example" { ``` + ## Schema ### Required @@ -42,8 +43,16 @@ data "stackit_mariadb_instance" "example" { - `version` (String) The service version. + ### Nested Schema for `parameters` Read-Only: -- `sgw_acl` (String) +- `enable_monitoring` (Boolean) Enable monitoring. +- `graphite` (String) +- `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 ID of the STACKIT monitoring 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. diff --git a/docs/data-sources/rabbitmq_instance.md b/docs/data-sources/rabbitmq_instance.md index 05fc6f46..bfd4d339 100644 --- a/docs/data-sources/rabbitmq_instance.md +++ b/docs/data-sources/rabbitmq_instance.md @@ -20,6 +20,7 @@ data "stackit_rabbitmq_instance" "example" { ``` + ## Schema ### Required @@ -42,6 +43,7 @@ data "stackit_rabbitmq_instance" "example" { - `version` (String) The service version. + ### Nested Schema for `parameters` Read-Only: @@ -52,7 +54,7 @@ Read-Only: - `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. +- `monitoring_instance_id` (String) The ID of the STACKIT monitoring instance. - `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. diff --git a/docs/data-sources/redis_instance.md b/docs/data-sources/redis_instance.md index 244ef30b..bc5d27c0 100644 --- a/docs/data-sources/redis_instance.md +++ b/docs/data-sources/redis_instance.md @@ -20,6 +20,7 @@ data "stackit_redis_instance" "example" { ``` + ## Schema ### Required @@ -42,6 +43,7 @@ data "stackit_redis_instance" "example" { - `version` (String) The service version. + ### Nested Schema for `parameters` Read-Only: @@ -60,7 +62,7 @@ Read-Only: - `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. +- `monitoring_instance_id` (String) The ID of the STACKIT monitoring instance. - `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. diff --git a/docs/resources/logme_instance.md b/docs/resources/logme_instance.md index 43200f76..496fc144 100644 --- a/docs/resources/logme_instance.md +++ b/docs/resources/logme_instance.md @@ -25,6 +25,7 @@ resource "stackit_logme_instance" "example" { ``` + ## Schema ### Required @@ -50,6 +51,7 @@ resource "stackit_logme_instance" "example" { - `plan_id` (String) The selected plan ID. + ### Nested Schema for `parameters` Optional: @@ -71,7 +73,7 @@ Optional: - `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 (in seconds). - `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. +- `monitoring_instance_id` (String) The ID of the STACKIT monitoring instance. - `opensearch_tls_ciphers` (List of String) - `opensearch_tls_protocols` (List of String) - `sgw_acl` (String) Comma separated list of IP networks in CIDR notation which are allowed to access this instance. diff --git a/docs/resources/mariadb_instance.md b/docs/resources/mariadb_instance.md index ab4715fa..198e3156 100644 --- a/docs/resources/mariadb_instance.md +++ b/docs/resources/mariadb_instance.md @@ -25,6 +25,7 @@ resource "stackit_mariadb_instance" "example" { ``` + ## Schema ### Required @@ -50,8 +51,16 @@ resource "stackit_mariadb_instance" "example" { - `plan_id` (String) The selected plan ID. + ### Nested Schema for `parameters` Optional: -- `sgw_acl` (String) +- `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 ID of the STACKIT monitoring 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. diff --git a/docs/resources/rabbitmq_instance.md b/docs/resources/rabbitmq_instance.md index 53cfc979..a226b9d9 100644 --- a/docs/resources/rabbitmq_instance.md +++ b/docs/resources/rabbitmq_instance.md @@ -28,6 +28,7 @@ resource "stackit_rabbitmq_instance" "example" { ``` + ## Schema ### Required @@ -53,6 +54,7 @@ resource "stackit_rabbitmq_instance" "example" { - `plan_id` (String) The selected plan ID. + ### Nested Schema for `parameters` Optional: @@ -63,7 +65,7 @@ Optional: - `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. +- `monitoring_instance_id` (String) The ID of the STACKIT monitoring instance. - `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. diff --git a/docs/resources/redis_instance.md b/docs/resources/redis_instance.md index aa020b24..2fc770bd 100644 --- a/docs/resources/redis_instance.md +++ b/docs/resources/redis_instance.md @@ -28,6 +28,7 @@ resource "stackit_redis_instance" "example" { ``` + ## Schema ### Required @@ -53,6 +54,7 @@ resource "stackit_redis_instance" "example" { - `plan_id` (String) The selected plan ID. + ### Nested Schema for `parameters` Optional: @@ -71,7 +73,7 @@ Optional: - `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. +- `monitoring_instance_id` (String) The ID of the STACKIT monitoring instance. - `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. diff --git a/stackit/internal/services/logme/instance/datasource.go b/stackit/internal/services/logme/instance/datasource.go index 0c53d1c4..7b2daf81 100644 --- a/stackit/internal/services/logme/instance/datasource.go +++ b/stackit/internal/services/logme/instance/datasource.go @@ -94,7 +94,7 @@ func (r *instanceDataSource) Schema(_ context.Context, _ datasource.SchemaReques "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 (in seconds).", "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.", + "monitoring_instance_id": "The ID of the STACKIT monitoring instance.", "java_heapspace": "The amount of memory (in MB) allocated as heap by the JVM for OpenSearch.", "java_maxmetaspace": "The amount of memory (in MB) used by the JVM to store metadata for OpenSearch.", "ism_deletion_after": "Combination of an integer and a timerange when an index will be considered \"old\" and can be deleted. Possible values for the timerange are `s`, `m`, `h` and `d`.", diff --git a/stackit/internal/services/logme/instance/resource.go b/stackit/internal/services/logme/instance/resource.go index 9c4ee0c2..6567a7af 100644 --- a/stackit/internal/services/logme/instance/resource.go +++ b/stackit/internal/services/logme/instance/resource.go @@ -177,7 +177,7 @@ func (r *instanceResource) Schema(_ context.Context, _ resource.SchemaRequest, r "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 (in seconds).", "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.", + "monitoring_instance_id": "The ID of the STACKIT monitoring instance.", "java_heapspace": "The amount of memory (in MB) allocated as heap by the JVM for OpenSearch.", "java_maxmetaspace": "The amount of memory (in MB) used by the JVM to store metadata for OpenSearch.", "ism_deletion_after": "Combination of an integer and a timerange when an index will be considered \"old\" and can be deleted. Possible values for the timerange are `s`, `m`, `h` and `d`.", @@ -339,6 +339,10 @@ func (r *instanceResource) Schema(_ context.Context, _ resource.SchemaRequest, r Description: parametersDescriptions["monitoring_instance_id"], Optional: true, Computed: true, + Validators: []validator.String{ + validate.UUID(), + validate.NoSeparator(), + }, }, "opensearch_tls_ciphers": schema.ListAttribute{ Description: parametersDescriptions["opensearch_tls_ciphers"], diff --git a/stackit/internal/services/mariadb/instance/datasource.go b/stackit/internal/services/mariadb/instance/datasource.go index b4849584..3ca1ad16 100644 --- a/stackit/internal/services/mariadb/instance/datasource.go +++ b/stackit/internal/services/mariadb/instance/datasource.go @@ -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" @@ -86,6 +87,16 @@ func (r *instanceDataSource) Schema(_ context.Context, _ datasource.SchemaReques "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.", + "enable_monitoring": "Enable monitoring.", + "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 ID of the STACKIT monitoring instance.", + "syslog": "List of syslog servers to send logs to.", + } + resp.Schema = schema.Schema{ Description: descriptions["main"], Attributes: map[string]schema.Attribute{ @@ -128,7 +139,37 @@ func (r *instanceDataSource) Schema(_ context.Context, _ datasource.SchemaReques "parameters": schema.SingleNestedAttribute{ Attributes: map[string]schema.Attribute{ "sgw_acl": schema.StringAttribute{ - Computed: true, + Description: parametersDescriptions["sgw_acl"], + Computed: true, + }, + "enable_monitoring": schema.BoolAttribute{ + Description: parametersDescriptions["enable_monitoring"], + Computed: true, + }, + "graphite": schema.StringAttribute{ + Description: parametersDescriptions["graphite"], + Computed: true, + }, + "max_disk_threshold": schema.Int64Attribute{ + Description: parametersDescriptions["max_disk_threshold"], + Computed: true, + }, + "metrics_frequency": schema.Int64Attribute{ + Description: parametersDescriptions["metrics_frequency"], + Computed: true, + }, + "metrics_prefix": schema.StringAttribute{ + Description: parametersDescriptions["metrics_prefix"], + Computed: true, + }, + "monitoring_instance_id": schema.StringAttribute{ + Description: parametersDescriptions["monitoring_instance_id"], + Computed: true, + }, + "syslog": schema.ListAttribute{ + Description: parametersDescriptions["syslog"], + ElementType: types.StringType, + Computed: true, }, }, Computed: true, diff --git a/stackit/internal/services/mariadb/instance/resource.go b/stackit/internal/services/mariadb/instance/resource.go index 4cb2d0c8..0ee15a5e 100644 --- a/stackit/internal/services/mariadb/instance/resource.go +++ b/stackit/internal/services/mariadb/instance/resource.go @@ -52,12 +52,26 @@ type Model struct { // Struct corresponding to DataSourceModel.Parameters type parametersModel struct { - SgwAcl types.String `tfsdk:"sgw_acl"` + SgwAcl types.String `tfsdk:"sgw_acl"` + 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"` + Syslog types.List `tfsdk:"syslog"` } // Types corresponding to parametersModel var parametersTypes = map[string]attr.Type{ - "sgw_acl": basetypes.StringType{}, + "sgw_acl": basetypes.StringType{}, + "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{}, + "syslog": basetypes.ListType{ElemType: types.StringType}, } // NewInstanceResource is a helper function to simplify the provider implementation. @@ -124,6 +138,17 @@ 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.", + "graphite": "Graphite server URL (host and port). If set, monitoring with Graphite will be enabled.", + "enable_monitoring": "Enable monitoring.", + "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 ID of the STACKIT monitoring instance.", + "syslog": "List of syslog servers to send logs to.", + } + resp.Schema = schema.Schema{ Description: descriptions["main"], Attributes: map[string]schema.Attribute{ @@ -183,8 +208,49 @@ 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, + }, + "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, + Validators: []validator.String{ + validate.UUID(), + validate.NoSeparator(), + }, + }, + "syslog": schema.ListAttribute{ + Description: parametersDescriptions["syslog"], + ElementType: types.StringType, + Optional: true, + Computed: true, }, }, Optional: true, @@ -235,8 +301,9 @@ func (r *instanceResource) Create(ctx context.Context, req resource.CreateReques projectId := model.ProjectId.ValueString() ctx = tflog.SetField(ctx, "project_id", projectId) - var parameters = ¶metersModel{} + var parameters *parametersModel if !(model.Parameters.IsNull() || model.Parameters.IsUnknown()) { + parameters = ¶metersModel{} diags = model.Parameters.As(ctx, parameters, basetypes.ObjectAsOptions{}) resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { @@ -346,8 +413,9 @@ func (r *instanceResource) Update(ctx context.Context, req resource.UpdateReques ctx = tflog.SetField(ctx, "project_id", projectId) ctx = tflog.SetField(ctx, "instance_id", instanceId) - var parameters = ¶metersModel{} + var parameters *parametersModel if !(model.Parameters.IsNull() || model.Parameters.IsUnknown()) { + parameters = ¶metersModel{} diags = model.Parameters.As(ctx, parameters, basetypes.ObjectAsOptions{}) resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { @@ -584,20 +652,14 @@ func toCreatePayload(model *Model, parameters *parametersModel) (*mariadb.Create if model == nil { return nil, fmt.Errorf("nil model") } - if parameters == nil { - return &mariadb.CreateInstancePayload{ - InstanceName: conversion.StringValueToPointer(model.Name), - PlanId: conversion.StringValueToPointer(model.PlanId), - }, nil - } - payloadParams := &mariadb.InstanceParameters{} - if parameters.SgwAcl.ValueString() != "" { - payloadParams.SgwAcl = conversion.StringValueToPointer(parameters.SgwAcl) + payloadParams, err := toInstanceParams(parameters) + if err != nil { + return nil, fmt.Errorf("convert parameters: %w", err) } return &mariadb.CreateInstancePayload{ InstanceName: conversion.StringValueToPointer(model.Name), - Parameters: payloadParams, PlanId: conversion.StringValueToPointer(model.PlanId), + Parameters: payloadParams, }, nil } @@ -605,20 +667,39 @@ func toUpdatePayload(model *Model, parameters *parametersModel) (*mariadb.Partia if model == nil { return nil, fmt.Errorf("nil model") } - - if parameters == nil { - return &mariadb.PartialUpdateInstancePayload{ - PlanId: conversion.StringValueToPointer(model.PlanId), - }, nil + payloadParams, err := toInstanceParams(parameters) + if err != nil { + return nil, fmt.Errorf("convert parameters: %w", err) } return &mariadb.PartialUpdateInstancePayload{ - Parameters: &mariadb.InstanceParameters{ - SgwAcl: conversion.StringValueToPointer(parameters.SgwAcl), - }, - PlanId: conversion.StringValueToPointer(model.PlanId), + PlanId: conversion.StringValueToPointer(model.PlanId), + Parameters: payloadParams, }, nil } +func toInstanceParams(parameters *parametersModel) (*mariadb.InstanceParameters, error) { + if parameters == nil { + return nil, nil + } + payloadParams := &mariadb.InstanceParameters{} + + payloadParams.SgwAcl = conversion.StringValueToPointer(parameters.SgwAcl) + 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) + + syslog, err := conversion.StringListToPointer(parameters.Syslog) + if err != nil { + return nil, fmt.Errorf("convert syslog: %w", err) + } + payloadParams.Syslog = syslog + + 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() diff --git a/stackit/internal/services/mariadb/instance/resource_test.go b/stackit/internal/services/mariadb/instance/resource_test.go index baa349d9..c9a1af9d 100644 --- a/stackit/internal/services/mariadb/instance/resource_test.go +++ b/stackit/internal/services/mariadb/instance/resource_test.go @@ -1,15 +1,53 @@ package mariadb 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/mariadb" ) +var fixtureModelParameters = types.ObjectValueMust(parametersTypes, map[string]attr.Value{ + "sgw_acl": types.StringValue("acl"), + "enable_monitoring": types.BoolValue(true), + "graphite": types.StringValue("graphite"), + "max_disk_threshold": types.Int64Value(10), + "metrics_frequency": types.Int64Value(10), + "metrics_prefix": types.StringValue("prefix"), + "monitoring_instance_id": types.StringValue("mid"), + "syslog": types.ListValueMust(types.StringType, []attr.Value{ + types.StringValue("syslog"), + types.StringValue("syslog2"), + }), +}) + +var fixtureNullModelParameters = types.ObjectValueMust(parametersTypes, map[string]attr.Value{ + "sgw_acl": types.StringNull(), + "enable_monitoring": types.BoolNull(), + "graphite": types.StringNull(), + "max_disk_threshold": types.Int64Null(), + "metrics_frequency": types.Int64Null(), + "metrics_prefix": types.StringNull(), + "monitoring_instance_id": types.StringNull(), + "syslog": types.ListNull(types.StringType), +}) + +var fixtureInstanceParameters = mariadb.InstanceParameters{ + SgwAcl: utils.Ptr("acl"), + EnableMonitoring: utils.Ptr(true), + Graphite: utils.Ptr("graphite"), + MaxDiskThreshold: utils.Ptr(int64(10)), + MetricsFrequency: utils.Ptr(int64(10)), + MetricsPrefix: utils.Ptr("prefix"), + MonitoringInstanceId: utils.Ptr("mid"), + Syslog: &[]string{"syslog", "syslog2"}, +} + func TestMapFields(t *testing.T) { tests := []struct { description string @@ -47,7 +85,14 @@ func TestMapFields(t *testing.T) { Name: utils.Ptr("name"), CfOrganizationGuid: utils.Ptr("org"), Parameters: &map[string]interface{}{ - "sgw_acl": "acl", + "sgw_acl": "acl", + "enable_monitoring": true, + "graphite": "graphite", + "max_disk_threshold": int64(10), + "metrics_frequency": int64(10), + "metrics_prefix": "prefix", + "monitoring_instance_id": "mid", + "syslog": []string{"syslog", "syslog2"}, }, }, Model{ @@ -61,9 +106,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,61 +168,48 @@ func TestMapFields(t *testing.T) { func TestToCreatePayload(t *testing.T) { tests := []struct { - description string - input *Model - inputParameters *parametersModel - expected *mariadb.CreateInstancePayload - isValid bool + description string + input *Model + expected *mariadb.CreateInstancePayload + isValid bool }{ { "default_values", &Model{}, - ¶metersModel{}, - &mariadb.CreateInstancePayload{ - Parameters: &mariadb.InstanceParameters{}, - }, + &mariadb.CreateInstancePayload{}, true, }, { "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, }, &mariadb.CreateInstancePayload{ InstanceName: utils.Ptr("name"), - Parameters: &mariadb.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: fixtureNullModelParameters, }, &mariadb.CreateInstancePayload{ InstanceName: utils.Ptr(""), - Parameters: &mariadb.InstanceParameters{ - SgwAcl: nil, - }, - PlanId: utils.Ptr(""), + Parameters: &mariadb.InstanceParameters{}, + PlanId: utils.Ptr(""), }, true, }, { "nil_model", nil, - ¶metersModel{}, nil, false, }, @@ -189,7 +219,6 @@ func TestToCreatePayload(t *testing.T) { Name: types.StringValue("name"), PlanId: types.StringValue("plan"), }, - nil, &mariadb.CreateInstancePayload{ InstanceName: utils.Ptr("name"), PlanId: utils.Ptr("plan"), @@ -199,7 +228,17 @@ func TestToCreatePayload(t *testing.T) { } 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()) { + parameters = ¶metersModel{} + 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,57 +257,44 @@ func TestToCreatePayload(t *testing.T) { func TestToUpdatePayload(t *testing.T) { tests := []struct { - description string - input *Model - inputParameters *parametersModel - expected *mariadb.PartialUpdateInstancePayload - isValid bool + description string + input *Model + expected *mariadb.PartialUpdateInstancePayload + isValid bool }{ { "default_values", &Model{}, - ¶metersModel{}, - &mariadb.PartialUpdateInstancePayload{ - Parameters: &mariadb.InstanceParameters{}, - }, + &mariadb.PartialUpdateInstancePayload{}, true, }, { "simple_values", &Model{ - PlanId: types.StringValue("plan"), - }, - ¶metersModel{ - SgwAcl: types.StringValue("sgw"), + PlanId: types.StringValue("plan"), + Parameters: fixtureModelParameters, }, &mariadb.PartialUpdateInstancePayload{ - Parameters: &mariadb.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: fixtureNullModelParameters, }, &mariadb.PartialUpdateInstancePayload{ - Parameters: &mariadb.InstanceParameters{ - SgwAcl: nil, - }, - PlanId: utils.Ptr(""), + Parameters: &mariadb.InstanceParameters{}, + PlanId: utils.Ptr(""), }, true, }, { "nil_model", nil, - ¶metersModel{}, nil, false, }, @@ -277,7 +303,6 @@ func TestToUpdatePayload(t *testing.T) { &Model{ PlanId: types.StringValue("plan"), }, - nil, &mariadb.PartialUpdateInstancePayload{ PlanId: utils.Ptr("plan"), }, @@ -286,7 +311,17 @@ func TestToUpdatePayload(t *testing.T) { } 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()) { + parameters = ¶metersModel{} + 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") } diff --git a/stackit/internal/services/mariadb/mariadb_acc_test.go b/stackit/internal/services/mariadb/mariadb_acc_test.go index 2d0caa63..a9207763 100644 --- a/stackit/internal/services/mariadb/mariadb_acc_test.go +++ b/stackit/internal/services/mariadb/mariadb_acc_test.go @@ -18,16 +18,39 @@ import ( // Instance resource data var instanceResource = map[string]string{ - "project_id": testutil.ProjectId, - "name": testutil.ResourceNameWithDateTime("mariadb"), - "plan_id": "683be856-3587-42de-b1b5-a792ff854f52", - "plan_name": "stackit-mariadb-1.4.10-single", - "version": "10.6", - "sgw_acl-1": "192.168.0.0/16", - "sgw_acl-2": "192.168.0.0/24", + "project_id": testutil.ProjectId, + "name": testutil.ResourceNameWithDateTime("mariadb"), + "plan_id": "683be856-3587-42de-b1b5-a792ff854f52", + "plan_name": "stackit-mariadb-1.4.10-single", + "version": "10.6", + "sgw_acl-1": "192.168.0.0/16", + "sgw_acl-2": "192.168.0.0/24", + "max_disk_threshold": "80", + "enable_monitoring": "false", + "metrics_prefix": "stackit_acc", + "syslog-0": "syslog.example.com:514", } -func resourceConfig(acls string) string { +func parametersConfig(params map[string]string) string { + nonStringParams := []string{ + "enable_monitoring", + "max_disk_threshold", + "metrics_frequency", + "syslog", + } + 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 @@ -36,9 +59,7 @@ func resourceConfig(acls string) string { name = "%s" plan_name = "%s" version = "%s" - parameters = { - sgw_acl = "%s" - } + %s } resource "stackit_mariadb_credential" "credential" { @@ -51,7 +72,7 @@ func resourceConfig(acls string) string { instanceResource["name"], instanceResource["plan_name"], instanceResource["version"], - acls, + parametersConfig(params), ) } func TestAccMariaDBResource(t *testing.T) { @@ -62,7 +83,15 @@ func TestAccMariaDBResource(t *testing.T) { // Creation { - Config: resourceConfig(instanceResource["sgw_acl-1"]), + Config: resourceConfig( + map[string]string{ + "sgw_acl": instanceResource["sgw_acl-1"], + "max_disk_threshold": instanceResource["max_disk_threshold"], + "metrics_frequency": "10", + "enable_monitoring": instanceResource["enable_monitoring"], + "metrics_prefix": instanceResource["metrics_prefix"], + "syslog": fmt.Sprintf(`[%q]`, instanceResource["syslog-0"]), + }), Check: resource.ComposeAggregateTestCheckFunc( // Instance data resource.TestCheckResourceAttr("stackit_mariadb_instance.instance", "project_id", instanceResource["project_id"]), @@ -72,6 +101,12 @@ func TestAccMariaDBResource(t *testing.T) { resource.TestCheckResourceAttr("stackit_mariadb_instance.instance", "version", instanceResource["version"]), resource.TestCheckResourceAttr("stackit_mariadb_instance.instance", "name", instanceResource["name"]), resource.TestCheckResourceAttr("stackit_mariadb_instance.instance", "parameters.sgw_acl", instanceResource["sgw_acl-1"]), + resource.TestCheckResourceAttr("stackit_mariadb_instance.instance", "parameters.max_disk_threshold", instanceResource["max_disk_threshold"]), + resource.TestCheckResourceAttr("stackit_mariadb_instance.instance", "parameters.metrics_frequency", "10"), + resource.TestCheckResourceAttr("stackit_mariadb_instance.instance", "parameters.enable_monitoring", instanceResource["enable_monitoring"]), + resource.TestCheckResourceAttr("stackit_mariadb_instance.instance", "parameters.metrics_prefix", instanceResource["metrics_prefix"]), + resource.TestCheckResourceAttr("stackit_mariadb_instance.instance", "parameters.syslog.#", "1"), + resource.TestCheckResourceAttr("stackit_mariadb_instance.instance", "parameters.syslog.0", instanceResource["syslog-0"]), // Credential data resource.TestCheckResourceAttrPair( @@ -101,7 +136,14 @@ func TestAccMariaDBResource(t *testing.T) { instance_id = stackit_mariadb_credential.credential.instance_id credential_id = stackit_mariadb_credential.credential.credential_id }`, - resourceConfig(instanceResource["sgw_acl-1"]), + resourceConfig(map[string]string{ + "sgw_acl": instanceResource["sgw_acl-1"], + "max_disk_threshold": instanceResource["max_disk_threshold"], + "metrics_frequency": "10", + "enable_monitoring": instanceResource["enable_monitoring"], + "metrics_prefix": instanceResource["metrics_prefix"], + "syslog": fmt.Sprintf(`[%q]`, instanceResource["syslog-0"]), + }), ), Check: resource.ComposeAggregateTestCheckFunc( // Instance data @@ -113,6 +155,12 @@ func TestAccMariaDBResource(t *testing.T) { resource.TestCheckResourceAttr("data.stackit_mariadb_instance.instance", "plan_id", instanceResource["plan_id"]), resource.TestCheckResourceAttr("data.stackit_mariadb_instance.instance", "name", instanceResource["name"]), resource.TestCheckResourceAttr("data.stackit_mariadb_instance.instance", "parameters.sgw_acl", instanceResource["sgw_acl-1"]), + resource.TestCheckResourceAttr("data.stackit_mariadb_instance.instance", "parameters.max_disk_threshold", instanceResource["max_disk_threshold"]), + resource.TestCheckResourceAttr("stackit_mariadb_instance.instance", "parameters.metrics_frequency", "10"), + resource.TestCheckResourceAttr("data.stackit_mariadb_instance.instance", "parameters.enable_monitoring", instanceResource["enable_monitoring"]), + resource.TestCheckResourceAttr("data.stackit_mariadb_instance.instance", "parameters.metrics_prefix", instanceResource["metrics_prefix"]), + resource.TestCheckResourceAttr("data.stackit_mariadb_instance.instance", "parameters.syslog.#", "1"), + resource.TestCheckResourceAttr("data.stackit_mariadb_instance.instance", "parameters.syslog.0", instanceResource["syslog-0"]), // Credential data resource.TestCheckResourceAttr("data.stackit_mariadb_credential.credential", "project_id", instanceResource["project_id"]), @@ -161,7 +209,14 @@ func TestAccMariaDBResource(t *testing.T) { }, // Update { - Config: resourceConfig(instanceResource["sgw_acl-2"]), + Config: resourceConfig(map[string]string{ + "sgw_acl": instanceResource["sgw_acl-2"], + "max_disk_threshold": instanceResource["max_disk_threshold"], + "metrics_frequency": "10", + "enable_monitoring": instanceResource["enable_monitoring"], + "metrics_prefix": instanceResource["metrics_prefix"], + "syslog": fmt.Sprintf(`[%q]`, instanceResource["syslog-0"]), + }), Check: resource.ComposeAggregateTestCheckFunc( // Instance data resource.TestCheckResourceAttr("stackit_mariadb_instance.instance", "project_id", instanceResource["project_id"]), @@ -171,6 +226,12 @@ func TestAccMariaDBResource(t *testing.T) { resource.TestCheckResourceAttr("stackit_mariadb_instance.instance", "version", instanceResource["version"]), resource.TestCheckResourceAttr("stackit_mariadb_instance.instance", "name", instanceResource["name"]), resource.TestCheckResourceAttr("stackit_mariadb_instance.instance", "parameters.sgw_acl", instanceResource["sgw_acl-2"]), + resource.TestCheckResourceAttr("stackit_mariadb_instance.instance", "parameters.max_disk_threshold", instanceResource["max_disk_threshold"]), + resource.TestCheckResourceAttr("stackit_mariadb_instance.instance", "parameters.metrics_frequency", "10"), + resource.TestCheckResourceAttr("stackit_mariadb_instance.instance", "parameters.enable_monitoring", instanceResource["enable_monitoring"]), + resource.TestCheckResourceAttr("stackit_mariadb_instance.instance", "parameters.metrics_prefix", instanceResource["metrics_prefix"]), + resource.TestCheckResourceAttr("stackit_mariadb_instance.instance", "parameters.syslog.#", "1"), + resource.TestCheckResourceAttr("stackit_mariadb_instance.instance", "parameters.syslog.0", instanceResource["syslog-0"]), ), }, // Deletion is done by the framework implicitly diff --git a/stackit/internal/services/rabbitmq/instance/datasource.go b/stackit/internal/services/rabbitmq/instance/datasource.go index 90826308..221c728e 100644 --- a/stackit/internal/services/rabbitmq/instance/datasource.go +++ b/stackit/internal/services/rabbitmq/instance/datasource.go @@ -95,7 +95,7 @@ func (r *instanceDataSource) Schema(_ context.Context, _ datasource.SchemaReques "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.", + "monitoring_instance_id": "The ID of the STACKIT monitoring instance.", "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.", diff --git a/stackit/internal/services/rabbitmq/instance/resource.go b/stackit/internal/services/rabbitmq/instance/resource.go index c69a53da..74dfe409 100644 --- a/stackit/internal/services/rabbitmq/instance/resource.go +++ b/stackit/internal/services/rabbitmq/instance/resource.go @@ -156,7 +156,7 @@ func (r *instanceResource) Schema(_ context.Context, _ resource.SchemaRequest, r "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.", + "monitoring_instance_id": "The ID of the STACKIT monitoring instance.", "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.", @@ -261,6 +261,10 @@ func (r *instanceResource) Schema(_ context.Context, _ resource.SchemaRequest, r Description: parametersDescriptions["monitoring_instance_id"], Optional: true, Computed: true, + Validators: []validator.String{ + validate.UUID(), + validate.NoSeparator(), + }, }, "plugins": schema.ListAttribute{ Description: parametersDescriptions["plugins"], diff --git a/stackit/internal/services/redis/instance/datasource.go b/stackit/internal/services/redis/instance/datasource.go index 59792dad..d764e8d0 100644 --- a/stackit/internal/services/redis/instance/datasource.go +++ b/stackit/internal/services/redis/instance/datasource.go @@ -103,7 +103,7 @@ func (r *instanceDataSource) Schema(_ context.Context, _ datasource.SchemaReques "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.", + "monitoring_instance_id": "The ID of the STACKIT monitoring instance.", "notify_keyspace_events": "The notify keyspace events.", "snapshot": "The snapshot configuration.", "syslog": "List of syslog servers to send logs to.", diff --git a/stackit/internal/services/redis/instance/resource.go b/stackit/internal/services/redis/instance/resource.go index d90a9bb8..7f384155 100644 --- a/stackit/internal/services/redis/instance/resource.go +++ b/stackit/internal/services/redis/instance/resource.go @@ -183,7 +183,7 @@ func (r *instanceResource) Schema(_ context.Context, _ resource.SchemaRequest, r "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.", + "monitoring_instance_id": "The ID of the STACKIT monitoring instance.", "notify_keyspace_events": "The notify keyspace events.", "snapshot": "The snapshot configuration.", "syslog": "List of syslog servers to send logs to.", @@ -329,6 +329,10 @@ func (r *instanceResource) Schema(_ context.Context, _ resource.SchemaRequest, r Description: parametersDescriptions["monitoring_instance_id"], Optional: true, Computed: true, + Validators: []validator.String{ + validate.UUID(), + validate.NoSeparator(), + }, }, "notify_keyspace_events": schema.StringAttribute{ Description: parametersDescriptions["notify_keyspace_events"],