Skip to content

Commit

Permalink
Add port/protocol for driver
Browse files Browse the repository at this point in the history
  • Loading branch information
Derek Rada committed Apr 7, 2022
1 parent 2f6fe43 commit b6f792a
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 17 deletions.
8 changes: 6 additions & 2 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,10 @@ provider "snowflake" {
oauth_redirect_url = "..."
// optional
role = "..."
host = "..."
role = "..."
host = "..."
protocol = "https"
port = 443
}
```

Expand All @@ -59,9 +61,11 @@ provider "snowflake" {
- **oauth_redirect_url** (String, Sensitive) Required when `oauth_refresh_token` is used. Can be sourced from `SNOWFLAKE_OAUTH_REDIRECT_URL` environment variable.
- **oauth_refresh_token** (String, Sensitive) Token for use with OAuth. Setup and generation of the token is left to other tools. Should be used in conjunction with `oauth_client_id`, `oauth_client_secret`, `oauth_endpoint`, `oauth_redirect_url`. Cannot be used with `browser_auth`, `private_key_path`, `oauth_access_token` or `password`. Can be sourced from `SNOWFLAKE_OAUTH_REFRESH_TOKEN` environment variable.
- **password** (String, Sensitive) Password for username+password auth. Cannot be used with `browser_auth` or `private_key_path`. Can be source from `SNOWFLAKE_PASSWORD` environment variable.
- **port** (Number) Support custom port values to snowflake go driver for use with privatelink. Can be sourced from `SNOWFLAKE_PORT` environment variable.
- **private_key** (String, Sensitive) Private Key for username+private-key auth. Cannot be used with `browser_auth` or `password`. Can be source from `SNOWFLAKE_PRIVATE_KEY` environment variable.
- **private_key_passphrase** (String, Sensitive) Supports the encryption ciphers aes-128-cbc, aes-128-gcm, aes-192-cbc, aes-192-gcm, aes-256-cbc, aes-256-gcm, and des-ede3-cbc
- **private_key_path** (String, Sensitive) Path to a private key for using keypair authentication. Cannot be used with `browser_auth`, `oauth_access_token` or `password`. Can be source from `SNOWFLAKE_PRIVATE_KEY_PATH` environment variable.
- **protocol** (String) Support custom protocols to snowflake go driver. Can be sourced from `SNOWFLAKE_PROTOCOL` environment variable.
- **region** (String) [Snowflake region](https://docs.snowflake.com/en/user-guide/intro-regions.html) to use. Can be source from the `SNOWFLAKE_REGION` environment variable.
- **role** (String) Snowflake role to use for operations. If left unset, default role for user will be used. Can come from the `SNOWFLAKE_ROLE` environment variable.

Expand Down
6 changes: 4 additions & 2 deletions examples/provider/provider.tf
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ provider "snowflake" {
oauth_redirect_url = "..."

// optional
role = "..."
host = "..."
role = "..."
host = "..."
protocol = "https"
port = 443
}
30 changes: 25 additions & 5 deletions pkg/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,18 @@ func Provider() *schema.Provider {
Optional: true,
DefaultFunc: schema.EnvDefaultFunc("SNOWFLAKE_HOST", nil),
},
"port": {
Type: schema.TypeInt,
Description: "Support custom port values to snowflake go driver for use with privatelink. Can be sourced from `SNOWFLAKE_PORT` environment variable.",
Optional: true,
DefaultFunc: schema.EnvDefaultFunc("SNOWFLAKE_PORT", 443),
},
"protocol": {
Type: schema.TypeString,
Description: "Support custom protocols to snowflake go driver. Can be sourced from `SNOWFLAKE_PROTOCOL` environment variable.",
Optional: true,
DefaultFunc: schema.EnvDefaultFunc("SNOWFLAKE_PROTOCOL", "https"),
},
},
ResourcesMap: getResources(),
DataSourcesMap: getDataSources(),
Expand Down Expand Up @@ -281,6 +293,8 @@ func ConfigureProvider(s *schema.ResourceData) (interface{}, error) {
oauthEndpoint := s.Get("oauth_endpoint").(string)
oauthRedirectURL := s.Get("oauth_redirect_url").(string)
host := s.Get("host").(string)
protocol := s.Get("protocol").(string)
port := s.Get("port").(int)

if oauthRefreshToken != "" {
accessToken, err := GetOauthAccessToken(oauthEndpoint, oauthClientID, oauthClientSecret, GetOauthData(oauthRefreshToken, oauthRedirectURL))
Expand All @@ -302,6 +316,8 @@ func ConfigureProvider(s *schema.ResourceData) (interface{}, error) {
region,
role,
host,
protocol,
port,
)
if err != nil {
return nil, errors.Wrap(err, "could not build dsn for snowflake connection")
Expand All @@ -326,7 +342,9 @@ func DSN(
oauthAccessToken,
region,
role,
host string) (string, error) {
host,
protocol string,
port int) (string, error) {

// us-west-2 is their default region, but if you actually specify that it won't trigger their default code
// https://github.com/snowflakedb/gosnowflake/blob/52137ce8c32eaf93b0bd22fc5c7297beff339812/dsn.go#L61
Expand All @@ -335,10 +353,12 @@ func DSN(
}

config := gosnowflake.Config{
Account: account,
User: user,
Region: region,
Role: role,
Account: account,
User: user,
Region: region,
Role: role,
Port: port,
Protocol: protocol,
}

// If host is set trust it and do not use the region value
Expand Down
18 changes: 10 additions & 8 deletions pkg/provider/provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,26 +34,28 @@ func TestDSN(t *testing.T) {
browserAuth bool
region,
role,
host string
host,
protocol string
port int
}
tests := []struct {
name string
args args
want string
wantErr bool
}{
{"simple", args{"acct", "user", "pass", false, "region", "role", ""},
{"simple", args{"acct", "user", "pass", false, "region", "role", "", "https", 443},
"user:[email protected]:443?ocspFailOpen=true&region=region&role=role&validateDefaultParameters=true", false},
{"us-west-2 special case", args{"acct2", "user2", "pass2", false, "us-west-2", "role2", ""},
{"us-west-2 special case", args{"acct2", "user2", "pass2", false, "us-west-2", "role2", "", "https", 443},
"user2:[email protected]:443?ocspFailOpen=true&role=role2&validateDefaultParameters=true", false},
{"customhostwregion", args{"acct3", "user3", "pass3", false, "", "role3", "zha123.us-east-1.privatelink.snowflakecomputing.com"},
{"customhostwregion", args{"acct3", "user3", "pass3", false, "", "role3", "zha123.us-east-1.privatelink.snowflakecomputing.com", "https", 443},
"user3:[email protected]:443?account=acct3&ocspFailOpen=true&role=role3&validateDefaultParameters=true", false},
{"customhostignoreregion", args{"acct4", "user4", "pass4", false, "fakeregion", "role4", "zha1234.us-east-1.privatelink.snowflakecomputing.com"},
"user4:[email protected]:443?account=acct4&ocspFailOpen=true&role=role4&validateDefaultParameters=true", false},
{"customhostignoreregion", args{"acct4", "user4", "pass4", false, "fakeregion", "role4", "zha1234.us-east-1.privatelink.snowflakecomputing.com", "http", 8443},
"user4:[email protected]:8443?account=acct4&ocspFailOpen=true&protocol=http&role=role4&validateDefaultParameters=true", false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := provider.DSN(tt.args.account, tt.args.user, tt.args.password, tt.args.browserAuth, "", "", "", "", tt.args.region, tt.args.role, tt.args.host)
got, err := provider.DSN(tt.args.account, tt.args.user, tt.args.password, tt.args.browserAuth, "", "", "", "", tt.args.region, tt.args.role, tt.args.host, tt.args.protocol, tt.args.port)
if (err != nil) != tt.wantErr {
t.Errorf("DSN() error = %v, wantErr %v", err, tt.wantErr)
return
Expand Down Expand Up @@ -89,7 +91,7 @@ func TestOAuthDSN(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := provider.DSN(tt.args.account, tt.args.user, "", false, "", "", "", tt.args.oauthAccessToken, tt.args.region, tt.args.role, "")
got, err := provider.DSN(tt.args.account, tt.args.user, "", false, "", "", "", tt.args.oauthAccessToken, tt.args.region, tt.args.role, "", "https", 443)

if (err != nil) != tt.wantErr {
t.Errorf("DSN() error = %v, dsn = %v, wantErr %v", err, got, tt.wantErr)
Expand Down

0 comments on commit b6f792a

Please sign in to comment.