Skip to content

Commit

Permalink
feat: Add support for generic oidc accounts
Browse files Browse the repository at this point in the history
  • Loading branch information
grace-rehn committed Dec 2, 2024
1 parent e709e02 commit 0ad741a
Show file tree
Hide file tree
Showing 8 changed files with 296 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
terraform import [options] octopusdeploy_generic_openid_connect_account.<name> <account-id>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
resource "octopusdeploy_azure_openid_connect" "example" {
name = "Generic OpenID Connect Account (OK to Delete)"
execution_subject_keys = ["space", "project"]
health_subject_keys = ["space", "target", "type"]
account_test_subject_keys = ["space", "type"]
audience = "api://Default"
}
1 change: 1 addition & 0 deletions octopusdeploy/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ func Provider() *schema.Provider {
"octopusdeploy_deployment_process": resourceDeploymentProcess(),
"octopusdeploy_dynamic_worker_pool": resourceDynamicWorkerPool(),
"octopusdeploy_gcp_account": resourceGoogleCloudPlatformAccount(),
"octopusdeploy_generic_openid_connect_account": resourceGenericOpenIDConnectAccount(),
"octopusdeploy_kubernetes_agent_deployment_target": resourceKubernetesAgentDeploymentTarget(),
"octopusdeploy_kubernetes_agent_worker": resourceKubernetesAgentWorker(),
"octopusdeploy_kubernetes_cluster_deployment_target": resourceKubernetesClusterDeploymentTarget(),
Expand Down
95 changes: 95 additions & 0 deletions octopusdeploy/resource_generic_oidc_account.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package octopusdeploy

import (
"context"
"github.com/OctopusDeploy/go-octopusdeploy/v2/pkg/accounts"
"github.com/OctopusDeploy/go-octopusdeploy/v2/pkg/client"
"github.com/OctopusDeploy/terraform-provider-octopusdeploy/internal/errors"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"log"
)

func resourceGenericOpenIDConnectAccount() *schema.Resource {
return &schema.Resource{
CreateContext: resourceGenericOpenIDConnectAccountCreate,
DeleteContext: resourceGenericOpenIDConnectAccountDelete,
Description: "This resource manages Generic OpenID Connect accounts in Octopus Deploy.",
Importer: getImporter(),
ReadContext: resourceGenericOpenIDConnectAccountRead,
Schema: getGenericOpenIdConnectAccountSchema(),
UpdateContext: resourceGenericOpenIDConnectAccountUpdate,
}
}

func resourceGenericOpenIDConnectAccountCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
account := expandGenericOpenIDConnectAccount(d)

log.Printf("[INFO] creating Generic OpenID Connect account: %#v", account)

client := m.(*client.Client)
createdAccount, err := accounts.Add(client, account)
if err != nil {
return diag.FromErr(err)
}

if err := setGenericOpenIDConnectAccount(ctx, d, createdAccount.(*accounts.GenericOIDCAccount)); err != nil {

Check failure on line 36 in octopusdeploy/resource_generic_oidc_account.go

View workflow job for this annotation

GitHub Actions / build

undefined: accounts.GenericOIDCAccount

Check failure on line 36 in octopusdeploy/resource_generic_oidc_account.go

View workflow job for this annotation

GitHub Actions / build

undefined: accounts.GenericOIDCAccount
return diag.FromErr(err)
}

d.SetId(createdAccount.GetID())

log.Printf("[INFO] Generic OpenID Connect account created (%s)", d.Id())
return nil
}

func resourceGenericOpenIDConnectAccountDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Printf("[INFO] deleting Generic OpenID Connect account (%s)", d.Id())

client := m.(*client.Client)
if err := accounts.DeleteByID(client, d.Get("space_id").(string), d.Id()); err != nil {
return diag.FromErr(err)
}

d.SetId("")

log.Printf("[INFO] Generic OpenID Connect account deleted")
return nil
}

func resourceGenericOpenIDConnectAccountRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Printf("[INFO] reading Generic OpenID Connect account (%s)", d.Id())

client := m.(*client.Client)
accountResource, err := accounts.GetByID(client, d.Get("space_id").(string), d.Id())
if err != nil {
return errors.ProcessApiError(ctx, d, err, "Generic OpenID Connect account")
}

genericOIDCAccount := accountResource.(*accounts.GenericOIDCAccount)

Check failure on line 69 in octopusdeploy/resource_generic_oidc_account.go

View workflow job for this annotation

GitHub Actions / build

undefined: accounts.GenericOIDCAccount

