Skip to content

Commit 29c063a

Browse files
committed
feat(cockpit): add scaleway_cockpit_sources data source
1 parent b5ff068 commit 29c063a

10 files changed

+4376
-0
lines changed
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
# scaleway_cockpit_sources
2+
3+
Gets information about multiple Cockpit data sources.
4+
5+
## Example Usage
6+
7+
### List all sources in a project
8+
9+
```hcl
10+
data "scaleway_cockpit_sources" "all" {
11+
project_id = "11111111-1111-1111-1111-111111111111"
12+
}
13+
```
14+
15+
### Filter sources by type
16+
17+
```hcl
18+
data "scaleway_cockpit_sources" "metrics" {
19+
project_id = "11111111-1111-1111-1111-111111111111"
20+
type = "metrics"
21+
}
22+
```
23+
24+
### Filter sources by name
25+
26+
```hcl
27+
data "scaleway_cockpit_sources" "my_sources" {
28+
project_id = "11111111-1111-1111-1111-111111111111"
29+
name = "my-data-source"
30+
}
31+
```
32+
33+
### Filter sources by origin
34+
35+
```hcl
36+
data "scaleway_cockpit_sources" "external" {
37+
project_id = "11111111-1111-1111-1111-111111111111"
38+
origin = "external"
39+
}
40+
```
41+
42+
### List default Scaleway sources
43+
44+
```hcl
45+
data "scaleway_cockpit_sources" "default" {
46+
project_id = "11111111-1111-1111-1111-111111111111"
47+
origin = "scaleway"
48+
}
49+
```
50+
51+
## Argument Reference
52+
53+
The following arguments are supported:
54+
55+
- `project_id` - (Optional) The project ID the cockpit sources are associated with.
56+
- `region` - (Optional) The region in which the cockpit sources are located.
57+
- `name` - (Optional) Filter sources by name.
58+
- `type` - (Optional) Filter sources by type. Possible values are: `metrics`, `logs`, `traces`.
59+
- `origin` - (Optional) Filter sources by origin. Possible values are: `scaleway`, `external`, `custom`.
60+
61+
## Attributes Reference
62+
63+
In addition to all arguments above, the following attributes are exported:
64+
65+
- `sources` - List of cockpit sources.
66+
67+
Each `sources` block contains:
68+
69+
- `id` - The ID of the data source.
70+
- `name` - Name of the datasource.
71+
- `url` - The URL of the datasource.
72+
- `type` - The type of the datasource.
73+
- `origin` - The origin of the datasource.
74+
- `synchronized_with_grafana` - Indicates whether the data source is synchronized with Grafana.
75+
- `created_at` - The date and time of the creation of the cockpit datasource.
76+
- `updated_at` - The date and time of the last update of the cockpit datasource.
77+
- `retention_days` - The number of days to retain data.
78+
- `push_url` - The URL endpoint used for pushing data to the cockpit data source.
79+
- `region` - The region of the data source.
80+
- `project_id` - The project ID of the data source.
81+
82+
## Use Cases
83+
84+
This data source is particularly useful when you need to:
85+
86+
- List all data sources in a project for monitoring or management purposes
87+
- Provision a separate Grafana instance with all available data sources
88+
- Iterate over multiple data sources using Terraform's `for_each` or `count` meta-arguments
89+
- Filter data sources by specific criteria without knowing their exact names or IDs
90+
91+
## Example: Provisioning Grafana with all data sources
92+
93+
```hcl
94+
data "scaleway_cockpit_sources" "all" {
95+
project_id = "11111111-1111-1111-1111-111111111111"
96+
}
97+
98+
resource "grafana_data_source" "cockpit_sources" {
99+
for_each = {
100+
for source in data.scaleway_cockpit_sources.all.sources : source.name => source
101+
}
102+
103+
type = "prometheus" # or "loki" for logs, "tempo" for traces
104+
name = each.value.name
105+
url = each.value.url
106+
}
107+
```

