Skip to content

Commit 59f5bcf

Browse files
authored
fix(cockpit): fix alert manager ID parsing (#3242)
* fix(cockpit): fix alert manager ID parsing * fix lint * fix cassette
1 parent 50c56a5 commit 59f5bcf

File tree

3 files changed

+1434
-7
lines changed

3 files changed

+1434
-7
lines changed

internal/services/cockpit/alert_manager.go

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"errors"
66
"fmt"
7+
"strings"
78

89
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
910
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
@@ -123,7 +124,11 @@ func ResourceCockpitAlertManagerRead(ctx context.Context, d *schema.ResourceData
123124
return diag.FromErr(err)
124125
}
125126

126-
projectID := d.Get("project_id").(string)
127+
// Parse the ID to get projectID
128+
_, projectID, err := ResourceCockpitAlertManagerParseID(d.Id())
129+
if err != nil {
130+
return diag.FromErr(err)
131+
}
127132

128133
alertManager, err := api.GetAlertManager(&cockpit.RegionalAPIGetAlertManagerRequest{
129134
Region: region,
@@ -136,6 +141,7 @@ func ResourceCockpitAlertManagerRead(ctx context.Context, d *schema.ResourceData
136141
_ = d.Set("enable_managed_alerts", alertManager.ManagedAlertsEnabled)
137142
_ = d.Set("region", alertManager.Region)
138143
_ = d.Set("alert_manager_url", alertManager.AlertManagerURL)
144+
_ = d.Set("project_id", projectID)
139145

140146
contactPoints, err := api.ListContactPoints(&cockpit.RegionalAPIListContactPointsRequest{
141147
Region: region,
@@ -167,7 +173,11 @@ func ResourceCockpitAlertManagerUpdate(ctx context.Context, d *schema.ResourceDa
167173
return diag.FromErr(err)
168174
}
169175

170-
projectID := d.Get("project_id").(string)
176+
// Parse the ID to get projectID
177+
_, projectID, err := ResourceCockpitAlertManagerParseID(d.Id())
178+
if err != nil {
179+
return diag.FromErr(err)
180+
}
171181

172182
if d.HasChange("enable_managed_alerts") {
173183
enable := d.Get("enable_managed_alerts").(bool)
@@ -247,7 +257,11 @@ func ResourceCockpitAlertManagerDelete(ctx context.Context, d *schema.ResourceDa
247257
return diag.FromErr(err)
248258
}
249259

250-
projectID := d.Get("project_id").(string)
260+
// Parse the ID to get projectID
261+
_, projectID, err := ResourceCockpitAlertManagerParseID(d.Id())
262+
if err != nil {
263+
return diag.FromErr(err)
264+
}
251265

252266
contactPoints, err := api.ListContactPoints(&cockpit.RegionalAPIListContactPointsRequest{
253267
Region: region,
@@ -291,6 +305,19 @@ func ResourceCockpitAlertManagerDelete(ctx context.Context, d *schema.ResourceDa
291305
return nil
292306
}
293307

308+
// ResourceCockpitAlertManagerID builds the resource identifier
309+
// The resource identifier format is "Region/ProjectID/1"
294310
func ResourceCockpitAlertManagerID(region scw.Region, projectID string) (resourceID string) {
295311
return fmt.Sprintf("%s/%s/1", region, projectID)
296312
}
313+
314+
// ResourceCockpitAlertManagerParseID extracts region and project ID from the resource identifier.
315+
// The resource identifier format is "Region/ProjectID/1"
316+
func ResourceCockpitAlertManagerParseID(resourceID string) (region scw.Region, projectID string, err error) {
317+
parts := strings.Split(resourceID, "/")
318+
if len(parts) != 3 {
319+
return "", "", fmt.Errorf("invalid alert manager ID format: %s", resourceID)
320+
}
321+
322+
return scw.Region(parts[0]), parts[1], nil
323+
}

internal/services/cockpit/alert_manager_test.go

Lines changed: 115 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
package cockpit_test
22

33
import (
4+
"errors"
45
"fmt"
6+
"strconv"
7+
"strings"
58
"testing"
69

710
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
@@ -166,6 +169,67 @@ func TestAccCockpitAlertManager_EnableDisable(t *testing.T) {
166169
})
167170
}
168171

172+
func TestAccCockpitAlertManager_IDHandling(t *testing.T) {
173+
tt := acctest.NewTestTools(t)
174+
defer tt.Cleanup()
175+
176+
resource.ParallelTest(t, resource.TestCase{
177+
PreCheck: func() { acctest.PreCheck(t) },
178+
ProviderFactories: tt.ProviderFactories,
179+
CheckDestroy: testAccCockpitAlertManagerAndContactsDestroy(tt),
180+
Steps: []resource.TestStep{
181+
{
182+
Config: `
183+
resource "scaleway_account_project" "project" {
184+
name = "tf_test_cockpit_alert_manager_id_parsing"
185+
}
186+
187+
resource "scaleway_cockpit_alert_manager" "main" {
188+
project_id = scaleway_account_project.project.id
189+
enable_managed_alerts = true
190+
191+
contact_points {
192+
193+
}
194+
}
195+
`,
196+
Check: resource.ComposeTestCheckFunc(
197+
resource.TestCheckResourceAttrSet("scaleway_cockpit_alert_manager.main", "id"),
198+
resource.TestCheckResourceAttrSet("scaleway_cockpit_alert_manager.main", "project_id"),
199+
resource.TestCheckResourceAttrSet("scaleway_cockpit_alert_manager.main", "region"),
200+
resource.TestCheckResourceAttr("scaleway_cockpit_alert_manager.main", "enable_managed_alerts", "true"),
201+
resource.TestCheckResourceAttrSet("scaleway_cockpit_alert_manager.main", "alert_manager_url"),
202+
resource.TestCheckResourceAttr("scaleway_cockpit_alert_manager.main", "contact_points.0.email", "[email protected]"),
203+
testAccCheckAlertManagerIDFormat(tt, "scaleway_cockpit_alert_manager.main"),
204+
),
205+
},
206+
{
207+
Config: `
208+
resource "scaleway_account_project" "project" {
209+
name = "tf_test_cockpit_alert_manager_id_parsing"
210+
}
211+
212+
resource "scaleway_cockpit_alert_manager" "main" {
213+
project_id = scaleway_account_project.project.id
214+
enable_managed_alerts = true
215+
216+
contact_points {
217+
218+
}
219+
}
220+
`,
221+
Check: resource.ComposeTestCheckFunc(
222+
resource.TestCheckResourceAttrSet("scaleway_cockpit_alert_manager.main", "id"),
223+
resource.TestCheckResourceAttrSet("scaleway_cockpit_alert_manager.main", "project_id"),
224+
resource.TestCheckResourceAttrSet("scaleway_cockpit_alert_manager.main", "region"),
225+
resource.TestCheckResourceAttr("scaleway_cockpit_alert_manager.main", "contact_points.0.email", "[email protected]"),
226+
testAccCheckAlertManagerIDFormat(tt, "scaleway_cockpit_alert_manager.main"),
227+
),
228+
},
229+
},
230+
})
231+
}
232+
169233
func testAccCockpitAlertManagerConfigWithContacts(contactPoints []map[string]string) string {
170234
contactsConfig := ""
171235
for _, contact := range contactPoints {
@@ -205,7 +269,7 @@ func testAccCheckAlertManagerEnabled(tt *acctest.TestTools, resourceName string,
205269
return func(s *terraform.State) error {
206270
rs, ok := s.RootModule().Resources[resourceName]
207271
if !ok {
208-
return fmt.Errorf("alert manager not found: %s", resourceName)
272+
return errors.New("alert manager not found: " + resourceName)
209273
}
210274

211275
api := cockpit.NewRegionalAPI(meta.ExtractScwClient(tt.Meta))
@@ -230,7 +294,7 @@ func testAccCheckCockpitContactPointExists(tt *acctest.TestTools, resourceName s
230294
return func(s *terraform.State) error {
231295
rs, ok := s.RootModule().Resources[resourceName]
232296
if !ok {
233-
return fmt.Errorf("alert manager not found: %s", resourceName)
297+
return errors.New("alert manager not found: " + resourceName)
234298
}
235299

236300
api := cockpit.NewRegionalAPI(meta.ExtractScwClient(tt.Meta))
@@ -249,7 +313,7 @@ func testAccCheckCockpitContactPointExists(tt *acctest.TestTools, resourceName s
249313
}
250314
}
251315

252-
return fmt.Errorf("contact point with email %s not found in project %s", rs.Primary.Attributes["emails.0"], projectID)
316+
return errors.New("contact point with email " + rs.Primary.Attributes["emails.0"] + " not found in project " + projectID)
253317
}
254318
}
255319

@@ -277,10 +341,57 @@ func testAccCockpitAlertManagerAndContactsDestroy(tt *acctest.TestTools) resourc
277341
}
278342

279343
if alertManager.AlertManagerEnabled {
280-
return fmt.Errorf("cockpit alert manager (%s) is still enabled", rs.Primary.ID)
344+
return errors.New("cockpit alert manager (" + rs.Primary.ID + ") is still enabled")
281345
}
282346
}
283347

284348
return nil
285349
}
286350
}
351+
352+
// testAccCheckAlertManagerIDFormat verifies the ID format
353+
func testAccCheckAlertManagerIDFormat(tt *acctest.TestTools, resourceName string) resource.TestCheckFunc {
354+
return func(s *terraform.State) error {
355+
rs, ok := s.RootModule().Resources[resourceName]
356+
if !ok {
357+
return errors.New("alert manager not found: " + resourceName)
358+
}
359+
360+
id := rs.Primary.ID
361+
if id == "" {
362+
return errors.New("alert manager ID is empty")
363+
}
364+
365+
parts := strings.Split(id, "/")
366+
if len(parts) != 3 {
367+
return errors.New("alert manager ID should have 3 parts, got " + strconv.Itoa(len(parts)) + ": " + id)
368+
}
369+
370+
region := parts[0]
371+
projectID := parts[1]
372+
373+
if region == "" {
374+
return errors.New("region part of ID is empty")
375+
}
376+
377+
if projectID == "" {
378+
return errors.New("project ID part of ID is empty")
379+
}
380+
381+
if parts[2] != "1" {
382+
return errors.New("third part of ID should be '1', got " + parts[2])
383+
}
384+
385+
expectedProjectID := rs.Primary.Attributes["project_id"]
386+
if expectedProjectID != projectID {
387+
return errors.New("project_id in attributes (" + expectedProjectID + ") doesn't match project_id in ID (" + projectID + ")")
388+
}
389+
390+
expectedRegion := rs.Primary.Attributes["region"]
391+
if expectedRegion != region {
392+
return errors.New("region in attributes (" + expectedRegion + ") doesn't match region in ID (" + region + ")")
393+
}
394+
395+
return nil
396+
}
397+
}

0 commit comments

Comments
 (0)