Skip to content

Commit

Permalink
Merge pull request #217 from aka-bo/go-dynamodb-updates
Browse files Browse the repository at this point in the history
[Go] DynamoDB config updates
  • Loading branch information
nikoo28 authored Jun 10, 2020
2 parents 1352279 + eac7e21 commit b9b27b5
Show file tree
Hide file tree
Showing 9 changed files with 70 additions and 25 deletions.
2 changes: 1 addition & 1 deletion go/appencryption/.versionfile
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.1.1
0.1.2
39 changes: 25 additions & 14 deletions go/appencryption/pkg/persistence/dynamodb.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ import (
)

const (
tableName = "EncryptionKey"
partitionKey = "Id"
sortKey = "Created"
keyRecord = "KeyRecord"
defaultTableName = "EncryptionKey"
partitionKey = "Id"
sortKey = "Created"
keyRecord = "KeyRecord"
)

var (
Expand All @@ -39,13 +39,14 @@ var (

// DynamoDBMetastore implements the Metastore interface.
type DynamoDBMetastore struct {
svc dynamodbiface.DynamoDBAPI
keySuffix string
svc dynamodbiface.DynamoDBAPI
regionSuffix string
tableName string
}

// GetSuffix returns the DynamoDB region suffix or blank if not configured.
func (d *DynamoDBMetastore) GetSuffix() string {
return d.keySuffix
// GetRegionSuffix returns the DynamoDB region suffix or blank if not configured.
func (d *DynamoDBMetastore) GetRegionSuffix() string {
return d.regionSuffix
}

// DynamoDBMetastoreOption is used to configure additional options in a DynamoDBMetastore.
Expand All @@ -58,14 +59,24 @@ func WithDynamoDBRegionSuffix(enabled bool) DynamoDBMetastoreOption {
return func(d *DynamoDBMetastore, p client.ConfigProvider) {
if enabled {
config := p.ClientConfig(dynamodb.EndpointsID)
d.keySuffix = *config.Config.Region
d.regionSuffix = *config.Config.Region
}
}
}

// WithTableName configures the DynamoDBMetastore to use the specified table name.
func WithTableName(table string) DynamoDBMetastoreOption {
return func(d *DynamoDBMetastore, p client.ConfigProvider) {
if len(table) > 0 {
d.tableName = table
}
}
}

func NewDynamoDBMetastore(sess client.ConfigProvider, opts ...DynamoDBMetastoreOption) *DynamoDBMetastore {
d := &DynamoDBMetastore{
svc: dynamodb.New(sess),
svc: dynamodb.New(sess),
tableName: defaultTableName,
}

for _, opt := range opts {
Expand Down Expand Up @@ -103,7 +114,7 @@ func (d *DynamoDBMetastore) Load(ctx context.Context, keyID string, created int6
sortKey: {N: aws.String(strconv.FormatInt(created, 10))},
},
ProjectionExpression: expr.Projection(),
TableName: aws.String(tableName),
TableName: aws.String(d.tableName),
ConsistentRead: aws.Bool(true), // always use strong consistency
})

Expand Down Expand Up @@ -140,7 +151,7 @@ func (d *DynamoDBMetastore) LoadLatest(ctx context.Context, keyID string) (*appe
Limit: aws.Int64(1), // limit 1
ProjectionExpression: expr.Projection(),
ScanIndexForward: aws.Bool(false), // sorts descending
TableName: aws.String(tableName),
TableName: aws.String(d.tableName),
})
if err != nil {
return nil, err
Expand Down Expand Up @@ -190,7 +201,7 @@ func (d *DynamoDBMetastore) Store(ctx context.Context, keyID string, created int
sortKey: {N: aws.String(strconv.FormatInt(created, 10))},
keyRecord: {M: av},
},
TableName: aws.String(tableName),
TableName: aws.String(d.tableName),
ConditionExpression: aws.String("attribute_not_exists(" + partitionKey + ")"),
})
if err != nil {
Expand Down
20 changes: 17 additions & 3 deletions go/appencryption/pkg/persistence/dynamodb_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ type DynamoDBSuite struct {
}

const (
tableName = "CustomTableName"
portProtocolDynamoDB = "8000/tcp"
maxTriesDynamoDB = 5
waitTimeDynamoDB = 10
Expand Down Expand Up @@ -172,7 +173,7 @@ func (suite *DynamoDBSuite) SetupTest() {
}
suite.putItemInDynamoDB(getDynamoDBItem(en, suite.instant))

suite.dynamodbMetastore = NewDynamoDBMetastore(suite.sess)
suite.dynamodbMetastore = NewDynamoDBMetastore(suite.sess, WithTableName(tableName))
suite.prefixedDynamodbMetastore = NewDynamoDBMetastore(suite.sess, WithDynamoDBRegionSuffix(true))
}

Expand Down Expand Up @@ -339,10 +340,23 @@ func (suite *DynamoDBSuite) TestDynamoDBMetastore_Store_WithFailureShouldReturnE

func (suite *DynamoDBSuite) TestDynamoDBMetastore_WithDynamoDBRegionSuffix() {
// keyPrefix should be empty unless WithDynamoDBRegionSuffix is used
assert.Empty(suite.T(), suite.dynamodbMetastore.keySuffix)
assert.Empty(suite.T(), suite.dynamodbMetastore.GetRegionSuffix())

// WithDynamoDBRegionSuffix should set the keyPrefix equal to the client's region
assert.Equal(suite.T(), *suite.sess.Config.Region, suite.prefixedDynamodbMetastore.keySuffix)
assert.Equal(suite.T(), *suite.sess.Config.Region, suite.prefixedDynamodbMetastore.GetRegionSuffix())
}

func (suite *DynamoDBSuite) TestDynamoDBMetastore_WithTableName() {
table := "DummyTable"
db := NewDynamoDBMetastore(suite.sess, WithTableName(table))

assert.Equal(suite.T(), table, db.tableName)
}

func (suite *DynamoDBSuite) TestDynamoDBMetastore_DefaultTableName() {
db := NewDynamoDBMetastore(suite.sess)

assert.Equal(suite.T(), defaultTableName, db.tableName)
}

func TestDynamoSuite(t *testing.T) {
Expand Down
4 changes: 2 additions & 2 deletions go/appencryption/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ func (f *SessionFactory) GetSession(id string) (*Session, error) {
}

var p partition
if v, ok := f.Metastore.(interface{ GetSuffix() string }); ok && len(v.GetSuffix()) > 0 {
p = newSuffixedPartition(id, f.Config.Service, f.Config.Product, v.GetSuffix())
if v, ok := f.Metastore.(interface{ GetRegionSuffix() string }); ok && len(v.GetRegionSuffix()) > 0 {
p = newSuffixedPartition(id, f.Config.Service, f.Config.Product, v.GetRegionSuffix())
} else {
p = newPartition(id, f.Config.Service, f.Config.Product)
}
Expand Down
6 changes: 3 additions & 3 deletions go/appencryption/session_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ type MockDynamoDBMetastore struct {
*MockMetastore
}

func (m *MockDynamoDBMetastore) GetSuffix() string {
func (m *MockDynamoDBMetastore) GetRegionSuffix() string {
args := m.Called()
return args.String(0)
}
Expand All @@ -299,7 +299,7 @@ func TestSessionFactory_GetSession_DefaultPartition(t *testing.T) {

func TestSessionFactory_GetSession_SuffixedPartition(t *testing.T) {
store := &MockDynamoDBMetastore{MockMetastore: new(MockMetastore)}
store.On("GetSuffix").Return("suffix")
store.On("GetRegionSuffix").Return("suffix")

factory := NewSessionFactory(new(Config), store, nil, nil)

Expand All @@ -313,7 +313,7 @@ func TestSessionFactory_GetSession_SuffixedPartition(t *testing.T) {

func TestSessionFactory_GetSession_Blank_GetSuffix_DefaultPartition(t *testing.T) {
store := &MockDynamoDBMetastore{MockMetastore: new(MockMetastore)}
store.On("GetSuffix").Return("")
store.On("GetRegionSuffix").Return("")

factory := NewSessionFactory(new(Config), store, nil, nil)

Expand Down
4 changes: 4 additions & 0 deletions server/go/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ Asherah Options:
[$ASHERAH_CONNECTION_STRING]
--enable-region-suffix Configure the metastore to use regional suffixes (only supported by
--metastore=dynamodb) [$ASHERAH_ENABLE_REGION_SUFFIX]
--dynamodb-endpoint= An optional endpoint URL (hostname only or fully qualified URI) (only
supported by --metastore=dynamodb) [$ASHERAH_DYNAMODB_ENDPOINT]
--dynamodb-region= The AWS region for DynamoDB requests (defaults to globally configured region)
(only supported by --metastore=dynamodb) [$ASHERAH_DYNAMODB_REGION]
--kms=[aws|static] Configures the master key management service (default: aws)
[$ASHERAH_KMS_MODE]
--region-map= A comma separated list of key-value pairs in the form of
Expand Down
2 changes: 2 additions & 0 deletions server/go/pkg/server/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ type Options struct {
Metastore string `long:"metastore" choice:"rdbms" choice:"dynamodb" choice:"memory" required:"yes" description:"Determines the type of metastore to use for persisting keys" env:"ASHERAH_METASTORE_MODE"`
ConnectionString string `long:"conn" description:"The database connection string (required if --metastore=rdbms)" env:"ASHERAH_CONNECTION_STRING"`
EnableRegionSuffix bool `long:"enable-region-suffix" description:"Configure the metastore to use regional suffixes (only supported by --metastore=dynamodb)" env:"ASHERAH_ENABLE_REGION_SUFFIX"`
DynamoDBEndpoint string `long:"dynamodb-endpoint" description:"An optional endpoint URL (hostname only or fully qualified URI) (only supported by --metastore=dynamodb)" env:"ASHERAH_DYNAMODB_ENDPOINT"`
DynamoDBRegion string `long:"dynamodb-region" description:"The AWS region for DynamoDB requests (defaults to globally configured region) (only supported by --metastore=dynamodb)" env:"ASHERAH_DYNAMODB_REGION"`
KMS string `long:"kms" choice:"aws" choice:"static" default:"aws" description:"Configures the master key management service" env:"ASHERAH_KMS_MODE"`
RegionMap RegionMap `long:"region-map" description:"A comma separated list of key-value pairs in the form of REGION1=ARN1[,REGION2=ARN2] (required if --kms=aws)" env:"ASHERAH_REGION_MAP"`
PreferredRegion string `long:"preferred-region" description:"The preferred AWS region (required if --kms=aws)" env:"ASHERAH_PREFERRED_REGION"`
Expand Down
15 changes: 13 additions & 2 deletions server/go/pkg/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"io"
"log"

"github.com/aws/aws-sdk-go/aws"
awssession "github.com/aws/aws-sdk-go/aws/session"
"github.com/godaddy/asherah/go/appencryption"
"github.com/godaddy/asherah/go/appencryption/pkg/crypto/aead"
Expand Down Expand Up @@ -105,9 +106,19 @@ func NewMetastore(opts *Options) appencryption.Metastore {

return persistence.NewSQLMetastore(db)
case "dynamodb":
sess := awssession.Must(awssession.NewSessionWithOptions(awssession.Options{
awsOpts := awssession.Options{
SharedConfigState: awssession.SharedConfigEnable,
}))
}

if len(opts.DynamoDBEndpoint) > 0 {
awsOpts.Config.Endpoint = aws.String(opts.DynamoDBEndpoint)
}

if len(opts.DynamoDBRegion) > 0 {
awsOpts.Config.Region = aws.String(opts.DynamoDBRegion)
}

sess := awssession.Must(awssession.NewSessionWithOptions(awsOpts))

return persistence.NewDynamoDBMetastore(sess, persistence.WithDynamoDBRegionSuffix(opts.EnableRegionSuffix))
default:
Expand Down
3 changes: 3 additions & 0 deletions server/go/pkg/server/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,10 @@ func Test_Streamer_NewHandler(t *testing.T) {
optCombos := []*Options{
{KMS: "aws", Metastore: "rdbms"},
{KMS: "aws", Metastore: "dynamodb"},
{KMS: "aws", Metastore: "dynamodb", DynamoDBRegion: "us-east-1"},
{KMS: "aws", Metastore: "dynamodb", DynamoDBEndpoint: "http://localhost:8000"},
{KMS: "static", Metastore: "rdbms"},
{KMS: "static", Metastore: "memory"},
}

for _, opts := range optCombos {
Expand Down

0 comments on commit b9b27b5

Please sign in to comment.