diff --git a/.changelog/719.txt b/.changelog/719.txt new file mode 100644 index 000000000..a6625b464 --- /dev/null +++ b/.changelog/719.txt @@ -0,0 +1,3 @@ +```release-note:new-resource + resource/harness_platform_delegatetoken: Added delegate token resource. +``` diff --git a/docs/data-sources/platform_delegate_token.md b/docs/data-sources/platform_delegate_token.md new file mode 100644 index 000000000..49d96254c --- /dev/null +++ b/docs/data-sources/platform_delegate_token.md @@ -0,0 +1,45 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "harness_platform_delegatetoken Data Source - terraform-provider-harness" +subcategory: "Next Gen" +description: |- + Data Source for retrieving delegate tokens. +--- + +# harness_platform_delegatetoken (Data Source) + +Data Source for retrieving delegate tokens. + +## Example Usage + +```terraform +data "harness_platform_token" "test" { + identifier = "test_token" + name = "test token" + account_id = "account_id" + org_id = "org_id" + project_id = "project_id" +} +``` + + +## Schema + +### Required + +- `account_id` (String) Account Identifier for the Entity +- `identifier` (String) Unique identifier of the resource. +- `name` (String) Name of the resource. + +### Optional + +- `token_status` (String) Status of Delegate Token (ACTIVE or REVOKED). If left empty both active and revoked tokens will be assumed. +- `created_at` (String) Time when the delegate token is created. +- `created_by` (String) created by details. +- `org_id` (String) Unique identifier of the organization. +- `project_id` (String) Unique identifier of the project. + +### Read-Only + +- `id` (String) The ID of this resource. +- `value` (String, Sensitive) Value of the delegate Token diff --git a/docs/resources/platform_delegate_token.md b/docs/resources/platform_delegate_token.md new file mode 100644 index 000000000..0d19561f4 --- /dev/null +++ b/docs/resources/platform_delegate_token.md @@ -0,0 +1,76 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "harness_platform_delegatetoken Resource - terraform-provider-harness" +subcategory: "Next Gen" +description: |- + Resource for creating delegate tokens. +--- + +# harness_platform_delegatetoken (Resource) + +Resource for creating delegate tokens. + +## Example Usage + +```terraform +# Create delegate token for account level +resource "harness_platform_delegatetoken" "test" { + identifier = "test_token" + name = "test token" + account_id = "account_id" +} + +# Create token for org level apikey +resource "harness_platform_token" "test" { + identifier = "test_token" + name = "test token" + account_id = "account_id" + org_id = "org_id" +} + +# Create token for project level apikey +resource "harness_platform_token" "test" { + identifier = "test_token" + name = "test token" + account_id = "account_id" + org_id = "org_id" + project_id = "project_id" +} +``` + + +## Schema + +### Required + +- `account_id` (String) Account Identifier for the Entity +- `identifier` (String) Unique identifier of the resource. +- `name` (String) Name of the resource. + +### Optional + +- `token_status` (String) Status of Delegate Token (ACTIVE or REVOKED). If left empty both active and revoked tokens will be assumed. +- `created_at` (String) Time when the delegate token is created. +- `created_by` (String) created by details. +- `org_id` (String) Unique identifier of the organization. +- `project_id` (String) Unique identifier of the project. + +### Read-Only + +- `id` (String) The ID of this resource. +- `value` (String, Sensitive) Value of the delegate Token + +## Import + +Import is supported using the following syntax: + +```shell +# Import account level delegate token +terraform import harness_platform_delegatetoken + +# Import org level delegate token +terraform import harness_platform_delegatetoken / + +# Import project level delegate token +terraform import harness_platform_delegatetoken // +``` diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 7e19a882a..2d77e9d26 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -41,6 +41,7 @@ import ( "github.com/harness/terraform-provider-harness/internal/service/platform/ccm_filters" "github.com/harness/terraform-provider-harness/internal/service/platform/connector" pl_current_user "github.com/harness/terraform-provider-harness/internal/service/platform/current_user" + pl_delegatetoken "github.com/harness/terraform-provider-harness/internal/service/platform/delegate_token" pl_environment "github.com/harness/terraform-provider-harness/internal/service/platform/environment" pl_environment_clusters_mapping "github.com/harness/terraform-provider-harness/internal/service/platform/environment_clusters_mapping" pl_environment_group "github.com/harness/terraform-provider-harness/internal/service/platform/environment_group" @@ -243,6 +244,7 @@ func Provider(version string) func() *schema.Provider { "harness_autostopping_aws_alb": load_balancer.DataSourceAwsALB(), "harness_autostopping_azure_gateway": load_balancer.DataSourceAzureGateway(), "harness_autostopping_schedule": schedule.DataSourceFixedSchedule(), + "harness_platform_delegatetoken": pl_delegatetoken.DataSourceDelegateToken(), }, ResourcesMap: map[string]*schema.Resource{ "harness_platform_template": pl_template.ResourceTemplate(), @@ -370,6 +372,7 @@ func Provider(version string) func() *schema.Provider { "harness_autostopping_aws_alb": load_balancer.ResourceAwsALB(), "harness_autostopping_azure_gateway": load_balancer.ResourceAzureGateway(), "harness_autostopping_schedule": schedule.ResourceVMRule(), + "harness_platform_delegatetoken": pl_delegatetoken.ResourceDelegateToken(), }, } diff --git a/internal/service/platform/delegate_token/data_source_delegateToken.go b/internal/service/platform/delegate_token/data_source_delegateToken.go new file mode 100644 index 000000000..76d2deae9 --- /dev/null +++ b/internal/service/platform/delegate_token/data_source_delegateToken.go @@ -0,0 +1,101 @@ +package delegatetoken + +import ( + "context" + "errors" + "net/http" + + "github.com/harness/harness-go-sdk/harness/nextgen" + "github.com/harness/terraform-provider-harness/helpers" + "github.com/harness/terraform-provider-harness/internal" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +func DataSourceDelegateToken() *schema.Resource { + resource := &schema.Resource{ + Description: "Data source for retrieving a Harness delegate Token.", + + ReadContext: dataSourceDelegateTokenRead, + + Schema: map[string]*schema.Schema{ + "name": { + Description: "Name of the delegate token", + Type: schema.TypeString, + Required: true, + }, + "account_id": { + Description: "Account Identifier for the Entity", + Type: schema.TypeString, + Required: true, + }, + "org_id": { + Description: "Org Identifier for the Entity", + Type: schema.TypeString, + Optional: true, + }, + "project_id": { + Description: "Project Identifier for the Entity", + Type: schema.TypeString, + Optional: true, + RequiredWith: []string{"org_id"}, + }, + "token_status": { + Description: "Status of Delegate Token (ACTIVE or REVOKED). If left empty both active and revoked tokens will be assumed", + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"ACTIVE", "REVOKED"}, false), + }, + "value": { + Description: "Value of the delegate token. Encoded in base64.", + Type: schema.TypeString, + Optional: true, + }, + "created_at": { + Description: "Time when the delegate token is created. This is an epoch timestamp.", + Type: schema.TypeInt, + Optional: true, + }, + }, + } + + return resource +} + +func dataSourceDelegateTokenRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + c, ctx := meta.(*internal.Session).GetPlatformClientWithContext(ctx) + + var delegateToken *nextgen.DelegateTokenDetails + + name := d.Get("name").(string) + + if name != "" { + var err error + var httpResp *http.Response + resp, httpResp, err := c.DelegateTokenResourceApi.GetDelegateTokens(ctx, c.AccountId, &nextgen.DelegateTokenResourceApiGetDelegateTokensOpts{ + OrgIdentifier: helpers.BuildField(d, "org_id"), + ProjectIdentifier: helpers.BuildField(d, "project_id"), + Name: helpers.BuildField(d, "name"), + Status: helpers.BuildField(d, "token_status"), + }) + if err != nil { + return helpers.HandleApiError(err, d, httpResp) + } + if resp.Resource != nil { + delegateToken = &resp.Resource[0] + } + + if delegateToken == nil { + d.SetId("") + d.MarkNewResource() + return nil + } + } else { + return diag.FromErr(errors.New("Name must be specified")) + } + + readDelegateToken(d, delegateToken) + + return nil +} diff --git a/internal/service/platform/delegate_token/data_source_delegateToken_test.go b/internal/service/platform/delegate_token/data_source_delegateToken_test.go new file mode 100644 index 000000000..014f4c8f3 --- /dev/null +++ b/internal/service/platform/delegate_token/data_source_delegateToken_test.go @@ -0,0 +1,145 @@ +package delegatetoken_test + +import ( + "fmt" + "os" + "testing" + + "github.com/harness/harness-go-sdk/harness/utils" + "github.com/harness/terraform-provider-harness/internal/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func TestAccDataSourceDelegateToken(t *testing.T) { + name := utils.RandStringBytes(5) + account_id := os.Getenv("HARNESS_ACCOUNT_ID") + + resourceName := "data.harness_platform_delegatetoken.test" + + resource.UnitTest(t, resource.TestCase{ + PreCheck: func() { acctest.TestAccPreCheck(t) }, + ProviderFactories: acctest.ProviderFactories, + Steps: []resource.TestStep{ + { + Config: tesAccDataSourceDelegateToken(name, account_id), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "name", name), + resource.TestCheckResourceAttr(resourceName, "token_status", "ACTIVE"), + ), + }, + }, + }) +} + +func TestAccDataSourceDelegateTokenOrgLevel(t *testing.T) { + name := utils.RandStringBytes(5) + account_id := os.Getenv("HARNESS_ACCOUNT_ID") + + resourceName := "data.harness_platform_delegatetoken.test" + + resource.UnitTest(t, resource.TestCase{ + PreCheck: func() { acctest.TestAccPreCheck(t) }, + ProviderFactories: acctest.ProviderFactories, + Steps: []resource.TestStep{ + { + Config: tesAccDataSourceDelegateTokenOrgLevel(name, account_id), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "name", name), + resource.TestCheckResourceAttr(resourceName, "token_status", "ACTIVE"), + resource.TestCheckResourceAttr(resourceName, "org_id", name), + ), + }, + }, + }) +} + +func TestAccDataSourceDelegateTokenProjectLevel(t *testing.T) { + name := utils.RandStringBytes(5) + account_id := os.Getenv("HARNESS_ACCOUNT_ID") + + resourceName := "data.harness_platform_delegatetoken.test" + + resource.UnitTest(t, resource.TestCase{ + PreCheck: func() { acctest.TestAccPreCheck(t) }, + ProviderFactories: acctest.ProviderFactories, + Steps: []resource.TestStep{ + { + Config: tesAccDataSourceDelegateTokenProjectLevel(name, account_id), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "name", name), + resource.TestCheckResourceAttr(resourceName, "token_status", "ACTIVE"), + resource.TestCheckResourceAttr(resourceName, "org_id", name), + resource.TestCheckResourceAttr(resourceName, "project_id", name), + ), + }, + }, + }) +} + +func tesAccDataSourceDelegateToken(name string, accountId string) string { + return fmt.Sprintf(` + resource "harness_platform_delegatetoken" "test" { + identifier = "%[1]s" + name = "%[1]s" + account_id = "%[2]s" + } + + data "harness_platform_delegatetoken" "test" { + name = harness_platform_delegatetoken.test.name + account_id = harness_platform_delegatetoken.test.account_id + } + `, name, accountId) +} + +func tesAccDataSourceDelegateTokenOrgLevel(name string, accountId string) string { + return fmt.Sprintf(` + resource "harness_platform_organization" "test" { + identifier = "%[1]s" + name = "%[1]s" + } + + resource "harness_platform_delegatetoken" "test" { + identifier = "%[1]s" + name = "%[1]s" + account_id = "%[2]s" + org_id = harness_platform_organization.test.id + } + + data "harness_platform_delegatetoken" "test" { + name = harness_platform_delegatetoken.test.name + account_id = harness_platform_delegatetoken.test.account_id + org_id = harness_platform_delegatetoken.test.org_id + } + `, name, accountId) +} + +func tesAccDataSourceDelegateTokenProjectLevel(name string, accountId string) string { + return fmt.Sprintf(` + resource "harness_platform_organization" "test" { + identifier = "%[1]s" + name = "%[1]s" + } + + resource "harness_platform_project" "test" { + identifier = "%[1]s" + name = "%[1]s" + org_id = harness_platform_organization.test.id + color = "#472848" + } + + resource "harness_platform_delegatetoken" "test" { + identifier = "%[1]s" + name = "%[1]s" + account_id = "%[2]s" + org_id = harness_platform_organization.test.id + project_id = harness_platform_project.test.id + } + + data "harness_platform_delegatetoken" "test" { + name = harness_platform_delegatetoken.test.name + account_id = harness_platform_delegatetoken.test.account_id + org_id = harness_platform_delegatetoken.test.org_id + project_id = harness_platform_delegatetoken.test.project_id + } + `, name, accountId) +} diff --git a/internal/service/platform/delegate_token/resource_delegateToken.go b/internal/service/platform/delegate_token/resource_delegateToken.go new file mode 100644 index 000000000..69a33d90c --- /dev/null +++ b/internal/service/platform/delegate_token/resource_delegateToken.go @@ -0,0 +1,208 @@ +package delegatetoken + +import ( + "context" + "net/http" + + "github.com/harness/harness-go-sdk/harness/nextgen" + "github.com/harness/terraform-provider-harness/helpers" + "github.com/harness/terraform-provider-harness/internal" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +func ResourceDelegateToken() *schema.Resource { + resource := &schema.Resource{ + Description: "Resource for creating delegate tokens.", + + ReadContext: resourceDelegateTokenRead, + CreateContext: resourceDelegateTokenCreateOrUpdate, + UpdateContext: resourceDelegateTokenCreateOrUpdate, + DeleteContext: resourceDelegateTokenDelete, + Importer: helpers.MultiLevelResourceImporter, + + Schema: map[string]*schema.Schema{ + "identifier": { + Description: "Identifier of the delegate token", + Type: schema.TypeString, + Required: true, + }, + "name": { + Description: "Name of the delegate token", + Type: schema.TypeString, + Required: true, + }, + "account_id": { + Description: "Account Identifier for the Entity", + Type: schema.TypeString, + Required: true, + }, + "org_id": { + Description: "Org Identifier for the Entity", + Type: schema.TypeString, + Optional: true, + }, + "project_id": { + Description: "Project Identifier for the Entity", + Type: schema.TypeString, + Optional: true, + RequiredWith: []string{"org_id"}, + }, + "token_status": { + Description: "Status of Delegate Token (ACTIVE or REVOKED). If left empty both active and revoked tokens will be assumed", + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringInSlice([]string{"ACTIVE", "REVOKED"}, false), + }, + "value": { + Description: "Value of the delegate token. Encoded in base64.", + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "created_at": { + Description: "Time when the delegate token is created. This is an epoch timestamp.", + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "created_by": { + Description: "created by details", + Type: schema.TypeMap, + Optional: true, + Computed: true, + }, + }, + } + + return resource +} + +func resourceDelegateTokenRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + c, ctx := meta.(*internal.Session).GetPlatformClientWithContext(ctx) + + resp, httpResp, err := c.DelegateTokenResourceApi.GetDelegateTokens(ctx, c.AccountId, &nextgen.DelegateTokenResourceApiGetDelegateTokensOpts{ + OrgIdentifier: helpers.BuildField(d, "org_id"), + ProjectIdentifier: helpers.BuildField(d, "project_id"), + Name: helpers.BuildField(d, "name"), + Status: helpers.BuildField(d, "token_status"), + }) + + if err != nil { + return helpers.HandleApiError(err, d, httpResp) + } + + if resp.Resource != nil { + readDelegateToken(d, &resp.Resource[0]) + } + + return nil +} + +func resourceDelegateTokenCreateOrUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + c, ctx := meta.(*internal.Session).GetPlatformClientWithContext(ctx) + + var err error + var resp nextgen.RestResponseDelegateTokenDetails + var httpResp *http.Response + + delegateToken := buildDelegateToken(d) + + if delegateToken.Value == "" { + resp, httpResp, err = c.DelegateTokenResourceApi.CreateDelegateToken(ctx, c.AccountId, delegateToken.Name, &nextgen.DelegateTokenResourceApiCreateDelegateTokenOpts{ + OrgIdentifier: helpers.BuildField(d, "org_id"), + ProjectIdentifier: helpers.BuildField(d, "project_id"), + }) + } else { + resp, httpResp, err = c.DelegateTokenResourceApi.RevokeDelegateToken(ctx, c.AccountId, delegateToken.Name, &nextgen.DelegateTokenResourceApiRevokeDelegateTokenOpts{ + OrgIdentifier: helpers.BuildField(d, "org_id"), + ProjectIdentifier: helpers.BuildField(d, "project_id"), + }) + } + + if err != nil { + return helpers.HandleApiError(err, d, httpResp) + } + + readDelegateToken(d, resp.Resource) + + return nil +} + +func resourceDelegateTokenDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + c, ctx := meta.(*internal.Session).GetPlatformClientWithContext(ctx) + + var err error + var resp nextgen.RestResponseDelegateTokenDetails + var httpResp *http.Response + + delegateToken := buildDelegateToken(d) + + resp, httpResp, err = c.DelegateTokenResourceApi.RevokeDelegateToken(ctx, c.AccountId, delegateToken.Name, &nextgen.DelegateTokenResourceApiRevokeDelegateTokenOpts{ + OrgIdentifier: helpers.BuildField(d, "org_id"), + ProjectIdentifier: helpers.BuildField(d, "project_id"), + }) + + if err != nil { + return helpers.HandleApiError(err, d, httpResp) + } + + readDelegateToken(d, resp.Resource) + + return nil + +} + +func buildDelegateToken(d *schema.ResourceData) *nextgen.DelegateTokenDetails { + delegateToken := &nextgen.DelegateTokenDetails{} + + if attr, ok := d.GetOk("account_id"); ok { + delegateToken.AccountId = attr.(string) + } + + if attr, ok := d.GetOk("name"); ok { + delegateToken.Name = attr.(string) + } + + if attr, ok := d.GetOk("created_at"); ok { + delegateToken.CreatedAt = int64(attr.(int)) + } + + if attr, ok := d.GetOk("token_status"); ok { + delegateToken.Status = attr.(string) + } + + if attr, ok := d.GetOk("value"); ok { + delegateToken.Value = attr.(string) + } + + return delegateToken +} + +func readDelegateToken(d *schema.ResourceData, delegateTokenDetails *nextgen.DelegateTokenDetails) { + d.SetId(delegateTokenDetails.Name) + d.Set("identifier", delegateTokenDetails.Name) + d.Set("name", delegateTokenDetails.Name) + d.Set("account_id", delegateTokenDetails.AccountId) + d.Set("token_status", delegateTokenDetails.Status) + d.Set("created_at", delegateTokenDetails.CreatedAt) + d.Set("created_by", readCreatedByData(delegateTokenDetails.CreatedByNgUser.Type_, delegateTokenDetails.CreatedByNgUser.Name, delegateTokenDetails.CreatedByNgUser.Jwtclaims)) + d.Set("value", delegateTokenDetails.Value) +} + +func readCreatedByData(userType string, name_ string, details map[string]string) map[string]string { + var result = make(map[string]string) + var type_ string + var name string + + result[type_] = userType + result[name] = name_ + + for key, value := range details { + result[key] = value + } + + return result +} diff --git a/internal/service/platform/delegate_token/resource_delegateToken_test.go b/internal/service/platform/delegate_token/resource_delegateToken_test.go new file mode 100644 index 000000000..f9a0ef0a3 --- /dev/null +++ b/internal/service/platform/delegate_token/resource_delegateToken_test.go @@ -0,0 +1,174 @@ +package delegatetoken_test + +import ( + "fmt" + "os" + "testing" + + "github.com/antihax/optional" + "github.com/harness/harness-go-sdk/harness/nextgen" + "github.com/harness/harness-go-sdk/harness/utils" + "github.com/harness/terraform-provider-harness/internal/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" +) + +func TestAccResourceDelegateToken(t *testing.T) { + name := utils.RandStringBytes(5) + account_id := os.Getenv("HARNESS_ACCOUNT_ID") + + resourceName := "harness_platform_delegatetoken.test" + + resource.UnitTest(t, resource.TestCase{ + PreCheck: func() { acctest.TestAccPreCheck(t) }, + ProviderFactories: acctest.ProviderFactories, + CheckDestroy: testDelegateTokenDestroy(resourceName), + Steps: []resource.TestStep{ + { + Config: tesAccResourceDelegateToken(name, account_id), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "name", name), + resource.TestCheckResourceAttr(resourceName, "token_status", "ACTIVE"), + ), + }, + }, + }) +} + +func TestAccResourceDelegateTokenOrgLevel(t *testing.T) { + name := utils.RandStringBytes(5) + account_id := os.Getenv("HARNESS_ACCOUNT_ID") + org_id := utils.RandStringBytes(5) + + resourceName := "harness_platform_delegatetoken.test" + + resource.UnitTest(t, resource.TestCase{ + PreCheck: func() { acctest.TestAccPreCheck(t) }, + ProviderFactories: acctest.ProviderFactories, + CheckDestroy: testDelegateTokenDestroy(resourceName), + Steps: []resource.TestStep{ + { + Config: tesAccResourceDelegateTokenOrgLevel(name, account_id, org_id), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "name", name), + resource.TestCheckResourceAttr(resourceName, "token_status", "ACTIVE"), + ), + }, + }, + }) +} + +func TestAccResourceDelegateTokenProjectLevel(t *testing.T) { + name := utils.RandStringBytes(5) + account_id := os.Getenv("HARNESS_ACCOUNT_ID") + org_id := utils.RandStringBytes(5) + project_id := utils.RandStringBytes(5) + + resourceName := "harness_platform_delegatetoken.test" + + resource.UnitTest(t, resource.TestCase{ + PreCheck: func() { acctest.TestAccPreCheck(t) }, + ProviderFactories: acctest.ProviderFactories, + CheckDestroy: testDelegateTokenDestroy(resourceName), + Steps: []resource.TestStep{ + { + Config: tesAccResourceDelegateTokenProjectLevel(name, account_id, org_id, project_id), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "name", name), + resource.TestCheckResourceAttr(resourceName, "token_status", "ACTIVE"), + ), + }, + }, + }) +} + +func tesAccResourceDelegateToken(name string, accountId string) string { + return fmt.Sprintf(` + resource "harness_platform_delegatetoken" "test" { + identifier = "%[1]s" + name = "%[1]s" + account_id = "%[2]s" + } + `, name, accountId) +} + +func tesAccResourceDelegateTokenOrgLevel(name string, accountId string, org_id string) string { + return fmt.Sprintf(` + resource "harness_platform_organization" "test" { + identifier = "%[1]s" + name = "%[1]s" + } + + resource "harness_platform_delegatetoken" "test" { + identifier = "%[1]s" + name = "%[1]s" + account_id = "%[2]s" + org_id = harness_platform_organization.test.id + } + `, name, accountId, org_id) +} + +func tesAccResourceDelegateTokenProjectLevel(name string, accountId string, org_id string, project_id string) string { + return fmt.Sprintf(` + resource "harness_platform_organization" "test" { + identifier = "%[3]s" + name = "%[1]s" + } + + resource "harness_platform_project" "test" { + identifier = "%[4]s" + name = "%[1]s" + org_id = harness_platform_organization.test.id + color = "#472848" + } + + resource "harness_platform_delegatetoken" "test" { + identifier = "%[1]s" + name = "%[1]s" + account_id = "%[2]s" + org_id = harness_platform_organization.test.id + project_id = harness_platform_project.test.id + } + `, name, accountId, org_id, project_id) +} + +func testAccGetResourceDelegateToken(resourceName string, state *terraform.State) (*nextgen.DelegateTokenDetails, error) { + d := acctest.TestAccGetResource(resourceName, state) + c, ctx := acctest.TestAccGetPlatformClientWithContext() + + resp, _, err := c.DelegateTokenResourceApi.GetDelegateTokens(ctx, c.AccountId, &nextgen.DelegateTokenResourceApiGetDelegateTokensOpts{ + OrgIdentifier: buildField(d, "org_id"), + ProjectIdentifier: buildField(d, "project_id"), + Name: buildField(d, "name"), + Status: buildField(d, "token_status"), + }) + + if err != nil { + return nil, err + } + + if resp.Resource == nil { + return nil, nil + } + + return &resp.Resource[0], nil +} + +func testDelegateTokenDestroy(resourceName string) resource.TestCheckFunc { + var token *nextgen.DelegateTokenDetails + return func(state *terraform.State) error { + token, _ = testAccGetResourceDelegateToken(resourceName, state) + if token.Status != "REVOKED" { + return fmt.Errorf("Token is not revoked : %s", token.Name) + } + + return nil + } +} + +func buildField(r *terraform.ResourceState, field string) optional.String { + if attr, ok := r.Primary.Attributes[field]; ok { + return optional.NewString(attr) + } + return optional.EmptyString() +}