From 101b25b1b8e4e1d3e45bda9e5b113facbe720b1c Mon Sep 17 00:00:00 2001 From: Volodymyr Manilo Date: Thu, 19 Oct 2023 05:55:07 +0200 Subject: [PATCH] fix service_account and service_key common lifecycle --- .github/workflows/ci.yml | 2 + twingate/internal/client/service-account.go | 13 ++++ .../acctests/resource/service-key_test.go | 70 +++++++++++++++++++ 3 files changed, 85 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ee1bfee8..043ed6dd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,6 +7,7 @@ on: pull_request: branches: - main + - fix/service-account-and-service-key paths-ignore: - 'README.md' @@ -15,6 +16,7 @@ on: - 'README.md' branches: - main + - fix/service-account-and-service-key # Ensures only 1 action runs per PR and previous is canceled on new trigger concurrency: diff --git a/twingate/internal/client/service-account.go b/twingate/internal/client/service-account.go index f8ef61e7..7d590838 100644 --- a/twingate/internal/client/service-account.go +++ b/twingate/internal/client/service-account.go @@ -72,6 +72,19 @@ func (client *Client) UpdateServiceAccount(ctx context.Context, serviceAccount * } func (client *Client) DeleteServiceAccount(ctx context.Context, serviceAccountID string) error { + serviceAccount, err := client.ReadServiceAccount(ctx, serviceAccountID) + if err != nil && !errors.Is(err, ErrGraphqlResultIsEmpty) { + return err + } + + if serviceAccount != nil { + for _, key := range serviceAccount.Keys { + if err := client.RevokeServiceKey(ctx, key); err != nil { + return err + } + } + } + opr := resourceServiceAccount.delete() if serviceAccountID == "" { diff --git a/twingate/internal/test/acctests/resource/service-key_test.go b/twingate/internal/test/acctests/resource/service-key_test.go index e1ba852e..36ef27a8 100644 --- a/twingate/internal/test/acctests/resource/service-key_test.go +++ b/twingate/internal/test/acctests/resource/service-key_test.go @@ -326,3 +326,73 @@ func TestAccTwingateServiceKeyReCreateAfterChangingExpirationTime(t *testing.T) }) }) } + +func TestAccTwingateServiceKeyAndServiceAccountLifecycle(t *testing.T) { + t.Run("Test Twingate Resource : Acc Service Key and Service Account Lifecycle", func(t *testing.T) { + serviceAccountName := test.RandomName() + terraformResourceName := test.TerraformRandName("test_lifecycle") + serviceAccount := acctests.TerraformServiceAccount(terraformResourceName) + serviceKey := acctests.TerraformServiceKey(terraformResourceName) + + serviceKeyResourceID := new(string) + serviceAccountResourceID := new(string) + + sdk.Test(t, sdk.TestCase{ + ProtoV6ProviderFactories: acctests.ProviderFactories, + PreCheck: func() { acctests.PreCheck(t) }, + CheckDestroy: acctests.CheckTwingateServiceAccountDestroy, + Steps: []sdk.TestStep{ + { + Config: createServiceKey(terraformResourceName, serviceAccountName), + Check: acctests.ComposeTestCheckFunc( + acctests.CheckTwingateResourceExists(serviceAccount), + sdk.TestCheckResourceAttr(serviceAccount, attr.Name, serviceAccountName), + acctests.CheckTwingateResourceExists(serviceKey), + sdk.TestCheckResourceAttrWith(serviceKey, attr.Token, nonEmptyValue), + acctests.GetTwingateResourceID(serviceKey, &serviceKeyResourceID), + acctests.GetTwingateResourceID(serviceKey, &serviceAccountResourceID), + + // delete service account via API + acctests.DeleteTwingateResource(serviceAccount, resource.TwingateServiceAccount), + acctests.WaitTestFunc(), + ), + ExpectNonEmptyPlan: true, + }, + { + Config: createServiceKey(terraformResourceName, serviceAccountName), + Check: acctests.ComposeTestCheckFunc( + acctests.CheckTwingateResourceExists(serviceAccount), + sdk.TestCheckResourceAttr(serviceAccount, attr.Name, serviceAccountName), + acctests.CheckTwingateResourceExists(serviceKey), + sdk.TestCheckResourceAttrWith(serviceKey, attr.Token, nonEmptyValue), + + // test resources were re-created + sdk.TestCheckResourceAttrWith(serviceKey, attr.ID, func(value string) error { + if *serviceKeyResourceID == "" { + return errors.New("failed to fetch service_key resource id") + } + + if value == *serviceKeyResourceID { + return errors.New("service_key resource was not re-created") + } + + return nil + }), + + sdk.TestCheckResourceAttrWith(serviceAccount, attr.ID, func(value string) error { + if *serviceAccountResourceID == "" { + return errors.New("failed to fetch service_account resource id") + } + + if value == *serviceAccountResourceID { + return errors.New("service_account resource was not re-created") + } + + return nil + }), + ), + }, + }, + }) + }) +}