Skip to content

Commit 8953152

Browse files
committed
feat(cockpit): add default_preconfigured_alert_ids field to track API defaults
1 parent a963535 commit 8953152

File tree

4 files changed

+74
-40
lines changed

4 files changed

+74
-40
lines changed

docs/resources/cockpit_alert_manager.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ resource "scaleway_cockpit_alert_manager" "alert_manager" {
8989

9090
This section lists the arguments that are supported:
9191

92-
- `preconfigured_alert_ids` - (Optional, Set of String) A set of preconfigured alert rule IDs to enable. Use the [`scaleway_cockpit_preconfigured_alert`](../data-sources/cockpit_preconfigured_alert.md) data source to list available alerts.
92+
- `preconfigured_alert_ids` - (Optional, Set of String) A set of preconfigured alert rule IDs to enable explicitly. Use the [`scaleway_cockpit_preconfigured_alert`](../data-sources/cockpit_preconfigured_alert.md) data source to list available alerts.
9393
- `enable_managed_alerts` - **Deprecated** (Optional, Boolean) Use `preconfigured_alert_ids` instead. This field will be removed in a future version.
9494
- `contact_points` - (Optional, List of Map) A list of contact points with email addresses that will receive alerts. Each map should contain a single key `email`.
9595
- `project_id` - (Defaults to the Project ID specified in the [provider configuration](../index.md#project_id)) The ID of the Project the Cockpit is associated with.
@@ -100,6 +100,7 @@ This section lists the arguments that are supported:
100100
In addition to all arguments above, the following attributes are exported:
101101

102102
- `alert_manager_url` - The URL of the alert manager.
103+
- `default_preconfigured_alert_ids` - (Set of String) A set of preconfigured alert rule IDs that are enabled automatically by the API when the alert manager is activated. This is a computed field that shows which alerts the API enables by default.
103104

104105

105106
## Import

internal/services/cockpit/alert_manager.go

Lines changed: 54 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,13 @@ func ResourceCockpitAlertManager() *schema.Resource {
3636
"preconfigured_alert_ids": {
3737
Type: schema.TypeSet,
3838
Optional: true,
39-
Description: "List of preconfigured alert rule IDs to enable. Use the scaleway_cockpit_preconfigured_alert data source to list available alerts.",
39+
Description: "List of preconfigured alert rule IDs to enable explicitly. Use the scaleway_cockpit_preconfigured_alert data source to list available alerts.",
40+
Elem: &schema.Schema{Type: schema.TypeString},
41+
},
42+
"default_preconfigured_alert_ids": {
43+
Type: schema.TypeSet,
44+
Computed: true,
45+
Description: "List of preconfigured alert rule IDs enabled automatically by the API when alert manager is activated.",
4046
Elem: &schema.Schema{Type: schema.TypeString},
4147
},
4248
"contact_points": {
@@ -94,8 +100,8 @@ func ResourceCockpitAlertManagerCreate(ctx context.Context, d *schema.ResourceDa
94100
return diag.FromErr(err)
95101
}
96102

97-
// Note: Waiting for alerts to be enabled will be handled by SDK waiters when available
98-
// For now, we continue without waiting as the Read function handles enabling/enabled states
103+
// Note: Waiting for alerts to be enabled will be handled by SDK waiters when available
104+
// For now, we continue without waiting as the Read function handles enabling/enabled states
99105
}
100106
}
101107

@@ -158,49 +164,59 @@ func ResourceCockpitAlertManagerRead(ctx context.Context, d *schema.ResourceData
158164
_ = d.Set("alert_manager_url", alertManager.AlertManagerURL)
159165
_ = d.Set("project_id", projectID)
160166

161-
// Get enabled preconfigured alerts
162-
// Only track the alerts that were explicitly requested by the user in the configuration.
163-
// The API may enable additional alerts automatically, but we ignore those to prevent perpetual drift.
164-
// We set the field based on what was requested in the config, not what the API returns.
165-
if v, ok := d.GetOk("preconfigured_alert_ids"); ok {
166-
requestedIDs := expandStringSet(v.(*schema.Set))
167-
168-
// List all preconfigured alerts to verify their status
169-
alerts, err := api.ListAlerts(&cockpit.RegionalAPIListAlertsRequest{
170-
Region: region,
171-
ProjectID: projectID,
172-
IsPreconfigured: scw.BoolPtr(true),
173-
}, scw.WithContext(ctx), scw.WithAllPages())
174-
if err != nil {
175-
return diag.FromErr(err)
167+
// Get enabled preconfigured alerts and separate user-requested vs API-default alerts
168+
alerts, err := api.ListAlerts(&cockpit.RegionalAPIListAlertsRequest{
169+
Region: region,
170+
ProjectID: projectID,
171+
IsPreconfigured: scw.BoolPtr(true),
172+
}, scw.WithContext(ctx), scw.WithAllPages())
173+
if err != nil {
174+
return diag.FromErr(err)
175+
}
176+
177+
// Build a map of alert statuses
178+
alertStatusMap := make(map[string]cockpit.AlertStatus)
179+
for _, alert := range alerts.Alerts {
180+
if alert.PreconfiguredData != nil && alert.PreconfiguredData.PreconfiguredRuleID != "" {
181+
alertStatusMap[alert.PreconfiguredData.PreconfiguredRuleID] = alert.RuleStatus
176182
}
183+
}
177184

178-
// Build a map of alert statuses
179-
alertStatusMap := make(map[string]cockpit.AlertStatus)
180-
for _, alert := range alerts.Alerts {
181-
if alert.PreconfiguredData != nil && alert.PreconfiguredData.PreconfiguredRuleID != "" {
182-
alertStatusMap[alert.PreconfiguredData.PreconfiguredRuleID] = alert.RuleStatus
183-
}
185+
// Separate user-requested alerts from API-default alerts
186+
var userRequestedIDs []string
187+
var defaultEnabledIDs []string
188+
189+
if v, ok := d.GetOk("preconfigured_alert_ids"); ok {
190+
requestedIDs := expandStringSet(v.(*schema.Set))
191+
requestedMap := make(map[string]bool)
192+
for _, id := range requestedIDs {
193+
requestedMap[id] = true
184194
}
185195

186-
// Keep the requested IDs that are enabled/enabling
187-
// This ensures we only track what the user explicitly configured
188-
var enabledRequestedIDs []string
189-
for _, requestedID := range requestedIDs {
190-
if status, found := alertStatusMap[requestedID]; found {
191-
// Include if enabled or enabling
192-
if status == cockpit.AlertStatusEnabled || status == cockpit.AlertStatusEnabling {
193-
enabledRequestedIDs = append(enabledRequestedIDs, requestedID)
196+
// Check all enabled/enabling alerts
197+
for ruleID, status := range alertStatusMap {
198+
if status == cockpit.AlertStatusEnabled || status == cockpit.AlertStatusEnabling {
199+
if requestedMap[ruleID] {
200+
// This alert was explicitly requested by the user
201+
userRequestedIDs = append(userRequestedIDs, ruleID)
202+
} else {
203+
// This alert was enabled automatically by the API
204+
defaultEnabledIDs = append(defaultEnabledIDs, ruleID)
194205
}
195206
}
196207
}
197-
198-
_ = d.Set("preconfigured_alert_ids", enabledRequestedIDs)
199208
} else {
200-
// No alerts requested, set empty list
201-
_ = d.Set("preconfigured_alert_ids", []string{})
209+
// No alerts explicitly requested, all enabled alerts are API defaults
210+
for ruleID, status := range alertStatusMap {
211+
if status == cockpit.AlertStatusEnabled || status == cockpit.AlertStatusEnabling {
212+
defaultEnabledIDs = append(defaultEnabledIDs, ruleID)
213+
}
214+
}
202215
}
203216

217+
_ = d.Set("preconfigured_alert_ids", userRequestedIDs)
218+
_ = d.Set("default_preconfigured_alert_ids", defaultEnabledIDs)
219+
204220
contactPoints, err := api.ListContactPoints(&cockpit.RegionalAPIListContactPointsRequest{
205221
Region: region,
206222
ProjectID: projectID,
@@ -254,7 +270,7 @@ func ResourceCockpitAlertManagerUpdate(ctx context.Context, d *schema.ResourceDa
254270
return diag.FromErr(err)
255271
}
256272

257-
// Note: Waiting for alerts to be disabled will be handled by SDK waiters when available
273+
// Note: Waiting for alerts to be disabled will be handled by SDK waiters when available
258274
}
259275

260276
// IDs to enable: in new but not in old
@@ -269,7 +285,7 @@ func ResourceCockpitAlertManagerUpdate(ctx context.Context, d *schema.ResourceDa
269285
return diag.FromErr(err)
270286
}
271287

272-
// Note: Waiting for alerts to be enabled will be handled by SDK waiters when available
288+
// Note: Waiting for alerts to be enabled will be handled by SDK waiters when available
273289
}
274290
}
275291

internal/services/cockpit/alert_manager_test.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,11 @@ func TestAccCockpitAlertManager_WithPreconfiguredAlerts(t *testing.T) {
413413
resource.TestCheckResourceAttrSet("scaleway_cockpit_alert_manager.main", "region"),
414414
resource.TestCheckResourceAttrSet("scaleway_cockpit_alert_manager.main", "alert_manager_url"),
415415
resource.TestCheckResourceAttr("scaleway_cockpit_alert_manager.main", "contact_points.0.email", "[email protected]"),
416+
resource.TestCheckResourceAttr("scaleway_cockpit_alert_manager.main", "preconfigured_alert_ids.#", "2"),
417+
resource.TestCheckTypeSetElemAttr("scaleway_cockpit_alert_manager.main", "preconfigured_alert_ids.*", "6c6843af-1815-46df-9e52-6feafcf31fd7"),
418+
resource.TestCheckTypeSetElemAttr("scaleway_cockpit_alert_manager.main", "preconfigured_alert_ids.*", "eb8a941e-698d-47d6-b62d-4b6c13f7b4b7"),
419+
// Check that default alerts may be present (computed field)
420+
resource.TestCheckResourceAttrSet("scaleway_cockpit_alert_manager.main", "default_preconfigured_alert_ids.#"),
416421
),
417422
},
418423
},
@@ -449,6 +454,10 @@ func TestAccCockpitAlertManager_UpdatePreconfiguredAlerts(t *testing.T) {
449454
Check: resource.ComposeTestCheckFunc(
450455
resource.TestCheckResourceAttrSet("scaleway_cockpit_alert_manager.main", "project_id"),
451456
testAccCheckPreconfiguredAlertsCount(tt, "scaleway_cockpit_alert_manager.main", 1),
457+
resource.TestCheckResourceAttr("scaleway_cockpit_alert_manager.main", "preconfigured_alert_ids.#", "1"),
458+
resource.TestCheckTypeSetElemAttr("scaleway_cockpit_alert_manager.main", "preconfigured_alert_ids.*", "6c6843af-1815-46df-9e52-6feafcf31fd7"),
459+
// Check that default alerts may be present (computed field)
460+
resource.TestCheckResourceAttrSet("scaleway_cockpit_alert_manager.main", "default_preconfigured_alert_ids.#"),
452461
),
453462
},
454463
{
@@ -473,6 +482,11 @@ func TestAccCockpitAlertManager_UpdatePreconfiguredAlerts(t *testing.T) {
473482
`,
474483
Check: resource.ComposeTestCheckFunc(
475484
testAccCheckPreconfiguredAlertsCount(tt, "scaleway_cockpit_alert_manager.main", 2),
485+
resource.TestCheckResourceAttr("scaleway_cockpit_alert_manager.main", "preconfigured_alert_ids.#", "2"),
486+
resource.TestCheckTypeSetElemAttr("scaleway_cockpit_alert_manager.main", "preconfigured_alert_ids.*", "6c6843af-1815-46df-9e52-6feafcf31fd7"),
487+
resource.TestCheckTypeSetElemAttr("scaleway_cockpit_alert_manager.main", "preconfigured_alert_ids.*", "eb8a941e-698d-47d6-b62d-4b6c13f7b4b7"),
488+
// Check that default alerts may be present (computed field)
489+
resource.TestCheckResourceAttrSet("scaleway_cockpit_alert_manager.main", "default_preconfigured_alert_ids.#"),
476490
),
477491
},
478492
{
@@ -495,6 +509,8 @@ func TestAccCockpitAlertManager_UpdatePreconfiguredAlerts(t *testing.T) {
495509
Check: resource.ComposeTestCheckFunc(
496510
resource.TestCheckResourceAttr("scaleway_cockpit_alert_manager.main", "preconfigured_alert_ids.#", "0"),
497511
testAccCheckPreconfiguredAlertsCount(tt, "scaleway_cockpit_alert_manager.main", 0),
512+
// Default alerts might still be present even when user requests none
513+
resource.TestCheckResourceAttrSet("scaleway_cockpit_alert_manager.main", "default_preconfigured_alert_ids.#"),
498514
),
499515
},
500516
},

templates/resources/cockpit_alert_manager.md.tmpl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ resource "scaleway_cockpit_alert_manager" "alert_manager" {
9090

9191
This section lists the arguments that are supported:
9292

93-
- `preconfigured_alert_ids` - (Optional, Set of String) A set of preconfigured alert rule IDs to enable. Use the [`scaleway_cockpit_preconfigured_alert`](../data-sources/cockpit_preconfigured_alert.md) data source to list available alerts.
93+
- `preconfigured_alert_ids` - (Optional, Set of String) A set of preconfigured alert rule IDs to enable explicitly. Use the [`scaleway_cockpit_preconfigured_alert`](../data-sources/cockpit_preconfigured_alert.md) data source to list available alerts.
9494
- `enable_managed_alerts` - **Deprecated** (Optional, Boolean) Use `preconfigured_alert_ids` instead. This field will be removed in a future version.
9595
- `contact_points` - (Optional, List of Map) A list of contact points with email addresses that will receive alerts. Each map should contain a single key `email`.
9696
- `project_id` - (Defaults to the Project ID specified in the [provider configuration](../index.md#project_id)) The ID of the Project the Cockpit is associated with.
@@ -101,6 +101,7 @@ This section lists the arguments that are supported:
101101
In addition to all arguments above, the following attributes are exported:
102102

103103
- `alert_manager_url` - The URL of the alert manager.
104+
- `default_preconfigured_alert_ids` - (Set of String) A set of preconfigured alert rule IDs that are enabled automatically by the API when the alert manager is activated. This is a computed field that shows which alerts the API enables by default.
104105

105106

106107
## Import

0 commit comments

Comments
 (0)