Check failure on line 69 in octopusdeploy/resource_generic_oidc_account.go

View workflow job for this annotation

GitHub Actions / build

undefined: accounts.GenericOIDCAccount
if err := setGenericOpenIDConnectAccount(ctx, d, genericOIDCAccount); err != nil {
return diag.FromErr(err)
}

log.Printf("[INFO] Generic OpenID Connect account read (%s)", d.Id())
return nil
}

func resourceGenericOpenIDConnectAccountUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
account := expandGenericOpenIDConnectAccount(d)

log.Printf("[INFO] updating Generic OpenID Connect account %#v", account)

client := m.(*client.Client)
updatedAccount, err := accounts.Update(client, account)
if err != nil {
return diag.FromErr(err)
}

if err := setGenericOpenIDConnectAccount(ctx, d, updatedAccount.(*accounts.GenericOIDCAccount)); err != nil {

Check failure on line 89 in octopusdeploy/resource_generic_oidc_account.go

View workflow job for this annotation

GitHub Actions / build

undefined: accounts.GenericOIDCAccount

Check failure on line 89 in octopusdeploy/resource_generic_oidc_account.go

View workflow job for this annotation

GitHub Actions / build

undefined: accounts.GenericOIDCAccount
return diag.FromErr(err)
}

log.Printf("[INFO] Generic OpenID Connect account updated (%s)", d.Id())
return nil
}
78 changes: 78 additions & 0 deletions octopusdeploy/resource_generic_oidc_account_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package octopusdeploy

import (
"fmt"
internalTest "github.com/OctopusDeploy/terraform-provider-octopusdeploy/internal/test"
"testing"

"github.com/OctopusDeploy/go-octopusdeploy/v2/pkg/core"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
)

func TestAccOctopusDeployGenericOpenIDConnectAccountBasic(t *testing.T) {
internalTest.SkipCI(t, "audience is not set on initial creation")
localName := acctest.RandStringFromCharSet(20, acctest.CharSetAlpha)
prefix := "octopusdeploy_generic_openid_connect_account." + localName

description := acctest.RandStringFromCharSet(20, acctest.CharSetAlpha)
name := acctest.RandStringFromCharSet(20, acctest.CharSetAlpha)
tenantedDeploymentMode := core.TenantedDeploymentModeTenantedOrUntenanted

executionKeys := []string{"space"}
healthKeys := []string{"target"}
accountKeys := []string{"type"}
audience := acctest.RandStringFromCharSet(20, acctest.CharSetAlpha)

newDescription := acctest.RandStringFromCharSet(20, acctest.CharSetAlpha)

resource.Test(t, resource.TestCase{
CheckDestroy: testAccountCheckDestroy,
PreCheck: func() { testAccPreCheck(t) },
ProtoV6ProviderFactories: ProtoV6ProviderFactories(),
Steps: []resource.TestStep{
{
Check: resource.ComposeTestCheckFunc(
testAccountExists(prefix),
resource.TestCheckResourceAttr(prefix, "description", description),
resource.TestCheckResourceAttr(prefix, "name", name),
resource.TestCheckResourceAttr(prefix, "tenanted_deployment_participation", string(tenantedDeploymentMode)),
resource.TestCheckResourceAttr(prefix, "execution_subject_keys.0", executionKeys[0]),
resource.TestCheckResourceAttr(prefix, "health_subject_keys.0", healthKeys[0]),
resource.TestCheckResourceAttr(prefix, "account_test_subject_keys.0", accountKeys[0]),
resource.TestCheckResourceAttr(prefix, "audience", audience),
),
Config: testGenericOpenIDConnectAccountBasic(localName, name, description, tenantedDeploymentMode, executionKeys, healthKeys, accountKeys, audience),
},
{
Check: resource.ComposeTestCheckFunc(
testAccountExists(prefix),
resource.TestCheckResourceAttr(prefix, "description", newDescription),
resource.TestCheckResourceAttr(prefix, "name", name),
resource.TestCheckResourceAttr(prefix, "tenanted_deployment_participation", string(tenantedDeploymentMode)),
resource.TestCheckResourceAttr(prefix, "execution_subject_keys.0", executionKeys[0]),
resource.TestCheckResourceAttr(prefix, "health_subject_keys.0", healthKeys[0]),
resource.TestCheckResourceAttr(prefix, "account_test_subject_keys.0", accountKeys[0]),
resource.TestCheckResourceAttr(prefix, "audience", audience),
),
Config: testGenericOpenIDConnectAccountBasic(localName, name, newDescription, tenantedDeploymentMode, executionKeys, healthKeys, accountKeys, audience),
},
},
})
}

