Skip to content

Commit

Permalink
feat(cockpit): add data source for source
Browse files Browse the repository at this point in the history
  • Loading branch information
jremy42 committed Dec 20, 2024
1 parent 5d65352 commit b7cbbc6
Show file tree
Hide file tree
Showing 8 changed files with 2,311 additions and 63 deletions.
79 changes: 79 additions & 0 deletions docs/data-sources/cockpit_source.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
---
subcategory: "Cockpit"
page_title: "Scaleway: scaleway_cockpit_source"
---

# Data Source: scaleway_cockpit_source

The `scaleway_cockpit_source` data source allows you to retrieve information about a specific [data source](https://www.scaleway.com/en/docs/observability/cockpit/concepts/#data-sources) in Scaleway's Cockpit.

Refer to Cockpit's [product documentation](https://www.scaleway.com/en/docs/observability/cockpit/concepts/) and [API documentation](https://www.scaleway.com/en/developers/api/cockpit/regional-api) for more information.

## Example Usage

### Retrieve a specific data source by ID

The following example retrieves a Cockpit data source by its unique ID.

```terraform
data "scaleway_cockpit_source" "example" {
id = "fr-par/11111111-1111-1111-1111-111111111111"
}
```

### Retrieve a data source by filters

You can also retrieve a data source by specifying filtering criteria such as `name`, `type`, and `origin`.

```terraform
data "scaleway_cockpit_source" "filtered" {
project_id = "11111111-1111-1111-1111-111111111111"
region = "fr-par"
name = "my-data-source"
}
```

## Argument Reference

This section lists the arguments that are supported:

- `id` - (Optional) The unique identifier of the Cockpit data source in the `{region}/{id}` format. If specified, other filters are ignored.

- `region` - (Optional) The [region](../guides/regions_and_zones.md#regions) where the data source is located. Defaults to the region specified in the [provider configuration](../index.md#region).

- `project_id` - (Required unless `id` is specified) The ID of the Project the data source is associated with. Defaults to the Project ID specified in the [provider configuration](../index.md#project_id).

- `name` - (Optional) The name of the data source.

- `type` - (Optional) The [type](https://www.scaleway.com/en/docs/observability/cockpit/concepts/#data-types) of data source. Possible values are: `metrics`, `logs`, or `traces`.

- `origin` - (Optional) The origin of the data source. Possible values are:
- `scaleway` - Data source managed by Scaleway.
- `external` - Data source created by the user.
- `custom` - User-defined custom data source.

## Attributes Reference

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

- `id` - The unique identifier of the data source in the `{region}/{id}` format.

- `url` - The URL of the Cockpit data source.

- `created_at` - The date and time the data source was created (in RFC 3339 format).

- `updated_at` - The date and time the data source was last updated (in RFC 3339 format).

- `origin` - The origin of the data source.

- `synchronized_with_grafana` - Indicates whether the data source is synchronized with Grafana.

- `retention_days` - The number of days the data is retained in the data source.

## Import

You can import a Cockpit data source using its unique ID in the `{region}/{id}` format.

```bash
terraform import scaleway_cockpit_source.example fr-par/11111111-1111-1111-1111-111111111111
```
2 changes: 1 addition & 1 deletion docs/resources/cockpit_source.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ page_title: "Scaleway: scaleway_cockpit_source"

# Resource: scaleway_cockpit_source

The `scaleway_cockpit_source` resource allows you to create and manage [data sources](https://www.scaleway.com/en/docs/observability/cockpit/concepts/#data-sources) in Scaleway's Cockpit.
The `scaleway_cockpit_sourource allows you to create and manage [data sources](https://www.scaleway.com/en/docs/observability/cockpit/concepts/#data-sources) in Scaleway's Cockpit.

Refer to Cockpit's [product documentation](https://www.scaleway.com/en/docs/observability/cockpit/concepts/) and [API documentation](https://www.scaleway.com/en/developers/api/cockpit/regional-api) for more information.

Expand Down
182 changes: 182 additions & 0 deletions internal/services/cockpit/source_data_source.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
package cockpit

import (
"context"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
"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/services/account"
"github.com/scaleway/terraform-provider-scaleway/v2/internal/types"
)

func DataSourceCockpitSource() *schema.Resource {
return &schema.Resource{
ReadContext: dataSourceCockpitSourceRead,
Schema: map[string]*schema.Schema{
"id": {
Type: schema.TypeString,
Optional: true,
Computed: true,
Description: "ID of the data source.",
},
"region": {
Type: schema.TypeString,
Computed: true,
Description: "The region of the data source.",
},
"project_id": account.ProjectIDSchema(),
"name": {
Type: schema.TypeString,
Optional: true,
Computed: true,
Description: "The name of the data source.",
},
"type": {
Type: schema.TypeString,
Optional: true,
Computed: true,
Description: "The type of the data source (e.g., 'metrics', 'logs', 'traces').",
ValidateFunc: validation.StringInSlice([]string{
"metrics", "logs", "traces",
}, false),
},
"origin": {
Type: schema.TypeString,
Optional: true,
Description: "The origin of the data source (e.g., 'scaleway', 'external', 'custom').",
Computed: true,
ValidateFunc: validation.StringInSlice([]string{
"scaleway", "external", "custom",
}, false),
},
// Computed fields
"url": {
Type: schema.TypeString,
Computed: true,
Description: "The URL of the data source.",
},
"created_at": {
Type: schema.TypeString,
Computed: true,
Description: "The creation date of the data source.",
},
"updated_at": {
Type: schema.TypeString,
Computed: true,
Description: "The last update date of the data source.",
},
"synchronized_with_grafana": {
Type: schema.TypeBool,
Computed: true,
Description: "Whether the data source is synchronized with Grafana.",
},
"retention_days": {
Type: schema.TypeInt,
Computed: true,
Description: "The retention period of the data source in days.",
},
},
}
}

func dataSourceCockpitSourceRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {

if _, ok := d.GetOk("id"); ok {
return fetchDataSourceByID(ctx, d, meta)
}

return fetchDataSourceByFilters(ctx, d, meta)
}

func fetchDataSourceByID(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {

regionalID := d.Get("id").(string)
api, region, id, err := NewAPIWithRegionAndID(meta, regionalID)
d.SetId(id)
if err != nil {
return diag.FromErr(err)
}
res, err := api.GetDataSource(&cockpit.RegionalAPIGetDataSourceRequest{
Region: region,
DataSourceID: id,
}, scw.WithContext(ctx))
if err != nil {
return diag.FromErr(err)
}
flattenDataSource(d, res)
return nil
}

func fetchDataSourceByFilters(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {

api, region, err := cockpitAPIWithRegion(d, meta)
if err != nil {
return diag.FromErr(err)
}

req := &cockpit.RegionalAPIListDataSourcesRequest{
Region: region,
ProjectID: d.Get("project_id").(string),
}

if v, ok := d.GetOk("type"); ok {
req.Types = []cockpit.DataSourceType{cockpit.DataSourceType(v.(string))}
}
if v, ok := d.GetOk("origin"); ok {
req.Origin = cockpit.DataSourceOrigin(v.(string))
}
var allDataSources []*cockpit.DataSource
page := int32(1)
for {
req.Page = &page
req.PageSize = scw.Uint32Ptr(1000)

res, err := api.ListDataSources(req, scw.WithContext(ctx))
if err != nil {
return diag.FromErr(err)
}

allDataSources = append(allDataSources, res.DataSources...)

if len(res.DataSources) < 1000 {
break
}

page++
}

if len(allDataSources) == 0 {
return diag.Errorf("no data source found matching the specified criteria")
}

if name, ok := d.GetOk("name"); ok {
for _, ds := range allDataSources {
if ds.Name == name.(string) {
flattenDataSource(d, ds)
return nil
}
}
return diag.Errorf("no data source found with name '%s'", name.(string))
}

flattenDataSource(d, allDataSources[0])
return nil
}

func flattenDataSource(d *schema.ResourceData, ds *cockpit.DataSource) {
d.SetId(regional.NewIDString(ds.Region, ds.ID))
_ = d.Set("project_id", ds.ProjectID)
_ = d.Set("name", ds.Name)
_ = d.Set("url", ds.URL)
_ = d.Set("type", ds.Type.String())
_ = d.Set("origin", ds.Origin.String())
_ = d.Set("created_at", types.FlattenTime(ds.CreatedAt))
_ = d.Set("updated_at", types.FlattenTime(ds.UpdatedAt))
_ = d.Set("synchronized_with_grafana", ds.SynchronizedWithGrafana)
_ = d.Set("retention_days", int(ds.RetentionDays))
_ = d.Set("region", ds.Region.String())
}
116 changes: 116 additions & 0 deletions internal/services/cockpit/source_data_source_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
package cockpit_test

import (
"fmt"
"testing"

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

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

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(t) },
ProviderFactories: tt.ProviderFactories,
CheckDestroy: isSourceDestroyed(tt),
Steps: []resource.TestStep{
{
Config: `
resource "scaleway_account_project" "project" {
name = "tf_tests_cockpit_datasource_by_id"
}
resource "scaleway_cockpit_source" "main" {
project_id = scaleway_account_project.project.id
name = "source-by-id"
type = "metrics"
retention_days = 30
}
data "scaleway_cockpit_source" "by_id" {
id = scaleway_cockpit_source.main.id
}
`,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrPair("data.scaleway_cockpit_source.by_id", "id", "scaleway_cockpit_source.main", "id"),
resource.TestCheckResourceAttr("data.scaleway_cockpit_source.by_id", "name", "source-by-id"),
resource.TestCheckResourceAttr("data.scaleway_cockpit_source.by_id", "type", "metrics"),
),
},
},
})
}

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

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(t) },
ProviderFactories: tt.ProviderFactories,
CheckDestroy: isSourceDestroyed(tt),
Steps: []resource.TestStep{
{
Config: `
resource "scaleway_account_project" "project" {
name = "tf_tests_cockpit_datasource_by_name"
}
resource "scaleway_cockpit_source" "main" {
project_id = scaleway_account_project.project.id
name = "source-by-name"
type = "logs"
retention_days = 30
}
data "scaleway_cockpit_source" "by_name" {
project_id = scaleway_account_project.project.id
name = "source-by-name"
depends_on = [scaleway_cockpit_source.main]
}
`,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrPair("data.scaleway_cockpit_source.by_name", "id", "scaleway_cockpit_source.main", "id"),
resource.TestCheckResourceAttr("data.scaleway_cockpit_source.by_name", "name", "source-by-name"),
resource.TestCheckResourceAttr("data.scaleway_cockpit_source.by_name", "type", "logs"),
),
},
},
})
}

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

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(t) },
ProviderFactories: tt.ProviderFactories,
Steps: []resource.TestStep{
{
Config: fmt.Sprintf(`
data "scaleway_cockpit_source" "default_metrics" {
type = "metrics"
origin = "scaleway"
}
data "scaleway_cockpit_source" "default_logs" {
type = "logs"
origin = "scaleway"
}
`),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("data.scaleway_cockpit_source.default_metrics", "name", "Scaleway Metrics"),
resource.TestCheckResourceAttr("data.scaleway_cockpit_source.default_metrics", "type", "metrics"),
resource.TestCheckResourceAttrSet("data.scaleway_cockpit_source.default_metrics", "url"),
resource.TestCheckResourceAttr("data.scaleway_cockpit_source.default_logs", "name", "Scaleway Logs"),
resource.TestCheckResourceAttr("data.scaleway_cockpit_source.default_logs", "type", "logs"),
resource.TestCheckResourceAttrSet("data.scaleway_cockpit_source.default_logs", "url"),
),
},
},
})
}
Loading

0 comments on commit b7cbbc6

Please sign in to comment.