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
116 changes: 53 additions & 63 deletions internal/services/cockpit/cockpit.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ 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 Down Expand Up @@ -37,11 +37,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 +78,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 +99,127 @@ 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 {
if httperrors.Is404(err) {
d.SetId("")
return 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)
}
endpoints := flattenCockpitEndpoints(dataSourcesRes.DataSources, grafana.GrafanaURL)

_ = 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))
_ = 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 +229,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
}
54 changes: 45 additions & 9 deletions internal/services/cockpit/cockpit_data_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ import (

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

Expand All @@ -19,31 +22,64 @@ func DataSourceCockpit() *schema.Resource {
Optional: true,
ValidateFunc: verify.IsUUID(),
}
delete(dsSchema, "plan")
dsSchema["plan"] = &schema.Schema{
Type: schema.TypeString,
Computed: true,
Description: "The current plan of the cockpit project",
}

return &schema.Resource{
ReadContext: dataSourceCockpitRead,
Schema: dsSchema,
ReadContext: dataSourceCockpitRead,
Schema: dsSchema,
DeprecationMessage: "The 'scaleway_cockpit' data source is deprecated because it duplicates the functionality of the 'scaleway_cockpit' resource. Please use the 'scaleway_cockpit' resource instead.",
}
}

func dataSourceCockpitRead(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)
}
regionalAPI, region, err := cockpitAPIWithRegion(d, m)
if err != nil {
return diag.FromErr(err)
}

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

res, err := waitForCockpit(ctx, api, projectID, d.Timeout(schema.TimeoutRead))
res, err := api.GetCurrentPlan(&cockpit.GlobalAPIGetCurrentPlanRequest{
ProjectID: projectID,
}, scw.WithContext(ctx))
if err != nil {
if httperrors.Is404(err) {
d.SetId("")
return nil
}
return diag.FromErr(err)
}
_ = d.Set("project_id", d.Get("project_id").(string))
_ = d.Set("plan", res.Name)
_ = d.Set("plan_id", res.Name)

d.SetId(res.ProjectID)
_ = d.Set("project_id", res.ProjectID)
_ = d.Set("plan_id", res.Plan.ID)
_ = d.Set("endpoints", flattenCockpitEndpoints(res.Endpoints))
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)
}
endpoints := flattenCockpitEndpoints(dataSourcesRes.DataSources, grafana.GrafanaURL)

_ = d.Set("endpoints", endpoints)
_ = d.Set("push_url", createCockpitPushURL(endpoints))
d.SetId(projectID)
return nil
}
56 changes: 41 additions & 15 deletions internal/services/cockpit/cockpit_data_source_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,37 +14,63 @@ func TestAccDataSourceCockpit_Basic(t *testing.T) {
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(t) },
ProviderFactories: tt.ProviderFactories,
CheckDestroy: isCockpitDestroyed(tt),
Steps: []resource.TestStep{
{
Config: `
resource "scaleway_account_project" "project" {
name = "tf_tests_datasource_cockpit_project_basic"
name = "tf_tests_cockpit_project_premium"
}

resource "scaleway_cockpit_source" "metrics" {
project_id = scaleway_account_project.project.id
name = "my-data-source-metrics"
type = "metrics"
}

resource "scaleway_cockpit_source" "logs" {
project_id = scaleway_account_project.project.id
name = "my-data-source-logs"
type = "logs"
}

resource "scaleway_cockpit_source" "traces" {
project_id = scaleway_account_project.project.id
name = "my-data-source-traces"
type = "traces"
}

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


resource "scaleway_cockpit" "main" {
project_id = scaleway_account_project.project.id
plan = "free"
depends_on = [
scaleway_cockpit_source.metrics,
scaleway_cockpit_source.logs,
scaleway_cockpit_source.traces,
scaleway_cockpit_alert_manager.alert_manager,
]
}

data "scaleway_cockpit" "selected" {
project_id = scaleway_cockpit.main.project_id
}

data "scaleway_cockpit_plan" "free" {
name = "free"
}

`,
Check: resource.ComposeTestCheckFunc(
isCockpitPresent(tt, "scaleway_cockpit.main"),
isCockpitPresent(tt, "data.scaleway_cockpit.selected"),

resource.TestCheckResourceAttrPair("data.scaleway_cockpit.selected", "plan_id", "data.scaleway_cockpit_plan.free", "id"),
resource.TestCheckResourceAttrSet("data.scaleway_cockpit.selected", "endpoints.0.metrics_url"),
resource.TestCheckResourceAttrSet("data.scaleway_cockpit.selected", "endpoints.0.metrics_url"),
resource.TestCheckResourceAttrSet("data.scaleway_cockpit.selected", "endpoints.0.logs_url"),
resource.TestCheckResourceAttrSet("data.scaleway_cockpit.selected", "endpoints.0.alertmanager_url"),
resource.TestCheckResourceAttrSet("data.scaleway_cockpit.selected", "endpoints.0.grafana_url"),
resource.TestCheckResourceAttrPair("data.scaleway_cockpit.selected", "project_id", "scaleway_account_project.project", "id"),
resource.TestCheckResourceAttr("scaleway_cockpit.main", "plan", "free"),
resource.TestCheckResourceAttr("scaleway_cockpit.main", "plan_id", "free"),
resource.TestCheckResourceAttrSet("scaleway_cockpit.main", "endpoints.0.metrics_url"),
resource.TestCheckResourceAttrSet("scaleway_cockpit.main", "endpoints.0.logs_url"),
resource.TestCheckResourceAttrSet("scaleway_cockpit.main", "endpoints.0.alertmanager_url"),
resource.TestCheckResourceAttrSet("scaleway_cockpit.main", "endpoints.0.traces_url"),
resource.TestCheckResourceAttrSet("scaleway_cockpit.main", "push_url.0.push_logs_url"),
resource.TestCheckResourceAttrSet("scaleway_cockpit.main", "push_url.0.push_metrics_url"),
),
},
},
Expand Down
Loading
Loading