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
24 changes: 24 additions & 0 deletions internal/locality/regional/schemas_framework.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package regional

import (
"github.com/hashicorp/terraform-plugin-framework/action/schema"
"github.com/scaleway/scaleway-sdk-go/scw"
)

// AllRegions returns all valid Scaleway regions as strings
func AllRegions() []string {
regions := make([]string, 0, len(scw.AllRegions))
for _, r := range scw.AllRegions {
regions = append(regions, r.String())
}

return regions
}

// SchemaAttribute returns a Plugin Framework schema attribute for a region field
func SchemaAttribute() schema.StringAttribute {
return schema.StringAttribute{
Optional: true,
Description: "The region you want to attach the resource to",
}
}
140 changes: 140 additions & 0 deletions internal/services/cockpit/action_trigger_test_alert_action.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
package cockpit

import (
"context"
"fmt"

"github.com/hashicorp/terraform-plugin-framework/action"
"github.com/hashicorp/terraform-plugin-framework/action/schema"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/scaleway/scaleway-sdk-go/api/cockpit/v1"
"github.com/scaleway/scaleway-sdk-go/scw"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality/regional"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/meta"
)

var (
_ action.Action = (*TriggerTestAlertAction)(nil)
_ action.ActionWithConfigure = (*TriggerTestAlertAction)(nil)
)

type TriggerTestAlertAction struct {
regionalAPI *cockpit.RegionalAPI
meta *meta.Meta
}

func (a *TriggerTestAlertAction) Configure(ctx context.Context, req action.ConfigureRequest, resp *action.ConfigureResponse) {
if req.ProviderData == nil {
return
}

m, ok := req.ProviderData.(*meta.Meta)
if !ok {
resp.Diagnostics.AddError(
"Unexpected Action Configure Type",
fmt.Sprintf("Expected *meta.Meta, got: %T. Please report this issue to the provider developers.", req.ProviderData),
)

return
}

client := m.ScwClient()
a.regionalAPI = cockpit.NewRegionalAPI(client)
a.meta = m
}

func (a *TriggerTestAlertAction) Metadata(ctx context.Context, req action.MetadataRequest, resp *action.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_cockpit_trigger_test_alert_action"
}

type TriggerTestAlertActionModel struct {
ProjectID types.String `tfsdk:"project_id"`
Region types.String `tfsdk:"region"`
}

func NewTriggerTestAlertAction() action.Action {
return &TriggerTestAlertAction{}
}

func (a *TriggerTestAlertAction) Schema(ctx context.Context, req action.SchemaRequest, resp *action.SchemaResponse) {
resp.Schema = schema.Schema{
Attributes: map[string]schema.Attribute{
"project_id": schema.StringAttribute{
Required: true,
Description: "ID of the Project",
},
"region": regional.SchemaAttribute(),
},
}
}

func (a *TriggerTestAlertAction) Invoke(ctx context.Context, req action.InvokeRequest, resp *action.InvokeResponse) {
var data TriggerTestAlertActionModel

resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)

if resp.Diagnostics.HasError() {
return
}

if a.regionalAPI == nil {
resp.Diagnostics.AddError(
"Unconfigured regionalAPI",
"The action was not properly configured. The Scaleway client is missing. "+
"This is usually a bug in the provider. Please report it to the maintainers.",
)

return
}

if data.ProjectID.IsNull() || data.ProjectID.ValueString() == "" {
resp.Diagnostics.AddError(
"Missing project_id",
"The project_id attribute is required to trigger a test alert.",
)

return
}

var region scw.Region

if !data.Region.IsNull() && data.Region.ValueString() != "" {
parsedRegion, err := scw.ParseRegion(data.Region.ValueString())
if err != nil {
resp.Diagnostics.AddError(
"Invalid region",
fmt.Sprintf("The region attribute must be a valid Scaleway region. Got %q: %s", data.Region.ValueString(), err),
)

return
}

region = parsedRegion
} else {
// Use default region from provider configuration
defaultRegion, exists := a.meta.ScwClient().GetDefaultRegion()
if !exists {
resp.Diagnostics.AddError(
"Missing region",
"The region attribute is required to trigger a test alert. Please provide it explicitly or configure a default region in the provider.",
)

return
}

region = defaultRegion
}

err := a.regionalAPI.TriggerTestAlert(&cockpit.RegionalAPITriggerTestAlertRequest{
ProjectID: data.ProjectID.ValueString(),
Region: region,
}, scw.WithContext(ctx))
if err != nil {
resp.Diagnostics.AddError(
"Error executing Cockpit TriggerTestAlert action",
fmt.Sprintf("Failed to trigger test alert for project %s: %s", data.ProjectID.ValueString(), err),
)

return
}
}
118 changes: 118 additions & 0 deletions internal/services/cockpit/action_trigger_test_alert_action_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
package cockpit_test

import (
"errors"
"strings"
"testing"

"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/hashicorp/terraform-plugin-testing/terraform"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/acctest"
)

func TestAccActionCockpitTriggerTestAlert_Basic(t *testing.T) {
if acctest.IsRunningOpenTofu() {
t.Skip("Skipping TestAccActionCockpitTriggerTestAlert_Basic because actions are not yet supported on OpenTofu")
}

tt := acctest.NewTestTools(t)
defer tt.Cleanup()

resource.ParallelTest(t, resource.TestCase{
ProtoV6ProviderFactories: tt.ProviderFactories,
Steps: []resource.TestStep{
{
Config: `
resource "scaleway_account_project" "project" {
name = "tf_tests_cockpit_trigger_test_alert"
}

resource "scaleway_cockpit_alert_manager" "main" {
project_id = scaleway_account_project.project.id
}

resource "scaleway_cockpit_source" "metrics" {
project_id = scaleway_account_project.project.id
name = "test-metrics-source"
type = "metrics"
retention_days = 31

lifecycle {
action_trigger {
events = [after_create]
actions = [action.scaleway_cockpit_trigger_test_alert_action.main]
}
}

depends_on = [scaleway_cockpit_alert_manager.main]
}

action "scaleway_cockpit_trigger_test_alert_action" "main" {
config {
project_id = scaleway_account_project.project.id
}
}
`,
},
{
Config: `
resource "scaleway_account_project" "project" {
name = "tf_tests_cockpit_trigger_test_alert"
}

resource "scaleway_cockpit_alert_manager" "main" {
project_id = scaleway_account_project.project.id
}

resource "scaleway_cockpit_source" "metrics" {
project_id = scaleway_account_project.project.id
name = "test-metrics-source"
type = "metrics"
retention_days = 31

lifecycle {
action_trigger {
events = [after_create]
actions = [action.scaleway_cockpit_trigger_test_alert_action.main]
}
}

depends_on = [scaleway_cockpit_alert_manager.main]
}

action "scaleway_cockpit_trigger_test_alert_action" "main" {
config {
project_id = scaleway_account_project.project.id
}
}

data "scaleway_audit_trail_event" "cockpit" {
project_id = scaleway_account_project.project.id
method_name = "TriggerTestAlert"
}
`,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet("data.scaleway_audit_trail_event.cockpit", "events.#"),
func(state *terraform.State) error {
rs, ok := state.RootModule().Resources["data.scaleway_audit_trail_event.cockpit"]
if !ok {
return errors.New("not found: data.scaleway_audit_trail_event.cockpit")
}

for key, value := range rs.Primary.Attributes {
if !strings.Contains(key, "method_name") {
continue
}

if value == "TriggerTestAlert" {
return nil
}
}

return errors.New("did not find the TriggerTestAlert event")
},
),
},
},
})
}
Loading
Loading