internal/provider/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,7 @@ func Provider(config *Config) plugin.ProviderFunc {
268268
"scaleway_block_volume": block.DataSourceVolume(),
269269
"scaleway_cockpit": cockpit.DataSourceCockpit(),
270270
"scaleway_cockpit_source": cockpit.DataSourceCockpitSource(),
271+
"scaleway_cockpit_sources": cockpit.DataSourceCockpitSources(),
271272
"scaleway_config": scwconfig.DataSourceConfig(),
272273
"scaleway_container": container.DataSourceContainer(),
273274
"scaleway_container_namespace": container.DataSourceNamespace(),
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
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/scaleway/scaleway-sdk-go/api/cockpit/v1"
9+
"github.com/scaleway/scaleway-sdk-go/scw"
10+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/datasource"
11+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality/regional"
12+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/meta"
13+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/types"
14+
)
15+
16+
func DataSourceCockpitSources() *schema.Resource {
17+
dsSchema := datasource.SchemaFromResourceSchema(ResourceCockpitSource().Schema)
18+
19+
sourceElementSchema := datasource.SchemaFromResourceSchema(ResourceCockpitSource().Schema)
20+
delete(sourceElementSchema, "sources")
21+
22+
sourceElementSchema["id"] = &schema.Schema{
23+
Type: schema.TypeString,
24+
Description: "The ID of the data source.",
25+
Computed: true,
26+
}
27+
28+
dsSchema["sources"] = &schema.Schema{
29+
Type: schema.TypeList,
30+
Description: "List of cockpit sources.",
31+
Computed: true,
32+
Elem: &schema.Resource{
33+
Schema: sourceElementSchema,
34+
},
35+
}
36+
37+
datasource.FixDatasourceSchemaFlags(dsSchema, false, "name", "project_id")
38+
datasource.AddOptionalFieldsToSchema(dsSchema, "region", "type", "origin")
39+
40+
return &schema.Resource{
41+
ReadContext: dataSourceCockpitSourcesRead,
42+
Schema: dsSchema,
43+
}
44+
}
45+
46+
func dataSourceCockpitSourcesRead(ctx context.Context, d *schema.ResourceData, m any) diag.Diagnostics {
47+
var region scw.Region
48+
var err error
49+
50+
if v, ok := d.GetOk("region"); ok && v.(string) != "" {
51+
region, err = scw.ParseRegion(v.(string))
52+
if err != nil {
53+
return diag.FromErr(err)
54+
}
55+
} else {
56+
_, region, err = cockpitAPIWithRegion(d, m)
57+
if err != nil {
58+
return diag.FromErr(err)
59+
}
60+
}
61+
62+
api := cockpit.NewRegionalAPI(meta.ExtractScwClient(m))
63+
64+
req := &cockpit.RegionalAPIListDataSourcesRequest{
65+
Region: region,
66+
ProjectID: d.Get("project_id").(string),
67+
}
68+
69+
if v, ok := d.GetOk("type"); ok {
70+
req.Types = []cockpit.DataSourceType{cockpit.DataSourceType(v.(string))}
71+
}
72+
73+
if v, ok := d.GetOk("origin"); ok {
74+
req.Origin = cockpit.DataSourceOrigin(v.(string))
75+
}
76+
77+
res, err := api.ListDataSources(req, scw.WithContext(ctx), scw.WithAllPages())
78+
if err != nil {
79+
return diag.FromErr(err)
80+
}
81+
82+
sources := []any(nil)
83+
84+
for _, ds := range res.DataSources {
85+
if name, ok := d.GetOk("name"); ok {
86+
if ds.Name != name.(string) {
87+
continue
88+
}
89+
}
90+
91+
rawSource := flattenDataSourceToMap(ds)
92+
sources = append(sources, rawSource)
93+
}
94+
95+
d.SetId(region.String())
96+
_ = d.Set("sources", sources)
97+
98+
return nil
99+
}
100+
101+
func flattenDataSourceToMap(ds *cockpit.DataSource) map[string]any {
102+
pushURL, _ := createCockpitPushURL(ds.Type, ds.URL)
103+
104+
return map[string]any{
105+
"id": regional.NewIDString(ds.Region, ds.ID),
106+
"project_id": ds.ProjectID,
107+
"name": ds.Name,
108+
"url": ds.URL,
109+
"type": ds.Type.String(),
110+
"origin": ds.Origin.String(),
111+
"created_at": types.FlattenTime(ds.CreatedAt),
112+
"updated_at": types.FlattenTime(ds.UpdatedAt),
113+
"synchronized_with_grafana": ds.SynchronizedWithGrafana,
114+
"retention_days": int(ds.RetentionDays),
115+
"region": ds.Region.String(),
116+
"push_url": pushURL,
117+
}
118+
}

0 commit comments

Comments
 (0)