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

Add proxy support #95

Merged
merged 3 commits into from
Nov 7, 2023
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions docs/data-sources/host.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,3 @@ data "opensearch_host" "test" {

- `id` (String) The ID of this resource.
- `url` (String) the url of the active cluster


1 change: 1 addition & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ EOF
- `insecure` (Boolean) Disable SSL verification of API calls
- `opensearch_version` (String) opensearch Version
- `password` (String) Password to use to connect to opensearch using basic auth
- `proxy` (String) Proxy URL to use for requests to opensearch.
- `sign_aws_requests` (Boolean) Enable signing of AWS opensearch requests. The `url` must refer to AWS ES domain (`*.<region>.es.amazonaws.com`), or `aws_region` must be specified explicitly.
- `sniff` (Boolean) Set the node sniffing option for the opensearch client. Client won't work with sniffing if nodes are not routable.
- `token` (String) A bearer token or ApiKey for an Authorization header, e.g. Active Directory API key.
Expand Down
2 changes: 0 additions & 2 deletions docs/resources/anomaly_detection.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,5 +78,3 @@ EOF
### Read-Only

- `id` (String) The ID of this resource.


2 changes: 0 additions & 2 deletions docs/resources/channel_configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,3 @@ Provides an OpenSearch channel configuration. Please refer to the OpenSearch cha
### Read-Only

- `id` (String) The ID of this resource.


2 changes: 0 additions & 2 deletions docs/resources/cluster_settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,5 +67,3 @@ resource "opensearch_cluster_settings" "global" {
### Read-Only

- `id` (String) The ID of this resource.


2 changes: 0 additions & 2 deletions docs/resources/dashboard_object.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,5 +106,3 @@ EOF
### Read-Only

- `id` (String) The ID of this resource.


2 changes: 0 additions & 2 deletions docs/resources/data_stream.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,3 @@ resource "opensearch_data_stream" "foo" {
### Read-Only

- `id` (String) The ID of this resource.


51 changes: 42 additions & 9 deletions provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ type ProviderConf struct {
certPemPath string
keyPemPath string
hostOverride string
proxy string
// determined after connecting to the server
flavor ServerFlavor
}
Expand Down Expand Up @@ -214,6 +215,11 @@ func Provider() *schema.Provider {
Default: "",
Description: "If provided, sets the 'Host' header of requests and the 'ServerName' for certificate validation to this value. See the documentation on connecting to opensearch via an SSH tunnel.",
},
"proxy": {
Type: schema.TypeString,
Optional: true,
Description: "Proxy URL to use for requests to opensearch.",
},
},

ResourcesMap: map[string]*schema.Resource{
Expand Down Expand Up @@ -280,6 +286,7 @@ func providerConfigure(c context.Context, d *schema.ResourceData) (interface{},
certPemPath: d.Get("client_cert_path").(string),
keyPemPath: d.Get("client_key_path").(string),
hostOverride: d.Get("host_override").(string),
proxy: d.Get("proxy").(string),
}, nil
}

Expand Down Expand Up @@ -457,20 +464,18 @@ func awsSession(region string, conf *ProviderConf, endpoint string) *awssession.
sessOpts.Profile = conf.awsProfile
}

transport := http.Transport{}
// If configured as insecure, turn off SSL verification
if conf.insecure {
client := &http.Client{Transport: &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}}
sessOpts.Config.HTTPClient = client
transport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
} else if conf.hostOverride != "" {
// Only use `host_override` to set `ServerName` if we're using a secure connection
client := &http.Client{Transport: &http.Transport{
TLSClientConfig: &tls.Config{ServerName: conf.hostOverride},
}}
sessOpts.Config.HTTPClient = client
transport.TLSClientConfig = &tls.Config{ServerName: conf.hostOverride}
}

client := &http.Client{Transport: &transport}
sessOpts.Config.HTTPClient = client

return awssession.Must(awssession.NewSessionWithOptions(sessOpts))
}

Expand All @@ -482,6 +487,17 @@ func awsHttpClient(region string, conf *ProviderConf, headers map[string]string)
if err != nil {
return nil, err
}

// Set the proxy URL after configuring AWS credentials since the proxy
// should be not used for credential sources that call a URL like ECS Task
// Roles or EC2 Instance Roles.
if conf.proxy != "" {
proxyURL, _ := url.Parse(conf.proxy)
transport, _ := session.Config.HTTPClient.Transport.(*http.Transport)
transport.Proxy = http.ProxyURL(proxyURL)
session.Config.HTTPClient.Transport = transport
}

signer := awssigv4.NewSigner(session.Config.Credentials)
client, err := aws_signing_client.New(signer, session.Config.HTTPClient, conf.awsSig4Service, region)
if err != nil {
Expand Down Expand Up @@ -509,6 +525,12 @@ func tokenHttpClient(conf *ProviderConf, headers map[string]string) *http.Client

// Wrapper to inject headers as needed
transport := &http.Transport{TLSClientConfig: tlsConfig}
// Configure a proxy URL if one is provided.
if conf.proxy != "" {
proxyURL, _ := url.Parse(conf.proxy)
transport.Proxy = http.ProxyURL(proxyURL)
}

rt := WithHeader(transport)
rt.hostOverride = conf.hostOverride
rt.Set("Authorization", fmt.Sprintf("%s %s", conf.tokenName, conf.token))
Expand Down Expand Up @@ -557,6 +579,11 @@ func tlsHttpClient(conf *ProviderConf, headers map[string]string) *http.Client {
}

transport := &http.Transport{TLSClientConfig: tlsConfig}
// Configure a proxy URL if one is provided.
if conf.proxy != "" {
proxyURL, _ := url.Parse(conf.proxy)
transport.Proxy = http.ProxyURL(proxyURL)
}

rt := WithHeader(transport)
rt.hostOverride = conf.hostOverride
Expand All @@ -578,8 +605,14 @@ func defaultHttpClient(conf *ProviderConf, headers map[string]string) *http.Clie
tlsConfig.ServerName = conf.hostOverride
}

// Wrapper to inject headers as needed
transport := &http.Transport{TLSClientConfig: tlsConfig}
// Configure a proxy URL if one is provided.
if conf.proxy != "" {
proxyURL, _ := url.Parse(conf.proxy)
transport.Proxy = http.ProxyURL(proxyURL)
}

// Wrapper to inject headers as needed
rt := WithHeader(transport)
rt.hostOverride = conf.hostOverride
for k, v := range headers {
Expand Down
23 changes: 23 additions & 0 deletions provider/provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,29 @@ func getCreds(t *testing.T, region string, config *ProviderConf, endpoint string
return creds
}

// Given:
// 1. A proxy URL is specified.
// 2. No additional AWS configuration is provided to the provider
//
// This tests that: the proxy value is set for the transport. Note we cannot get the credentials, because that requires connecting to AWS.
func TestAWSSocksProxy(t *testing.T) {
testRegion := "us-east-1"

testConfig := map[string]interface{}{
"proxy": "socks://127.0.0.1:8080",
}

testConfigData := schema.TestResourceDataRaw(t, Provider().Schema, testConfig)

conf := &ProviderConf{
proxy: testConfigData.Get("proxy").(string),
}
s := awsSession(testRegion, conf, "")
if s == nil {
t.Fatalf("awsSession returned nil")
}
}

type mockServer struct {
ResponseFixturePath string
ExpectedAccessKeyId string
Expand Down
Loading