Skip to content

Commit

Permalink
tailscale: add dns_split_nameservers resource
Browse files Browse the repository at this point in the history
Add `resource_dns_split_nameservers` to allow for controlling split DNS
settings for a given tailnet.

Updates tailscale/corp#19483

Signed-off-by: Mario Minardi <mario@tailscale.com>
  • Loading branch information
mpminardi committed Apr 24, 2024
1 parent 8141642 commit 8cb204b
Show file tree
Hide file tree
Showing 7 changed files with 192 additions and 10 deletions.
33 changes: 33 additions & 0 deletions docs/resources/dns_split_nameservers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "tailscale_dns_split_nameservers Resource - terraform-provider-tailscale"
subcategory: ""
description: |-
The dnssplitnameservers resource allows you to configure split DNS nameservers for your Tailscale network. See https://tailscale.com/kb/1054/dns for more information.
---

# tailscale_dns_split_nameservers (Resource)

The dns_split_nameservers resource allows you to configure split DNS nameservers for your Tailscale network. See https://tailscale.com/kb/1054/dns for more information.

## Example Usage

```terraform
resource "tailscale_dns_split_nameservers" "sample_split_nameservers" {
domain = "foo.example.com"
nameservers = ["1.1.1.1"]
}
```

<!-- schema generated by tfplugindocs -->
## Schema

### Required

- `domain` (String) Domain to configure split DNS for. Requests for this domain will be resolved using the provided nameservers.
- `nameservers` (Set of String) Devices on your network will use these nameservers to resolve DNS names. IPv4 or IPv6 addresses are accepted.

### Read-Only

- `id` (String) The ID of this resource.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
resource "tailscale_dns_split_nameservers" "sample_split_nameservers" {
domain = "foo.example.com"

nameservers = ["1.1.1.1"]
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ require (
github.com/hashicorp/terraform-plugin-sdk/v2 v2.33.0
github.com/stretchr/testify v1.9.0
github.com/tailscale/hujson v0.0.0-20221223112325-20486734a56a
github.com/tailscale/tailscale-client-go v1.16.0
github.com/tailscale/tailscale-client-go v1.16.1-0.20240424180809-5a248d9547d4
golang.org/x/tools v0.18.0
tailscale.com v1.60.1
)
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,8 @@ github.com/tailscale/hujson v0.0.0-20221223112325-20486734a56a h1:SJy1Pu0eH1C29X
github.com/tailscale/hujson v0.0.0-20221223112325-20486734a56a/go.mod h1:DFSS3NAGHthKo1gTlmEcSBiZrRJXi28rLNd/1udP1c8=
github.com/tailscale/tailscale-client-go v1.16.0 h1:mipLVbha5SAVGZT/h3I5qZMrrGXz0iAw4QWXKDfe0l0=
github.com/tailscale/tailscale-client-go v1.16.0/go.mod h1:v7ssNztaIngJixKoWAgnfhEbzOyRVPI5qT/niBcoI4k=
github.com/tailscale/tailscale-client-go v1.16.1-0.20240424180809-5a248d9547d4 h1:25DO9pOi+kHDkQzuUEbPuQY9fSClaMZBG04f/pKuhhg=
github.com/tailscale/tailscale-client-go v1.16.1-0.20240424180809-5a248d9547d4/go.mod h1:v7ssNztaIngJixKoWAgnfhEbzOyRVPI5qT/niBcoI4k=
github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI=
github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
Expand Down
19 changes: 10 additions & 9 deletions tailscale/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,15 +66,16 @@ func Provider(options ...ProviderOption) *schema.Provider {
},
},
ResourcesMap: map[string]*schema.Resource{
"tailscale_acl": resourceACL(),
"tailscale_dns_nameservers": resourceDNSNameservers(),
"tailscale_dns_preferences": resourceDNSPreferences(),
"tailscale_dns_search_paths": resourceDNSSearchPaths(),
"tailscale_device_subnet_routes": resourceDeviceSubnetRoutes(),
"tailscale_device_authorization": resourceDeviceAuthorization(),
"tailscale_tailnet_key": resourceTailnetKey(),
"tailscale_device_tags": resourceDeviceTags(),
"tailscale_device_key": resourceDeviceKey(),
"tailscale_acl": resourceACL(),
"tailscale_dns_nameservers": resourceDNSNameservers(),
"tailscale_dns_preferences": resourceDNSPreferences(),
"tailscale_dns_search_paths": resourceDNSSearchPaths(),
"tailscale_dns_split_nameservers": resourceDNSSplitNameservers(),
"tailscale_device_subnet_routes": resourceDeviceSubnetRoutes(),
"tailscale_device_authorization": resourceDeviceAuthorization(),
"tailscale_tailnet_key": resourceTailnetKey(),
"tailscale_device_tags": resourceDeviceTags(),
"tailscale_device_key": resourceDeviceKey(),
},
DataSourcesMap: map[string]*schema.Resource{
"tailscale_device": dataSourceDevice(),
Expand Down
112 changes: 112 additions & 0 deletions tailscale/resource_dns_split_nameservers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
package tailscale

import (
"context"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"

"github.com/tailscale/tailscale-client-go/tailscale"
)

func resourceDNSSplitNameservers() *schema.Resource {
return &schema.Resource{
Description: "The dns_split_nameservers resource allows you to configure split DNS nameservers for your Tailscale network. See https://tailscale.com/kb/1054/dns for more information.",
ReadContext: resourceSplitDNSNameserversRead,
CreateContext: resourceSplitDNSNameserversCreate,
UpdateContext: resourceSplitDNSNameserversUpdate,
DeleteContext: resourceSplitDNSNameserversDelete,
Schema: map[string]*schema.Schema{
"domain": {
Type: schema.TypeString,
Description: "Domain to configure split DNS for. Requests for this domain will be resolved using the provided nameservers.",
Required: true,
},
"nameservers": {
Type: schema.TypeSet,
Description: "Devices on your network will use these nameservers to resolve DNS names. IPv4 or IPv6 addresses are accepted.",
Required: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
},
}
}

func resourceSplitDNSNameserversRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
client := m.(*tailscale.Client)
splitDNS, err := client.DNSSplitDNS(ctx)
if err != nil {
return diagnosticsError(err, "Failed to fetch split DNS configs")
}

nameservers := splitDNS[d.Get("domain").(string)]

if err = d.Set("nameservers", nameservers); err != nil {
return diag.FromErr(err)
}

return nil
}

func resourceSplitDNSNameserversCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
client := m.(*tailscale.Client)
nameserversSet := d.Get("nameservers").(*schema.Set)
domain := d.Get("domain").(string)

nameserversList := nameserversSet.List()

req := make(tailscale.SplitDnsRequest)
var nameservers []string
for _, nameserver := range nameserversList {
nameservers = append(nameservers, nameserver.(string))
}
req[domain] = &nameservers

if err := client.UpdateDNSSplitDNS(ctx, req); err != nil {
return diagnosticsError(err, "Failed to set dns split nameservers")
}

d.SetId(domain)
return nil
}

func resourceSplitDNSNameserversUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
if !d.HasChange("nameservers") {
return resourceSplitDNSNameserversRead(ctx, d, m)
}

client := m.(*tailscale.Client)
domain := d.Get("domain").(string)
nameserversSet := d.Get("nameservers").(*schema.Set)

nameserversList := nameserversSet.List()

req := make(tailscale.SplitDnsRequest)
var nameservers []string
for _, nameserver := range nameserversList {
nameservers = append(nameservers, nameserver.(string))
}
req[domain] = &nameservers

if err := client.UpdateDNSSplitDNS(ctx, req); err != nil {
return diagnosticsError(err, "Failed to set dns split nameservers")
}

return nil
}

func resourceSplitDNSNameserversDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
client := m.(*tailscale.Client)
domain := d.Get("domain").(string)

req := make(tailscale.SplitDnsRequest)
req[domain] = &[]string{}

if err := client.UpdateDNSSplitDNS(ctx, req); err != nil {
return diagnosticsError(err, "Failed to set dns split nameservers")
}

return nil
}
29 changes: 29 additions & 0 deletions tailscale/resource_dns_split_nameservers_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package tailscale_test

import (
"net/http"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
)

const testSplitNameservers = `
resource "tailscale_dns_split_nameservers" "test_nameservers" {
domain = "example.com"
nameservers = ["1.2.3.4", "4.5.6.7"]
}`

func TestProvider_TailscaleSplitDNSNameservers(t *testing.T) {
resource.Test(t, resource.TestCase{
IsUnitTest: true,
PreCheck: func() {
testServer.ResponseCode = http.StatusOK
testServer.ResponseBody = nil
},
ProviderFactories: testProviderFactories(t),
Steps: []resource.TestStep{
testResourceCreated("tailscale_dns_split_nameservers.test_nameservers", testSplitNameservers),
testResourceDestroyed("tailscale_dns_split_nameservers.test_nameservers", testSplitNameservers),
},
})
}

0 comments on commit 8cb204b

Please sign in to comment.