Compare commits

..
17 Commits
Author SHA1 Message Date
beatzaplenty b7bc2dd9c7 update .gitignore
ci / test (push) Failing after 5m12s
2026-08-05 08:53:55 +10:00
beatzaplenty 54d07a05a9 terraform-registry help
ci / test (push) Failing after 6m7s
2026-08-05 08:52:30 +10:00
beatzaplentyandClaude Sonnet 4.6 ae75b2a937 fix: use actions/checkout@v4 in release workflow
ci / test (push) Failing after 5m47s
Matches the version used in ci.yml; v6 does not exist.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-05 07:10:13 +10:00
beatzaplentyandClaude Sonnet 4.6 81c8c54f07 bump version references to v0.4.0
ci / test (push) Failing after 5m14s
Release / goreleaser (push) Failing after 4m58s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LFZyrmtKsezBwFWGTWsb2y
2026-08-04 00:04:55 +10:00
beatzaplentyandClaude Sonnet 4.6 70bb75ad46 bump to v0.2.0: complete provider implementation with live-tested DNS record types
ci / test (push) Failing after 5m55s
- DYNU_API_KEY env var fallback in provider config
- dynu_domain resource: add 9 computed attributes (unicode_name, ipv4/ipv6 flags,
  wildcard aliases, allow_zone_transfer, dnssec, created_on, updated_on)
- dynu_dns_records data source: add 6 type-specific fields (priority, weight,
  port, flags, tag, value)
- Fix normalizeRecordContentForState for MX/SRV/NS/PTR (read host field) and CAA
  (read value field) to avoid plan/state inconsistency
- Allow underscore-prefixed DNS labels in hostname validator (RFC 2782 SRV)
- Preserve plan/state hostname across create/update/read to prevent inconsistent
  result errors when API returns full FQDN for node_name-style records
