Skip to content

Commit

Permalink
Implement devices datasource (#34)
Browse files Browse the repository at this point in the history
This commit implements the `tailscale_devices` data source and allows for
a `name_prefix` argument to filter the list of devices.

Closes #32

Signed-off-by: David Bond <[email protected]>
  • Loading branch information
davidsbond committed Aug 25, 2021
1 parent 4845a46 commit b2fa62c
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 2 deletions.
31 changes: 31 additions & 0 deletions docs/data-sources/devices.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
page_title: "devices Data Source - terraform-provider-tailscale"
subcategory: ""
description: |-
"The devices data source describes a list of devices in a tailnet.
---
# Data Source `devices`
The devices data source describes a list of devices in a tailnet.
## Example Usage
```terraform
data "tailscale_devices" "sample_devices" {
name_prefix = "example-"
}

```
## Argument Reference
- `name_prefix` - (Optional) Filters the returned list of devices to those whose name have this prefix.

## Attributes Reference

The following attributes are exported.

- `devices` - The list of devices returned from the Tailscale API. Each element contains the following:
- `id` - The unique identifier of the device
- `name` - The name of the device
72 changes: 72 additions & 0 deletions tailscale/data_source_devices.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package tailscale

import (
"context"
"strings"

"github.com/davidsbond/terraform-provider-tailscale/internal/tailscale"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

func dataSourceDevices() *schema.Resource {
return &schema.Resource{
Description: "The devices data source describes a list of devices in a tailnet",
ReadContext: dataSourceDevicesRead,
Schema: map[string]*schema.Schema{
"name_prefix": {
Optional: true,
Type: schema.TypeString,
Description: "Filters the device list to elements whose name has the provided prefix",
},
"devices": {
Computed: true,
Type: schema.TypeList,
Description: "The list of devices in the tailnet",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Description: "The name of the device",
Computed: true,
},
"id": {
Type: schema.TypeString,
Description: "The unique identifier of the device",
Computed: true,
},
},
},
},
},
}
}

func dataSourceDevicesRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
client := m.(*tailscale.Client)

devices, err := client.Devices(ctx)
if err != nil {
return diagnosticsError(err, "Failed to fetch devices")
}

namePrefix, _ := d.Get("name_prefix").(string)
deviceMaps := make([]map[string]interface{}, 0)
for _, device := range devices {
if namePrefix != "" && !strings.HasPrefix(device.Name, namePrefix) {
continue
}

deviceMaps = append(deviceMaps, map[string]interface{}{
"name": device.Name,
"id": device.ID,
})
}

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

d.SetId(createUUID())
return nil
}
3 changes: 2 additions & 1 deletion tailscale/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ func Provider() *schema.Provider {
"tailscale_device_subnet_routes": resourceDeviceSubnetRoutes(),
},
DataSourcesMap: map[string]*schema.Resource{
"tailscale_device": dataSourceDevice(),
"tailscale_device": dataSourceDevice(),
"tailscale_devices": dataSourceDevices(),
},
}
}
Expand Down
2 changes: 1 addition & 1 deletion tailscale/resource_device_subnet_routes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const testDeviceSubnetRoutes = `
}
resource "tailscale_device_subnet_routes" "test_subnet_routes" {
device_id = tailscale_device.test_device.id,
device_id = data.tailscale_device.test_device.id,
routes = [
"10.0.1.0/24",
"1.2.0.0/16",
Expand Down

0 comments on commit b2fa62c

Please sign in to comment.