Skip to content

Commit b7cbbc6

Browse files
committed
feat(cockpit): add data source for source
1 parent 5d65352 commit b7cbbc6

8 files changed

+2311
-63
lines changed
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
---
2+
subcategory: "Cockpit"
3+
page_title: "Scaleway: scaleway_cockpit_source"
4+
---
5+
6+
# Data Source: scaleway_cockpit_source
7+
8+
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.
9+
10+
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.
11+
12+
## Example Usage
13+
14+
### Retrieve a specific data source by ID
15+
16+
The following example retrieves a Cockpit data source by its unique ID.
17+
18+
```terraform
19+
data "scaleway_cockpit_source" "example" {
20+
id = "fr-par/11111111-1111-1111-1111-111111111111"
21+
}
22+
```
23+
24+
### Retrieve a data source by filters
25+
26+
You can also retrieve a data source by specifying filtering criteria such as `name`, `type`, and `origin`.
27+
28+
```terraform
29+
data "scaleway_cockpit_source" "filtered" {
30+
project_id = "11111111-1111-1111-1111-111111111111"
31+
region = "fr-par"
32+
name = "my-data-source"
33+
}
34+
```
35+
36+
## Argument Reference
37+
38+
This section lists the arguments that are supported:
39+
40+
- `id` - (Optional) The unique identifier of the Cockpit data source in the `{region}/{id}` format. If specified, other filters are ignored.
41+
42+
- `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).
43+
44+
- `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).
45+
46+
- `name` - (Optional) The name of the data source.
47+
48+
- `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`.
49+
50+
- `origin` - (Optional) The origin of the data source. Possible values are:
51+
- `scaleway` - Data source managed by Scaleway.
52+
- `external` - Data source created by the user.
53+
- `custom` - User-defined custom data source.
54+
55+
## Attributes Reference
56+
57+
In addition to all arguments above, the following attributes are exported:
58+
59+
- `id` - The unique identifier of the data source in the `{region}/{id}` format.
60+
61+
- `url` - The URL of the Cockpit data source.
62+
63+
- `created_at` - The date and time the data source was created (in RFC 3339 format).
64+
65+
- `updated_at` - The date and time the data source was last updated (in RFC 3339 format).
66+
67+
- `origin` - The origin of the data source.
68+
69+
- `synchronized_with_grafana` - Indicates whether the data source is synchronized with Grafana.
70+
71+
- `retention_days` - The number of days the data is retained in the data source.
72+
73+
## Import
74+
75+
You can import a Cockpit data source using its unique ID in the `{region}/{id}` format.
76+
77+
```bash
78+
terraform import scaleway_cockpit_source.example fr-par/11111111-1111-1111-1111-111111111111
79+
```

docs/resources/cockpit_source.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ page_title: "Scaleway: scaleway_cockpit_source"
55

66
# Resource: scaleway_cockpit_source
77

8-
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.
8+
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.
99

