Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

config: Add support for SharedConfig file ca_bundle parameter #1593

Merged
merged 2 commits into from Feb 23, 2022
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 8 additions & 0 deletions .changelog/aacb97e021754263bfbfe819a6e5d7c9.json
@@ -0,0 +1,8 @@
{
"id": "aacb97e0-2175-4263-bfbf-e819a6e5d7c9",
"type": "feature",
"description": "Adds support for the `ca_bundle` parameter in shared config and credentials files. The usage of the file is the same as environment variable, `AWS_CA_BUNDLE`, but sourced from shared config. Fixes [#1589](https://github.com/aws/aws-sdk-go-v2/issues/1589)",
"modules": [
"config"
]
}
2 changes: 1 addition & 1 deletion config/codegen/main.go
Expand Up @@ -22,7 +22,7 @@ const (
var implAsserts = map[string][]string{
"sharedConfigProfileProvider": {envConfigType, loadOptionsType},
"sharedConfigFilesProvider": {envConfigType, loadOptionsType},
"customCABundleProvider": {envConfigType, loadOptionsType},
"customCABundleProvider": {envConfigType, sharedConfigType, loadOptionsType},
"regionProvider": {envConfigType, sharedConfigType, loadOptionsType, ec2IMDSRegionType},
"credentialsProviderProvider": {loadOptionsType},
"defaultRegionProvider": {loadOptionsType},
Expand Down
1 change: 1 addition & 0 deletions config/provider_assert_test.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

42 changes: 40 additions & 2 deletions config/shared_config.go
@@ -1,9 +1,12 @@
package config

import (
"bytes"
"context"
"errors"
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"
"strings"
Expand Down Expand Up @@ -81,6 +84,8 @@ const (
// Retry options
retryMaxAttemptsKey = "max_attempts"
retryModeKey = "retry_mode"

caBundleKey = "ca_bundle"
)

// defaultSharedConfigProfile allows for swapping the default profile for testing
Expand Down Expand Up @@ -171,12 +176,14 @@ type SharedConfig struct {
// s3_use_arn_region=true
S3UseARNRegion *bool

// Specifies the EC2 Instance Metadata Service default endpoint selection mode (IPv4 or IPv6)
// Specifies the EC2 Instance Metadata Service default endpoint selection
// mode (IPv4 or IPv6)
//
// ec2_metadata_service_endpoint_mode=IPv6
EC2IMDSEndpointMode imds.EndpointModeState

// Specifies the EC2 Instance Metadata Service endpoint to use. If specified it overrides EC2IMDSEndpointMode.
// Specifies the EC2 Instance Metadata Service endpoint to use. If
// specified it overrides EC2IMDSEndpointMode.
//
// ec2_metadata_service_endpoint=http://fd00:ec2::254
EC2IMDSEndpoint string
Expand Down Expand Up @@ -214,6 +221,22 @@ type SharedConfig struct {
//
// retry_mode=standard
RetryMode aws.RetryMode

// Sets the path to a custom Credentials Authority (CA) Bundle PEM file
// that the SDK will use instead of the system's root CA bundle. Only use
// this if you want to configure the SDK to use a custom set of CAs.
//
// Enabling this option will attempt to merge the Transport into the SDK's
// HTTP client. If the client's Transport is not a http.Transport an error
// will be returned. If the Transport's TLS config is set this option will
// cause the SDK to overwrite the Transport's TLS config's RootCAs value.
//
// Setting a custom HTTPClient in the aws.Config options will override this
// setting. To use this option and custom HTTP client, the HTTP client
// needs to be provided when creating the config. Not the service client.
//
// ca_bundle=$HOME/my_custom_ca_bundle
CustomCABundle string
}

func (c SharedConfig) getDefaultsMode(ctx context.Context) (value aws.DefaultsMode, ok bool, err error) {
Expand Down Expand Up @@ -323,6 +346,19 @@ func (c SharedConfig) GetUseFIPSEndpoint(ctx context.Context) (value aws.FIPSEnd
return c.UseFIPSEndpoint, true, nil
}

// GetCustomCABundle returns the custom CA bundle's PEM bytes if the file was
func (c SharedConfig) getCustomCABundle(context.Context) (io.Reader, bool, error) {
if len(c.CustomCABundle) == 0 {
return nil, false, nil
}

b, err := ioutil.ReadFile(c.CustomCABundle)
if err != nil {
return nil, false, err
}
return bytes.NewReader(b), true, nil
}

// loadSharedConfigIgnoreNotExist is an alias for loadSharedConfig with the
// addition of ignoring when none of the files exist or when the profile
// is not found in any of the files.
Expand Down Expand Up @@ -871,6 +907,8 @@ func (c *SharedConfig) setFromIniSection(profile string, section ini.Section) er
return fmt.Errorf("failed to load %s from shared config, %w", retryModeKey, err)
}

updateString(&c.CustomCABundle, section, caBundleKey)

// Shared Credentials
creds := aws.Credentials{
AccessKeyID: section.String(accessKeyIDKey),
Expand Down
9 changes: 9 additions & 0 deletions config/shared_config_test.go
Expand Up @@ -574,6 +574,15 @@ func TestNewSharedConfig(t *testing.T) {
Profile: "retrywithinvalidattempts",
Err: fmt.Errorf("failed to load max_attempts from shared config, invalid value max_attempts=invalid, expect integer"),
},
"ca bundle options": {
ConfigFilenames: []string{testConfigFilename},
CredentialsFilenames: []string{testCredentialsFilename},
Profile: "with_ca_bundle",
Expected: SharedConfig{
Profile: "with_ca_bundle",
CustomCABundle: "custom_ca_bundle_file.pem",
},
},
"merged profiles across files": {
ConfigFilenames: []string{testConfigFilename},
CredentialsFilenames: []string{testCredentialsFilename},
Expand Down
3 changes: 3 additions & 0 deletions config/testdata/shared_config
Expand Up @@ -257,3 +257,6 @@ retry_mode = invalid

[profile retrywithinvalidattempts]
max_attempts = invalid

[profile with_ca_bundle]
ca_bundle = custom_ca_bundle_file.pem