From a5978b72d5978816d1a97f15dd1eaf8cc5eb19e7 Mon Sep 17 00:00:00 2001 From: Percy Wegmann Date: Thu, 1 Aug 2024 15:59:06 -0500 Subject: [PATCH] tailscale: use V2 client for device authorization Updates tailscale/corp#21867 Signed-off-by: Percy Wegmann --- go.mod | 2 +- go.sum | 4 +- tailscale/resource_device_authorization.go | 56 +++++-------------- .../resource_device_authorization_test.go | 47 +++++----------- 4 files changed, 30 insertions(+), 79 deletions(-) diff --git a/go.mod b/go.mod index 6c0962f5..59b6e234 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/stretchr/testify v1.9.0 github.com/tailscale/hujson v0.0.0-20221223112325-20486734a56a github.com/tailscale/tailscale-client-go v1.17.1-0.20240729175651-90a1e935cc19 - github.com/tailscale/tailscale-client-go/v2 v2.0.0-20240801195603-6096900af9df + github.com/tailscale/tailscale-client-go/v2 v2.0.0-20240802211229-cd6477962499 golang.org/x/tools v0.23.0 tailscale.com v1.70.0 ) diff --git a/go.sum b/go.sum index 083c5ff5..f30773d8 100644 --- a/go.sum +++ b/go.sum @@ -190,8 +190,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.17.1-0.20240729175651-90a1e935cc19 h1:fRLv1yZH1ueL1cnpLhOnOymoBfMCIviCn0e0VkAjkK4= github.com/tailscale/tailscale-client-go v1.17.1-0.20240729175651-90a1e935cc19/go.mod h1:jbwJyHniK3nyLttwcDTXnfdDQEnADvc4VMOP8hZWnR0= -github.com/tailscale/tailscale-client-go/v2 v2.0.0-20240801195603-6096900af9df h1:XjHI0pFxhttM1nEn/WNGOO3wrJYEJSZarJm0i5WFXgY= -github.com/tailscale/tailscale-client-go/v2 v2.0.0-20240801195603-6096900af9df/go.mod h1:i/MSgQ71kdyh1Wdp50XxrIgtsyO4uZ2SZSPd83lGKHM= +github.com/tailscale/tailscale-client-go/v2 v2.0.0-20240802211229-cd6477962499 h1:s/S/5fW23fpk0YsMDCsB6i72OwRyGDTwDz68E4lyclQ= +github.com/tailscale/tailscale-client-go/v2 v2.0.0-20240802211229-cd6477962499/go.mod h1:i/MSgQ71kdyh1Wdp50XxrIgtsyO4uZ2SZSPd83lGKHM= 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= diff --git a/tailscale/resource_device_authorization.go b/tailscale/resource_device_authorization.go index 7416df7c..7b8badbc 100644 --- a/tailscale/resource_device_authorization.go +++ b/tailscale/resource_device_authorization.go @@ -5,8 +5,6 @@ import ( "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 resourceDeviceAuthorization() *schema.Resource { @@ -35,41 +33,27 @@ func resourceDeviceAuthorization() *schema.Resource { } func resourceDeviceAuthorizationRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - client := m.(*Clients).V1 + client := m.(*Clients).V2 deviceID := d.Id() - devices, err := client.Devices(ctx) + device, err := client.Devices().Get(ctx, deviceID) if err != nil { - return diagnosticsError(err, "Failed to fetch devices") - } - - var selected *tailscale.Device - for _, device := range devices { - if device.ID != deviceID { - continue - } - - selected = &device - break - } - - if selected == nil { - return diag.Errorf("Could not find device with id %s", deviceID) + return diagnosticsError(err, "Failed to fetch device") } - d.SetId(selected.ID) - d.Set("device_id", selected.ID) - d.Set("authorized", selected.Authorized) + d.SetId(device.ID) + d.Set("device_id", device.ID) + d.Set("authorized", device.Authorized) return nil } func resourceDeviceAuthorizationCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - client := m.(*Clients).V1 + client := m.(*Clients).V2 deviceID := d.Get("device_id").(string) authorized := d.Get("authorized").(bool) if authorized { - if err := client.AuthorizeDevice(ctx, deviceID); err != nil { + if err := client.Devices().SetAuthorized(ctx, deviceID, true); err != nil { return diagnosticsError(err, "Failed to authorize device") } } @@ -79,36 +63,22 @@ func resourceDeviceAuthorizationCreate(ctx context.Context, d *schema.ResourceDa } func resourceDeviceAuthorizationUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - client := m.(*Clients).V1 + client := m.(*Clients).V2 deviceID := d.Get("device_id").(string) - devices, err := client.Devices(ctx) + device, err := client.Devices().Get(ctx, deviceID) if err != nil { - return diagnosticsError(err, "Failed to fetch devices") - } - - var selected *tailscale.Device - for _, device := range devices { - if device.ID != deviceID { - continue - } - - selected = &device - break - } - - if selected == nil { - return diag.Errorf("Could not find device with id %s", deviceID) + return diagnosticsError(err, "Failed to fetch device") } // Currently, the Tailscale API only supports authorizing a device, but not un-authorizing one. So if the device // data from the API states it is authorized then we can't do anything else here. - if selected.Authorized { + if device.Authorized { d.Set("authorized", true) return nil } - if err = client.AuthorizeDevice(ctx, deviceID); err != nil { + if err = client.Devices().SetAuthorized(ctx, deviceID, true); err != nil { return diagnosticsError(err, "Failed to authorize device") } diff --git a/tailscale/resource_device_authorization_test.go b/tailscale/resource_device_authorization_test.go index aa912480..13cf18b9 100644 --- a/tailscale/resource_device_authorization_test.go +++ b/tailscale/resource_device_authorization_test.go @@ -9,10 +9,11 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" - "github.com/tailscale/tailscale-client-go/tailscale" + tsclient "github.com/tailscale/tailscale-client-go/v2" + "github.com/tailscale/terraform-provider-tailscale/tailscale" ) -const testDeviceAuthorization = ` +var testDeviceAuthorization = fmt.Sprintf(` data "tailscale_device" "test_device" { name = "%s" } @@ -20,7 +21,11 @@ const testDeviceAuthorization = ` resource "tailscale_device_authorization" "test_authorization" { device_id = data.tailscale_device.test_device.id authorized = true - }` + }`, os.Getenv("TAILSCALE_TEST_DEVICE_NAME")) + +var expectedDeviceAuthorizationBasic = &tsclient.Device{ + Authorized: true, +} func TestAccTailscaleDeviceAuthorization_Basic(t *testing.T) { resource.Test(t, resource.TestCase{ @@ -59,27 +64,15 @@ func testAccCheckDeviceAuthorized(resourceName string) resource.TestCheckFunc { return fmt.Errorf("resource has no ID set") } - client := testAccProvider.Meta().(*tailscale.Client) + client := testAccProvider.Meta().(*tailscale.Clients).V2 // Devices are not currently deauthorized when this resource is deleted, // expect that the device both exists and is still authorized. - devices, err := client.Devices(context.Background()) + device, err := client.Devices().Get(context.Background(), rs.Primary.ID) if err != nil { return err } - var selected *tailscale.Device - for _, device := range devices { - if device.ID == rs.Primary.ID { - selected = &device - break - } - } - - if selected == nil { - return fmt.Errorf("expected device with id %q to exist", rs.Primary.ID) - } - - if selected.Authorized != true { + if device.Authorized != true { return fmt.Errorf("device with id %q is not authorized", rs.Primary.ID) } @@ -88,7 +81,7 @@ func testAccCheckDeviceAuthorized(resourceName string) resource.TestCheckFunc { } func testAccCheckDeviceAuthorizationDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*tailscale.Client) + client := testAccProvider.Meta().(*tailscale.Clients).V2 for _, rs := range s.RootModule().Resources { if rs.Type != "tailscale_device_authorization" { @@ -101,24 +94,12 @@ func testAccCheckDeviceAuthorizationDestroy(s *terraform.State) error { // Devices are not currently deauthorized when this resource is deleted, // expect that the device both exists and is still authorized. - devices, err := client.Devices(context.Background()) + device, err := client.Devices().Get(context.Background(), rs.Primary.ID) if err != nil { return err } - var selected *tailscale.Device - for _, device := range devices { - if device.ID == rs.Primary.ID { - selected = &device - break - } - } - - if selected == nil { - return fmt.Errorf("expected device with id %q to exist", rs.Primary.ID) - } - - if selected.Authorized != true { + if device.Authorized != true { return fmt.Errorf("device with id %q is not authorized", rs.Primary.ID) } }