Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion pkg/platformhubaccounts/platform_hub_account_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,19 @@ import (

// PlatformHubAccountResource represents details for all Platform Hub accounts.
type PlatformHubAccountResource struct {
AccountType PlatformHubAccountType `json:"AccountType" validate:"required,oneof=AmazonWebServicesAccount"`
AccountType PlatformHubAccountType `json:"AccountType" validate:"required,oneof=AmazonWebServicesAccount AmazonWebServicesOidcAccount"`
Description string `json:"Description,omitempty"`
Name string `json:"Name" validate:"required,notall"`
AccessKey string `json:"AccessKey,omitempty"`
SecretKey *core.SensitiveValue `json:"SecretKey,omitempty"`

// OIDC-specific fields
RoleArn string `json:"RoleArn,omitempty"`
SessionDuration string `json:"SessionDuration,omitempty"`
DeploymentSubjectKeys []string `json:"DeploymentSubjectKeys,omitempty"`
HealthCheckSubjectKeys []string `json:"HealthCheckSubjectKeys,omitempty"`
AccountTestSubjectKeys []string `json:"AccountTestSubjectKeys,omitempty"`

resources.Resource
}

Expand Down Expand Up @@ -70,6 +77,16 @@ func (r *PlatformHubAccountResource) ToPlatformHubAccount() (IPlatformHubAccount
return nil, err
}
account = awsAccount
case AccountTypePlatformHubAwsOIDCAccount:
oidcAccount, err := NewPlatformHubAwsOIDCAccount(r.GetName(), r.RoleArn)
if err != nil {
return nil, err
}
oidcAccount.SessionDuration = r.SessionDuration
oidcAccount.DeploymentSubjectKeys = r.DeploymentSubjectKeys
oidcAccount.HealthCheckSubjectKeys = r.HealthCheckSubjectKeys
oidcAccount.AccountTestSubjectKeys = r.AccountTestSubjectKeys
account = oidcAccount
default:
return nil, internal.CreateInvalidParameterError("ToPlatformHubAccount", "AccountType")
}
Expand Down Expand Up @@ -101,6 +118,13 @@ func ToPlatformHubAccountResource(account IPlatformHubAccount) (*PlatformHubAcco
awsAccount := account.(*PlatformHubAwsAccount)
resource.AccessKey = awsAccount.AccessKey
resource.SecretKey = awsAccount.SecretKey
case AccountTypePlatformHubAwsOIDCAccount:
oidcAccount := account.(*PlatformHubAwsOIDCAccount)
resource.RoleArn = oidcAccount.RoleArn
resource.SessionDuration = oidcAccount.SessionDuration
resource.DeploymentSubjectKeys = oidcAccount.DeploymentSubjectKeys
resource.HealthCheckSubjectKeys = oidcAccount.HealthCheckSubjectKeys
resource.AccountTestSubjectKeys = oidcAccount.AccountTestSubjectKeys
default:
return nil, internal.CreateInvalidParameterError("ToPlatformHubAccountResource", "AccountType")
}
Expand Down
3 changes: 2 additions & 1 deletion pkg/platformhubaccounts/platform_hub_account_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ package platformhubaccounts
type PlatformHubAccountType string

const (
AccountTypePlatformHubAwsAccount = PlatformHubAccountType("AmazonWebServicesAccount")
AccountTypePlatformHubAwsAccount = PlatformHubAccountType("AmazonWebServicesAccount")
AccountTypePlatformHubAwsOIDCAccount = PlatformHubAccountType("AmazonWebServicesOidcAccount")
)
58 changes: 58 additions & 0 deletions pkg/platformhubaccounts/platform_hub_aws_oidc_account.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package platformhubaccounts

import (
"github.com/OctopusDeploy/go-octopusdeploy/v2/internal"
"github.com/OctopusDeploy/go-octopusdeploy/v2/pkg/constants"
validation "github.com/OctopusDeploy/go-octopusdeploy/v2/pkg/validation"
"github.com/go-playground/validator/v10"
"github.com/go-playground/validator/v10/non-standard/validators"
)

// PlatformHubAwsOIDCAccount represents a Platform Hub AWS OIDC account.
type PlatformHubAwsOIDCAccount struct {
RoleArn string `json:"RoleArn" validate:"required"`
SessionDuration string `json:"SessionDuration,omitempty"`
DeploymentSubjectKeys []string `json:"DeploymentSubjectKeys,omitempty" validate:"omitempty,dive,oneof=space environment project tenant runbook account type'"`
HealthCheckSubjectKeys []string `json:"HealthCheckSubjectKeys,omitempty" validate:"omitempty,dive,oneof=space account target type'"`
AccountTestSubjectKeys []string `json:"AccountTestSubjectKeys,omitempty" validate:"omitempty,dive,oneof=space account type'"`

platformHubAccount
}

