Files
threshold-plugin-gcp/internal/credential/attributes_test.go
T

280 lines
8.3 KiB
Go
Raw Normal View History

// Copyright IBM Corp. 2024, 2026
2024-04-02 15:47:49 -04:00
// SPDX-License-Identifier: MPL-2.0
package credential
import (
"testing"
"github.com/stretchr/testify/require"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/types/known/structpb"
)
func TestGetCredentialAttributes(t *testing.T) {
cases := []struct {
name string
in map[string]any
expected *CredentialAttributes
expectedErrContains string
}{
{
name: "missing project",
in: map[string]any{},
2024-09-17 10:50:10 -04:00
expectedErrContains: "missing required value \"project_id\"",
2024-04-02 15:47:49 -04:00
},
{
name: "missing zone",
in: map[string]any{},
expectedErrContains: "missing required value \"zone\"",
},
2024-08-06 11:51:00 -04:00
{
name: "valid project and zone",
in: map[string]any{
2024-09-17 10:50:10 -04:00
ConstProjectId: "test-project",
ConstZone: "us-central-1",
2024-08-06 11:51:00 -04:00
},
expected: &CredentialAttributes{
2024-09-17 10:50:10 -04:00
ProjectId: "test-project",
Zone: "us-central-1",
DisableCredentialRotation: false,
},
},
{
name: "with disable_credential_rotation",
in: map[string]any{
ConstDisableCredentialRotation: true,
ConstProjectId: "test-project",
ConstZone: "us-central-1",
},
expected: &CredentialAttributes{
DisableCredentialRotation: true,
ProjectId: "test-project",
Zone: "us-central-1",
},
},
{
name: "with client_email",
in: map[string]any{
ConstClientEmail: "test@test.com",
ConstProjectId: "test-project",
ConstZone: "us-central-1",
},
expected: &CredentialAttributes{
ClientEmail: "test@test.com",
ProjectId: "test-project",
Zone: "us-central-1",
},
},
{
name: "with target_service_account_id",
in: map[string]any{
ConstTargetServiceAccountID: "test-target-service-account",
ConstProjectId: "test-project",
ConstZone: "us-central-1",
},
expected: &CredentialAttributes{
TargetServiceAccountId: "test-target-service-account",
ProjectId: "test-project",
Zone: "us-central-1",
2024-08-06 11:51:00 -04:00
},
},
2024-04-02 15:47:49 -04:00
}
for _, tc := range cases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
require := require.New(t)
input, err := structpb.NewStruct(tc.in)
require.NoError(err)
actual, err := GetCredentialAttributes(input)
if tc.expectedErrContains != "" {
require.Error(err)
require.Contains(err.Error(), tc.expectedErrContains)
require.Equal(status.Code(err), codes.InvalidArgument)
return
}
require.NoError(err)
2024-09-17 10:50:10 -04:00
require.EqualValues(tc.expected.ProjectId, actual.ProjectId)
2024-04-02 15:47:49 -04:00
require.EqualValues(tc.expected.Zone, actual.Zone)
})
}
}
2024-10-21 10:47:06 -04:00
func TestGetCredentialsConfig(t *testing.T) {
cases := []struct {
name string
secrets map[string]any
attrs *CredentialAttributes
expected *Config
expectedErrContains string
}{
{
name: "nil secrets",
attrs: &CredentialAttributes{
Zone: "us-central-1a",
},
expected: &Config{
Zone: "us-central-1a",
Scopes: []string{defaultGCPScope},
validateServiceAccountKeyTimeout: defaultValidateServiceAccountKeyTimeout,
2024-10-21 10:47:06 -04:00
},
},
{
2024-10-30 13:58:45 -04:00
name: "nil attributes",
attrs: nil,
expected: &Config{
Scopes: []string{defaultGCPScope},
validateServiceAccountKeyTimeout: defaultValidateServiceAccountKeyTimeout,
2024-10-30 13:58:45 -04:00
},
2024-10-21 10:47:06 -04:00
},
{
name: "unknown fields in secrets",
secrets: map[string]any{
"unknown_field": "value",
},
attrs: &CredentialAttributes{
ProjectId: "test-project",
Zone: "us-central-1a",
},
expectedErrContains: "secrets.unknown_field: unrecognized field",
},
{
name: "valid ignore creds_last_rotated_time",
secrets: map[string]any{
ConstPrivateKeyId: "test-private-key-id",
ConstPrivateKey: "test-private-key",
ConstCredsLastRotatedTime: "2006-01-02T15:04:05+07:00",
},
attrs: &CredentialAttributes{
ProjectId: "test-project",
Zone: "us-central-1a",
ClientEmail: "test@test.com",
},
expected: &Config{
ProjectId: "test-project",
Zone: "us-central-1a",
ClientEmail: "test@test.com",
PrivateKey: "test-private-key",
PrivateKeyId: "test-private-key-id",
Scopes: []string{defaultGCPScope},
validateServiceAccountKeyTimeout: defaultValidateServiceAccountKeyTimeout,
2024-10-21 10:47:06 -04:00
},
},
{
name: "missing private key with target service account id",
secrets: map[string]any{
ConstClientEmail: "test@test.com",
},
attrs: &CredentialAttributes{
ProjectId: "test-project",
Zone: "us-central-1a",
TargetServiceAccountId: "test-target-service-account",
},
expectedErrContains: "must not be empty when target service account id is set",
},
{
name: "missing client email with target service account id",
secrets: map[string]any{
ConstPrivateKey: "private-key",
},
attrs: &CredentialAttributes{
ProjectId: "test-project",
Zone: "us-central-1a",
TargetServiceAccountId: "test-target-service-account",
},
expectedErrContains: "must not be empty when target service account id is set",
},
{
name: "missing client email with private key",
secrets: map[string]any{
ConstPrivateKeyId: "test-private-key-id",
ConstPrivateKey: "test-private-key",
},
attrs: &CredentialAttributes{
ProjectId: "test-project",
Zone: "us-central-1a",
},
expectedErrContains: "must not be empty when private key is set",
},
{
name: "missing private key with client email",
secrets: map[string]any{},
attrs: &CredentialAttributes{
ClientEmail: "test@test.com",
ProjectId: "test-project",
Zone: "us-central-1a",
},
expectedErrContains: "must not be empty when client email is set",
},
{
name: "valid static credentials",
secrets: map[string]any{
ConstPrivateKeyId: "test-private-key-id",
ConstPrivateKey: "test-private-key",
},
attrs: &CredentialAttributes{
ClientEmail: "test@test.com",
ProjectId: "test-project",
Zone: "us-central-1a",
},
expected: &Config{
ProjectId: "test-project",
Zone: "us-central-1a",
PrivateKey: "test-private-key",
PrivateKeyId: "test-private-key-id",
ClientEmail: "test@test.com",
Scopes: []string{defaultGCPScope},
validateServiceAccountKeyTimeout: defaultValidateServiceAccountKeyTimeout,
2024-10-21 10:47:06 -04:00
},
},
{
name: "valid dynamic credentials",
secrets: map[string]any{
ConstPrivateKeyId: "test-private-key-id",
ConstPrivateKey: "test-private-key",
},
attrs: &CredentialAttributes{
ClientEmail: "test@test.com",
ProjectId: "test-project",
Zone: "us-central-1a",
TargetServiceAccountId: "test-target-service-account",
},
expected: &Config{
ProjectId: "test-project",
Zone: "us-central-1a",
PrivateKey: "test-private-key",
PrivateKeyId: "test-private-key-id",
ClientEmail: "test@test.com",
TargetServiceAccountId: "test-target-service-account",
Scopes: []string{defaultGCPScope},
validateServiceAccountKeyTimeout: defaultValidateServiceAccountKeyTimeout,
2024-10-21 10:47:06 -04:00
},
},
}
for _, tc := range cases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
require := require.New(t)
secrets, err := structpb.NewStruct(tc.secrets)
require.NoError(err)
actual, err := GetCredentialsConfig(secrets, tc.attrs)
if tc.expectedErrContains != "" {
require.Error(err)
require.Contains(err.Error(), tc.expectedErrContains)
require.Equal(status.Code(err), codes.InvalidArgument)
return
}
require.NoError(err)
require.EqualValues(tc.expected, actual)
})
}
}