Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 30 additions & 3 deletions internal/services/cockpit/alert_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"errors"
"fmt"
"strings"

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

projectID := d.Get("project_id").(string)
// Parse the ID to get projectID
_, projectID, err := ResourceCockpitAlertManagerParseID(d.Id())
if err != nil {
return diag.FromErr(err)
}

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

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

projectID := d.Get("project_id").(string)
// Parse the ID to get projectID
_, projectID, err := ResourceCockpitAlertManagerParseID(d.Id())
if err != nil {
return diag.FromErr(err)
}

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

projectID := d.Get("project_id").(string)
// Parse the ID to get projectID
_, projectID, err := ResourceCockpitAlertManagerParseID(d.Id())
if err != nil {
return diag.FromErr(err)
}

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

// ResourceCockpitAlertManagerID builds the resource identifier
// The resource identifier format is "Region/ProjectID/1"
func ResourceCockpitAlertManagerID(region scw.Region, projectID string) (resourceID string) {
return fmt.Sprintf("%s/%s/1", region, projectID)
}

// ResourceCockpitAlertManagerParseID extracts region and project ID from the resource identifier.
// The resource identifier format is "Region/ProjectID/1"
func ResourceCockpitAlertManagerParseID(resourceID string) (region scw.Region, projectID string, err error) {
parts := strings.Split(resourceID, "/")
if len(parts) != 3 {
return "", "", fmt.Errorf("invalid alert manager ID format: %s", resourceID)
}

return scw.Region(parts[0]), parts[1], nil
}
119 changes: 115 additions & 4 deletions internal/services/cockpit/alert_manager_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package cockpit_test

import (
"errors"
"fmt"
"strconv"
"strings"
"testing"

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

func TestAccCockpitAlertManager_IDHandling(t *testing.T) {
tt := acctest.NewTestTools(t)
defer tt.Cleanup()

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(t) },
ProviderFactories: tt.ProviderFactories,
CheckDestroy: testAccCockpitAlertManagerAndContactsDestroy(tt),
Steps: []resource.TestStep{
{
Config: `
resource "scaleway_account_project" "project" {
name = "tf_test_cockpit_alert_manager_id_parsing"
}

resource "scaleway_cockpit_alert_manager" "main" {
project_id = scaleway_account_project.project.id
enable_managed_alerts = true

contact_points {
email = "[email protected]"
}
}
`,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet("scaleway_cockpit_alert_manager.main", "id"),
resource.TestCheckResourceAttrSet("scaleway_cockpit_alert_manager.main", "project_id"),
resource.TestCheckResourceAttrSet("scaleway_cockpit_alert_manager.main", "region"),
resource.TestCheckResourceAttr("scaleway_cockpit_alert_manager.main", "enable_managed_alerts", "true"),
resource.TestCheckResourceAttrSet("scaleway_cockpit_alert_manager.main", "alert_manager_url"),
resource.TestCheckResourceAttr("scaleway_cockpit_alert_manager.main", "contact_points.0.email", "[email protected]"),
testAccCheckAlertManagerIDFormat(tt, "scaleway_cockpit_alert_manager.main"),
),
},
{
Config: `
resource "scaleway_account_project" "project" {
name = "tf_test_cockpit_alert_manager_id_parsing"
}

resource "scaleway_cockpit_alert_manager" "main" {
project_id = scaleway_account_project.project.id
enable_managed_alerts = true

contact_points {
email = "[email protected]"
}
}
`,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet("scaleway_cockpit_alert_manager.main", "id"),
resource.TestCheckResourceAttrSet("scaleway_cockpit_alert_manager.main", "project_id"),
resource.TestCheckResourceAttrSet("scaleway_cockpit_alert_manager.main", "region"),
resource.TestCheckResourceAttr("scaleway_cockpit_alert_manager.main", "contact_points.0.email", "[email protected]"),
testAccCheckAlertManagerIDFormat(tt, "scaleway_cockpit_alert_manager.main"),
),
},
},
})
}

func testAccCockpitAlertManagerConfigWithContacts(contactPoints []map[string]string) string {
contactsConfig := ""
for _, contact := range contactPoints {
Expand Down Expand Up @@ -205,7 +269,7 @@ func testAccCheckAlertManagerEnabled(tt *acctest.TestTools, resourceName string,
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[resourceName]
if !ok {
return fmt.Errorf("alert manager not found: %s", resourceName)
return errors.New("alert manager not found: " + resourceName)
}

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

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

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

Expand Down Expand Up @@ -277,10 +341,57 @@ func testAccCockpitAlertManagerAndContactsDestroy(tt *acctest.TestTools) resourc
}

if alertManager.AlertManagerEnabled {
return fmt.Errorf("cockpit alert manager (%s) is still enabled", rs.Primary.ID)
return errors.New("cockpit alert manager (" + rs.Primary.ID + ") is still enabled")
}
}

return nil
}
}

// testAccCheckAlertManagerIDFormat verifies the ID format
func testAccCheckAlertManagerIDFormat(tt *acctest.TestTools, resourceName string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[resourceName]
if !ok {
return errors.New("alert manager not found: " + resourceName)
}

id := rs.Primary.ID
if id == "" {
return errors.New("alert manager ID is empty")
}

parts := strings.Split(id, "/")
if len(parts) != 3 {
return errors.New("alert manager ID should have 3 parts, got " + strconv.Itoa(len(parts)) + ": " + id)
}

region := parts[0]
projectID := parts[1]

if region == "" {
return errors.New("region part of ID is empty")
}

if projectID == "" {
return errors.New("project ID part of ID is empty")
}

if parts[2] != "1" {
return errors.New("third part of ID should be '1', got " + parts[2])
}

expectedProjectID := rs.Primary.Attributes["project_id"]
if expectedProjectID != projectID {
return errors.New("project_id in attributes (" + expectedProjectID + ") doesn't match project_id in ID (" + projectID + ")")
}

expectedRegion := rs.Primary.Attributes["region"]
if expectedRegion != region {
return errors.New("region in attributes (" + expectedRegion + ") doesn't match region in ID (" + region + ")")
}

return nil
}
}
Loading
Loading