From 1fc2a2792bcebc509c79bdf1374746a6a2f8ff2c Mon Sep 17 00:00:00 2001 From: mitterle-sit <195103606+mitterle-sit@users.noreply.github.com> Date: Thu, 9 Oct 2025 14:32:41 +0200 Subject: [PATCH 1/4] feat(observability/instance): add PlanModifiers Computed and Opsgenie nil handler --- .../observability/instance/resource.go | 55 ++++++++++++++++++- 1 file changed, 53 insertions(+), 2 deletions(-) diff --git a/stackit/internal/services/observability/instance/resource.go b/stackit/internal/services/observability/instance/resource.go index accf435db..b59a6932b 100644 --- a/stackit/internal/services/observability/instance/resource.go +++ b/stackit/internal/services/observability/instance/resource.go @@ -8,6 +8,7 @@ import ( "strings" "github.com/google/go-cmp/cmp" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64planmodifier" "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/utils" observabilityUtils "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/services/observability/utils" @@ -459,6 +460,9 @@ func (r *instanceResource) Schema(_ context.Context, _ resource.SchemaRequest, r Validators: []validator.String{ validate.UUID(), }, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, }, "parameters": schema.MapAttribute{ Description: "Additional parameters.", @@ -516,16 +520,25 @@ func (r *instanceResource) Schema(_ context.Context, _ resource.SchemaRequest, r Description: "Specifies for how many days the raw metrics are kept. Default is set to `90`.", Optional: true, Computed: true, + PlanModifiers: []planmodifier.Int64{ + int64planmodifier.UseStateForUnknown(), + }, }, "metrics_retention_days_5m_downsampling": schema.Int64Attribute{ Description: "Specifies for how many days the 5m downsampled metrics are kept. must be less than the value of the general retention. Default is set to `90`.", Optional: true, Computed: true, + PlanModifiers: []planmodifier.Int64{ + int64planmodifier.UseStateForUnknown(), + }, }, "metrics_retention_days_1h_downsampling": schema.Int64Attribute{ Description: "Specifies for how many days the 1h downsampled metrics are kept. must be less than the value of the 5m downsampling retention. Default is set to `90`.", Optional: true, Computed: true, + PlanModifiers: []planmodifier.Int64{ + int64planmodifier.UseStateForUnknown(), + }, }, "metrics_url": schema.StringAttribute{ Description: "Specifies metrics URL.", @@ -777,10 +790,18 @@ func (r *instanceResource) Schema(_ context.Context, _ resource.SchemaRequest, r Description: "The API key for OpsGenie.", Optional: true, Sensitive: true, + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, }, "opsgenie_api_url": schema.StringAttribute{ Description: "The host to send OpsGenie API requests to. Must be a valid URL", Optional: true, + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, }, "resolve_timeout": schema.StringAttribute{ Description: "The default value used by alertmanager if the alert does not include EndsAt. After this time passes, it can declare the alert as resolved if it has not been updated. This has no impact on alerts from Prometheus, as they always include EndsAt.", @@ -793,24 +814,43 @@ func (r *instanceResource) Schema(_ context.Context, _ resource.SchemaRequest, r "smtp_auth_identity": schema.StringAttribute{ Description: "SMTP authentication information. Must be a valid email address", Optional: true, + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, }, "smtp_auth_password": schema.StringAttribute{ Description: "SMTP Auth using LOGIN and PLAIN.", Optional: true, Sensitive: true, + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, }, "smtp_auth_username": schema.StringAttribute{ Description: "SMTP Auth using CRAM-MD5, LOGIN and PLAIN. If empty, Alertmanager doesn't authenticate to the SMTP server.", Optional: true, + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, }, "smtp_from": schema.StringAttribute{ Description: "The default SMTP From header field. Must be a valid email address", Optional: true, Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, }, "smtp_smart_host": schema.StringAttribute{ Description: "The default SMTP smarthost used for sending emails, including port number in format `host:port` (eg. `smtp.example.com:587`). Port number usually is 25, or 587 for SMTP over TLS (sometimes referred to as STARTTLS).", Optional: true, + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, }, }, }, @@ -1619,10 +1659,21 @@ func mapGlobalConfigToAttributes(respGlobalConfigs *observability.Global, global smtpAuthUsername = sdkUtils.Ptr(globalConfigsTF.SmtpAuthUsername.ValueString()) } } + //handle nil value from api + opsgenieApiKey := respGlobalConfigs.OpsgenieApiKey + opsgenieApiUrl := respGlobalConfigs.OpsgenieApiUrl + if globalConfigsTF != nil { + if respGlobalConfigs.OpsgenieApiKey == nil { + opsgenieApiKey = sdkUtils.Ptr(globalConfigsTF.OpsgenieApiKey.ValueString()) + } + if respGlobalConfigs.OpsgenieApiUrl == nil { + opsgenieApiUrl = sdkUtils.Ptr(globalConfigsTF.OpsgenieApiUrl.ValueString()) + } + } globalConfigObject, diags := types.ObjectValue(globalConfigurationTypes, map[string]attr.Value{ - "opsgenie_api_key": types.StringPointerValue(respGlobalConfigs.OpsgenieApiKey), - "opsgenie_api_url": types.StringPointerValue(respGlobalConfigs.OpsgenieApiUrl), + "opsgenie_api_key": types.StringPointerValue(opsgenieApiKey), + "opsgenie_api_url": types.StringPointerValue(opsgenieApiUrl), "resolve_timeout": types.StringPointerValue(respGlobalConfigs.ResolveTimeout), "smtp_from": types.StringPointerValue(respGlobalConfigs.SmtpFrom), "smtp_auth_identity": types.StringPointerValue(smtpAuthIdentity), From 1b7bc0597834e64dadbd12788e2112061a089d6b Mon Sep 17 00:00:00 2001 From: mitterle-sit <195103606+mitterle-sit@users.noreply.github.com> Date: Wed, 29 Oct 2025 16:09:42 +0100 Subject: [PATCH 2/4] fix: lint issue --- stackit/internal/services/observability/instance/resource.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stackit/internal/services/observability/instance/resource.go b/stackit/internal/services/observability/instance/resource.go index cc048ba60..0a61f01ed 100644 --- a/stackit/internal/services/observability/instance/resource.go +++ b/stackit/internal/services/observability/instance/resource.go @@ -1834,7 +1834,7 @@ func mapGlobalConfigToAttributes(respGlobalConfigs *observability.Global, global smtpAuthUsername = sdkUtils.Ptr(globalConfigsTF.SmtpAuthUsername.ValueString()) } } - //handle nil value from api + // handle nil value from api opsgenieApiKey := respGlobalConfigs.OpsgenieApiKey opsgenieApiUrl := respGlobalConfigs.OpsgenieApiUrl if globalConfigsTF != nil { From 5280e79085fb717b7a4f7b63340dbd227fbd8d42 Mon Sep 17 00:00:00 2001 From: mitterle-sit <195103606+mitterle-sit@users.noreply.github.com> Date: Mon, 10 Nov 2025 08:19:43 +0100 Subject: [PATCH 3/4] feat: add send_resolved values --- .../internal/services/observability/instance/resource.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/stackit/internal/services/observability/instance/resource.go b/stackit/internal/services/observability/instance/resource.go index 0a61f01ed..ae18391e7 100644 --- a/stackit/internal/services/observability/instance/resource.go +++ b/stackit/internal/services/observability/instance/resource.go @@ -672,6 +672,8 @@ func (r *instanceResource) Schema(_ context.Context, _ resource.SchemaRequest, r "send_resolved": schema.BoolAttribute{ Description: "Whether to notify about resolved alerts.", Optional: true, + Computed: true, + Default: booldefault.StaticBool(true), }, "smart_host": schema.StringAttribute{ Description: "The SMTP host through which emails are sent.", @@ -711,6 +713,8 @@ func (r *instanceResource) Schema(_ context.Context, _ resource.SchemaRequest, r "send_resolved": schema.BoolAttribute{ Description: "Whether to notify about resolved alerts.", Optional: true, + Computed: true, + Default: booldefault.StaticBool(true), }, }, }, @@ -746,6 +750,8 @@ func (r *instanceResource) Schema(_ context.Context, _ resource.SchemaRequest, r "send_resolved": schema.BoolAttribute{ Description: "Whether to notify about resolved alerts.", Optional: true, + Computed: true, + Default: booldefault.StaticBool(true), }, }, }, From 62b3432853c37ac88cfb05075c1b5b67df5b9864 Mon Sep 17 00:00:00 2001 From: mitterle-sit <195103606+mitterle-sit@users.noreply.github.com> Date: Fri, 14 Nov 2025 11:03:31 +0100 Subject: [PATCH 4/4] fix: remove PlanModifiers from plan_id --- stackit/internal/services/observability/instance/resource.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/stackit/internal/services/observability/instance/resource.go b/stackit/internal/services/observability/instance/resource.go index ae18391e7..89a5e03c6 100644 --- a/stackit/internal/services/observability/instance/resource.go +++ b/stackit/internal/services/observability/instance/resource.go @@ -462,9 +462,6 @@ func (r *instanceResource) Schema(_ context.Context, _ resource.SchemaRequest, r Validators: []validator.String{ validate.UUID(), }, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - }, }, "parameters": schema.MapAttribute{ Description: "Additional parameters.",