Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(cockpit): migrate legacy cockpit resources to v1 API #2679

Merged
merged 12 commits into from
Aug 12, 2024
15 changes: 9 additions & 6 deletions docs/data-sources/cockpit.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ page_title: "Scaleway: scaleway_cockpit"
---
# scaleway_cockpit


~> **Important:** The data source `scaleway_cockpit` has been deprecated and will no longer be supported. Instead, use resource `scaleway_cockpit`.

-> **Note:**
As of April 2024, Cockpit has introduced regionalization to offer more flexibility and resilience.
If you have customized dashboards in Grafana for monitoring Scaleway resources, please update your queries to accommodate the new regionalized [data sources](../resources/cockpit_source.md).
Expand Down Expand Up @@ -35,9 +38,9 @@ data "scaleway_cockpit" "main" {

In addition to all arguments above, the following attributes are exported:

- `plan_id` - The ID of the current plan
- `endpoints` - Endpoints
- `metrics_url` - The metrics URL
- `logs_url` - The logs URL
- `alertmanager_url` - The alertmanager URL
- `grafana_url` - The grafana URL
- `plan_id` - (Deprecated) The ID of the current plan
- `endpoints` - (Deprecated) Endpoints
- `metrics_url` - (Deprecated) The metrics URL
- `logs_url` - (Deprecated) The logs URL
- `alertmanager_url` - (Deprecated) The alertmanager URL
- `grafana_url` - (Deprecated) The grafana URL
31 changes: 20 additions & 11 deletions docs/resources/cockpit.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,29 @@ For more information consult the [documentation](https://www.scaleway.com/en/doc

## Example Usage

### Activate Cockpit in the default project
### Manage Cockpit in the default project

```terraform
resource "scaleway_cockpit" "main" {}
```

### Activate Cockpit in a specific project
### Manage Cockpit in a specific project

```terraform
resource "scaleway_cockpit" "main" {
project_id = "11111111-1111-1111-1111-111111111111"
}
```

### Choose a specific plan for Cockpit

```terraform
resource "scaleway_cockpit" "main" {
project_id = "11111111-1111-1111-1111-111111111111"
plan = "premium"
}
```

### Use the Grafana Terraform provider

```terraform
Expand All @@ -53,25 +62,25 @@ resource "grafana_folder" "test_folder" {
## Argument Reference

- `project_id` - (Defaults to [provider](../index.md#project_id) `project_id`) The ID of the project the cockpit is associated with.
- `plan` - (Optional) Name or ID of the plan to use.
- `plan` - (Optional) Name of the plan to use. Available plans are free, premium, and custom.


## Attributes Reference

In addition to all arguments above, the following attributes are exported:

- `plan_id` - The ID of the current plan.
- `endpoints` - Endpoints.
- `metrics_url` - The metrics URL.
- `logs_url` - The logs URL.
- `alertmanager_url` - The alertmanager URL.
- `grafana_url` - The grafana URL.
- `traces_url` - The traces URL.
- `plan_id` - (Deprecated) The ID of the current plan. Please use plan instead.
- `endpoints` - (Deprecated) Endpoints. Please use scaleway_cockpit_source instead.
- `metrics_url` - (Deprecated) The metrics URL.
- `logs_url` - (Deprecated) The logs URL.
- `alertmanager_url` - (Deprecated) The alertmanager URL.
- `grafana_url` - (Deprecated) The grafana URL.
- `traces_url` - (Deprecated) The traces URL.

## Import

Cockpits can be imported using the `{project_id}`, e.g.

```bash
terraform import scaleway_cockpit.main 11111111-1111-1111-1111-111111111111
```
```
139 changes: 65 additions & 74 deletions internal/services/cockpit/cockpit.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@ import (

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
cockpit "github.com/scaleway/scaleway-sdk-go/api/cockpit/v1beta1"
"github.com/scaleway/scaleway-sdk-go/api/cockpit/v1"
"github.com/scaleway/scaleway-sdk-go/scw"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/httperrors"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/services/account"
)

Expand All @@ -17,12 +16,6 @@ func ResourceCockpit() *schema.Resource {
ReadContext: ResourceCockpitRead,
UpdateContext: ResourceCockpitUpdate,
DeleteContext: ResourceCockpitDelete,
Timeouts: &schema.ResourceTimeout{
Create: schema.DefaultTimeout(DefaultCockpitTimeout),
Read: schema.DefaultTimeout(DefaultCockpitTimeout),
Delete: schema.DefaultTimeout(DefaultCockpitTimeout),
Default: schema.DefaultTimeout(DefaultCockpitTimeout),
},
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},
Expand All @@ -37,11 +30,13 @@ func ResourceCockpit() *schema.Resource {
Type: schema.TypeString,
Computed: true,
Description: "The plan ID of the cockpit",
Deprecated: "Please use Name only",
},
"endpoints": {
Type: schema.TypeList,
Computed: true,
Description: "Endpoints",
Deprecated: "Please use `scaleway_cockpit_source` instead",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"metrics_url": {
Expand Down Expand Up @@ -76,6 +71,7 @@ func ResourceCockpit() *schema.Resource {
Type: schema.TypeList,
Computed: true,
Description: "Push_url",
Deprecated: "Please use `scaleway_cockpit_source` instead",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"push_metrics_url": {
Expand All @@ -96,114 +92,135 @@ func ResourceCockpit() *schema.Resource {
}

func ResourceCockpitCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
api, err := NewAPI(m)
api, err := NewGlobalAPI(m)
if err != nil {
return diag.FromErr(err)
}

projectID := d.Get("project_id").(string)

res, err := api.ActivateCockpit(&cockpit.ActivateCockpitRequest{
ProjectID: projectID,
}, scw.WithContext(ctx))
if err != nil {
return diag.FromErr(err)
}

if targetPlanI, ok := d.GetOk("plan"); ok {
targetPlan := targetPlanI.(string)

plans, err := api.ListPlans(&cockpit.ListPlansRequest{}, scw.WithContext(ctx), scw.WithAllPages())
plans, err := api.ListPlans(&cockpit.GlobalAPIListPlansRequest{}, scw.WithContext(ctx), scw.WithAllPages())
if err != nil {
return diag.FromErr(err)
}

var planID string
var planName string
for _, plan := range plans.Plans {
if plan.Name.String() == targetPlan || plan.ID == targetPlan {
planID = plan.ID
if plan.Name.String() == targetPlan {
planName = plan.Name.String()
break
}
}

if planID == "" {
if planName == "" {
return diag.Errorf("plan %s not found", targetPlan)
}

_, err = api.SelectPlan(&cockpit.SelectPlanRequest{
_, err = api.SelectPlan(&cockpit.GlobalAPISelectPlanRequest{
ProjectID: projectID,
PlanID: planID,
PlanName: cockpit.PlanName(planName),
}, scw.WithContext(ctx))
if err != nil {
return diag.FromErr(err)
}
}

d.SetId(res.ProjectID)
d.SetId(projectID)
return ResourceCockpitRead(ctx, d, m)
}

func ResourceCockpitRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
api, err := NewAPI(m)
api, err := NewGlobalAPI(m)
if err != nil {
return diag.FromErr(err)
}

res, err := waitForCockpit(ctx, api, d.Id(), d.Timeout(schema.TimeoutRead))
regionalAPI, region, err := cockpitAPIWithRegion(d, m)
if err != nil {
return diag.FromErr(err)
}

res, err := api.GetCurrentPlan(&cockpit.GlobalAPIGetCurrentPlanRequest{
ProjectID: d.Get("project_id").(string),
}, scw.WithContext(ctx))
if err != nil {
return diag.FromErr(err)
}
_ = d.Set("project_id", d.Get("project_id").(string))
_ = d.Set("plan", res.Name.String())
_ = d.Set("plan_id", res.Name.String())

dataSourcesRes, err := regionalAPI.ListDataSources(&cockpit.RegionalAPIListDataSourcesRequest{
Region: region,
ProjectID: d.Get("project_id").(string),
Origin: "external",
}, scw.WithContext(ctx), scw.WithAllPages())
if err != nil {
return diag.FromErr(err)
}

grafana, err := api.GetGrafana(&cockpit.GlobalAPIGetGrafanaRequest{
ProjectID: d.Get("project_id").(string),
}, scw.WithContext(ctx))
if err != nil {
return diag.FromErr(err)
}

alertManager, err := regionalAPI.GetAlertManager(&cockpit.RegionalAPIGetAlertManagerRequest{
ProjectID: d.Get("project_id").(string),
})
if err != nil {
if httperrors.Is404(err) {
d.SetId("")
return nil
}
return diag.FromErr(err)
}
alertManagerURL := ""
if alertManager.AlertManagerURL != nil {
alertManagerURL = *alertManager.AlertManagerURL
}

_ = d.Set("project_id", res.ProjectID)
_ = d.Set("plan_id", res.Plan.ID)
_ = d.Set("endpoints", flattenCockpitEndpoints(res.Endpoints))
_ = d.Set("push_url", createCockpitPushURL(res.Endpoints))
endpoints := flattenCockpitEndpoints(dataSourcesRes.DataSources, grafana.GrafanaURL, alertManagerURL)

_ = d.Set("endpoints", endpoints)
_ = d.Set("push_url", createCockpitPushURL(endpoints))

return nil
}

func ResourceCockpitUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
api, err := NewAPI(m)
api, err := NewGlobalAPI(m)
if err != nil {
return diag.FromErr(err)
}

projectID := d.Id()
_, err = waitForCockpit(ctx, api, projectID, d.Timeout(schema.TimeoutDelete))
if err != nil {
return diag.FromErr(err)
}

if d.HasChange("plan") {
targetPlan := cockpit.PlanNameFree.String()
if targetPlanI, ok := d.GetOk("plan"); ok {
targetPlan = targetPlanI.(string)
}

plans, err := api.ListPlans(&cockpit.ListPlansRequest{}, scw.WithContext(ctx), scw.WithAllPages())
plans, err := api.ListPlans(&cockpit.GlobalAPIListPlansRequest{}, scw.WithContext(ctx), scw.WithAllPages())
if err != nil {
return diag.FromErr(err)
}

var planID string
var planName string
for _, plan := range plans.Plans {
if plan.Name.String() == targetPlan || plan.ID == targetPlan {
planID = plan.ID
if plan.Name.String() == targetPlan {
planName = plan.Name.String()
break
}
}

if planID == "" {
if planName == "" {
return diag.Errorf("plan %s not found", targetPlan)
}

_, err = api.SelectPlan(&cockpit.SelectPlanRequest{
_, err = api.SelectPlan(&cockpit.GlobalAPISelectPlanRequest{
ProjectID: projectID,
PlanID: planID,
PlanName: cockpit.PlanName(planName),
}, scw.WithContext(ctx))
if err != nil {
return diag.FromErr(err)
Expand All @@ -213,32 +230,6 @@ func ResourceCockpitUpdate(ctx context.Context, d *schema.ResourceData, m interf
return ResourceCockpitRead(ctx, d, m)
}

func ResourceCockpitDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
api, err := NewAPI(m)
if err != nil {
return diag.FromErr(err)
}

_, err = waitForCockpit(ctx, api, d.Id(), d.Timeout(schema.TimeoutDelete))
if err != nil {
if httperrors.Is404(err) {
d.SetId("")
return nil
}
return diag.FromErr(err)
}

_, err = api.DeactivateCockpit(&cockpit.DeactivateCockpitRequest{
ProjectID: d.Id(),
}, scw.WithContext(ctx))
if err != nil && !httperrors.Is404(err) {
return diag.FromErr(err)
}

_, err = waitForCockpit(ctx, api, d.Id(), d.Timeout(schema.TimeoutDelete))
if err != nil && !httperrors.Is404(err) {
return diag.FromErr(err)
}

func ResourceCockpitDelete(_ context.Context, _ *schema.ResourceData, _ interface{}) diag.Diagnostics {
return nil
}
Loading
Loading