-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add data provider for monitoring IPs (#114)
- Loading branch information
Showing
12 changed files
with
299 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
--- | ||
# generated by https://github.com/hashicorp/terraform-plugin-docs | ||
page_title: "betteruptime_ip_list Data Source - terraform-provider-better-uptime" | ||
subcategory: "" | ||
description: |- | ||
Monitoring IPs lookup. | ||
--- | ||
|
||
# betteruptime_ip_list (Data Source) | ||
|
||
Monitoring IPs lookup. | ||
|
||
|
||
|
||
<!-- schema generated by tfplugindocs --> | ||
## Schema | ||
|
||
### Optional | ||
|
||
- **filter_clusters** (List of String) The optional list of clusters used to filter the IPs. | ||
|
||
### Read-Only | ||
|
||
- **all_clusters** (List of String) The list of all clusters. | ||
- **id** (String) The internal ID of the resource, can be ignored. | ||
- **ips** (List of String) The list of IPs used for monitoring. | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
This directory contains a sample Terraform configuration for getting all IPs used by Better Stack for Uptime monitoring. | ||
These IPs can be used to configure resources in other providers accordingly. | ||
|
||
## Usage | ||
|
||
```shell script | ||
git clone https://github.com/BetterStackHQ/terraform-provider-better-uptime && \ | ||
cd terraform-provider-better-uptime/examples/ips | ||
|
||
echo '# See variables.tf for more. | ||
betteruptime_api_token = "XXXXXXXXXXXXXXXXXXXXXXXX" | ||
betteruptime_clusters = ["us"] | ||
' > terraform.tfvars | ||
|
||
terraform init | ||
terraform apply | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
provider "betteruptime" { | ||
api_token = var.betteruptime_api_token | ||
} | ||
|
||
data "betteruptime_ip_list" "this" { | ||
filter_clusters = var.betteruptime_clusters | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
output "monitoring_ips" { | ||
value = data.betteruptime_ip_list.this.ips | ||
} | ||
|
||
output "monitoring_clusters" { | ||
value = data.betteruptime_ip_list.this.all_clusters | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
variable "betteruptime_api_token" { | ||
type = string | ||
description = <<EOF | ||
Better Stack Uptime API Token | ||
(https://betterstack.com/docs/uptime/api/getting-started-with-uptime-api/#obtaining-an-uptime-api-token) | ||
EOF | ||
# The value can be omitted if BETTERUPTIME_API_TOKEN env var is set. | ||
default = null | ||
} | ||
|
||
variable "betteruptime_clusters" { | ||
type = list(string) | ||
description = "Names of the clusters to fetch IPs from. Omit to fetch all IPs." | ||
default = null | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
terraform { | ||
required_version = ">= 0.14" | ||
required_providers { | ||
betteruptime = { | ||
source = "BetterStackHQ/better-uptime" | ||
version = ">= 0.11.10" | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
package provider | ||
|
||
import ( | ||
"bytes" | ||
"context" | ||
"encoding/json" | ||
"io" | ||
"net" | ||
"net/http" | ||
"sort" | ||
|
||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||
) | ||
|
||
func newIpListDataSource() *schema.Resource { | ||
return &schema.Resource{ | ||
ReadContext: ipListLookup, | ||
Description: "Monitoring IPs lookup.", | ||
Schema: ipListSchema, | ||
} | ||
} | ||
|
||
func ipListLookup(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { | ||
res, err := meta.(*client).Get(ctx, "/ips-by-cluster.json") | ||
if err != nil { | ||
return diag.FromErr(err) | ||
} | ||
defer func() { | ||
// Keep-Alive. | ||
_, _ = io.Copy(io.Discard, res.Body) | ||
_ = res.Body.Close() | ||
}() | ||
body, err := io.ReadAll(res.Body) | ||
if err != nil { | ||
return diag.FromErr(err) | ||
} | ||
if res.StatusCode != http.StatusOK { | ||
return diag.Errorf("GET %s returned %d: %s", res.Request.URL.String(), res.StatusCode, string(body)) | ||
} | ||
|
||
// Unmarshal the JSON into a map | ||
var ipData map[string][]string | ||
err = json.Unmarshal(body, &ipData) | ||
if err != nil { | ||
return diag.FromErr(err) | ||
} | ||
|
||
// Retrieve the clusters specified by the user from the Terraform resource data | ||
requestedClusters := d.Get("filter_clusters").([]interface{}) | ||
filterClusters := make(map[string]bool) | ||
for _, cluster := range requestedClusters { | ||
filterClusters[cluster.(string)] = true | ||
} | ||
|
||
// Filter IPs based on the specified clusters, and fetch all clusters | ||
var filteredIPs []string | ||
var allClusters []string | ||
for cluster, ips := range ipData { | ||
if len(filterClusters) == 0 || filterClusters[cluster] { | ||
filteredIPs = append(filteredIPs, ips...) | ||
} | ||
allClusters = append(allClusters, cluster) | ||
} | ||
|
||
// Sort the IPs and cluster to be deterministic | ||
sort.Slice(filteredIPs, func(i, j int) bool { | ||
ip1 := net.ParseIP(filteredIPs[i]) | ||
ip2 := net.ParseIP(filteredIPs[j]) | ||
|
||
if ip1.To4() != nil && ip2.To4() == nil { | ||
return true // IPv4 before IPv6 | ||
} | ||
if ip1.To4() == nil && ip2.To4() != nil { | ||
return false // IPv6 after IPv4 | ||
} | ||
|
||
// Compare IPs directly | ||
return bytes.Compare(ip1, ip2) < 0 | ||
}) | ||
sort.Strings(allClusters) | ||
|
||
// Set the data in the Terraform schema | ||
d.SetId("betterstack_ip_list") | ||
if err := d.Set("ips", filteredIPs); err != nil { | ||
return diag.FromErr(err) | ||
} | ||
if err := d.Set("all_clusters", allClusters); err != nil { | ||
return diag.FromErr(err) | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
package provider | ||
|
||
import ( | ||
"net/http" | ||
"net/http/httptest" | ||
"testing" | ||
|
||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||
) | ||
|
||
func TestIpListData(t *testing.T) { | ||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||
t.Log("Received " + r.Method + " " + r.RequestURI) | ||
|
||
switch { | ||
case r.Method == http.MethodGet && r.RequestURI == "/ips-by-cluster.json": | ||
_, _ = w.Write([]byte(`{"eu":["139.162.215.1","139.162.215.2"],"us":["66.228.56.1","66.228.56.2","66.228.56.3"]}`)) | ||
default: | ||
t.Fatal("Unexpected " + r.Method + " " + r.RequestURI) | ||
t.Fail() | ||
} | ||
})) | ||
defer server.Close() | ||
|
||
resource.Test(t, resource.TestCase{ | ||
IsUnitTest: true, | ||
ProviderFactories: map[string]func() (*schema.Provider, error){ | ||
"betteruptime": func() (*schema.Provider, error) { | ||
return New(WithURL(server.URL)), nil | ||
}, | ||
}, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: ` | ||
provider "betteruptime" { | ||
api_token = "foo" | ||
} | ||
data "betteruptime_ip_list" "this" { | ||
} | ||
`, | ||
Check: resource.ComposeTestCheckFunc( | ||
resource.TestCheckResourceAttrSet("data.betteruptime_ip_list.this", "id"), | ||
resource.TestCheckResourceAttr("data.betteruptime_ip_list.this", "ips.0", "66.228.56.1"), | ||
resource.TestCheckResourceAttr("data.betteruptime_ip_list.this", "ips.1", "66.228.56.2"), | ||
resource.TestCheckResourceAttr("data.betteruptime_ip_list.this", "ips.2", "66.228.56.3"), | ||
resource.TestCheckResourceAttr("data.betteruptime_ip_list.this", "ips.3", "139.162.215.1"), | ||
resource.TestCheckResourceAttr("data.betteruptime_ip_list.this", "ips.4", "139.162.215.2"), | ||
resource.TestCheckNoResourceAttr("data.betteruptime_ip_list.this", "ips.5"), | ||
resource.TestCheckResourceAttr("data.betteruptime_ip_list.this", "all_clusters.0", "eu"), | ||
resource.TestCheckResourceAttr("data.betteruptime_ip_list.this", "all_clusters.1", "us"), | ||
resource.TestCheckNoResourceAttr("data.betteruptime_ip_list.this", "all_clusters.2"), | ||
), | ||
}, | ||
{ | ||
Config: ` | ||
provider "betteruptime" { | ||
api_token = "foo" | ||
} | ||
data "betteruptime_ip_list" "this" { | ||
filter_clusters = ["us"] | ||
} | ||
`, | ||
Check: resource.ComposeTestCheckFunc( | ||
resource.TestCheckResourceAttrSet("data.betteruptime_ip_list.this", "id"), | ||
resource.TestCheckResourceAttr("data.betteruptime_ip_list.this", "ips.0", "66.228.56.1"), | ||
resource.TestCheckResourceAttr("data.betteruptime_ip_list.this", "ips.1", "66.228.56.2"), | ||
resource.TestCheckResourceAttr("data.betteruptime_ip_list.this", "ips.2", "66.228.56.3"), | ||
resource.TestCheckNoResourceAttr("data.betteruptime_ip_list.this", "ips.3"), | ||
resource.TestCheckResourceAttr("data.betteruptime_ip_list.this", "all_clusters.0", "eu"), | ||
resource.TestCheckResourceAttr("data.betteruptime_ip_list.this", "all_clusters.1", "us"), | ||
resource.TestCheckNoResourceAttr("data.betteruptime_ip_list.this", "all_clusters.2"), | ||
), | ||
}, | ||
}, | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package provider | ||
|
||
import ( | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||
) | ||
|
||
var ipListSchema = map[string]*schema.Schema{ | ||
"id": { | ||
Description: "The internal ID of the resource, can be ignored.", | ||
Type: schema.TypeString, | ||
Optional: false, | ||
Computed: true, | ||
}, | ||
"ips": { | ||
Description: "The list of IPs used for monitoring.", | ||
Type: schema.TypeList, | ||
Optional: false, | ||
Computed: true, | ||
Elem: &schema.Schema{ | ||
Type: schema.TypeString, | ||
}, | ||
}, | ||
"all_clusters": { | ||
Description: "The list of all clusters.", | ||
Type: schema.TypeList, | ||
Optional: false, | ||
Computed: true, | ||
Elem: &schema.Schema{ | ||
Type: schema.TypeString, | ||
}, | ||
}, | ||
"filter_clusters": { | ||
Description: "The optional list of clusters used to filter the IPs.", | ||
Type: schema.TypeList, | ||
Optional: true, | ||
Computed: false, | ||
Elem: &schema.Schema{ | ||
Type: schema.TypeString, | ||
}, | ||
}, | ||
} |