Skip to content

Commit 5f191c7

Browse files
Add new datasource: Cloud IPs (#507)
* Add new datasource: Cloud IPs Simply the list of IPs to allow, from https://grafana.com/docs/grafana-cloud/reference/allow-list/ Closes #314 * Fix linter
1 parent 0e6ec6d commit 5f191c7

File tree

5 files changed

+180
-0
lines changed

5 files changed

+180
-0
lines changed

docs/data-sources/cloud_ips.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
---
2+
# generated by https://github.com/hashicorp/terraform-plugin-docs
3+
page_title: "grafana_cloud_ips Data Source - terraform-provider-grafana"
4+
subcategory: ""
5+
description: |-
6+
Data source for retrieving sets of cloud IPs. See https://grafana.com/docs/grafana-cloud/reference/allow-list/ for more info
7+
---
8+
9+
# grafana_cloud_ips (Data Source)
10+
11+
Data source for retrieving sets of cloud IPs. See https://grafana.com/docs/grafana-cloud/reference/allow-list/ for more info
12+
13+
## Example Usage
14+
15+
```terraform
16+
data "grafana_cloud_ips" "test" {}
17+
```
18+
19+
<!-- schema generated by tfplugindocs -->
20+
## Schema
21+
22+
### Read-Only
23+
24+
- `hosted_alerts` (Set of String) Set of IP addresses that are used for hosted alerts.
25+
- `hosted_grafana` (Set of String) Set of IP addresses that are used for hosted Grafana.
26+
- `hosted_logs` (Set of String) Set of IP addresses that are used for hosted logs.
27+
- `hosted_metrics` (Set of String) Set of IP addresses that are used for hosted metrics.
28+
- `hosted_traces` (Set of String) Set of IP addresses that are used for hosted traces.
29+
- `id` (String) The ID of this resource.
30+
31+
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
data "grafana_cloud_ips" "test" {}

grafana/data_source_cloud_ips.go

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
package grafana
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"io"
7+
"net/http"
8+
"strings"
9+
10+
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
11+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
12+
)
13+
14+
func DatasourceCloudIPs() *schema.Resource {
15+
return &schema.Resource{
16+
Description: "Data source for retrieving sets of cloud IPs. See https://grafana.com/docs/grafana-cloud/reference/allow-list/ for more info",
17+
ReadContext: dataSourceCloudIPsRead,
18+
Schema: map[string]*schema.Schema{
19+
"hosted_alerts": {
20+
Description: "Set of IP addresses that are used for hosted alerts.",
21+
Type: schema.TypeSet,
22+
Computed: true,
23+
Elem: &schema.Schema{
24+
Type: schema.TypeString,
25+
},
26+
},
27+
"hosted_grafana": {
28+
Description: "Set of IP addresses that are used for hosted Grafana.",
29+
Type: schema.TypeSet,
30+
Computed: true,
31+
Elem: &schema.Schema{
32+
Type: schema.TypeString,
33+
},
34+
},
35+
"hosted_metrics": {
36+
Description: "Set of IP addresses that are used for hosted metrics.",
37+
Type: schema.TypeSet,
38+
Computed: true,
39+
Elem: &schema.Schema{
40+
Type: schema.TypeString,
41+
},
42+
},
43+
"hosted_traces": {
44+
Description: "Set of IP addresses that are used for hosted traces.",
45+
Type: schema.TypeSet,
46+
Computed: true,
47+
Elem: &schema.Schema{
48+
Type: schema.TypeString,
49+
},
50+
},
51+
"hosted_logs": {
52+
Description: "Set of IP addresses that are used for hosted logs.",
53+
Type: schema.TypeSet,
54+
Computed: true,
55+
Elem: &schema.Schema{
56+
Type: schema.TypeString,
57+
},
58+
},
59+
},
60+
}
61+
}
62+
63+
func dataSourceCloudIPsRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
64+
d.SetId("cloud_ips")
65+
for attr, dataURL := range map[string]string{
66+
"hosted_alerts": "https://grafana.com/api/hosted-alerts/source-ips.txt",
67+
"hosted_grafana": "https://grafana.com/api/hosted-grafana/source-ips.txt",
68+
"hosted_metrics": "https://grafana.com/api/hosted-metrics/source-ips.txt",
69+
"hosted_traces": "https://grafana.com/api/hosted-traces/source-ips.txt",
70+
"hosted_logs": "https://grafana.com/api/hosted-logs/source-ips.txt",
71+
} {
72+
// nolint: gosec
73+
resp, err := http.Get(dataURL)
74+
if err != nil {
75+
return diag.Errorf("error querying IPs for %s (%s): %v", attr, dataURL, err)
76+
}
77+
defer resp.Body.Close()
78+
79+
b, err := io.ReadAll(resp.Body)
80+
if err != nil {
81+
return diag.Errorf("error reading response body for %s (%s): %v", attr, dataURL, err)
82+
}
83+
var ipStr []string
84+
for _, ip := range strings.Split(string(b), "\n") {
85+
ip = strings.TrimSpace(ip)
86+
if ip != "" {
87+
ipStr = append(ipStr, ip)
88+
}
89+
}
90+
91+
if err := d.Set(attr, ipStr); err != nil {
92+
return diag.FromErr(fmt.Errorf("error setting %s: %v", attr, err))
93+
}
94+
}
95+
96+
return nil
97+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package grafana
2+
3+
import (
4+
"fmt"
5+
"net"
6+
"strconv"
7+
"strings"
8+
"testing"
9+
10+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
11+
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
12+
)
13+
14+
func TestAccDataSourceCloudIPsRead(t *testing.T) {
15+
t.Parallel()
16+
CheckCloudAPITestsEnabled(t)
17+
18+
resource.Test(t, resource.TestCase{
19+
ProviderFactories: testAccProviderFactories,
20+
Steps: []resource.TestStep{
21+
{
22+
Config: testAccExample(t, "data-sources/grafana_cloud_ips/data-source.tf"),
23+
Check: func(s *terraform.State) error {
24+
rs := s.RootModule().Resources["data.grafana_cloud_ips.test"]
25+
26+
for k, v := range rs.Primary.Attributes {
27+
// Attributes have two parts, the count of a list and the list items
28+
if strings.HasSuffix(k, ".#") {
29+
// This is the count
30+
intValue, err := strconv.Atoi(v)
31+
if err != nil {
32+
return fmt.Errorf("could not convert attribute %s (value: %s) to int: %s", k, v, err)
33+
}
34+
if intValue == 0 {
35+
return fmt.Errorf("attribute %s is empty", k)
36+
}
37+
} else if k != "id" && k != "%" {
38+
// Other items are IPs
39+
if parsed := net.ParseIP(v); parsed == nil {
40+
return fmt.Errorf("invalid IP in attribute %s: %s", k, v)
41+
}
42+
}
43+
}
44+
45+
return nil
46+
},
47+
},
48+
},
49+
})
50+
}

grafana/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ func Provider(version string) func() *schema.Provider {
211211
"grafana_organization": DatasourceOrganization(),
212212

213213
// Cloud
214+
"grafana_cloud_ips": DatasourceCloudIPs(),
214215
"grafana_cloud_stack": DatasourceCloudStack(),
215216

216217
// Synthetic Monitoring

0 commit comments

Comments
 (0)