func testGenericOpenIDConnectAccountBasic(localName string, name string, description string, tenantedDeploymentParticipation core.TenantedDeploymentMode, execution_subject_keys []string, health_subject_keys []string, account_test_subject_keys []string, audience string) string {
return fmt.Sprintf(`resource "octopusdeploy_generic_openid_connect_account" "%s" {
description = "%s"
name = "%s"
tenanted_deployment_participation = "%s"
execution_subject_keys = %s
health_subject_keys = %s
account_test_subject_keys = %s
audience = "%s"
}
data "octopusdeploy_accounts" "test" {
ids = [octopusdeploy_generic_openid_connect_account.%s.id]
}`, localName, description, name, tenantedDeploymentParticipation, StringArrayToTerraformArrayFormat(execution_subject_keys), StringArrayToTerraformArrayFormat(health_subject_keys), StringArrayToTerraformArrayFormat(account_test_subject_keys), audience, localName)
}
110 changes: 110 additions & 0 deletions octopusdeploy/schema_generic_oidc_account.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package octopusdeploy

import (
"context"
"fmt"
"github.com/OctopusDeploy/go-octopusdeploy/v2/pkg/accounts"
"github.com/OctopusDeploy/go-octopusdeploy/v2/pkg/core"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

func expandGenericOpenIDConnectAccount(d *schema.ResourceData) *accounts.GenericOIDCAccount {

Check failure on line 11 in octopusdeploy/schema_generic_oidc_account.go

View workflow job for this annotation

GitHub Actions / build

undefined: accounts.GenericOIDCAccount

Check failure on line 11 in octopusdeploy/schema_generic_oidc_account.go

View workflow job for this annotation

GitHub Actions / build

undefined: accounts.GenericOIDCAccount
name := d.Get("name").(string)

account, _ := accounts.NewGenericOIDCAccount(name)

Check failure on line 14 in octopusdeploy/schema_generic_oidc_account.go

View workflow job for this annotation

GitHub Actions / build

undefined: accounts.NewGenericOIDCAccount

Check failure on line 14 in octopusdeploy/schema_generic_oidc_account.go

View workflow job for this annotation

GitHub Actions / build

undefined: accounts.NewGenericOIDCAccount
account.ID = d.Id()

if v, ok := d.GetOk("description"); ok {
account.SetDescription(v.(string))
}

if v, ok := d.GetOk("environments"); ok {
account.EnvironmentIDs = getSliceFromTerraformTypeList(v)
}

if v, ok := d.GetOk("name"); ok {
account.SetName(v.(string))
}

if v, ok := d.GetOk("space_id"); ok {
account.SetSpaceID(v.(string))
}

if v, ok := d.GetOk("tenanted_deployment_participation"); ok {
account.TenantedDeploymentMode = core.TenantedDeploymentMode(v.(string))
}

if v, ok := d.GetOk("tenant_tags"); ok {
account.TenantTags = getSliceFromTerraformTypeList(v)
}

if v, ok := d.GetOk("tenants"); ok {
account.TenantIDs = getSliceFromTerraformTypeList(v)
}

if v, ok := d.GetOk("execution_subject_keys"); ok {
account.DeploymentSubjectKeys = getSliceFromTerraformTypeList(v)
}

if v, ok := d.GetOk("health_subject_keys"); ok {
account.HealthCheckSubjectKeys = getSliceFromTerraformTypeList(v)
}

if v, ok := d.GetOk("account_test_subject_keys"); ok {
account.AccountTestSubjectKeys = getSliceFromTerraformTypeList(v)
}

return account
}

func getGenericOpenIdConnectAccountSchema() map[string]*schema.Schema {
return map[string]*schema.Schema{
"description": getDescriptionSchema("Azure OpenID Connect account"),
"environments": getEnvironmentsSchema(),
"id": getIDSchema(),
"name": getNameSchema(true),
"space_id": getSpaceIDSchema(),
"tenanted_deployment_participation": getTenantedDeploymentSchema(),
"tenants": getTenantsSchema(),
"tenant_tags": getTenantTagsSchema(),
"execution_subject_keys": getSubjectKeysSchema(SchemaSubjectKeysDescriptionExecution),
"health_subject_keys": getSubjectKeysSchema(SchemaSubjectKeysDescriptionHealth),
"account_test_subject_keys": getSubjectKeysSchema(SchemaSubjectKeysDescriptionAccountTest),
"audience": getOidcAudienceSchema(),
}
}

func setGenericOpenIDConnectAccount(ctx context.Context, d *schema.ResourceData, account *accounts.GenericOIDCAccount) error {

Check failure on line 77 in octopusdeploy/schema_generic_oidc_account.go

View workflow job for this annotation

GitHub Actions / build

undefined: accounts.GenericOIDCAccount

Check failure on line 77 in octopusdeploy/schema_generic_oidc_account.go

View workflow job for this annotation

GitHub Actions / build

undefined: accounts.GenericOIDCAccount
d.Set("description", account.GetDescription())
d.Set("id", account.GetID())
d.Set("name", account.GetName())
d.Set("space_id", account.GetSpaceID())
d.Set("tenanted_deployment_participation", account.GetTenantedDeploymentMode())
d.Set("audience", account.Audience)

if err := d.Set("environments", account.GetEnvironmentIDs()); err != nil {
return fmt.Errorf("error setting environments: %s", err)
}

if err := d.Set("tenants", account.GetTenantIDs()); err != nil {
return fmt.Errorf("error setting tenants: %s", err)
}

if err := d.Set("tenant_tags", account.TenantTags); err != nil {
return fmt.Errorf("error setting tenant_tags: %s", err)
}

if err := d.Set("execution_subject_keys", account.DeploymentSubjectKeys); err != nil {
return fmt.Errorf("error setting execution_subject_keys: %s", err)
}

if err := d.Set("health_subject_keys", account.HealthCheckSubjectKeys); err != nil {
return fmt.Errorf("error setting health_subject_keys: %s", err)
}

if err := d.Set("account_test_subject_keys", account.AccountTestSubjectKeys); err != nil {
return fmt.Errorf("error setting account_test_subject_keys: %s", err)
}

return nil
}
3 changes: 2 additions & 1 deletion octopusdeploy/schema_queries.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (

func getQueryAccountType() *schema.Schema {
return &schema.Schema{
Description: "A filter to search by a list of account types. Valid account types are `AmazonWebServicesAccount`, `AmazonWebServicesRoleAccount`, `AmazonWebServicesOidcAccount`, `AzureServicePrincipal`, `AzureSubscription`, `None`, `SshKeyPair`, `Token`, or `UsernamePassword`.",
Description: "A filter to search by a list of account types. Valid account types are `AmazonWebServicesAccount`, `AmazonWebServicesRoleAccount`, `AmazonWebServicesOidcAccount`, `AzureServicePrincipal`, `AzureSubscription`, `GenericOidcAccount`, `None`, `SshKeyPair`, `Token`, or `UsernamePassword`.",
Optional: true,
Type: schema.TypeString,
ValidateDiagFunc: validation.ToDiagFunc(validation.StringInSlice([]string{
Expand All @@ -17,6 +17,7 @@ func getQueryAccountType() *schema.Schema {
"AzureServicePrincipal",
"AzureOIDC",
"AzureSubscription",
"GenericOidcAccount",
"None",
"SshKeyPair",
"Token",
Expand Down
3 changes: 2 additions & 1 deletion octopusdeploy/schema_utilities.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (

func getAccountTypeSchema(isRequired bool) *schema.Schema {
schema := &schema.Schema{
Description: "Specifies the type of the account. Valid account types are `AmazonWebServicesAccount`, `AmazonWebServicesRoleAccount`, `AzureServicePrincipal`, `AzureOIDC`, `AzureSubscription`, `AmazonWebServicesOidcAccount`, `None`, `SshKeyPair`, `Token`, or `UsernamePassword`.",
Description: "Specifies the type of the account. Valid account types are `AmazonWebServicesAccount`, `AmazonWebServicesRoleAccount`, `AzureServicePrincipal`, `AzureOIDC`, `AzureSubscription`, `AmazonWebServicesOidcAccount`, `GenericOidcAccount`, `None`, `SshKeyPair`, `Token`, or `UsernamePassword`.",
ForceNew: true,
Type: schema.TypeString,
ValidateDiagFunc: validation.ToDiagFunc(validation.StringInSlice([]string{
Expand All @@ -18,6 +18,7 @@ func getAccountTypeSchema(isRequired bool) *schema.Schema {
"AzureServicePrincipal",
"AzureOIDC",
"AzureSubscription",
"GenericOidcAccount",
"None",
"SshKeyPair",
"Token",
Expand Down

0 comments on commit 0ad741a

Please sign in to comment.