Skip to content

Commit

Permalink
feat: Add generic oidc account
Browse files Browse the repository at this point in the history
  • Loading branch information
grace-rehn committed Nov 28, 2024
1 parent b692e57 commit f67d169
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 1 deletion.
2 changes: 1 addition & 1 deletion pkg/accounts/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ type IAccount interface {

// account is the embedded struct used for all accounts.
type account struct {
AccountType AccountType `json:"AccountType" validate:"required,oneof=None UsernamePassword SshKeyPair AzureSubscription AzureServicePrincipal AzureOidc AmazonWebServicesAccount AmazonWebServicesOidcAccount AmazonWebServicesRoleAccount GoogleCloudAccount Token"`
AccountType AccountType `json:"AccountType" validate:"required,oneof=None UsernamePassword SshKeyPair AzureSubscription AzureServicePrincipal AzureOidc AmazonWebServicesAccount AmazonWebServicesOidcAccount AmazonWebServicesRoleAccount GoogleCloudAccount Token GenericOidcAccount"`
Description string `json:"Description,omitempty"`
EnvironmentIDs []string `json:"EnvironmentIds,omitempty"`
Name string `json:"Name" validate:"required,notblank,notall"`
Expand Down
1 change: 1 addition & 0 deletions pkg/accounts/account_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const (
AccountTypeAzureOIDC = AccountType("AzureOidc")
AccountTypeAwsOIDC = AccountType("AmazonWebServicesOidcAccount")
AccountTypeAzureSubscription = AccountType("AzureSubscription")
AccountTypeGenericOIDCAccount = AccountType("GenericOidcAccount")
AccountTypeGoogleCloudPlatformAccount = AccountType("GoogleCloudAccount")
AccountTypeSSHKeyPair = AccountType("SshKeyPair")
AccountTypeToken = AccountType("Token")
Expand Down
10 changes: 10 additions & 0 deletions pkg/accounts/account_utilities.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,16 @@ func ToAccount(accountResource *AccountResource) (IAccount, error) {
azureSubscriptionAccount.ManagementEndpoint = accountResource.ManagementEndpoint
azureSubscriptionAccount.StorageEndpointSuffix = accountResource.StorageEndpointSuffix
account = azureSubscriptionAccount
case AccountTypeGenericOIDCAccount:
genericOIDCAccount, err := NewGenericOIDCAccount(accountResource.GetName())
if err != nil {
return nil, err
}
genericOIDCAccount.Audience = accountResource.Audience
genericOIDCAccount.DeploymentSubjectKeys = accountResource.DeploymentSubjectKeys
genericOIDCAccount.AccountTestSubjectKeys = accountResource.AccountTestSubjectKeys
genericOIDCAccount.HealthCheckSubjectKeys = accountResource.HealthCheckSubjectKeys
account = genericOIDCAccount
case AccountTypeGoogleCloudPlatformAccount:
googleCloudPlatformAccount, err := NewGoogleCloudPlatformAccount(accountResource.GetName(), accountResource.JsonKey)
if err != nil {
Expand Down
7 changes: 7 additions & 0 deletions pkg/accounts/accounts.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,13 @@ func (a *Accounts) UnmarshalJSON(b []byte) error {
return err
}
a.Items = append(a.Items, azureSubscriptionAccount)
case AccountTypeGenericOIDCAccount:
var genericOIDCAccount *GenericOIDCAccount
err := json.Unmarshal(*account, &genericOIDCAccount)
if err != nil {
return err
}
a.Items = append(a.Items, genericOIDCAccount)
case AccountTypeGoogleCloudPlatformAccount:
var googleCloudAccount *GoogleCloudPlatformAccount
err := json.Unmarshal(*account, &googleCloudAccount)
Expand Down
51 changes: 51 additions & 0 deletions pkg/accounts/generic_oidc_account.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package accounts

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

// GenericOIDCAccount represents a Generic OIDC account.
type GenericOIDCAccount struct {
Audience string `json:"Audience,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'"`

account
}

// NewGenericOIDCAccount creates and initializes a Generic OIDC account.
func NewGenericOIDCAccount(name string) (*GenericOIDCAccount, error) {
if internal.IsEmpty(name) {
return nil, internal.CreateRequiredParameterIsEmptyOrNilError("name")
}

account := GenericOIDCAccount{
account: *newAccount(name, AccountTypeGenericOIDCAccount),
}

// 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 *GenericOIDCAccount) 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)
}
73 changes: 73 additions & 0 deletions pkg/accounts/generic_oidc_account_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package accounts

import (
"github.com/OctopusDeploy/go-octopusdeploy/v2/internal"
"github.com/stretchr/testify/require"
"testing"
)

func TestGenericOIDCAccount(t *testing.T) {
name := internal.GetRandomName()
audience := "api://default"
deploymentSubjectKeys := []string{"space", "project", "tenant", "environment"}
healthCheckSubjectKeys := []string{"space", "target"}
accountTestSubjectKeys := []string{"space", "account"}
invalidDeploymentSubjectKeys := []string{"space", "target"}
invalidHealthCheckSubjectKeys := []string{"space", "project"}
invalidAccountTestSubjectKeys := []string{"space", "project"}

testCases := []struct {
TestName string
IsError bool
Name string
Audience string
DeploymentSubjectKeys []string
HealthCheckSubjectKeys []string
AccountTestSubjectKeys []string
}{
{"Valid", false, name, audience, deploymentSubjectKeys, healthCheckSubjectKeys, accountTestSubjectKeys},
{"EmptyName", true, "", audience, deploymentSubjectKeys, healthCheckSubjectKeys, accountTestSubjectKeys},
{"NilSubjectKeys", false, name, "", nil, nil, nil},
{"InvalidDeploymentSubjectKeys", true, name, "", invalidDeploymentSubjectKeys, healthCheckSubjectKeys, accountTestSubjectKeys},
{"InvalidHealthCheckSubjectKeys", true, name, "", deploymentSubjectKeys, invalidHealthCheckSubjectKeys, invalidAccountTestSubjectKeys},
{"InvalidAccountTestSubjectKeys", true, name, "", deploymentSubjectKeys, healthCheckSubjectKeys, invalidAccountTestSubjectKeys},
}

for _, tc := range testCases {
t.Run(tc.TestName, func(t *testing.T) {
genericOIDCAccount := &GenericOIDCAccount{
Audience: tc.Audience,
DeploymentSubjectKeys: tc.DeploymentSubjectKeys,
HealthCheckSubjectKeys: tc.HealthCheckSubjectKeys,
AccountTestSubjectKeys: tc.AccountTestSubjectKeys,
}
genericOIDCAccount.AccountType = AccountTypeGenericOIDCAccount
genericOIDCAccount.Name = tc.Name
if tc.IsError {
require.Error(t, genericOIDCAccount.Validate())
} else {
require.NoError(t, genericOIDCAccount.Validate())

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

func TestGenericOIDCAccountNew(t *testing.T) {
name := internal.GetRandomName()

account, err := NewGenericOIDCAccount(name)

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

0 comments on commit f67d169

Please sign in to comment.