// NewPlatformHubAwsOIDCAccount initializes and returns a Platform Hub AWS OIDC account with a name and role ARN.
func NewPlatformHubAwsOIDCAccount(name string, roleArn string) (*PlatformHubAwsOIDCAccount, error) {
if internal.IsEmpty(name) {
return nil, internal.CreateRequiredParameterIsEmptyOrNilError(constants.ParameterName)
}

if internal.IsEmpty(roleArn) {
return nil, internal.CreateRequiredParameterIsEmptyOrNilError("roleArn")
}

account := PlatformHubAwsOIDCAccount{
RoleArn: roleArn,
platformHubAccount: *newPlatformHubAccount(name, AccountTypePlatformHubAwsOIDCAccount),
}

// validate to ensure that all expectations are met
err := account.Validate()
if err != nil {
return nil, err
}

return &account, nil
}

// Validate checks the state of this account and returns an error if invalid.
func (a *PlatformHubAwsOIDCAccount) Validate() error {
v := validator.New()
err := v.RegisterValidation("notblank", validators.NotBlank)
if err != nil {
return err
}
err = v.RegisterValidation("notall", validation.NotAll)
if err != nil {
return err
}
return v.Struct(a)
}
205 changes: 205 additions & 0 deletions pkg/platformhubaccounts/platform_hub_aws_oidc_account_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
package platformhubaccounts

import (
"encoding/json"
"fmt"
"testing"
"time"

"github.com/OctopusDeploy/go-octopusdeploy/v2/internal"
"github.com/kinbiko/jsonassert"
"github.com/stretchr/testify/require"
)

func TestPlatformHubAwsOIDCAccount(t *testing.T) {
name := internal.GetRandomName()
roleArn := "arn:aws:iam::123456789012:role/MyRole"
sessionDuration := "3600"
deploymentSubjectKeys := []string{"space", "environment", "project"}
healthCheckSubjectKeys := []string{"space", "target"}
accountTestSubjectKeys := []string{"space", "account"}
invalidDeploymentSubjectKeys := []string{"space", "invalid"}
invalidHealthCheckSubjectKeys := []string{"space", "project"}
invalidAccountTestSubjectKeys := []string{"space", "environment"}

testCases := []struct {
TestName string
IsError bool
Name string
RoleArn string
SessionDuration string
DeploymentSubjectKeys []string
HealthCheckSubjectKeys []string
AccountTestSubjectKeys []string
}{
{"Valid", false, name, roleArn, sessionDuration, deploymentSubjectKeys, healthCheckSubjectKeys, accountTestSubjectKeys},
{"EmptyName", true, "", roleArn, sessionDuration, deploymentSubjectKeys, healthCheckSubjectKeys, accountTestSubjectKeys},
{"WhitespaceName", true, " ", roleArn, sessionDuration, deploymentSubjectKeys, healthCheckSubjectKeys, accountTestSubjectKeys},
{"EmptyRoleArn", true, name, "", sessionDuration, deploymentSubjectKeys, healthCheckSubjectKeys, accountTestSubjectKeys},
{"NilSubjectKeys", false, name, roleArn, sessionDuration, nil, nil, nil},
{"EmptySessionDuration", false, name, roleArn, "", deploymentSubjectKeys, healthCheckSubjectKeys, accountTestSubjectKeys},
{"InvalidDeploymentSubjectKeys", true, name, roleArn, sessionDuration, invalidDeploymentSubjectKeys, healthCheckSubjectKeys, accountTestSubjectKeys},
{"InvalidHealthCheckSubjectKeys", true, name, roleArn, sessionDuration, deploymentSubjectKeys, invalidHealthCheckSubjectKeys, accountTestSubjectKeys},
{"InvalidAccountTestSubjectKeys", true, name, roleArn, sessionDuration, deploymentSubjectKeys, healthCheckSubjectKeys, invalidAccountTestSubjectKeys},
}
for _, tc := range testCases {
t.Run(tc.TestName, func(t *testing.T) {
account := &PlatformHubAwsOIDCAccount{
RoleArn: tc.RoleArn,
SessionDuration: tc.SessionDuration,
DeploymentSubjectKeys: tc.DeploymentSubjectKeys,
HealthCheckSubjectKeys: tc.HealthCheckSubjectKeys,
AccountTestSubjectKeys: tc.AccountTestSubjectKeys,
}
account.AccountType = AccountTypePlatformHubAwsOIDCAccount
account.Name = tc.Name

if tc.IsError {
require.Error(t, account.Validate())
} else {
require.NoError(t, account.Validate())
require.Equal(t, AccountTypePlatformHubAwsOIDCAccount, account.GetAccountType())
require.Equal(t, tc.Name, account.GetName())
}

account.SetName(tc.Name)
if tc.IsError {
require.Error(t, account.Validate())
} else {
require.NoError(t, account.Validate())
require.Equal(t, tc.Name, account.GetName())
}
})
}
}

