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

Add transfer lock management to registered domain resource #143

Merged
merged 8 commits into from
Sep 1, 2023
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 CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ FEATURES:

- **New Resource:** `dnsimple_registered_domain_contact` (dnsimple/terraform-provider-dnsimple#142)
- **New Data Source:** `dnsimple_registrant_change_check` (dnsimple/terraform-provider-dnsimple#142)
- **Updated Resource:** `dnsimple_registered_domain` now supports `transfer_lock_enabled` argument which you can use to manage the domain transfer lock state of your registered domains (dnsimple/terraform-provider-dnsimple#143)

## 1.1.2

Expand Down
2 changes: 2 additions & 0 deletions docs/resources/registered_domain.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ resource "dnsimple_registered_domain" "appleseed_bio" {

contact_id = dnsimple_contact.alice_main.id
auto_renew_enabled = true
transfer_lock_enabled = true
whois_privacy_enabled = true
dnssec_enabled = false

Expand All @@ -49,6 +50,7 @@ The following argument(s) are supported:
* `auto_renew_enabled` - (Optional) Whether the domain should be set to auto-renew (default: `false`)
* `whois_privacy_enabled` - (Optional) Whether the domain should have WhoIs privacy enabled (default: `false`)
* `dnssec_enabled` - (Optional) Whether the domain should have DNSSEC enabled (default: `false`)
* `transfer_lock_enabled` - (Optional) Whether the domain transfer lock protection is enabled (default: `true`)
* `premium_price` - (Optional) The premium price for the domain registration. This is only required if the domain is a premium domain. You can use our [Check domain API](https://developer.dnsimple.com/v2/registrar/#checkDomain) to check if a domain is premium. And [Retrieve domain prices API](https://developer.dnsimple.com/v2/registrar/#getDomainPrices) to retrieve the premium price for a domain.
* `extended_attributes` - (Optional) A map of extended attributes to be set for the domain registration. To see if there are any required extended attributes for any TLD use our [Lists the TLD Extended Attributes API](https://developer.dnsimple.com/v2/tlds/#getTldExtendedAttributes).
* `timeouts` - (Optional) (see [below for nested schema](#nestedblock--timeouts))
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module github.com/terraform-providers/terraform-provider-dnsimple

require (
github.com/dnsimple/dnsimple-go v1.3.0
github.com/dnsimple/dnsimple-go v1.4.0
github.com/hashicorp/terraform-plugin-docs v0.14.1
github.com/hashicorp/terraform-plugin-framework v1.2.0
github.com/hashicorp/terraform-plugin-go v0.15.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dnsimple/dnsimple-go v1.3.0 h1:8hv9JZdfMLGUp5QIX1VndDWsMd3kY/9H3TRA7Zyyo/E=
github.com/dnsimple/dnsimple-go v1.3.0/go.mod h1:G7a16dj2TULTldjxg1EAcSxonEqx0gkTOP8PESBai+4=
github.com/dnsimple/dnsimple-go v1.4.0 h1:nBqtRXI9dYx6k6YJDlPZ1x/JuTP86KMtgbsBj6/6sMA=
github.com/dnsimple/dnsimple-go v1.4.0/go.mod h1:G7a16dj2TULTldjxg1EAcSxonEqx0gkTOP8PESBai+4=
github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg=
github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
Expand Down
35 changes: 34 additions & 1 deletion internal/framework/resources/registered_domain/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,35 @@ func (r *RegisteredDomainResource) setDNSSEC(ctx context.Context, data *Register
return diagnostics
}

func (r *RegisteredDomainResource) updateModelFromAPIResponse(ctx context.Context, data *RegisteredDomainResourceModel, domainRegistration *dnsimple.DomainRegistration, domain *dnsimple.Domain, dnssec *dnsimple.Dnssec) diag.Diagnostics {
func (r *RegisteredDomainResource) setTransferLock(ctx context.Context, data *RegisteredDomainResourceModel) diag.Diagnostics {
diagnostics := diag.Diagnostics{}

tflog.Debug(ctx, fmt.Sprintf("setting transfer_lock_enabled to %t", data.TransferLockEnabled.ValueBool()))

if data.TransferLockEnabled.ValueBool() {
_, err := r.config.Client.Registrar.EnableDomainTransferLock(ctx, r.config.AccountID, data.Name.ValueString())

if err != nil {
diagnostics.AddError(
fmt.Sprintf("failed to enable DNSimple Domain transfer lock: %s, %d", data.Name.ValueString(), data.Id.ValueInt64()),
err.Error(),
)
}
return diagnostics
}

_, err := r.config.Client.Registrar.DisableDomainTransferLock(ctx, r.config.AccountID, data.Name.ValueString())
if err != nil {
diagnostics.AddError(
fmt.Sprintf("failed to disable DNSimple Domain transfer lock: %s, %d", data.Name.ValueString(), data.Id.ValueInt64()),
err.Error(),
)
}

return diagnostics
}

func (r *RegisteredDomainResource) updateModelFromAPIResponse(ctx context.Context, data *RegisteredDomainResourceModel, domainRegistration *dnsimple.DomainRegistration, domain *dnsimple.Domain, dnssec *dnsimple.Dnssec, transferLock *dnsimple.DomainTransferLock) diag.Diagnostics {
diags := diag.Diagnostics{}

if domainRegistration != nil {
Expand Down Expand Up @@ -149,6 +177,10 @@ Until the change has completed successfully you will continue to receive this wa
data.DNSSECEnabled = types.BoolValue(dnssec.Enabled)
}

if transferLock != nil {
data.TransferLockEnabled = types.BoolValue(transferLock.Enabled)
}

return diags
}

Expand Down Expand Up @@ -181,6 +213,7 @@ func (r *RegisteredDomainResource) updateModelFromAPIResponsePartialCreate(ctx c
}

data.DNSSECEnabled = types.BoolValue(false)
data.TransferLockEnabled = types.BoolValue(false)

return nil
}
Expand Down
20 changes: 19 additions & 1 deletion internal/framework/resources/registered_domain/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,14 @@ func (r *RegisteredDomainResource) Create(ctx context.Context, req resource.Crea
}
}

if !data.TransferLockEnabled.IsNull() && data.TransferLockEnabled.ValueBool() {
diags := r.setTransferLock(ctx, data)
if diags.HasError() {
resp.Diagnostics.Append(diags...)
return
}
}

domainResponse, err := r.config.Client.Domains.GetDomain(ctx, r.config.AccountID, data.Name.ValueString())

if err != nil {
Expand All @@ -136,7 +144,17 @@ func (r *RegisteredDomainResource) Create(ctx context.Context, req resource.Crea
return
}

diags := r.updateModelFromAPIResponse(ctx, data, registerDomainResponse.Data, domainResponse.Data, dnssecResponse.Data)
transferLockResponse, err := r.config.Client.Registrar.GetDomainTransferLock(ctx, r.config.AccountID, data.Name.ValueString())

if err != nil {
resp.Diagnostics.AddError(
fmt.Sprintf("failed to read DNSimple Domain transfer lock status: %s", data.Name.ValueString()),
err.Error(),
)
return
}

diags := r.updateModelFromAPIResponse(ctx, data, registerDomainResponse.Data, domainResponse.Data, dnssecResponse.Data, transferLockResponse.Data)
if diags != nil && diags.HasError() {
resp.Diagnostics.Append(diags...)
return
Expand Down
14 changes: 12 additions & 2 deletions internal/framework/resources/registered_domain/read.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,20 @@ func (r *RegisteredDomainResource) Read(ctx context.Context, req resource.ReadRe
return
}

transferLockResponse, err := r.config.Client.Registrar.GetDomainTransferLock(ctx, r.config.AccountID, data.Name.ValueString())

if err != nil {
resp.Diagnostics.AddError(
fmt.Sprintf("failed to read DNSimple Domain transfer lock status: %s", data.Name.ValueString()),
err.Error(),
)
return
}

if domainRegistrationResponse == nil {
diags = r.updateModelFromAPIResponse(ctx, data, nil, domainResponse.Data, dnssecResponse.Data)
diags = r.updateModelFromAPIResponse(ctx, data, nil, domainResponse.Data, dnssecResponse.Data, transferLockResponse.Data)
} else {
diags = r.updateModelFromAPIResponse(ctx, data, domainRegistrationResponse.Data, domainResponse.Data, dnssecResponse.Data)
diags = r.updateModelFromAPIResponse(ctx, data, domainRegistrationResponse.Data, domainResponse.Data, dnssecResponse.Data, transferLockResponse.Data)
}

if diags != nil && diags.HasError() {
Expand Down
11 changes: 7 additions & 4 deletions internal/framework/resources/registered_domain/resource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,26 +121,28 @@ func TestAccRegisteredDomainResource_WithOptions(t *testing.T) {
CheckDestroy: testAccCheckRegisteredDomainResourceDestroy,
Steps: []resource.TestStep{
{
Config: testAccRegisteredDomainResourceConfig_WithOptions(domainName, contactID, false, true, true),
Config: testAccRegisteredDomainResourceConfig_WithOptions(domainName, contactID, false, true, true, true),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr(resourceName, "name", domainName),
resource.TestCheckResourceAttr(resourceName, "state", "registered"),
resource.TestCheckResourceAttrSet(resourceName, "domain_registration.id"),
resource.TestCheckResourceAttr(resourceName, "auto_renew_enabled", "false"),
resource.TestCheckResourceAttr(resourceName, "whois_privacy_enabled", "true"),
resource.TestCheckResourceAttr(resourceName, "dnssec_enabled", "true"),
resource.TestCheckResourceAttr(resourceName, "transfer_lock_enabled", "true"),
resource.TestCheckResourceAttrSet(resourceName, "expires_at"),
),
},
{
Config: testAccRegisteredDomainResourceConfig_WithOptions(domainName, contactID, true, false, false),
Config: testAccRegisteredDomainResourceConfig_WithOptions(domainName, contactID, true, false, false, false),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr(resourceName, "name", domainName),
resource.TestCheckResourceAttr(resourceName, "state", "registered"),
resource.TestCheckResourceAttrSet(resourceName, "domain_registration.id"),
resource.TestCheckResourceAttr(resourceName, "auto_renew_enabled", "true"),
resource.TestCheckResourceAttr(resourceName, "whois_privacy_enabled", "false"),
resource.TestCheckResourceAttr(resourceName, "dnssec_enabled", "false"),
resource.TestCheckResourceAttr(resourceName, "transfer_lock_enabled", "false"),
resource.TestCheckResourceAttrSet(resourceName, "expires_at"),
),
},
Expand Down Expand Up @@ -274,7 +276,7 @@ resource "dnsimple_registered_domain" "test" {
}`, domainName, contactId)
}

func testAccRegisteredDomainResourceConfig_WithOptions(domainName string, contactId int, withAutoRenew, withWhoisPrivacy, withDNSSEC bool) string {
func testAccRegisteredDomainResourceConfig_WithOptions(domainName string, contactId int, withAutoRenew, withWhoisPrivacy, withDNSSEC bool, withTransferLock bool) string {
return fmt.Sprintf(`
resource "dnsimple_registered_domain" "test" {
name = %[1]q
Expand All @@ -283,5 +285,6 @@ resource "dnsimple_registered_domain" "test" {
auto_renew_enabled = %[3]t
whois_privacy_enabled = %[4]t
dnssec_enabled = %[5]t
}`, domainName, contactId, withAutoRenew, withWhoisPrivacy, withDNSSEC)
transfer_lock_enabled = %[6]t
}`, domainName, contactId, withAutoRenew, withWhoisPrivacy, withDNSSEC, withTransferLock)
}
5 changes: 5 additions & 0 deletions internal/framework/resources/registered_domain/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ type RegisteredDomainResourceModel struct {
AutoRenewEnabled types.Bool `tfsdk:"auto_renew_enabled"`
WhoisPrivacyEnabled types.Bool `tfsdk:"whois_privacy_enabled"`
DNSSECEnabled types.Bool `tfsdk:"dnssec_enabled"`
TransferLockEnabled types.Bool `tfsdk:"transfer_lock_enabled"`
ContactId types.Int64 `tfsdk:"contact_id"`
ExpiresAt types.String `tfsdk:"expires_at"`
ExtendedAttributes types.Map `tfsdk:"extended_attributes"`
Expand Down Expand Up @@ -88,6 +89,10 @@ func (r *RegisteredDomainResource) Schema(_ context.Context, _ resource.SchemaRe
Optional: true,
Computed: true,
},
"transfer_lock_enabled": schema.BoolAttribute{
Optional: true,
Computed: true,
},
"contact_id": schema.Int64Attribute{
Required: true,
},
Expand Down
23 changes: 21 additions & 2 deletions internal/framework/resources/registered_domain/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,15 @@ func (r *RegisteredDomainResource) Update(ctx context.Context, req resource.Upda
}
}

if planData.TransferLockEnabled.ValueBool() != stateData.TransferLockEnabled.ValueBool() {

diags := r.setTransferLock(ctx, planData)
if diags.HasError() {
resp.Diagnostics.Append(diags...)
return
}
}

domainResponse, err := r.config.Client.Domains.GetDomain(ctx, r.config.AccountID, planData.Name.ValueString())

if err != nil {
Expand All @@ -145,10 +154,20 @@ func (r *RegisteredDomainResource) Update(ctx context.Context, req resource.Upda
return
}

transferLockResponse, err := r.config.Client.Registrar.GetDomainTransferLock(ctx, r.config.AccountID, planData.Name.ValueString())

if err != nil {
resp.Diagnostics.AddError(
fmt.Sprintf("failed to read DNSimple Domain transfer lock status: %s", planData.Name.ValueString()),
err.Error(),
)
return
}

if domainRegistrationResponse == nil {
diags = r.updateModelFromAPIResponse(ctx, planData, nil, domainResponse.Data, dnssecResponse.Data)
diags = r.updateModelFromAPIResponse(ctx, planData, nil, domainResponse.Data, dnssecResponse.Data, transferLockResponse.Data)
} else {
diags = r.updateModelFromAPIResponse(ctx, planData, domainRegistrationResponse.Data, domainResponse.Data, dnssecResponse.Data)
diags = r.updateModelFromAPIResponse(ctx, planData, domainRegistrationResponse.Data, domainResponse.Data, dnssecResponse.Data, transferLockResponse.Data)
}
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
Expand Down