1010
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.
1111

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
package cockpit
2+
3+
import (
4+
"context"
5+
6+
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
7+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
8+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
9+
"github.com/scaleway/scaleway-sdk-go/api/cockpit/v1"
10+
"github.com/scaleway/scaleway-sdk-go/scw"
11+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality/regional"
12+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/services/account"
13+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/types"
14+
)
15+
16+
func DataSourceCockpitSource() *schema.Resource {
17+
return &schema.Resource{
18+
ReadContext: dataSourceCockpitSourceRead,
19+
Schema: map[string]*schema.Schema{
20+
"id": {
21+
Type: schema.TypeString,
22+
Optional: true,
23+
Computed: true,
24+
Description: "ID of the data source.",
25+
},
26+
"region": {
27+
Type: schema.TypeString,
28+
Computed: true,
29+
Description: "The region of the data source.",
30+
},
31+
"project_id": account.ProjectIDSchema(),
32+
"name": {
33+
Type: schema.TypeString,
34+
Optional: true,
35+
Computed: true,
36+
Description: "The name of the data source.",
37+
},
38+
"type": {
39+
Type: schema.TypeString,
40+
Optional: true,
41+
Computed: true,
42+
Description: "The type of the data source (e.g., 'metrics', 'logs', 'traces').",
43+
ValidateFunc: validation.StringInSlice([]string{
44+
"metrics", "logs", "traces",
45+
}, false),
46+
},
47+
"origin": {
48+
Type: schema.TypeString,
49+
Optional: true,
50+
Description: "The origin of the data source (e.g., 'scaleway', 'external', 'custom').",
51+
Computed: true,
52+
ValidateFunc: validation.StringInSlice([]string{
53+
"scaleway", "external", "custom",
54+
}, false),
55+
},
56+
// Computed fields
57+
"url": {
58+
Type: schema.TypeString,
59+
Computed: true,
60+
Description: "The URL of the data source.",
61+
},
62+
"created_at": {
63+
Type: schema.TypeString,
64+
Computed: true,
65+
Description: "The creation date of the data source.",
66+
},
67+
"updated_at": {
68+
Type: schema.TypeString,
69+
Computed: true,
70+
Description: "The last update date of the data source.",
71+
},
72+
"synchronized_with_grafana": {
73+
Type: schema.TypeBool,
74+
Computed: true,
75+
Description: "Whether the data source is synchronized with Grafana.",
76+
},
77+
"retention_days": {
78+
Type: schema.TypeInt,
79+
Computed: true,
80+
Description: "The retention period of the data source in days.",
81+
},
82+
},
83+
}
84+
}
85+
86+
func dataSourceCockpitSourceRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
87+
88+
if _, ok := d.GetOk("id"); ok {
89+
return fetchDataSourceByID(ctx, d, meta)
90+
}
91+
92+
return fetchDataSourceByFilters(ctx, d, meta)
93+
}
94+
95+
func fetchDataSourceByID(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
96+
97+
regionalID := d.Get("id").(string)
98+
api, region, id, err := NewAPIWithRegionAndID(meta, regionalID)
99+
d.SetId(id)
100+
if err != nil {
101+
return diag.FromErr(err)
102+
}
103+
res, err := api.GetDataSource(&cockpit.RegionalAPIGetDataSourceRequest{
104+
Region: region,
105+
DataSourceID: id,
106+
}, scw.WithContext(ctx))
107+
if err != nil {
108+
return diag.FromErr(err)
109+
}
110+
flattenDataSource(d, res)
111+
return nil
112+
}
113+
114+
func fetchDataSourceByFilters(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
115+
116+
api, region, err := cockpitAPIWithRegion(d, meta)
117+
if err != nil {
118+
return diag.FromErr(err)
119+
}
120+
121+
req := &cockpit.RegionalAPIListDataSourcesRequest{
122+
Region: region,
123+
ProjectID: d.Get("project_id").(string),
124+
}
125+
126+
if v, ok := d.GetOk("type"); ok {
127+
req.Types = []cockpit.DataSourceType{cockpit.DataSourceType(v.(string))}
128+
}
129+
if v, ok := d.GetOk("origin"); ok {
130+
req.Origin = cockpit.DataSourceOrigin(v.(string))
131+
}
132+
var allDataSources []*cockpit.DataSource
133+
page := int32(1)
134+
for {
135+
req.Page = &page
136+
req.PageSize = scw.Uint32Ptr(1000)
137+
138+
res, err := api.ListDataSources(req, scw.WithContext(ctx))
139+
if err != nil {
140+
return diag.FromErr(err)
141+
}
142+
143+
allDataSources = append(allDataSources, res.DataSources...)
144+
145+
if len(res.DataSources) < 1000 {
146+
break
147+
}
148+
149+
page++
150+
}
151+
152+
if len(allDataSources) == 0 {
153+
return diag.Errorf("no data source found matching the specified criteria")
154+
}
155+
156+
if name, ok := d.GetOk("name"); ok {
157+
for _, ds := range allDataSources {
158+
if ds.Name == name.(string) {
159+
flattenDataSource(d, ds)
160+
return nil
161+
}
162+
}
163+
return diag.Errorf("no data source found with name '%s'", name.(string))
164+
}
165+
166+
flattenDataSource(d, allDataSources[0])
167+
return nil
168+
}
169+
170+
func flattenDataSource(d *schema.ResourceData, ds *cockpit.DataSource) {
171+
d.SetId(regional.NewIDString(ds.Region, ds.ID))
172+
_ = d.Set("project_id", ds.ProjectID)
173+
_ = d.Set("name", ds.Name)
174+
_ = d.Set("url", ds.URL)
175+
_ = d.Set("type", ds.Type.String())
176+
_ = d.Set("origin", ds.Origin.String())
177+
_ = d.Set("created_at", types.FlattenTime(ds.CreatedAt))
178+
_ = d.Set("updated_at", types.FlattenTime(ds.UpdatedAt))
179+
_ = d.Set("synchronized_with_grafana", ds.SynchronizedWithGrafana)
180+
_ = d.Set("retention_days", int(ds.RetentionDays))
181+
_ = d.Set("region", ds.Region.String())
182+
}
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
package cockpit_test
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
7+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
8+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/acctest"
9+
)
10+
11+
func TestAccCockpitSource_DataSource_ByID(t *testing.T) {
12+
tt := acctest.NewTestTools(t)
13+
defer tt.Cleanup()
14+
15+
resource.ParallelTest(t, resource.TestCase{
16+
PreCheck: func() { acctest.PreCheck(t) },
17+
ProviderFactories: tt.ProviderFactories,
18+
CheckDestroy: isSourceDestroyed(tt),
19+
Steps: []resource.TestStep{
20+
{
21+
Config: `
22+
resource "scaleway_account_project" "project" {
23+
name = "tf_tests_cockpit_datasource_by_id"
24+
}
25+
26+
resource "scaleway_cockpit_source" "main" {
27+
project_id = scaleway_account_project.project.id
28+
name = "source-by-id"
29+
type = "metrics"
30+
retention_days = 30
31+
}
32+
33+
data "scaleway_cockpit_source" "by_id" {
34+
id = scaleway_cockpit_source.main.id
35+
}
36+
`,
37+
Check: resource.ComposeTestCheckFunc(
38+
resource.TestCheckResourceAttrPair("data.scaleway_cockpit_source.by_id", "id", "scaleway_cockpit_source.main", "id"),
39+
resource.TestCheckResourceAttr("data.scaleway_cockpit_source.by_id", "name", "source-by-id"),
40+
resource.TestCheckResourceAttr("data.scaleway_cockpit_source.by_id", "type", "metrics"),
41+
),
42+
},
43+
},
44+
})
45+
}
46+
47+
func TestAccCockpitSource_DataSource_ByName(t *testing.T) {
48+
tt := acctest.NewTestTools(t)
49+
defer tt.Cleanup()
50+
51+
resource.ParallelTest(t, resource.TestCase{
52+
PreCheck: func() { acctest.PreCheck(t) },
53+
ProviderFactories: tt.ProviderFactories,
54+
CheckDestroy: isSourceDestroyed(tt),
55+
Steps: []resource.TestStep{
56+
{
57+
Config: `
58+
resource "scaleway_account_project" "project" {
59+
name = "tf_tests_cockpit_datasource_by_name"
60+
}
61+
62+
resource "scaleway_cockpit_source" "main" {
63+
project_id = scaleway_account_project.project.id
64+
name = "source-by-name"
65+
type = "logs"
66+
retention_days = 30
67+
}
68+
69+
data "scaleway_cockpit_source" "by_name" {
70+
project_id = scaleway_account_project.project.id
71+
name = "source-by-name"
72+
depends_on = [scaleway_cockpit_source.main]
73+
}
74+
`,
75+
Check: resource.ComposeTestCheckFunc(
76+
resource.TestCheckResourceAttrPair("data.scaleway_cockpit_source.by_name", "id", "scaleway_cockpit_source.main", "id"),
77+
resource.TestCheckResourceAttr("data.scaleway_cockpit_source.by_name", "name", "source-by-name"),
78+
resource.TestCheckResourceAttr("data.scaleway_cockpit_source.by_name", "type", "logs"),
79+
),
80+
},
81+
},
82+
})
83+
}
84+
85+
func TestAccCockpitSource_DataSource_Defaults(t *testing.T) {
86+
tt := acctest.NewTestTools(t)
87+
defer tt.Cleanup()
88+
89+
resource.ParallelTest(t, resource.TestCase{
90+
PreCheck: func() { acctest.PreCheck(t) },
91+
ProviderFactories: tt.ProviderFactories,
92+
Steps: []resource.TestStep{
93+
{
94+
Config: fmt.Sprintf(`
95+
data "scaleway_cockpit_source" "default_metrics" {
96+
type = "metrics"
97+
origin = "scaleway"
98+
}
99+
100+
data "scaleway_cockpit_source" "default_logs" {
101+
type = "logs"
102+
origin = "scaleway"
103+
}
104+
`),
105+
Check: resource.ComposeTestCheckFunc(
106+
resource.TestCheckResourceAttr("data.scaleway_cockpit_source.default_metrics", "name", "Scaleway Metrics"),
107+
resource.TestCheckResourceAttr("data.scaleway_cockpit_source.default_metrics", "type", "metrics"),
108+
resource.TestCheckResourceAttrSet("data.scaleway_cockpit_source.default_metrics", "url"),
109+
resource.TestCheckResourceAttr("data.scaleway_cockpit_source.default_logs", "name", "Scaleway Logs"),
110+
resource.TestCheckResourceAttr("data.scaleway_cockpit_source.default_logs", "type", "logs"),
111+
resource.TestCheckResourceAttrSet("data.scaleway_cockpit_source.default_logs", "url"),
112+
),
113+
},
114+
},
115+
})
116+
}

0 commit comments

Comments
 (0)