- Update all version references from 0.1.0 to 0.2.0

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LFZyrmtKsezBwFWGTWsb2y
2026-08-03 23:40:27 +10:00
beatzaplenty 12b8f2460d remove version constraints for terraform and provider in examples
ci / test (push) Failing after 5m47s
2026-05-13 05:01:38 +10:00
beatzaplenty c418039617 Merge remote-tracking branch 'origin/codex/prepare-terraform-provider-for-public-registry' 2026-05-13 04:10:52 +10:00
beatzaplenty 53ffb89eed Merge branch 'codex/prepare-terraform-provider-for-public-registry' of https://github.com/beatz174-bit/terraform-dynu-provider into codex/prepare-terraform-provider-for-public-registry 2026-05-13 04:08:00 +10:00
beatzaplenty 95bcee16f1 changed terraform format check to just run the format command 2026-05-13 04:06:44 +10:00
beatz174-bit 6a051d9c89 Update ci.yml 2026-05-13 04:04:18 +10:00
beatzaplenty e220eed917 change terraform fmt command to run format and not check it. 2026-05-13 03:59:21 +10:00
beatzaplenty bc8971b456 added .key to .gitignore 2026-05-13 03:57:41 +10:00
beatzaplenty 80116cfa52 updated ci action to go ver 6 and added .key to gitignore 2026-05-13 03:57:14 +10:00
beatz174-bit 69bc53f018 Merge pull request #56 from beatz174-bit/codex/fix-codex-review-issues-for-pr-#55
Follow-up: exclude unsupported darwin/arm GoReleaser build target
2026-05-13 03:36:39 +10:00
beatz174-bit 26db375b38 Fix unsupported darwin/arm release target 2026-05-13 03:35:19 +10:00
beatzaplenty 054394f3b2 moved to registry provider ver 0.2.0 2026-05-12 19:12:46 +10:00
beatz174-bit ace79751a9 Merge pull request #55 from beatz174-bit/codex/prepare-terraform-provider-for-public-registry
Prepare provider for public Terraform Registry publishing
2026-05-12 18:44:23 +10:00
26 changed files with 175 additions and 43 deletions
+4
View File
@@ -0,0 +1,4 @@
export CI=1
export TERM=xterm-256color
export GIT_PAGER=cat
export PATH="$(pwd)/.codex/bin:$PATH"
+3 -3
View File
@@ -13,7 +13,7 @@ jobs:
uses: actions/checkout@v4
- name: Setup Go
uses: actions/setup-go@v5
uses: actions/setup-go@v6
with:
go-version-file: go.mod
@@ -36,8 +36,8 @@ jobs:
- name: Go tests
run: go test ./...
- name: Terraform fmt check
run: terraform fmt -check -recursive examples
- name: Terraform fmt
run: terraform fmt -recursive examples
- name: Repository quality gate
run: ./scripts/check.sh
+1 -1
View File
@@ -12,7 +12,7 @@ jobs:
goreleaser:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v4
with:
fetch-depth: 0
+2 -1
View File
@@ -4,6 +4,7 @@
*.dll
*.so
*.dylib
*.key
terraform-provider-dynu
terraform-provider-dynu_v*
dist/
@@ -23,7 +24,7 @@ go.work.sum
# env file
.env
! .terraform-registry
# Terraform local artifacts
.terraform/
**/.terraform/
+2
View File
@@ -30,6 +30,8 @@ builds:
ignore:
- goos: darwin
goarch: "386"
- goos: darwin
goarch: arm
- goos: windows
goarch: arm
+3
View File
@@ -0,0 +1,3 @@
Request: Re-establish link between github repo and hasicorp registry provider
Registry Link: https://registry.terraform.io/providers/beatz174-bit/dynu
Request by: wayne.bennett@live.com
+2 -2
View File
@@ -23,7 +23,7 @@ terraform {
required_providers {
dynu = {
source = "beatz174-bit/dynu"
version = "~> 0.1.0"
version = "~> 0.4.0"
}
}
}
@@ -107,7 +107,7 @@ Use a disposable domain/subdomain only.
- Terraform provider source address: `beatz174-bit/dynu`.
- Repository name must remain `terraform-provider-dynu`.
- Releases are triggered by pushing a semantic version tag such as `v0.1.0`.
- Releases are triggered by pushing a semantic version tag such as `v0.4.0`.
- Required GitHub Actions secrets:
- `GPG_PRIVATE_KEY`
- `PASSPHRASE`
+6
View File
@@ -37,3 +37,9 @@ data "dynu_dns_records" "records" {
- `updated_on` (String)
- `group` (String)
- `host` (String)
- `priority` (Number) Priority for MX and SRV records.
- `weight` (Number) Weight for SRV records.
- `port` (Number) Port for SRV records.
- `flags` (Number) Flags for CAA records.
- `tag` (String) Tag for CAA records.
- `value` (String) Value for CAA records.
+1 -1
View File
@@ -16,7 +16,7 @@ terraform {
required_providers {
dynu = {
source = "beatz174-bit/dynu"
version = "~> 0.1.0"
version = "~> 0.4.0"
}
}
}
+9
View File
@@ -38,6 +38,15 @@ These fields can be configured, and also reflect values returned by Dynu.
- `id` (Number) Dynu numeric domain ID.
- `state` (String) Dynu state.
- `token` (String, Sensitive) Dynu domain token.
- `unicode_name` (String) Unicode representation of the domain name.
- `ipv4` (Boolean) Whether IPv4 support is enabled.
- `ipv6` (Boolean) Whether IPv6 support is enabled.
- `ipv4_wildcard_alias` (Boolean) Whether IPv4 wildcard alias is enabled.
- `ipv6_wildcard_alias` (Boolean) Whether IPv6 wildcard alias is enabled.
- `allow_zone_transfer` (Boolean) Whether zone transfer is allowed.
- `dnssec` (Boolean) Whether DNSSEC is enabled.
- `created_on` (String) Creation timestamp as returned by Dynu.
- `updated_on` (String) Last update timestamp as returned by Dynu.
## Import
@@ -2,7 +2,7 @@ terraform {
required_providers {
dynu = {
source = "beatz174-bit/dynu"
version = "~> 0.1.0"
version = "~> 0.4.0"
}
}
}
@@ -2,7 +2,7 @@ terraform {
required_providers {
dynu = {
source = "beatz174-bit/dynu"
version = "~> 0.1.0"
version = "~> 0.4.0"
}
}
}
@@ -2,7 +2,7 @@ terraform {
required_providers {
dynu = {
source = "beatz174-bit/dynu"
version = "~> 0.1.0"
version = "~> 0.4.0"
}
}
}
+1 -1
View File
@@ -2,7 +2,7 @@ terraform {
required_providers {
dynu = {
source = "beatz174-bit/dynu"
version = "~> 0.1.0"
version = "~> 0.4.0"
}
}
}
@@ -4,7 +4,6 @@ terraform {
required_providers {
dynu = {
source = "beatz174-bit/dynu"
version = "~> 0.1.0"
}
}
}
+1 -1
View File
@@ -2,7 +2,7 @@ terraform {
required_providers {
dynu = {
source = "beatz174-bit/dynu"
version = "~> 0.1.0"
# version = "~> 0.4.0"
}
}
}
-1
View File
@@ -4,7 +4,6 @@ terraform {
required_providers {
dynu = {
source = "beatz174-bit/dynu"
version = "~> 0.1.0"
}
}
}
@@ -41,6 +41,12 @@ type dnsRecordStateItem struct {
UpdatedOn types.String `tfsdk:"updated_on"`
Group types.String `tfsdk:"group"`
Host types.String `tfsdk:"host"`
Priority types.Int64 `tfsdk:"priority"`
Weight types.Int64 `tfsdk:"weight"`
Port types.Int64 `tfsdk:"port"`
Flags types.Int64 `tfsdk:"flags"`
Tag types.String `tfsdk:"tag"`
Value types.String `tfsdk:"value"`
}
func NewDNSRecordsDataSource() datasource.DataSource {
@@ -81,6 +87,12 @@ func (d *dnsRecordsDataSource) Schema(_ context.Context, _ datasource.SchemaRequ
"updated_on": schema.StringAttribute{Computed: true, Description: "Last update timestamp as returned by Dynu."},
"group": schema.StringAttribute{Computed: true, Description: "Dynu group value for this record."},
"host": schema.StringAttribute{Computed: true, Description: "Host field as returned by Dynu."},
"priority": schema.Int64Attribute{Computed: true, Description: "Priority for MX and SRV records."},
"weight": schema.Int64Attribute{Computed: true, Description: "Weight for SRV records."},
"port": schema.Int64Attribute{Computed: true, Description: "Port for SRV records."},
"flags": schema.Int64Attribute{Computed: true, Description: "Flags for CAA records."},
"tag": schema.StringAttribute{Computed: true, Description: "Tag for CAA records."},
"value": schema.StringAttribute{Computed: true, Description: "Value for CAA records."},
}},
},
},
@@ -145,6 +157,12 @@ func (d *dnsRecordsDataSource) Read(ctx context.Context, req datasource.ReadRequ
UpdatedOn: mapString(record.UpdatedOn),
Group: mapString(record.Group),
Host: mapString(record.Host),
Priority: types.Int64Value(record.Priority),
Weight: types.Int64Value(record.Weight),
Port: types.Int64Value(record.Port),
Flags: types.Int64Value(record.Flags),
Tag: mapString(record.Tag),
Value: mapString(record.Value),
})
}
+2 -1
View File
@@ -18,7 +18,8 @@ var (
_ datasource.DataSourceWithConfigure = &domainDataSource{}
)
var hostnameValidator = regexp.MustCompile(`^([a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$`)
// Allows underscore-prefixed labels (RFC 2782 SRV, RFC 6763 DNS-SD, etc.)
var hostnameValidator = regexp.MustCompile(`^([a-zA-Z0-9_](?:[a-zA-Z0-9_-]{0,61}[a-zA-Z0-9_])?\.)+[a-zA-Z]{2,}$`)
type domainDataSource struct {
clientProvider *providerData
+6 -3
View File
@@ -2,6 +2,7 @@ package provider
import (
"context"
"os"
"strings"
"github.com/hashicorp/terraform-plugin-framework/datasource"
@@ -47,7 +48,7 @@ func (p *dynuProvider) Schema(_ context.Context, _ provider.SchemaRequest, resp
"api_key": schema.StringAttribute{
Optional: true,
Sensitive: true,
Description: "Dynu API key. Set this explicitly, such as via a Terraform variable in terraform.tfvars.",
Description: "Dynu API key. Can also be set via the DYNU_API_KEY environment variable.",
},
"base_url": schema.StringAttribute{
Optional: true,
@@ -82,9 +83,11 @@ func (p *dynuProvider) Configure(ctx context.Context, req provider.ConfigureRequ
func resolveAPIKey(configValue types.String) string {
if !configValue.IsNull() && !configValue.IsUnknown() {
return strings.TrimSpace(configValue.ValueString())
if v := strings.TrimSpace(configValue.ValueString()); v != "" {
return v
}
}
return ""
return strings.TrimSpace(os.Getenv("DYNU_API_KEY"))
}
func (p *dynuProvider) DataSources(_ context.Context) []func() datasource.DataSource {
@@ -128,6 +128,20 @@ func TestIntegrationDataSourceDNSRecords(t *testing.T) {
if len(state.Records) != 2 || state.Records[0].ID.ValueInt64() != 10 {
t.Fatalf("unexpected records state: %#v", state.Records)
}
for _, rec := range state.Records {
if rec.Priority.IsNull() || rec.Priority.IsUnknown() {
t.Fatalf("expected priority to be a known value (zero for non-MX), got null/unknown for record %d", rec.ID.ValueInt64())
}
if rec.Weight.IsNull() || rec.Weight.IsUnknown() {
t.Fatalf("expected weight to be a known value, got null/unknown for record %d", rec.ID.ValueInt64())
}
if rec.Port.IsNull() || rec.Port.IsUnknown() {
t.Fatalf("expected port to be a known value, got null/unknown for record %d", rec.ID.ValueInt64())
}
if rec.Flags.IsNull() || rec.Flags.IsUnknown() {
t.Fatalf("expected flags to be a known value, got null/unknown for record %d", rec.ID.ValueInt64())
}
}
}
func TestIntegrationDataSourceDiagnosticsFromAPIError(t *testing.T) {
+7
View File
@@ -16,16 +16,23 @@ func TestResolveAPIKey(t *testing.T) {
tests := []struct {
name string
config types.String
envVal string
want string
}{
{name: "configured", config: types.StringValue("config-key"), want: "config-key"},
{name: "null when missing", config: types.StringNull(), want: ""},
{name: "trim spaces", config: types.StringValue(" config-key "), want: "config-key"},
{name: "unknown when pending", config: types.StringUnknown(), want: ""},
{name: "env var fallback when null", config: types.StringNull(), envVal: "env-key", want: "env-key"},
{name: "config takes priority over env", config: types.StringValue("config-key"), envVal: "env-key", want: "config-key"},
{name: "env var fallback when unknown", config: types.StringUnknown(), envVal: "env-key", want: "env-key"},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
if tc.envVal != "" {
t.Setenv("DYNU_API_KEY", tc.envVal)
}
if got := resolveAPIKey(tc.config); got != tc.want {
t.Fatalf("resolveAPIKey() = %q, want %q", got, tc.want)
}
+15 -3
View File
@@ -189,6 +189,8 @@ func (r *dnsRecordResource) Create(ctx context.Context, req resource.CreateReque
state := mapDNSRecordToState(*record, dynamicIntent)
state.ID = types.StringValue(formatDNSRecordID(record.DomainID, record.ID))
// Preserve plan hostname so node_name overrides don't produce a plan/state inconsistency.
state.Hostname = plan.Hostname
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
}
@@ -219,6 +221,8 @@ func (r *dnsRecordResource) Read(ctx context.Context, req resource.ReadRequest,
dynamicIntent := inferDynamicIntentFromState(state.RecordType, state.Content, state.Dynamic)
nextState := mapDNSRecordToState(*record, dynamicIntent)
nextState.ID = state.ID
// Preserve the stored hostname so node_name overrides remain stable across refreshes.
nextState.Hostname = state.Hostname
resp.Diagnostics.Append(resp.State.Set(ctx, &nextState)...)
}
@@ -318,6 +322,8 @@ func (r *dnsRecordResource) Update(ctx context.Context, req resource.UpdateReque
nextState := mapDNSRecordToState(*record, dynamicIntent)
nextState.ID = state.ID
// Preserve plan hostname so node_name overrides remain stable after updates.
nextState.Hostname = plan.Hostname
resp.Diagnostics.Append(resp.State.Set(ctx, &nextState)...)
}
@@ -357,7 +363,7 @@ func (r *dnsRecordResource) ImportState(ctx context.Context, req resource.Import
}
func mapDNSRecordToState(record dynuclient.DNSRecord, dynamicIntent bool) dnsRecordResourceModel {
content := normalizeRecordContentForState(record.RecordType, record.Content, dynamicIntent, record.Host)
content := normalizeRecordContentForState(record.RecordType, record.Content, dynamicIntent, record.Host, record.Value)
return dnsRecordResourceModel{
Hostname: mapString(record.Hostname),
RecordType: mapString(record.RecordType),
@@ -676,7 +682,7 @@ func inferDynamicIntentFromState(recordType types.String, content types.String,
return content.IsNull() || (content.IsUnknown())
}
func normalizeRecordContentForState(recordType string, content string, dynamicIntent bool, host string) types.String {
func normalizeRecordContentForState(recordType string, content string, dynamicIntent bool, host string, value string) types.String {
if dynamicIntent {
return types.StringNull()
}
@@ -696,11 +702,17 @@ func normalizeRecordContentForState(recordType string, content string, dynamicIn
if addr, err := netip.ParseAddr(trimmed); err == nil && addr.Is4() {
return types.StringValue(addr.String())
}
case "CNAME":
case "CNAME", "MX", "SRV", "NS", "PTR":
// API returns the target in host field; content contains zone-style prefix (e.g. "10 mail.example.com.")
if trimmedHost := strings.TrimSpace(host); trimmedHost != "" {
return types.StringValue(strings.TrimSuffix(trimmedHost, "."))
}
return types.StringValue(strings.TrimSuffix(trimmed, "."))
case "CAA":
// API returns the certificate authority in value field; content contains "flags tag value"
if trimmedValue := strings.TrimSpace(value); trimmedValue != "" {
return types.StringValue(strings.TrimSuffix(trimmedValue, "."))
}
}
return types.StringValue(trimmed)
+13 -4
View File
@@ -148,18 +148,27 @@ func TestStringPointerFromOptionalContentForValidation(t *testing.T) {
}
func TestNormalizeRecordContentForState(t *testing.T) {
if got := normalizeRecordContentForState("AAAA", "2001:0db8:0000:0000:0000:0000:0000:0123", false, ""); got.ValueString() != "2001:db8::123" {
if got := normalizeRecordContentForState("AAAA", "2001:0db8:0000:0000:0000:0000:0000:0123", false, "", ""); got.ValueString() != "2001:db8::123" {
t.Fatalf("expected canonical IPv6, got %q", got.ValueString())
}
if got := normalizeRecordContentForState("CNAME", "Example.COM.", false, ""); got.ValueString() != "Example.COM" {
if got := normalizeRecordContentForState("CNAME", "Example.COM.", false, "", ""); got.ValueString() != "Example.COM" {
t.Fatalf("expected trailing dot removed, got %q", got.ValueString())
}
if got := normalizeRecordContentForState("CNAME", "old.example.com", false, "new.example.co."); got.ValueString() != "new.example.co" {
if got := normalizeRecordContentForState("CNAME", "old.example.com", false, "new.example.co.", ""); got.ValueString() != "new.example.co" {
t.Fatalf("expected CNAME content to come from host, got %q", got.ValueString())
}
if got := normalizeRecordContentForState("A", "(167.179.167.166)", true, ""); !got.IsNull() {
if got := normalizeRecordContentForState("A", "(167.179.167.166)", true, "", ""); !got.IsNull() {
t.Fatalf("expected dynamic content to remain null, got %q", got.ValueString())
}
if got := normalizeRecordContentForState("MX", "10 mail.example.com.", false, "mail.example.com", ""); got.ValueString() != "mail.example.com" {
t.Fatalf("expected MX content from host field, got %q", got.ValueString())
}
if got := normalizeRecordContentForState("SRV", "10 5 5060 sip.example.com.", false, "sip.example.com", ""); got.ValueString() != "sip.example.com" {
t.Fatalf("expected SRV content from host field, got %q", got.ValueString())
}
if got := normalizeRecordContentForState("CAA", "0 issue letsencrypt.org", false, "", "letsencrypt.org"); got.ValueString() != "letsencrypt.org" {
t.Fatalf("expected CAA content from value field, got %q", got.ValueString())
}
}
func TestNormalizeDNSRecordUpdateRequestForType(t *testing.T) {
+53 -17
View File
@@ -25,14 +25,23 @@ var (
type domainResource struct{ clientProvider *providerData }
type domainResourceModel struct {
ID types.Int64 `tfsdk:"id"`
Name types.String `tfsdk:"name"`
IPv4Address types.String `tfsdk:"ipv4_address"`
IPv6Address types.String `tfsdk:"ipv6_address"`
TTL types.Int64 `tfsdk:"ttl"`
Group types.String `tfsdk:"group"`
State types.String `tfsdk:"state"`
Token types.String `tfsdk:"token"`
ID types.Int64 `tfsdk:"id"`
Name types.String `tfsdk:"name"`
IPv4Address types.String `tfsdk:"ipv4_address"`
IPv6Address types.String `tfsdk:"ipv6_address"`
TTL types.Int64 `tfsdk:"ttl"`
Group types.String `tfsdk:"group"`
State types.String `tfsdk:"state"`
Token types.String `tfsdk:"token"`
UnicodeName types.String `tfsdk:"unicode_name"`
IPv4 types.Bool `tfsdk:"ipv4"`
IPv6 types.Bool `tfsdk:"ipv6"`
IPv4WildcardAlias types.Bool `tfsdk:"ipv4_wildcard_alias"`
IPv6WildcardAlias types.Bool `tfsdk:"ipv6_wildcard_alias"`
AllowZoneTransfer types.Bool `tfsdk:"allow_zone_transfer"`
DNSSEC types.Bool `tfsdk:"dnssec"`
CreatedOn types.String `tfsdk:"created_on"`
UpdatedOn types.String `tfsdk:"updated_on"`
}
func NewDomainResource() resource.Resource { return &domainResource{} }
@@ -41,14 +50,23 @@ func (r *domainResource) Metadata(_ context.Context, req resource.MetadataReques
}
func (r *domainResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {
resp.Schema = schema.Schema{Description: "Manages a Dynu DNS domain.", Attributes: map[string]schema.Attribute{
"id": schema.Int64Attribute{Computed: true},
"name": schema.StringAttribute{Required: true, PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}},
"ipv4_address": schema.StringAttribute{Optional: true, Computed: true},
"ipv6_address": schema.StringAttribute{Optional: true, Computed: true},
"ttl": schema.Int64Attribute{Optional: true, Computed: true},
"group": schema.StringAttribute{Optional: true, Computed: true},
"state": schema.StringAttribute{Computed: true},
"token": schema.StringAttribute{Computed: true, Sensitive: true},
"id": schema.Int64Attribute{Computed: true},
"name": schema.StringAttribute{Required: true, PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}},
"ipv4_address": schema.StringAttribute{Optional: true, Computed: true},
"ipv6_address": schema.StringAttribute{Optional: true, Computed: true},
"ttl": schema.Int64Attribute{Optional: true, Computed: true},
"group": schema.StringAttribute{Optional: true, Computed: true},
"state": schema.StringAttribute{Computed: true},
"token": schema.StringAttribute{Computed: true, Sensitive: true},
"unicode_name": schema.StringAttribute{Computed: true, Description: "Unicode representation of the domain name."},
"ipv4": schema.BoolAttribute{Computed: true, Description: "Whether IPv4 support is enabled for this domain."},
"ipv6": schema.BoolAttribute{Computed: true, Description: "Whether IPv6 support is enabled for this domain."},
"ipv4_wildcard_alias": schema.BoolAttribute{Computed: true, Description: "Whether IPv4 wildcard alias is enabled."},
"ipv6_wildcard_alias": schema.BoolAttribute{Computed: true, Description: "Whether IPv6 wildcard alias is enabled."},
"allow_zone_transfer": schema.BoolAttribute{Computed: true, Description: "Whether zone transfer is allowed for this domain."},
"dnssec": schema.BoolAttribute{Computed: true, Description: "Whether DNSSEC is enabled for this domain."},
"created_on": schema.StringAttribute{Computed: true, Description: "Creation timestamp as returned by Dynu."},
"updated_on": schema.StringAttribute{Computed: true, Description: "Last update timestamp as returned by Dynu."},
}}
}
func (r *domainResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) {
@@ -138,5 +156,23 @@ func (r *domainResource) ImportState(ctx context.Context, req resource.ImportSta
}
func mapDomainResource(domain dynuclient.Domain) domainResourceModel {
return domainResourceModel{ID: types.Int64Value(domain.ID), Name: types.StringValue(strings.TrimSpace(domain.Name)), IPv4Address: mapString(domain.IPv4Address), IPv6Address: mapString(domain.IPv6Address), TTL: types.Int64Value(domain.TTL), Group: mapString(domain.Group), State: mapString(domain.State), Token: mapString(domain.Token)}
return domainResourceModel{
ID: types.Int64Value(domain.ID),
Name: types.StringValue(strings.TrimSpace(domain.Name)),
IPv4Address: mapString(domain.IPv4Address),
IPv6Address: mapString(domain.IPv6Address),
TTL: types.Int64Value(domain.TTL),
Group: mapString(domain.Group),
State: mapString(domain.State),
Token: mapString(domain.Token),
UnicodeName: mapString(domain.UnicodeName),
IPv4: types.BoolValue(domain.IPv4),
IPv6: types.BoolValue(domain.IPv6),
IPv4WildcardAlias: types.BoolValue(domain.IPv4WildcardAlias),
IPv6WildcardAlias: types.BoolValue(domain.IPv6WildcardAlias),
AllowZoneTransfer: types.BoolValue(domain.AllowZoneTransfer),
DNSSEC: types.BoolValue(domain.DNSSEC),
CreatedOn: mapString(domain.CreatedOn),
UpdatedOn: mapString(domain.UpdatedOn),
}
}
@@ -34,6 +34,15 @@ func TestIntegrationResourceDomainLifecycleAndImport(t *testing.T) {
if state.ID.ValueInt64() == 0 {
t.Fatal("expected created id")
}
if state.State.IsNull() || state.State.IsUnknown() {
t.Fatal("expected state attribute to be populated after create")
}
if state.UnicodeName.IsNull() || state.UnicodeName.IsUnknown() {
t.Fatal("expected unicode_name to be populated after create")
}
if state.DNSSEC.IsNull() || state.DNSSEC.IsUnknown() {
t.Fatal("expected dnssec to be a known bool after create")
}
state.TTL = types.Int64Value(300)
plan = tfsdk.Plan{Schema: schemaResp.Schema}