Skip to content

Commit

Permalink
Add data_region to the recognized fields (#28)
Browse files Browse the repository at this point in the history
Co-authored-by: Petr Heinz <[email protected]>
  • Loading branch information
gyfis and PetrHeinz authored Jan 7, 2025
1 parent 4173cd8 commit f7ea69d
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 1 deletion.
1 change: 1 addition & 0 deletions docs/data-sources/source.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ This Data Source allows you to look up existing Sources using their table name.
### Read-Only

- **created_at** (String) The time when this monitor group was created.
- **data_region** (String) Region where we store your data.
- **id** (String) The ID of this source.
- **ingesting_paused** (Boolean) This property allows you to temporarily pause data ingesting for this source (e.g., when you are reaching your plan's usage quota and you want to prioritize some sources over others).
- **live_tail_pattern** (String) Freeform text template for formatting Live tail output with columns wrapped in {column} brackets. Example: "PID: {message_json.pid} {level} {message}"
Expand Down
1 change: 1 addition & 0 deletions docs/resources/source.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ This resource allows you to create, modify, and delete your Sources. For more in

### Optional

- **data_region** (String) Region where we store your data.
- **ingesting_paused** (Boolean) This property allows you to temporarily pause data ingesting for this source (e.g., when you are reaching your plan's usage quota and you want to prioritize some sources over others).
- **live_tail_pattern** (String) Freeform text template for formatting Live tail output with columns wrapped in {column} brackets. Example: "PID: {message_json.pid} {level} {message}"
- **logs_retention** (Number) Data retention for logs in days. There might be additional charges for longer retention.
Expand Down
25 changes: 24 additions & 1 deletion internal/provider/resource_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,12 @@ var sourceSchema = map[string]*schema.Schema{
Optional: true,
Sensitive: true,
},
"data_region": {
Description: "Region where we store your data.",
Type: schema.TypeString,
Optional: true,
Computed: true,
},
}

func newSourceResource() *schema.Resource {
Expand All @@ -200,7 +206,7 @@ func newSourceResource() *schema.Resource {
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},
CustomizeDiff: validateRequestHeaders,
CustomizeDiff: validateSource,
Description: "This resource allows you to create, modify, and delete your Sources. For more information about the Sources API check https://betterstack.com/docs/logs/api/list-all-existing-sources/",
Schema: sourceSchema,
}
Expand All @@ -223,6 +229,7 @@ type source struct {
ScrapeRequestHeaders *[]map[string]interface{} `json:"scrape_request_headers,omitempty"`
ScrapeRequestBasicAuthUser *string `json:"scrape_request_basic_auth_user,omitempty"`
ScrapeRequestBasicAuthPassword *string `json:"scrape_request_basic_auth_password,omitempty"`
DataRegion *string `json:"data_region,omitempty"`
}

type sourceHTTPResponse struct {
Expand Down Expand Up @@ -255,6 +262,7 @@ func sourceRef(in *source) []struct {
{k: "scrape_request_headers", v: &in.ScrapeRequestHeaders},
{k: "scrape_request_basic_auth_user", v: &in.ScrapeRequestBasicAuthUser},
{k: "scrape_request_basic_auth_password", v: &in.ScrapeRequestBasicAuthPassword},
{k: "data_region", v: &in.DataRegion},
}
}

Expand All @@ -263,7 +271,9 @@ func sourceCreate(ctx context.Context, d *schema.ResourceData, meta interface{})
for _, e := range sourceRef(&in) {
load(d, e.k, e.v)
}

load(d, "team_name", &in.TeamName)

var out sourceHTTPResponse
if err := resourceCreate(ctx, meta, "/api/v1/sources", &in, &out); err != nil {
return err
Expand All @@ -290,6 +300,7 @@ func sourceCopyAttrs(d *schema.ResourceData, in *source) diag.Diagnostics {
derr = append(derr, diag.FromErr(err)[0])
}
}

return derr
}

Expand All @@ -307,6 +318,18 @@ func sourceDelete(ctx context.Context, d *schema.ResourceData, meta interface{})
return resourceDelete(ctx, meta, fmt.Sprintf("/api/v1/sources/%s", url.PathEscape(d.Id())))
}

func validateSource(ctx context.Context, diff *schema.ResourceDiff, v interface{}) error {
if diff.Id() != "" && diff.HasChange("data_region") {
return fmt.Errorf("data_region cannot be changed after source is created")
}

if err := validateRequestHeaders(ctx, diff, v); err != nil {
return err
}

return nil
}

func validateRequestHeaders(ctx context.Context, diff *schema.ResourceDiff, v interface{}) error {
if headers, ok := diff.GetOk("scrape_request_headers"); ok {
for _, header := range headers.([]interface{}) {
Expand Down
25 changes: 25 additions & 0 deletions internal/provider/resource_source_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,15 @@ func TestResourceSource(t *testing.T) {
resource "logtail_source" "this" {
name = "%s"
platform = "%s"
data_region = "eu-hel-1-legacy"
}
`, name, platform),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet("logtail_source.this", "id"),
resource.TestCheckResourceAttr("logtail_source.this", "name", name),
resource.TestCheckResourceAttr("logtail_source.this", "platform", platform),
resource.TestCheckResourceAttr("logtail_source.this", "token", "generated_by_logtail"),
resource.TestCheckResourceAttr("logtail_source.this", "data_region", "eu-hel-1-legacy"),
),
},
// Step 2 - update.
Expand All @@ -121,6 +123,7 @@ func TestResourceSource(t *testing.T) {
resource.TestCheckResourceAttr("logtail_source.this", "platform", platform),
resource.TestCheckResourceAttr("logtail_source.this", "ingesting_paused", "true"),
resource.TestCheckResourceAttr("logtail_source.this", "token", "generated_by_logtail"),
resource.TestCheckResourceAttr("logtail_source.this", "data_region", "eu-hel-1-legacy"),
),
},
// Step 3 - make no changes, check plan is empty (omitted attributes are not controlled)
Expand Down Expand Up @@ -423,6 +426,28 @@ func TestResourceSource(t *testing.T) {
PlanOnly: true,
ExpectError: regexp.MustCompile(`Invalid request header map\[X-TEST:test\]: must contain 'name' key with a non-empty string value`),
},
// Step 8 - change of data region
{
Config: fmt.Sprintf(`
provider "logtail" {
api_token = "foo"
}
resource "logtail_source" "this" {
name = "%s"
platform = "%s"
scrape_request_headers = [
{
name = "X-TEST"
value = "test"
}
]
data_region = "new_data_region"
}
`, name, platform_scrape),
PlanOnly: true,
ExpectError: regexp.MustCompile(`data_region cannot be changed after source is created`),
},
},
})
}
Expand Down

0 comments on commit f7ea69d

Please sign in to comment.