From 57cf97db6a846b31cc2ff0b2858a02eb9a414405 Mon Sep 17 00:00:00 2001 From: Gregory Reshetniak Date: Wed, 4 Oct 2017 11:28:00 +0200 Subject: [PATCH 1/4] added AWS enpoint handling --- builtin/logical/aws/client.go | 11 +++++++++++ builtin/logical/aws/path_config_root.go | 11 +++++++++++ helper/awsutil/generate_credentials.go | 3 +++ 3 files changed, 25 insertions(+) diff --git a/builtin/logical/aws/client.go b/builtin/logical/aws/client.go index f6bbbe2e521a..05b8372a65c9 100644 --- a/builtin/logical/aws/client.go +++ b/builtin/logical/aws/client.go @@ -29,6 +29,7 @@ func getRootConfig(s logical.Storage) (*aws.Config, error) { credsConfig.AccessKey = config.AccessKey credsConfig.SecretKey = config.SecretKey credsConfig.Region = config.Region + credsConfig.Endpoint = config.Endpoint } if credsConfig.Region == "" { @@ -51,6 +52,7 @@ func getRootConfig(s logical.Storage) (*aws.Config, error) { return &aws.Config{ Credentials: creds, Region: aws.String(credsConfig.Region), + Endpoint: aws.String(credsConfig.Endpoint), HTTPClient: cleanhttp.DefaultClient(), }, nil } @@ -60,7 +62,13 @@ func clientIAM(s logical.Storage) (*iam.IAM, error) { if err != nil { return nil, err } + client := iam.New(session.New(awsConfig)) + + if *awsConfig.Endpoint != "none" { + client = iam.New(session.New(awsConfig.WithEndpoint(*awsConfig.Endpoint))) + } + if client == nil { return nil, fmt.Errorf("could not obtain iam client") } @@ -73,6 +81,9 @@ func clientSTS(s logical.Storage) (*sts.STS, error) { return nil, err } client := sts.New(session.New(awsConfig)) + if *awsConfig.Endpoint != "none" { + client = sts.New(session.New(awsConfig.WithEndpoint(*awsConfig.Endpoint))) + } if client == nil { return nil, fmt.Errorf("could not obtain sts client") } diff --git a/builtin/logical/aws/path_config_root.go b/builtin/logical/aws/path_config_root.go index 754e5b2a4318..aa083f29566c 100644 --- a/builtin/logical/aws/path_config_root.go +++ b/builtin/logical/aws/path_config_root.go @@ -23,6 +23,10 @@ func pathConfigRoot() *framework.Path { Type: framework.TypeString, Description: "Region for API calls.", }, + "endpoint": &framework.FieldSchema{ + Type: framework.TypeString, + Description: "Endpoint to custom IAM server URL", + }, }, Callbacks: map[logical.Operation]framework.OperationFunc{ @@ -37,10 +41,16 @@ func pathConfigRoot() *framework.Path { func pathConfigRootWrite( req *logical.Request, data *framework.FieldData) (*logical.Response, error) { region := data.Get("region").(string) + endpoint := data.Get("endpoint").(string) + + if endpoint == "" { + endpoint = "none" + } entry, err := logical.StorageEntryJSON("config/root", rootConfig{ AccessKey: data.Get("access_key").(string), SecretKey: data.Get("secret_key").(string), + Endpoint: endpoint, Region: region, }) if err != nil { @@ -57,6 +67,7 @@ func pathConfigRootWrite( type rootConfig struct { AccessKey string `json:"access_key"` SecretKey string `json:"secret_key"` + Endpoint string `json:"endpoint"` Region string `json:"region"` } diff --git a/helper/awsutil/generate_credentials.go b/helper/awsutil/generate_credentials.go index 6b1896832989..fe32f94d595d 100644 --- a/helper/awsutil/generate_credentials.go +++ b/helper/awsutil/generate_credentials.go @@ -24,6 +24,9 @@ type CredentialsConfig struct { // the client elsewhere. Region string + //Endpoint to custom IAM server URL + Endpoint string + // The filename for the shared credentials provider, if being used Filename string From c8c9de233a1fd2ce4975cd6da5400eaa02ebf1ba Mon Sep 17 00:00:00 2001 From: Gregory Reshetniak Date: Wed, 4 Oct 2017 21:24:30 +0200 Subject: [PATCH 2/4] added separate STS/IAM endpoints --- builtin/logical/aws/client.go | 14 ++++++----- builtin/logical/aws/path_config_root.go | 31 ++++++++++++++----------- helper/awsutil/generate_credentials.go | 5 +++- 3 files changed, 29 insertions(+), 21 deletions(-) diff --git a/builtin/logical/aws/client.go b/builtin/logical/aws/client.go index 05b8372a65c9..c8953fe1649d 100644 --- a/builtin/logical/aws/client.go +++ b/builtin/logical/aws/client.go @@ -29,7 +29,8 @@ func getRootConfig(s logical.Storage) (*aws.Config, error) { credsConfig.AccessKey = config.AccessKey credsConfig.SecretKey = config.SecretKey credsConfig.Region = config.Region - credsConfig.Endpoint = config.Endpoint + credsConfig.IAMEndpoint = config.IAMEndpoint + credsConfig.STSEndpoint = config.STSEndpoint } if credsConfig.Region == "" { @@ -52,7 +53,8 @@ func getRootConfig(s logical.Storage) (*aws.Config, error) { return &aws.Config{ Credentials: creds, Region: aws.String(credsConfig.Region), - Endpoint: aws.String(credsConfig.Endpoint), + IAMEndpoint: aws.String(credsConfig.IAMEndpoint), + STSEndpoint: aws.String(credsConfig.STSEndpoint), HTTPClient: cleanhttp.DefaultClient(), }, nil } @@ -65,8 +67,8 @@ func clientIAM(s logical.Storage) (*iam.IAM, error) { client := iam.New(session.New(awsConfig)) - if *awsConfig.Endpoint != "none" { - client = iam.New(session.New(awsConfig.WithEndpoint(*awsConfig.Endpoint))) + if *awsConfig.IAMEndpoint != "" { + client = iam.New(session.New(awsConfig.WithEndpoint(*awsConfig.IAMEndpoint))) } if client == nil { @@ -81,8 +83,8 @@ func clientSTS(s logical.Storage) (*sts.STS, error) { return nil, err } client := sts.New(session.New(awsConfig)) - if *awsConfig.Endpoint != "none" { - client = sts.New(session.New(awsConfig.WithEndpoint(*awsConfig.Endpoint))) + if *awsConfig.STSEndpoint != "" { + client = sts.New(session.New(awsConfig.WithEndpoint(*awsConfig.STSEndpoint))) } if client == nil { return nil, fmt.Errorf("could not obtain sts client") diff --git a/builtin/logical/aws/path_config_root.go b/builtin/logical/aws/path_config_root.go index aa083f29566c..31baf5838f5b 100644 --- a/builtin/logical/aws/path_config_root.go +++ b/builtin/logical/aws/path_config_root.go @@ -23,10 +23,14 @@ func pathConfigRoot() *framework.Path { Type: framework.TypeString, Description: "Region for API calls.", }, - "endpoint": &framework.FieldSchema{ + "iamendpoint": &framework.FieldSchema{ Type: framework.TypeString, Description: "Endpoint to custom IAM server URL", }, + "stsendpoint": &framework.FieldSchema{ + Type: framework.TypeString, + Description: "Endpoint to custom STS server URL", + }, }, Callbacks: map[logical.Operation]framework.OperationFunc{ @@ -41,17 +45,15 @@ func pathConfigRoot() *framework.Path { func pathConfigRootWrite( req *logical.Request, data *framework.FieldData) (*logical.Response, error) { region := data.Get("region").(string) - endpoint := data.Get("endpoint").(string) - - if endpoint == "" { - endpoint = "none" - } + iamendpoint := data.Get("iamendpoint").(string) + stsendpoint := data.Get("stsendpoint").(string) entry, err := logical.StorageEntryJSON("config/root", rootConfig{ - AccessKey: data.Get("access_key").(string), - SecretKey: data.Get("secret_key").(string), - Endpoint: endpoint, - Region: region, + AccessKey: data.Get("access_key").(string), + SecretKey: data.Get("secret_key").(string), + IAMEndpoint: iamendpoint, + STSEndpoint: stsendpoint, + Region: region, }) if err != nil { return nil, err @@ -65,10 +67,11 @@ func pathConfigRootWrite( } type rootConfig struct { - AccessKey string `json:"access_key"` - SecretKey string `json:"secret_key"` - Endpoint string `json:"endpoint"` - Region string `json:"region"` + AccessKey string `json:"access_key"` + SecretKey string `json:"secret_key"` + IAMEndpoint string `json:"iamendpoint"` + STSEndpoint string `json:"stsendpoint"` + Region string `json:"region"` } const pathConfigRootHelpSyn = ` diff --git a/helper/awsutil/generate_credentials.go b/helper/awsutil/generate_credentials.go index fe32f94d595d..773e3283f35b 100644 --- a/helper/awsutil/generate_credentials.go +++ b/helper/awsutil/generate_credentials.go @@ -25,7 +25,10 @@ type CredentialsConfig struct { Region string //Endpoint to custom IAM server URL - Endpoint string + IAMEndpoint string + + //Endpoint to custom STS server URL + STSEndpoint string // The filename for the shared credentials provider, if being used Filename string From 77627200e657d457c05797c365661128c501b56c Mon Sep 17 00:00:00 2001 From: Gregory Reshetniak Date: Fri, 6 Oct 2017 11:37:07 +0200 Subject: [PATCH 3/4] added clientType to getRootConfig --- builtin/logical/aws/client.go | 26 ++++++++++++------------- builtin/logical/aws/path_config_root.go | 12 ++++++------ helper/awsutil/generate_credentials.go | 6 ------ 3 files changed, 18 insertions(+), 26 deletions(-) diff --git a/builtin/logical/aws/client.go b/builtin/logical/aws/client.go index c8953fe1649d..3702f75aa6c4 100644 --- a/builtin/logical/aws/client.go +++ b/builtin/logical/aws/client.go @@ -13,8 +13,9 @@ import ( "github.com/hashicorp/vault/logical" ) -func getRootConfig(s logical.Storage) (*aws.Config, error) { +func getRootConfig(s logical.Storage, clientType string) (*aws.Config, error) { credsConfig := &awsutil.CredentialsConfig{} + var endpoint string entry, err := s.Get("config/root") if err != nil { @@ -29,8 +30,12 @@ func getRootConfig(s logical.Storage) (*aws.Config, error) { credsConfig.AccessKey = config.AccessKey credsConfig.SecretKey = config.SecretKey credsConfig.Region = config.Region - credsConfig.IAMEndpoint = config.IAMEndpoint - credsConfig.STSEndpoint = config.STSEndpoint + switch { + case clientType == "iam" && config.IAMEndpoint != "": + endpoint = *aws.String(config.IAMEndpoint) + case clientType == "sts" && config.STSEndpoint != "": + endpoint = *aws.String(config.STSEndpoint) + } } if credsConfig.Region == "" { @@ -53,24 +58,19 @@ func getRootConfig(s logical.Storage) (*aws.Config, error) { return &aws.Config{ Credentials: creds, Region: aws.String(credsConfig.Region), - IAMEndpoint: aws.String(credsConfig.IAMEndpoint), - STSEndpoint: aws.String(credsConfig.STSEndpoint), + Endpoint: &endpoint, HTTPClient: cleanhttp.DefaultClient(), }, nil } func clientIAM(s logical.Storage) (*iam.IAM, error) { - awsConfig, err := getRootConfig(s) + awsConfig, err := getRootConfig(s, "iam") if err != nil { return nil, err } client := iam.New(session.New(awsConfig)) - if *awsConfig.IAMEndpoint != "" { - client = iam.New(session.New(awsConfig.WithEndpoint(*awsConfig.IAMEndpoint))) - } - if client == nil { return nil, fmt.Errorf("could not obtain iam client") } @@ -78,14 +78,12 @@ func clientIAM(s logical.Storage) (*iam.IAM, error) { } func clientSTS(s logical.Storage) (*sts.STS, error) { - awsConfig, err := getRootConfig(s) + awsConfig, err := getRootConfig(s, "sts") if err != nil { return nil, err } client := sts.New(session.New(awsConfig)) - if *awsConfig.STSEndpoint != "" { - client = sts.New(session.New(awsConfig.WithEndpoint(*awsConfig.STSEndpoint))) - } + if client == nil { return nil, fmt.Errorf("could not obtain sts client") } diff --git a/builtin/logical/aws/path_config_root.go b/builtin/logical/aws/path_config_root.go index 31baf5838f5b..b85015c7492e 100644 --- a/builtin/logical/aws/path_config_root.go +++ b/builtin/logical/aws/path_config_root.go @@ -23,11 +23,11 @@ func pathConfigRoot() *framework.Path { Type: framework.TypeString, Description: "Region for API calls.", }, - "iamendpoint": &framework.FieldSchema{ + "iam_endpoint": &framework.FieldSchema{ Type: framework.TypeString, Description: "Endpoint to custom IAM server URL", }, - "stsendpoint": &framework.FieldSchema{ + "sts_endpoint": &framework.FieldSchema{ Type: framework.TypeString, Description: "Endpoint to custom STS server URL", }, @@ -45,8 +45,8 @@ func pathConfigRoot() *framework.Path { func pathConfigRootWrite( req *logical.Request, data *framework.FieldData) (*logical.Response, error) { region := data.Get("region").(string) - iamendpoint := data.Get("iamendpoint").(string) - stsendpoint := data.Get("stsendpoint").(string) + iamendpoint := data.Get("iam_endpoint").(string) + stsendpoint := data.Get("sts_endpoint").(string) entry, err := logical.StorageEntryJSON("config/root", rootConfig{ AccessKey: data.Get("access_key").(string), @@ -69,8 +69,8 @@ func pathConfigRootWrite( type rootConfig struct { AccessKey string `json:"access_key"` SecretKey string `json:"secret_key"` - IAMEndpoint string `json:"iamendpoint"` - STSEndpoint string `json:"stsendpoint"` + IAMEndpoint string `json:"iam_endpoint"` + STSEndpoint string `json:"sts_endpoint"` Region string `json:"region"` } diff --git a/helper/awsutil/generate_credentials.go b/helper/awsutil/generate_credentials.go index 773e3283f35b..6b1896832989 100644 --- a/helper/awsutil/generate_credentials.go +++ b/helper/awsutil/generate_credentials.go @@ -24,12 +24,6 @@ type CredentialsConfig struct { // the client elsewhere. Region string - //Endpoint to custom IAM server URL - IAMEndpoint string - - //Endpoint to custom STS server URL - STSEndpoint string - // The filename for the shared credentials provider, if being used Filename string From db384627fdbb76248c4191f58d604af359ff6d14 Mon Sep 17 00:00:00 2001 From: Gregory Reshetniak Date: Tue, 24 Oct 2017 10:00:29 +0200 Subject: [PATCH 4/4] added docs --- website/source/api/secret/aws/index.html.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/website/source/api/secret/aws/index.html.md b/website/source/api/secret/aws/index.html.md index 825604bc58b6..dc8f04bdc43f 100644 --- a/website/source/api/secret/aws/index.html.md +++ b/website/source/api/secret/aws/index.html.md @@ -52,6 +52,10 @@ valid AWS credentials with proper permissions. will use the `AWS_REGION` env var, `AWS_DEFAULT_REGION` env var, or `us-east-1` in that order. +- `iam_endpoint` `(string: )` – Specifies a custom HTTP IAM endpoint to use. + +- `sts_endpoint` `(string: )` – Specifies a custom HTTP STS endpoint to use. + ### Sample Payload ```json