Skip to content

Commit efd9758

Browse files
senthilhnsritek01
andauthored
Added purge_on_delete attribute for real deleting of delegate token after revoke (#1329)
* Added purge_on_delete attribute for real deleting of delegate token after revoke of token * Added purge_on_delete attribute for real deleting of delegate token after revoke --------- Co-authored-by: Ritek <ritek.rounak@harness.io>
1 parent f3dc389 commit efd9758

File tree

2 files changed

+162
-1
lines changed

2 files changed

+162
-1
lines changed

internal/service/platform/delegate_token/resource_delegateToken.go

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ func ResourceDelegateToken() *schema.Resource {
2121
ReadContext: resourceDelegateTokenRead,
2222
CreateContext: resourceDelegateTokenCreate,
2323
UpdateContext: resourceDelegateTokenRevoke,
24-
DeleteContext: resourceDelegateTokenRevoke,
24+
DeleteContext: resourceDelegateTokenDestroy,
2525
Importer: helpers.MultiLevelResourceImporter,
2626

2727
Schema: map[string]*schema.Schema{
@@ -81,6 +81,11 @@ func ResourceDelegateToken() *schema.Resource {
8181
Optional: true,
8282
Computed: true,
8383
},
84+
"purge_on_delete": {
85+
Type: schema.TypeBool,
86+
Optional: true,
87+
Default: false,
88+
},
8489
},
8590
}
8691

@@ -164,6 +169,44 @@ func resourceDelegateTokenRevoke(ctx context.Context, d *schema.ResourceData, me
164169

165170
}
166171

172+
func resourceDelegateTokenDestroy(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
173+
dg := resourceDelegateTokenRevoke(ctx, d, meta)
174+
if dg != nil {
175+
return dg
176+
}
177+
178+
purgeAndDelete := d.Get("purge_on_delete").(bool)
179+
if purgeAndDelete {
180+
return resourceDelegateTokenDelete(ctx, d, meta)
181+
}
182+
183+
log.Printf("resourceDelegateTokenDelete delegatetoken delete: completed successfully")
184+
d.SetId("")
185+
return nil
186+
}
187+
188+
func resourceDelegateTokenDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
189+
c, ctx := meta.(*internal.Session).GetPlatformClientWithContext(ctx)
190+
191+
delegateToken := buildDelegateToken(d)
192+
httpResp, err := c.DelegateTokenResourceApi.DeleteCgDelegateToken(ctx, c.AccountId, delegateToken.Name, &nextgen.DelegateTokenResourceApiDeleteCgDelegateTokenOpts{
193+
OrgIdentifier: helpers.BuildField(d, "org_id"),
194+
ProjectIdentifier: helpers.BuildField(d, "project_id"),
195+
})
196+
if err != nil {
197+
if httpResp != nil && httpResp.StatusCode == http.StatusNotFound {
198+
log.Printf("resourceDelegateTokenDelete delegatetoken delete (delete step): token not found; treating as deleted")
199+
d.SetId("")
200+
return nil
201+
}
202+
return helpers.HandleApiError(err, d, httpResp)
203+
}
204+
205+
log.Printf("resourceDelegateTokenDelete delegatetoken delete: completed successfully")
206+
d.SetId("")
207+
return nil
208+
}
209+
167210
func buildDelegateToken(d *schema.ResourceData) *nextgen.DelegateTokenDetails {
168211
delegateToken := &nextgen.DelegateTokenDetails{}
169212

internal/service/platform/delegate_token/resource_delegateToken_test.go

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package delegatetoken_test
22

33
import (
4+
"errors"
45
"fmt"
56
"os"
7+
"strings"
68
"testing"
79

810
"github.com/antihax/optional"
@@ -11,6 +13,7 @@ import (
1113
"github.com/harness/terraform-provider-harness/internal/acctest"
1214
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
1315
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
16+
"net/http"
1417
)
1518

1619
func TestAccResourceDelegateToken(t *testing.T) {
@@ -337,9 +340,124 @@ func testDelegateTokenDestroy(resourceName string) resource.TestCheckFunc {
337340
}
338341
}
339342

343+
// check actual deletion
344+
func testDelegateTokenPurged(resourceName string) resource.TestCheckFunc {
345+
return func(state *terraform.State) error {
346+
httpResp, err := testAccGetResourceDelegateTokenForDestroy(resourceName, state)
347+
if err != nil {
348+
return err
349+
}
350+
if httpResp == nil {
351+
return fmt.Errorf("Token is not revoked : %s", resourceName)
352+
}
353+
if strings.Contains(httpResp.Status, "200") {
354+
return nil
355+
}
356+
return fmt.Errorf("Token is not revoked : %s", resourceName)
357+
}
358+
}
359+
360+
// check if token is revoked
361+
func testDelegateTokenRevoked(resourceName string) resource.TestCheckFunc {
362+
return func(state *terraform.State) error {
363+
_, err := testAccGetResourceDelegateTokenForDestroy(resourceName, state)
364+
if err != nil {
365+
if strings.Contains(err.Error(), "404") {
366+
return nil
367+
}
368+
}
369+
return fmt.Errorf("Token is not revoked : %s", resourceName)
370+
}
371+
}
372+
340373
func buildField(r *terraform.ResourceState, field string) optional.String {
341374
if attr, ok := r.Primary.Attributes[field]; ok {
342375
return optional.NewString(attr)
343376
}
344377
return optional.EmptyString()
345378
}
379+
380+
// test for purge_on_delete
381+
func TestAccResourceDelegateTokenAccountAndProjectLevel(t *testing.T) {
382+
orgID := fmt.Sprintf("o%s", utils.RandStringBytes(5))
383+
projectID := fmt.Sprintf("p%s", utils.RandStringBytes(5))
384+
accountID := os.Getenv("HARNESS_ACCOUNT_ID")
385+
386+
accountLevelTokenName := fmt.Sprintf("acctok-%s", utils.RandStringBytes(5))
387+
projectLevelTokenName := fmt.Sprintf("projtok-%s", utils.RandStringBytes(5))
388+
389+
accountLevelResourceName := "harness_platform_delegatetoken.account_level"
390+
projectLevelResourceName := "harness_platform_delegatetoken.project_level"
391+
392+
resource.UnitTest(t, resource.TestCase{
393+
PreCheck: func() { acctest.TestAccPreCheck(t) },
394+
ProviderFactories: acctest.ProviderFactories,
395+
CheckDestroy: resource.ComposeTestCheckFunc(
396+
testDelegateTokenPurged(accountLevelResourceName),
397+
testDelegateTokenRevoked(projectLevelResourceName),
398+
),
399+
Steps: []resource.TestStep{
400+
{
401+
Config: testAccResourceDelegateTokenAccountAndProjectLevel(orgID, projectID, accountID, accountLevelTokenName, projectLevelTokenName),
402+
Check: resource.ComposeTestCheckFunc(
403+
resource.TestCheckResourceAttr(accountLevelResourceName, "name", accountLevelTokenName),
404+
resource.TestCheckResourceAttr(accountLevelResourceName, "token_status", "ACTIVE"),
405+
resource.TestCheckResourceAttr(accountLevelResourceName, "purge_on_delete", "true"),
406+
resource.TestCheckResourceAttr(projectLevelResourceName, "name", projectLevelTokenName),
407+
resource.TestCheckResourceAttr(projectLevelResourceName, "token_status", "ACTIVE"),
408+
),
409+
},
410+
},
411+
})
412+
}
413+
414+
func testAccResourceDelegateTokenAccountAndProjectLevel(orgID string, projectID string, accountID string, accountLevelTokenName string, projectLevelTokenName string) string {
415+
return fmt.Sprintf(`
416+
resource "harness_platform_organization" "test" {
417+
identifier = "%[1]s"
418+
name = "%[1]s"
419+
}
420+
421+
resource "harness_platform_project" "test" {
422+
identifier = "%[2]s"
423+
name = "%[2]s"
424+
org_id = harness_platform_organization.test.id
425+
color = "#472848"
426+
}
427+
428+
resource "harness_platform_delegatetoken" "account_level" {
429+
name = "%[4]s"
430+
account_id = "%[3]s"
431+
purge_on_delete = true
432+
}
433+
434+
resource "harness_platform_delegatetoken" "project_level" {
435+
name = "%[5]s"
436+
account_id = "%[3]s"
437+
org_id = harness_platform_organization.test.id
438+
project_id = harness_platform_project.test.id
439+
}
440+
`, orgID, projectID, accountID, accountLevelTokenName, projectLevelTokenName)
441+
}
442+
443+
func testAccGetResourceDelegateTokenForDestroy(resourceName string, state *terraform.State) (*http.Response, error) {
444+
rm := state.RootModule()
445+
if rm == nil {
446+
return nil, errors.New("root module nil")
447+
}
448+
r, ok := rm.Resources[resourceName]
449+
if !ok || r == nil {
450+
return nil, errors.New("resource not found")
451+
}
452+
453+
c, ctx := acctest.TestAccGetPlatformClientWithContext()
454+
455+
_, httpResp, err := c.DelegateTokenResourceApi.GetCgDelegateTokens(ctx, c.AccountId, &nextgen.DelegateTokenResourceApiGetCgDelegateTokensOpts{
456+
OrgIdentifier: buildField(r, "org_id"),
457+
ProjectIdentifier: buildField(r, "project_id"),
458+
Name: buildField(r, "name"),
459+
Status: optional.EmptyString(),
460+
})
461+
462+
return httpResp, err
463+
}

0 commit comments

Comments
 (0)