func TestPlatformHubAwsOIDCAccountNew(t *testing.T) {
name := internal.GetRandomName()
roleArn := "arn:aws:iam::123456789012:role/MyRole"
accountType := AccountTypePlatformHubAwsOIDCAccount
description := ""

account, err := NewPlatformHubAwsOIDCAccount(name, roleArn)

require.NotNil(t, account)
require.NoError(t, err)
require.NoError(t, account.Validate())

// resource
require.Equal(t, "", account.ID)
require.Equal(t, "", account.ModifiedBy)
require.Nil(t, account.ModifiedOn)
require.NotNil(t, account.Links)

// IResource
require.Equal(t, "", account.GetID())
require.Equal(t, "", account.GetModifiedBy())
require.Nil(t, account.GetModifiedOn())
require.NotNil(t, account.GetLinks())

// IPlatformHubAccount
require.Equal(t, accountType, account.GetAccountType())
require.Equal(t, description, account.GetDescription())
require.Equal(t, name, account.GetName())

// PlatformHubAwsOIDCAccount
require.Equal(t, roleArn, account.RoleArn)
}

func TestPlatformHubAwsOIDCAccountMarshalJSON(t *testing.T) {
name := internal.GetRandomName()
roleArn := "arn:aws:iam::123456789012:role/MyRole"
sessionDuration := "3600"
deploymentSubjectKeys := []string{"space", "environment"}
healthCheckSubjectKeys := []string{"space", "target"}
accountTestSubjectKeys := []string{"space", "account"}

deploymentSubjectKeysJSON, err := json.Marshal(deploymentSubjectKeys)
require.NoError(t, err)
require.NotNil(t, deploymentSubjectKeysJSON)

healthCheckSubjectKeysJSON, err := json.Marshal(healthCheckSubjectKeys)
require.NoError(t, err)
require.NotNil(t, healthCheckSubjectKeysJSON)

accountTestSubjectKeysJSON, err := json.Marshal(accountTestSubjectKeys)
require.NoError(t, err)
require.NotNil(t, accountTestSubjectKeysJSON)

expectedJson := fmt.Sprintf(`{
"AccountType": "AmazonWebServicesOidcAccount",
"Name": "%s",
"RoleArn": "%s",
"SessionDuration": "%s",
"DeploymentSubjectKeys": %s,
"HealthCheckSubjectKeys": %s,
"AccountTestSubjectKeys": %s
}`, name, roleArn, sessionDuration, deploymentSubjectKeysJSON, healthCheckSubjectKeysJSON, accountTestSubjectKeysJSON)

account, err := NewPlatformHubAwsOIDCAccount(name, roleArn)
require.NoError(t, err)
require.NotNil(t, account)

account.SessionDuration = sessionDuration
account.DeploymentSubjectKeys = deploymentSubjectKeys
account.HealthCheckSubjectKeys = healthCheckSubjectKeys
account.AccountTestSubjectKeys = accountTestSubjectKeys

accountAsJSON, err := json.Marshal(account)
require.NoError(t, err)
require.NotNil(t, accountAsJSON)

jsonassert.New(t).Assertf(expectedJson, string(accountAsJSON))
}

func TestPlatformHubAwsOIDCAccountNewWithConfigs(t *testing.T) {
name := internal.GetRandomName()
roleArn := "arn:aws:iam::123456789012:role/MyRole"
sessionDuration := "3600"
deploymentSubjectKeys := []string{"space", "environment", "project"}
healthCheckSubjectKeys := []string{"space", "target"}
accountTestSubjectKeys := []string{"space", "account"}
accountType := AccountTypePlatformHubAwsOIDCAccount
id := internal.GetRandomName()
modifiedBy := internal.GetRandomName()
modifiedOn := time.Now()
description := "Description for " + name + " (OK to Delete)"

account, err := NewPlatformHubAwsOIDCAccount(name, roleArn)
require.NoError(t, err)
require.NotNil(t, account)
require.NoError(t, account.Validate())

account.Description = description
account.SessionDuration = sessionDuration
account.DeploymentSubjectKeys = deploymentSubjectKeys
account.HealthCheckSubjectKeys = healthCheckSubjectKeys
account.AccountTestSubjectKeys = accountTestSubjectKeys
account.ID = id
account.ModifiedBy = modifiedBy
account.ModifiedOn = &modifiedOn

// resource
require.Equal(t, id, account.ID)
require.Equal(t, modifiedBy, account.ModifiedBy)
require.Equal(t, &modifiedOn, account.ModifiedOn)
require.NotNil(t, account.Links)

// IResource
require.Equal(t, id, account.GetID())
require.Equal(t, modifiedBy, account.GetModifiedBy())
require.Equal(t, &modifiedOn, account.GetModifiedOn())
require.NotNil(t, account.GetLinks())

// IPlatformHubAccount
require.Equal(t, accountType, account.GetAccountType())
require.Equal(t, description, account.GetDescription())
require.Equal(t, name, account.GetName())

// PlatformHubAwsOIDCAccount
require.Equal(t, roleArn, account.RoleArn)
require.Equal(t, sessionDuration, account.SessionDuration)
require.Equal(t, deploymentSubjectKeys, account.DeploymentSubjectKeys)
require.Equal(t, healthCheckSubjectKeys, account.HealthCheckSubjectKeys)
require.Equal(t, accountTestSubjectKeys, account.AccountTestSubjectKeys)
}
Loading