mirror of
https://github.com/opentffoundation/opentf.git
synced 2025-12-21 10:47:34 -05:00
297 lines
7.6 KiB
Go
297 lines
7.6 KiB
Go
// Copyright (c) The OpenTofu Authors
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
// Copyright (c) 2023 HashiCorp, Inc.
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
package aws_kms
|
|
|
|
import (
|
|
"fmt"
|
|
"reflect"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/aws/aws-sdk-go-v2/aws"
|
|
"github.com/aws/aws-sdk-go-v2/feature/ec2/imds"
|
|
"github.com/aws/aws-sdk-go-v2/service/kms/types"
|
|
"github.com/davecgh/go-spew/spew"
|
|
awsbase "github.com/hashicorp/aws-sdk-go-base/v2"
|
|
"github.com/hashicorp/hcl/v2"
|
|
"github.com/hashicorp/hcl/v2/gohcl"
|
|
"github.com/hashicorp/hcl/v2/hclsyntax"
|
|
"github.com/opentofu/opentofu/internal/httpclient"
|
|
"github.com/opentofu/opentofu/version"
|
|
)
|
|
|
|
func TestConfig_asAWSBase(t *testing.T) {
|
|
testCases := []struct {
|
|
name string
|
|
input string
|
|
expected awsbase.Config
|
|
}{
|
|
{
|
|
name: "minconfig",
|
|
input: `
|
|
kms_key_id = "my-kms-key-id"
|
|
key_spec = "AES_256"
|
|
region = "magic-mountain"`,
|
|
expected: awsbase.Config{
|
|
Region: "magic-mountain",
|
|
CallerDocumentationURL: "https://opentofu.org/docs/language/settings/backends/s3",
|
|
CallerName: "KMS Key Provider",
|
|
MaxRetries: 5,
|
|
APNInfo: &awsbase.APNInfo{
|
|
PartnerName: "OpenTofu-AWS-KMS",
|
|
Products: []awsbase.UserAgentProduct{
|
|
{Name: httpclient.DefaultApplicationName, Version: version.String()},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "maxconfig",
|
|
input: `
|
|
kms_key_id = "my-kms-key-id"
|
|
key_spec = "AES_256"
|
|
|
|
access_key = "my-access-key"
|
|
endpoints {
|
|
iam = "endpoint-iam"
|
|
sts = "endpoint-sts"
|
|
}
|
|
max_retries = 42
|
|
profile = "my-profile"
|
|
region = "my-region"
|
|
secret_key = "my-secret-key"
|
|
skip_credentials_validation = true
|
|
skip_requesting_account_id = true
|
|
sts_region = "my-sts-region"
|
|
token = "my-token"
|
|
http_proxy = "my-http-proxy"
|
|
https_proxy = "my-https-proxy"
|
|
no_proxy = "my-noproxy"
|
|
insecure = true
|
|
use_dualstack_endpoint = true
|
|
use_fips_endpoint = true
|
|
custom_ca_bundle = "my-custom-ca-bundle"
|
|
ec2_metadata_service_endpoint = "my-emde"
|
|
ec2_metadata_service_endpoint_mode = "my-emde-mode"
|
|
skip_metadata_api_check = false
|
|
shared_credentials_files = ["my-scredf"]
|
|
shared_config_files = ["my-sconff"]
|
|
assume_role = {
|
|
role_arn = "ar_arn"
|
|
duration = "4h"
|
|
external_id = "ar_extid"
|
|
policy = "ar_policy"
|
|
policy_arns = ["arn:aws:iam::123456789012:policy/AR"]
|
|
session_name = "ar_session_name"
|
|
tags = {
|
|
foo = "bar"
|
|
}
|
|
transitive_tag_keys = ["ar_tags"]
|
|
}
|
|
assume_role_with_web_identity = {
|
|
role_arn = "wi_arn"
|
|
duration = "5h"
|
|
policy = "wi_policy"
|
|
policy_arns = ["arn:aws:iam::123456789012:policy/WI"]
|
|
session_name = "wi_session_name"
|
|
web_identity_token = "wi_token"
|
|
//web_identity_token_file = "wi_token_file"
|
|
}
|
|
allowed_account_ids = ["account"]
|
|
//forbidden_account_ids = ?
|
|
retry_mode = "adaptive"
|
|
`,
|
|
expected: awsbase.Config{
|
|
CallerDocumentationURL: "https://opentofu.org/docs/language/settings/backends/s3",
|
|
CallerName: "KMS Key Provider",
|
|
APNInfo: &awsbase.APNInfo{
|
|
PartnerName: "OpenTofu-AWS-KMS",
|
|
Products: []awsbase.UserAgentProduct{
|
|
{Name: httpclient.DefaultApplicationName, Version: version.String()},
|
|
},
|
|
},
|
|
AccessKey: "my-access-key",
|
|
IamEndpoint: "https://endpoint-iam",
|
|
MaxRetries: 42,
|
|
Profile: "my-profile",
|
|
Region: "my-region",
|
|
SecretKey: "my-secret-key",
|
|
SkipCredsValidation: true,
|
|
SkipRequestingAccountId: true,
|
|
StsEndpoint: "https://endpoint-sts",
|
|
StsRegion: "my-sts-region",
|
|
Token: "my-token",
|
|
HTTPProxy: aws.String("my-http-proxy"),
|
|
HTTPSProxy: aws.String("my-https-proxy"),
|
|
NoProxy: "my-noproxy",
|
|
Insecure: true,
|
|
UseDualStackEndpoint: true,
|
|
UseFIPSEndpoint: true,
|
|
CustomCABundle: "my-custom-ca-bundle",
|
|
EC2MetadataServiceEnableState: imds.ClientDisabled,
|
|
EC2MetadataServiceEndpoint: "my-emde",
|
|
EC2MetadataServiceEndpointMode: "my-emde-mode",
|
|
SharedCredentialsFiles: []string{"my-scredf"},
|
|
SharedConfigFiles: []string{"my-sconff"},
|
|
AssumeRole: []awsbase.AssumeRole{
|
|
{
|
|
RoleARN: "ar_arn",
|
|
Duration: time.Hour * 4,
|
|
ExternalID: "ar_extid",
|
|
Policy: "ar_policy",
|
|
PolicyARNs: []string{
|
|
"arn:aws:iam::123456789012:policy/AR",
|
|
},
|
|
SessionName: "ar_session_name",
|
|
Tags: map[string]string{
|
|
"foo": "bar",
|
|
},
|
|
TransitiveTagKeys: []string{
|
|
"ar_tags",
|
|
},
|
|
},
|
|
},
|
|
AssumeRoleWithWebIdentity: &awsbase.AssumeRoleWithWebIdentity{
|
|
RoleARN: "wi_arn",
|
|
Duration: time.Hour * 5,
|
|
Policy: "wi_policy",
|
|
PolicyARNs: []string{
|
|
"arn:aws:iam::123456789012:policy/WI",
|
|
},
|
|
SessionName: "wi_session_name",
|
|
WebIdentityToken: "wi_token",
|
|
WebIdentityTokenFile: "",
|
|
},
|
|
AllowedAccountIds: []string{"account"},
|
|
RetryMode: aws.RetryModeAdaptive,
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
input, diags := hclsyntax.ParseConfig([]byte(tc.input), "test", hcl.InitialPos)
|
|
if diags.HasErrors() {
|
|
t.Fatal(diags.Error())
|
|
}
|
|
|
|
config := new(Config)
|
|
|
|
diags = gohcl.DecodeBody(input.Body, nil, config)
|
|
if diags.HasErrors() {
|
|
t.Fatal(diags.Error())
|
|
}
|
|
|
|
if config.KMSKeyID != "my-kms-key-id" {
|
|
t.Fatal("missing kms_key_id")
|
|
}
|
|
if config.KeySpec != "AES_256" {
|
|
t.Fatal("missing key_spec")
|
|
}
|
|
|
|
actual, err := config.asAWSBase()
|
|
if err != nil {
|
|
t.Fatal(err.Error())
|
|
}
|
|
if !reflect.DeepEqual(tc.expected, *actual) {
|
|
t.Fatalf("Expected %s, got %s", spew.Sdump(tc.expected), spew.Sdump(*actual))
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestValidate(t *testing.T) {
|
|
testCases := []struct {
|
|
name string
|
|
input Config
|
|
expected error
|
|
}{
|
|
{
|
|
name: "valid",
|
|
input: Config{
|
|
KMSKeyID: "my-kms-key-id",
|
|
KeySpec: "AES_256",
|
|
},
|
|
expected: nil,
|
|
},
|
|
{
|
|
name: "missing kms_key_id",
|
|
input: Config{
|
|
KMSKeyID: "",
|
|
KeySpec: "AES_256",
|
|
},
|
|
expected: fmt.Errorf("no kms_key_id provided"),
|
|
},
|
|
{
|
|
name: "missing key_spec",
|
|
input: Config{
|
|
KMSKeyID: "my-kms-key-id",
|
|
KeySpec: "",
|
|
},
|
|
expected: fmt.Errorf("no key_spec provided"),
|
|
},
|
|
{
|
|
name: "invalid key_spec",
|
|
input: Config{
|
|
KMSKeyID: "my-kms-key-id",
|
|
KeySpec: "invalid??",
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
err := tc.input.validate()
|
|
// check if the error message is the same
|
|
if tc.expected != nil {
|
|
if err.Error() != tc.expected.Error() {
|
|
t.Fatalf("Expected %q, got %q", tc.expected.Error(), err.Error())
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGetKeySpecAsAWSType(t *testing.T) {
|
|
|
|
aes256 := types.DataKeySpecAes256
|
|
aes128 := types.DataKeySpecAes128
|
|
|
|
cases := []struct {
|
|
key string
|
|
expected *types.DataKeySpec
|
|
}{
|
|
{
|
|
key: "AES_256",
|
|
expected: &aes256,
|
|
},
|
|
{
|
|
key: "AES_128",
|
|
expected: &aes128,
|
|
},
|
|
{
|
|
key: "",
|
|
expected: nil,
|
|
},
|
|
{
|
|
key: "invalidKey",
|
|
expected: nil,
|
|
},
|
|
}
|
|
|
|
for _, c := range cases {
|
|
t.Run(c.key, func(t *testing.T) {
|
|
config := Config{
|
|
KeySpec: c.key,
|
|
}
|
|
actual := config.getKeySpecAsAWSType()
|
|
if !reflect.DeepEqual(c.expected, actual) {
|
|
t.Fatalf("Expected %s, got %s", spew.Sdump(c.expected), spew.Sdump(actual))
|
|
}
|
|
})
|
|
}
|
|
}
|