Skip to content

Commit 195ce65

Browse files
authored
feat(cockpit): add support for cockpit actions (#3499)
* feat(cockpit): add support for cockpit actions * feat: add Cockpit TriggerTestAlert action and remove deprecated Grafana actions * fix: add missing blank line and include cassette file * fix: correct gofumpt formatting issue * feat: add regional schema helper for Plugin Framework actions * feat: compress cockpit trigger test alert action cassette * Remove strict region validator to allow new regions
1 parent c4ee92c commit 195ce65

File tree

6 files changed

+1726
-0
lines changed

6 files changed

+1726
-0
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package regional
2+
3+
import (
4+
"github.com/hashicorp/terraform-plugin-framework/action/schema"
5+
"github.com/scaleway/scaleway-sdk-go/scw"
6+
)
7+
8+
// AllRegions returns all valid Scaleway regions as strings
9+
func AllRegions() []string {
10+
regions := make([]string, 0, len(scw.AllRegions))
11+
for _, r := range scw.AllRegions {
12+
regions = append(regions, r.String())
13+
}
14+
15+
return regions
16+
}
17+
18+
// SchemaAttribute returns a Plugin Framework schema attribute for a region field
19+
func SchemaAttribute() schema.StringAttribute {
20+
return schema.StringAttribute{
21+
Optional: true,
22+
Description: "The region you want to attach the resource to",
23+
}
24+
}
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
package cockpit
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/hashicorp/terraform-plugin-framework/action"
8+
"github.com/hashicorp/terraform-plugin-framework/action/schema"
9+
"github.com/hashicorp/terraform-plugin-framework/types"
10+
"github.com/scaleway/scaleway-sdk-go/api/cockpit/v1"
11+
"github.com/scaleway/scaleway-sdk-go/scw"
12+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality/regional"
13+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/meta"
14+
)
15+
16+
var (
17+
_ action.Action = (*TriggerTestAlertAction)(nil)
18+
_ action.ActionWithConfigure = (*TriggerTestAlertAction)(nil)
19+
)
20+
21+
type TriggerTestAlertAction struct {
22+
regionalAPI *cockpit.RegionalAPI
23+
meta *meta.Meta
24+
}
25+
26+
func (a *TriggerTestAlertAction) Configure(ctx context.Context, req action.ConfigureRequest, resp *action.ConfigureResponse) {
27+
if req.ProviderData == nil {
28+
return
29+
}
30+
31+
m, ok := req.ProviderData.(*meta.Meta)
32+
if !ok {
33+
resp.Diagnostics.AddError(
34+
"Unexpected Action Configure Type",
35+
fmt.Sprintf("Expected *meta.Meta, got: %T. Please report this issue to the provider developers.", req.ProviderData),
36+
)
37+
38+
return
39+
}
40+
41+
client := m.ScwClient()
42+
a.regionalAPI = cockpit.NewRegionalAPI(client)
43+
a.meta = m
44+
}
45+
46+
func (a *TriggerTestAlertAction) Metadata(ctx context.Context, req action.MetadataRequest, resp *action.MetadataResponse) {
47+
resp.TypeName = req.ProviderTypeName + "_cockpit_trigger_test_alert_action"
48+
}
49+
50+
type TriggerTestAlertActionModel struct {
51+
ProjectID types.String `tfsdk:"project_id"`
52+
Region types.String `tfsdk:"region"`
53+
}
54+
55+
func NewTriggerTestAlertAction() action.Action {
56+
return &TriggerTestAlertAction{}
57+
}
58+
59+
func (a *TriggerTestAlertAction) Schema(ctx context.Context, req action.SchemaRequest, resp *action.SchemaResponse) {
60+
resp.Schema = schema.Schema{
61+
Attributes: map[string]schema.Attribute{
62+
"project_id": schema.StringAttribute{
63+
Required: true,
64+
Description: "ID of the Project",
65+
},
66+
"region": regional.SchemaAttribute(),
67+
},
68+
}
69+
}
70+
71+
func (a *TriggerTestAlertAction) Invoke(ctx context.Context, req action.InvokeRequest, resp *action.InvokeResponse) {
72+
var data TriggerTestAlertActionModel
73+
74+
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
75+
76+
if resp.Diagnostics.HasError() {
77+
return
78+
}
79+
80+
if a.regionalAPI == nil {
81+
resp.Diagnostics.AddError(
82+
"Unconfigured regionalAPI",
83+
"The action was not properly configured. The Scaleway client is missing. "+
84+
"This is usually a bug in the provider. Please report it to the maintainers.",
85+
)
86+
87+
return
88+
}
89+
90+
if data.ProjectID.IsNull() || data.ProjectID.ValueString() == "" {
91+
resp.Diagnostics.AddError(
92+
"Missing project_id",
93+
"The project_id attribute is required to trigger a test alert.",
94+
)
95+
96+
return
97+
}
98+
99+
var region scw.Region
100+
101+
if !data.Region.IsNull() && data.Region.ValueString() != "" {
102+
parsedRegion, err := scw.ParseRegion(data.Region.ValueString())
103+
if err != nil {
104+
resp.Diagnostics.AddError(
105+
"Invalid region",
106+
fmt.Sprintf("The region attribute must be a valid Scaleway region. Got %q: %s", data.Region.ValueString(), err),
107+
)
108+
109+
return
110+
}
111+
112+
region = parsedRegion
113+
} else {
114+
// Use default region from provider configuration
115+
defaultRegion, exists := a.meta.ScwClient().GetDefaultRegion()
116+
if !exists {
117+
resp.Diagnostics.AddError(
118+
"Missing region",
119+
"The region attribute is required to trigger a test alert. Please provide it explicitly or configure a default region in the provider.",
120+
)
121+
122+
return
123+
}
124+
125+
region = defaultRegion
126+
}
127+
128+
err := a.regionalAPI.TriggerTestAlert(&cockpit.RegionalAPITriggerTestAlertRequest{
129+
ProjectID: data.ProjectID.ValueString(),
130+
Region: region,
131+
}, scw.WithContext(ctx))
132+
if err != nil {
133+
resp.Diagnostics.AddError(
134+
"Error executing Cockpit TriggerTestAlert action",
135+
fmt.Sprintf("Failed to trigger test alert for project %s: %s", data.ProjectID.ValueString(), err),
136+
)
137+
138+
return
139+
}
140+
}
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
package cockpit_test
2+
3+
import (
4+
"errors"
5+
"strings"
6+
"testing"
7+
8+
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
9+
"github.com/hashicorp/terraform-plugin-testing/terraform"
10+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/acctest"
11+
)
12+
13+
func TestAccActionCockpitTriggerTestAlert_Basic(t *testing.T) {
14+
if acctest.IsRunningOpenTofu() {
15+
t.Skip("Skipping TestAccActionCockpitTriggerTestAlert_Basic because actions are not yet supported on OpenTofu")
16+
}
17+
18+
tt := acctest.NewTestTools(t)
19+
defer tt.Cleanup()
20+
21+
resource.ParallelTest(t, resource.TestCase{
22+
ProtoV6ProviderFactories: tt.ProviderFactories,
23+
Steps: []resource.TestStep{
24+
{
25+
Config: `
26+
resource "scaleway_account_project" "project" {
27+
name = "tf_tests_cockpit_trigger_test_alert"
28+
}
29+
30+
resource "scaleway_cockpit_alert_manager" "main" {
31+
project_id = scaleway_account_project.project.id
32+
}
33+
34+
resource "scaleway_cockpit_source" "metrics" {
35+
project_id = scaleway_account_project.project.id
36+
name = "test-metrics-source"
37+
type = "metrics"
38+
retention_days = 31
39+
40+
lifecycle {
41+
action_trigger {
42+
events = [after_create]
43+
actions = [action.scaleway_cockpit_trigger_test_alert_action.main]
44+
}
45+
}
46+
47+
depends_on = [scaleway_cockpit_alert_manager.main]
48+
}
49+
50+
action "scaleway_cockpit_trigger_test_alert_action" "main" {
51+
config {
52+
project_id = scaleway_account_project.project.id
53+
}
54+
}
55+
`,
56+
},
57+
{
58+
Config: `
59+
resource "scaleway_account_project" "project" {
60+
name = "tf_tests_cockpit_trigger_test_alert"
61+
}
62+
63+
resource "scaleway_cockpit_alert_manager" "main" {
64+
project_id = scaleway_account_project.project.id
65+
}
66+
67+
resource "scaleway_cockpit_source" "metrics" {
68+
project_id = scaleway_account_project.project.id
69+
name = "test-metrics-source"
70+
type = "metrics"
71+
retention_days = 31
72+
73+
lifecycle {
74+
action_trigger {
75+
events = [after_create]
76+
actions = [action.scaleway_cockpit_trigger_test_alert_action.main]
77+
}
78+
}
79+
80+
depends_on = [scaleway_cockpit_alert_manager.main]
81+
}
82+
83+
action "scaleway_cockpit_trigger_test_alert_action" "main" {
84+
config {
85+
project_id = scaleway_account_project.project.id
86+
}
87+
}
88+
89+
data "scaleway_audit_trail_event" "cockpit" {
90+
project_id = scaleway_account_project.project.id
91+
method_name = "TriggerTestAlert"
92+
}
93+
`,
94+
Check: resource.ComposeTestCheckFunc(
95+
resource.TestCheckResourceAttrSet("data.scaleway_audit_trail_event.cockpit", "events.#"),
96+
func(state *terraform.State) error {
97+
rs, ok := state.RootModule().Resources["data.scaleway_audit_trail_event.cockpit"]
98+
if !ok {
99+
return errors.New("not found: data.scaleway_audit_trail_event.cockpit")
100+
}
101+
102+
for key, value := range rs.Primary.Attributes {
103+
if !strings.Contains(key, "method_name") {
104+
continue
105+
}
106+
107+
if value == "TriggerTestAlert" {
108+
return nil
109+
}
110+
}
111+
112+
return errors.New("did not find the TriggerTestAlert event")
113+
},
114+
),
115+
},
116+
},
117+
})
118+
}

0 commit comments

Comments
 (0)