Skip to content

Commit

Permalink
Adding example for rdsutils and also adding scheme if one wasn't prov…
Browse files Browse the repository at this point in the history
…ided when creating authentication tokens
  • Loading branch information
xibz committed May 9, 2017
1 parent 5407208 commit 4acf213
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 12 deletions.
15 changes: 15 additions & 0 deletions example/service/rds/rdsutils/authentication/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Example

This is an example using the AWS SDK for Go to create an Amazon RDS DB token using the
rdsutils package.

# Usage

```sh
go run iam_authetnication.go <region> <db user> <db name> <endpoint to database> <iam arn>
```

Output:
```
Successfully opened connection to database
```
45 changes: 45 additions & 0 deletions example/service/rds/rdsutils/authentication/iam_authentication.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package main

import (
"database/sql"
"fmt"
"log"
"os"

"github.com/go-sql-driver/mysql"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/credentials/stscreds"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/rds/rdsutils"
)

// Usage ./iam_authentication <region> <db user> <db name> <endpoint to database> <iam arn>
func main() {
if len(os.Args) < 5 {
log.Println("USAGE ERROR: go run concatenateObjects.go <region> <endpoint to database> <iam arn>")
os.Exit(1)
}

awsRegion := os.Args[1]
dbUser := os.Args[2]
dbName := os.Args[3]
dbEndpoint := os.Args[4]
awsCreds := stscreds.NewCredentials(session.New(&aws.Config{Region: &awsRegion}), os.Args[5])
authToken, err := rdsutils.BuildAuthToken(dbEndpoint, awsRegion, dbUser, awsCreds)

// Create the MySQL DNS string for the DB connection
// user:password@protocol(endpoint)/dbname?<params>
dnsStr := fmt.Sprintf("%s:%s@tcp(%s)/%s?tls=true",
dbUser, authToken, dbEndpoint, dbName,
)

driver := mysql.MySQLDriver{}
_ = driver
// Use db to perform SQL operations on database
if _, err = sql.Open("mysql", dnsStr); err != nil {
panic(err)
}

fmt.Println("Successfully opened connection to database")
}
14 changes: 9 additions & 5 deletions service/rds/rdsutils/connect.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,10 @@ import (
// BuildAuthToken will return a authentication token for the database's connect
// based on the RDS database endpoint, AWS region, IAM user or role, and AWS credentials.
//
// Endpoint consists of the scheme, hostname, and port. IE scheme://{hostname}[:port]
// of the RDS database. Region is the AWS region the RDS database is in and where
// the authentication token will be generated for. DbUser is the IAM user or role
// the request will be authenticated for. The creds is the AWS credentials
// the authentication token is signed with.
// Endpoint consists of the hostname and port, IE hostname:port, of the RDS database.
// Region is the AWS region the RDS database is in and where the authentication token
// will be generated for. DbUser is the IAM user or role the request will be authenticated
// for. The creds is the AWS credentials the authentication token is signed with.
//
// An error is returned if the authentication token is unable to be signed with
// the credentials, or the endpoint is not a valid URL.
Expand All @@ -38,6 +37,11 @@ import (
// See http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.html
// for more information on using IAM database authentication with RDS.
func BuildAuthToken(endpoint, region, dbUser string, creds *credentials.Credentials) (string, error) {
// the scheme is arbitrary and is only needed because validation of the URL requires one.
if !(strings.HasPrefix(endpoint, "http://") || strings.HasPrefix(endpoint, "https://")) {
endpoint = "https://" + endpoint
}

req, err := http.NewRequest("GET", endpoint, nil)
if err != nil {
return "", err
Expand Down
32 changes: 25 additions & 7 deletions service/rds/rdsutils/connect_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,30 @@ import (
)

func TestBuildAuthToken(t *testing.T) {
endpoint := "https://prod-instance.us-east-1.rds.amazonaws.com:3306"
region := "us-west-2"
creds := credentials.NewStaticCredentials("AKID", "SECRET", "SESSION")
user := "mysqlUser"
cases := []struct {
endpoint string
region string
user string
expectedRegex string
}{
{
"https://prod-instance.us-east-1.rds.amazonaws.com:3306",
"us-west-2",
"mysqlUser",
`^prod-instance\.us-east-1\.rds\.amazonaws\.com:3306\?Action=connect.*?DBUser=mysqlUser.*`,
},
{
"prod-instance.us-east-1.rds.amazonaws.com:3306",
"us-west-2",
"mysqlUser",
`^prod-instance\.us-east-1\.rds\.amazonaws\.com:3306\?Action=connect.*?DBUser=mysqlUser.*`,
},
}

url, err := rdsutils.BuildAuthToken(endpoint, region, user, creds)
assert.NoError(t, err)
assert.Regexp(t, `^prod-instance\.us-east-1\.rds\.amazonaws\.com:3306\?Action=connect.*?DBUser=mysqlUser.*`, url)
for _, c := range cases {
creds := credentials.NewStaticCredentials("AKID", "SECRET", "SESSION")
url, err := rdsutils.BuildAuthToken(c.endpoint, c.region, c.user, creds)
assert.NoError(t, err)
assert.Regexp(t, c.expectedRegex, url)
}
}

0 comments on commit 4acf213

Please sign in to comment.