Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Increase default Abion Core API timeout and make timeout configurable #11

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,4 @@ provider "abion" {

- `apikey` (String, Sensitive) The Abion API key. Contact [Abion](https://abion.com) for help on how to create an account and an API key and whitelist IP addresses to be able to access the Abion API. This value can also be set using the `ABION_API_KEY` environment variable. The order of precedence: Terraform configuration value (highest priority) > environment variable (lowest priority).
- `host` (String) The Abion API host URL. If not set, defaults to `https://api.abion.com`. This value can also be set using the `ABION_API_HOST` environment variable. The order of precedence: Terraform configuration value (highest priority) > environment variable > default value.
- `timeout` (Number) The Abion API timeout in seconds. If not set, defaults to `60`. This value can also be set using the `ABION_API_TIMEOUT` environment variable. The order of precedence: Terraform configuration value (highest priority) > environment variable > default value.
2 changes: 2 additions & 0 deletions examples/resources/test_multi_dev/import.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# DNS TXT records can be imported by specifying the string identifier. The import ID should be in the format: "zone/name". The `@` character represents the root of the zone, E.g., "example.com/@"
terraform import abion_dns_txt_record.example "example.com/www"
76 changes: 76 additions & 0 deletions examples/resources/test_multi_dev/resource.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
terraform {
required_providers {
abion = {
source = "abion/abion"
}
}
}

provider "abion" {
#dev
# apikey = "+FOQDv1eG4BBFmYV3WwxtTI0pKZSK+g2rF+F9fmZGWJRZj/0qzM51ZYbcRl0vZuM1Hv9dbJj7eBmRG8ijNWASA=="
#demo
apikey = "p/cEqe8kBSF68Ft8+I7H39FmBALgaAswVXRog7Wo7ec="
}

resource "abion_dns_a_record" "example_x" {
zone = "pmapitest10.com"
name = "test20241203-1"
records = [
{
ip_address = "203.0.113.0"
comments = "test comment"
ttl = "300"
}
]
}

resource "abion_dns_txt_record" "example_x" {
zone = "pmapitest10.com"
name = "test20241205"
records = [
{
txt_data = "txt 1"
},
{
txt_data = "txt 2"
comments = "test comment"
},
{
txt_data = "txt 3"
ttl = "300"
},
]
}

resource "abion_dns_cname_record" "example_x" {
zone = "pmapitest10.com"
name = "testcname20241205"
record = {
cname = "www.devabion.se."
ttl = "3600"
comments = "test comment"
}
}


resource "abion_dns_mx_record" "example_x" {
zone = "pmapitest10.com"
name = "testzone20241205"
records = [
{
host = "mail1.example.com."
priority = "10"
},
{
host = "mail2.example.com."
priority = "20"
comments = "test comment"
},
{
host = "mail3.example.com."
priority = "30"
ttl = "300"
},
]
}
10 changes: 8 additions & 2 deletions internal/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"context"
"encoding/json"
"fmt"
"github.com/hashicorp/terraform-plugin-log/tflog"
"golang.org/x/net/html"
"io"
"net/http"
Expand Down Expand Up @@ -35,7 +36,7 @@ type ApiClient interface {
}

// NewAbionClient Creates a new Client.
func NewAbionClient(host string, apiKey string) (*Client, error) {
func NewAbionClient(host string, apiKey string, timeout int) (*Client, error) {
baseURL, err := url.Parse(host)

if err != nil {
Expand All @@ -45,7 +46,7 @@ func NewAbionClient(host string, apiKey string) (*Client, error) {
return &Client{
apiKey: apiKey,
baseURL: baseURL,
HTTPClient: &http.Client{Timeout: 10 * time.Second},
HTTPClient: &http.Client{Timeout: time.Duration(timeout) * time.Second},
}, nil
}

Expand All @@ -69,6 +70,11 @@ func (c *Client) GetZone(ctx context.Context, name string) (*APIResponse[*Zone],

// PatchZone Updates a zone by patching it according to JSON Merge Patch format (RFC 7396).
func (c *Client) PatchZone(ctx context.Context, name string, patch ZoneRequest) (*APIResponse[*Zone], error) {

ctx = tflog.SetField(ctx, "key", c.apiKey)
ctx = tflog.SetField(ctx, "url", c.baseURL)
tflog.Debug(ctx, "Sending patch request")

endpoint := c.baseURL.JoinPath("v1", "zones", name)

req, err := newJSONRequest(ctx, http.MethodPatch, endpoint, patch)
Expand Down
50 changes: 46 additions & 4 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-log/tflog"
"os"
"strconv"
abionclient "terraform-provider-abion/internal/client"
)

Expand All @@ -31,8 +32,9 @@ type AbionDnsProvider struct {

// AbionProviderModel describes the provider data model.
type AbionProviderModel struct {
Host types.String `tfsdk:"host"`
Apikey types.String `tfsdk:"apikey"`
Host types.String `tfsdk:"host"`
Apikey types.String `tfsdk:"apikey"`
Timeout types.Int32 `tfsdk:"timeout"`
}

// Metadata returns the provider type name.
Expand Down Expand Up @@ -61,6 +63,13 @@ func (p *AbionDnsProvider) Schema(ctx context.Context, req provider.SchemaReques
Optional: true,
Sensitive: true,
},
"timeout": schema.Int32Attribute{
MarkdownDescription: "The Abion API timeout in seconds. If not set, defaults to `60`. " +
"This value can also be set using the `ABION_API_TIMEOUT` environment variable. " +
"The order of precedence: Terraform configuration value (highest priority) > " +
"environment variable > default value.",
Optional: true,
},
},
}
}
Expand All @@ -82,7 +91,16 @@ func (p *AbionDnsProvider) Configure(ctx context.Context, req provider.Configure
path.Root("host"),
"Unknown Abion API Host",
"The provider cannot create the Abion API client as there is an unknown configuration value for the Abion API host. "+
"Either target apply the source of the value first, set the value statically in the configuration, or use the ABION_API_KEY environment variable.",
"Either target apply the source of the value first, set the value statically in the configuration, or use the ABION_API_HOST environment variable.",
)
}

if config.Timeout.IsUnknown() {
resp.Diagnostics.AddAttributeError(
path.Root("timeout"),
"Unknown Abion API timeout",
"The provider cannot create the Abion API client as there is an unknown configuration value for the Abion API timeout. "+
"Either target apply the source of the value first, set the value statically in the configuration, or use the ABION_API_TIMEOUT environment variable.",
)
}

Expand Down Expand Up @@ -110,6 +128,29 @@ func (p *AbionDnsProvider) Configure(ctx context.Context, req provider.Configure
host = "https://api.abion.com"
}

// Environment variable ABION_API_TIMEOUT
timeoutEnv := os.Getenv("ABION_API_TIMEOUT")

var timeout int
if !config.Timeout.IsNull() {
// If Terraform configuration is set, use it
timeout = int(config.Timeout.ValueInt32())
} else if timeoutEnv != "" {
// If ABION_API_TIMEOUT environment variable is set, convert it
timeoutInt, err := strconv.Atoi(timeoutEnv)
if err != nil {
resp.Diagnostics.AddAttributeError(
path.Root("timeout"),
"Invalid ABION_API_TIMEOUT value in environment",
"Must be an integer.",
)
}
timeout = timeoutInt
} else {
// Use the default value
timeout = 60
}

apikey := os.Getenv("ABION_API_KEY")

if !config.Apikey.IsNull() {
Expand All @@ -132,12 +173,13 @@ func (p *AbionDnsProvider) Configure(ctx context.Context, req provider.Configure

ctx = tflog.SetField(ctx, "abion_host", host)
ctx = tflog.SetField(ctx, "abion_apikey", apikey)
ctx = tflog.SetField(ctx, "timeout", timeout)
ctx = tflog.MaskFieldValuesWithFieldKeys(ctx, "abion_apikey")

tflog.Debug(ctx, "Creating Abion client")

// Create a new Abion client using the configuration values
client, err := abionclient.NewAbionClient(host, apikey)
client, err := abionclient.NewAbionClient(host, apikey, timeout)

if err != nil {
resp.Diagnostics.AddError(
Expand Down
Loading