add support for dynamodb_table
parent
cb5b62b3df
commit
73ffe8280f
|
@ -135,7 +135,14 @@ As AWS documentation recommends, the below policy is granting only the permissio
|
|||
"sns:ListTagsForResource",
|
||||
"sns:ListSubscriptions",
|
||||
"sns:ListSubscriptionsByTopic",
|
||||
"sns:GetSubscriptionAttributes"
|
||||
"sns:GetSubscriptionAttributes",
|
||||
"dynamodb:ListTables",
|
||||
"dynamodb:DescribeTable",
|
||||
"dynamodb:DescribeGlobalTable",
|
||||
"dynamodb:ListTagsOfResource",
|
||||
"dynamodb:DescribeTimeToLive",
|
||||
"dynamodb:DescribeTableReplicaAutoScaling",
|
||||
"dynamodb:DescribeContinuousBackups"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
@ -258,3 +265,8 @@ As AWS documentation recommends, the below policy is granting only the permissio
|
|||
- [x] aws_sns_topic_subscription
|
||||
- [ ] aws_sns_platform_application
|
||||
- [ ] aws_sns_sms_preferences
|
||||
|
||||
## DynamoDB
|
||||
- [x] aws_dynamodb_table
|
||||
- [ ] aws_dynamodb_global_table
|
||||
- [ ] aws_dynamodb_table_item
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
// Code generated by mockery v1.0.0. DO NOT EDIT.
|
||||
|
||||
package mocks
|
||||
|
||||
import mock "github.com/stretchr/testify/mock"
|
||||
|
||||
// DynamoDBRepository is an autogenerated mock type for the DynamoDBRepository type
|
||||
type DynamoDBRepository struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
// ListAllTables provides a mock function with given fields:
|
||||
func (_m *DynamoDBRepository) ListAllTables() ([]*string, error) {
|
||||
ret := _m.Called()
|
||||
|
||||
var r0 []*string
|
||||
if rf, ok := ret.Get(0).(func() []*string); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]*string)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func() error); ok {
|
||||
r1 = rf()
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -52,5 +52,6 @@ func Deserializers() []deserializer.CTYDeserializer {
|
|||
awsdeserializer.NewSNSTopicDeserializer(),
|
||||
awsdeserializer.NewSNSTopicPolicyDeserializer(),
|
||||
awsdeserializer.NewSNSTopicSubscriptionDeserializer(),
|
||||
awsdeserializer.NewDynamoDBTableDeserializer(),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -79,6 +79,7 @@ func TestTerraformStateReader_Resources(t *testing.T) {
|
|||
{name: "SNS Topic", dirName: "sns_topic", wantErr: false},
|
||||
{name: "SNS Topic Policy", dirName: "sns_topic_policy", wantErr: false},
|
||||
{name: "SNS Topic Subscription", dirName: "sns_topic_subscription", wantErr: false},
|
||||
{name: "DynamoDB table", dirName: "dynamodb_table", wantErr: false},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
[
|
||||
{
|
||||
"Arn": "arn:aws:dynamodb:us-east-1:526954929923:table/GameScores",
|
||||
"BillingMode": "PROVISIONED",
|
||||
"HashKey": "UserId",
|
||||
"Id": "GameScores",
|
||||
"Name": "GameScores",
|
||||
"RangeKey": "GameTitle",
|
||||
"ReadCapacity": 20,
|
||||
"StreamArn": "",
|
||||
"StreamEnabled": false,
|
||||
"StreamLabel": "",
|
||||
"StreamViewType": "",
|
||||
"Tags": {
|
||||
"Environment": "production",
|
||||
"Name": "dynamodb-table-1"
|
||||
},
|
||||
"WriteCapacity": 20,
|
||||
"Attribute": [
|
||||
{
|
||||
"Name": "GameTitle",
|
||||
"Type": "S"
|
||||
},
|
||||
{
|
||||
"Name": "TopScore",
|
||||
"Type": "N"
|
||||
},
|
||||
{
|
||||
"Name": "UserId",
|
||||
"Type": "S"
|
||||
}
|
||||
],
|
||||
"GlobalSecondaryIndex": [
|
||||
{
|
||||
"HashKey": "GameTitle",
|
||||
"Name": "GameTitleIndex",
|
||||
"NonKeyAttributes": [
|
||||
"UserId"
|
||||
],
|
||||
"ProjectionType": "INCLUDE",
|
||||
"RangeKey": "TopScore",
|
||||
"ReadCapacity": 10,
|
||||
"WriteCapacity": 10
|
||||
}
|
||||
],
|
||||
"LocalSecondaryIndex": [],
|
||||
"PointInTimeRecovery": [
|
||||
{
|
||||
"Enabled": false
|
||||
}
|
||||
],
|
||||
"Replica": [],
|
||||
"ServerSideEncryption": [],
|
||||
"Timeouts": null,
|
||||
"Ttl": [
|
||||
{
|
||||
"AttributeName": "",
|
||||
"Enabled": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Arn": "arn:aws:dynamodb:us-east-1:526954929923:table/example",
|
||||
"BillingMode": "PAY_PER_REQUEST",
|
||||
"HashKey": "TestTableHashKey",
|
||||
"Id": "example",
|
||||
"Name": "example",
|
||||
"RangeKey": null,
|
||||
"ReadCapacity": 0,
|
||||
"StreamArn": "arn:aws:dynamodb:us-east-1:526954929923:table/example/stream/2021-02-10T15:07:54.928",
|
||||
"StreamEnabled": true,
|
||||
"StreamLabel": "2021-02-10T15:07:54.928",
|
||||
"StreamViewType": "NEW_AND_OLD_IMAGES",
|
||||
"Tags": {},
|
||||
"WriteCapacity": 0,
|
||||
"Attribute": [
|
||||
{
|
||||
"Name": "TestTableHashKey",
|
||||
"Type": "S"
|
||||
}
|
||||
],
|
||||
"GlobalSecondaryIndex": [],
|
||||
"LocalSecondaryIndex": [],
|
||||
"PointInTimeRecovery": [
|
||||
{
|
||||
"Enabled": false
|
||||
}
|
||||
],
|
||||
"Replica": [
|
||||
{
|
||||
"RegionName": "us-east-2"
|
||||
},
|
||||
{
|
||||
"RegionName": "us-west-2"
|
||||
}
|
||||
],
|
||||
"ServerSideEncryption": [],
|
||||
"Timeouts": null,
|
||||
"Ttl": [
|
||||
{
|
||||
"AttributeName": "",
|
||||
"Enabled": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,139 @@
|
|||
{
|
||||
"version": 4,
|
||||
"terraform_version": "0.14.5",
|
||||
"serial": 45,
|
||||
"lineage": "30081725-54a2-ce02-6ff5-45c4d961c652",
|
||||
"outputs": {},
|
||||
"resources": [
|
||||
{
|
||||
"mode": "managed",
|
||||
"type": "aws_dynamodb_table",
|
||||
"name": "basic-dynamodb-table",
|
||||
"provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
|
||||
"instances": [
|
||||
{
|
||||
"schema_version": 1,
|
||||
"attributes": {
|
||||
"arn": "arn:aws:dynamodb:us-east-1:526954929923:table/GameScores",
|
||||
"attribute": [
|
||||
{
|
||||
"name": "GameTitle",
|
||||
"type": "S"
|
||||
},
|
||||
{
|
||||
"name": "TopScore",
|
||||
"type": "N"
|
||||
},
|
||||
{
|
||||
"name": "UserId",
|
||||
"type": "S"
|
||||
}
|
||||
],
|
||||
"billing_mode": "PROVISIONED",
|
||||
"global_secondary_index": [
|
||||
{
|
||||
"hash_key": "GameTitle",
|
||||
"name": "GameTitleIndex",
|
||||
"non_key_attributes": [
|
||||
"UserId"
|
||||
],
|
||||
"projection_type": "INCLUDE",
|
||||
"range_key": "TopScore",
|
||||
"read_capacity": 10,
|
||||
"write_capacity": 10
|
||||
}
|
||||
],
|
||||
"hash_key": "UserId",
|
||||
"id": "GameScores",
|
||||
"local_secondary_index": [],
|
||||
"name": "GameScores",
|
||||
"point_in_time_recovery": [
|
||||
{
|
||||
"enabled": false
|
||||
}
|
||||
],
|
||||
"range_key": "GameTitle",
|
||||
"read_capacity": 20,
|
||||
"replica": [],
|
||||
"server_side_encryption": [],
|
||||
"stream_arn": "",
|
||||
"stream_enabled": false,
|
||||
"stream_label": "",
|
||||
"stream_view_type": "",
|
||||
"tags": {
|
||||
"Environment": "production",
|
||||
"Name": "dynamodb-table-1"
|
||||
},
|
||||
"timeouts": null,
|
||||
"ttl": [
|
||||
{
|
||||
"attribute_name": "",
|
||||
"enabled": false
|
||||
}
|
||||
],
|
||||
"write_capacity": 20
|
||||
},
|
||||
"sensitive_attributes": [],
|
||||
"private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjo2MDAwMDAwMDAwMDAsImRlbGV0ZSI6NjAwMDAwMDAwMDAwLCJ1cGRhdGUiOjM2MDAwMDAwMDAwMDB9LCJzY2hlbWFfdmVyc2lvbiI6IjEifQ=="
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"mode": "managed",
|
||||
"type": "aws_dynamodb_table",
|
||||
"name": "example",
|
||||
"provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
|
||||
"instances": [
|
||||
{
|
||||
"schema_version": 1,
|
||||
"attributes": {
|
||||
"arn": "arn:aws:dynamodb:us-east-1:526954929923:table/example",
|
||||
"attribute": [
|
||||
{
|
||||
"name": "TestTableHashKey",
|
||||
"type": "S"
|
||||
}
|
||||
],
|
||||
"billing_mode": "PAY_PER_REQUEST",
|
||||
"global_secondary_index": [],
|
||||
"hash_key": "TestTableHashKey",
|
||||
"id": "example",
|
||||
"local_secondary_index": [],
|
||||
"name": "example",
|
||||
"point_in_time_recovery": [
|
||||
{
|
||||
"enabled": false
|
||||
}
|
||||
],
|
||||
"range_key": null,
|
||||
"read_capacity": 0,
|
||||
"replica": [
|
||||
{
|
||||
"region_name": "us-east-2"
|
||||
},
|
||||
{
|
||||
"region_name": "us-west-2"
|
||||
}
|
||||
],
|
||||
"server_side_encryption": [],
|
||||
"stream_arn": "arn:aws:dynamodb:us-east-1:526954929923:table/example/stream/2021-02-10T15:07:54.928",
|
||||
"stream_enabled": true,
|
||||
"stream_label": "2021-02-10T15:07:54.928",
|
||||
"stream_view_type": "NEW_AND_OLD_IMAGES",
|
||||
"tags": {},
|
||||
"timeouts": null,
|
||||
"ttl": [
|
||||
{
|
||||
"attribute_name": "",
|
||||
"enabled": false
|
||||
}
|
||||
],
|
||||
"write_capacity": 0
|
||||
},
|
||||
"sensitive_attributes": [],
|
||||
"private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjo2MDAwMDAwMDAwMDAsImRlbGV0ZSI6NjAwMDAwMDAwMDAwLCJ1cGRhdGUiOjM2MDAwMDAwMDAwMDB9LCJzY2hlbWFfdmVyc2lvbiI6IjEifQ=="
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
package aws
|
||||
|
||||
import (
|
||||
"github.com/cloudskiff/driftctl/pkg/remote/aws/repository"
|
||||
remoteerror "github.com/cloudskiff/driftctl/pkg/remote/error"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
|
||||
"github.com/cloudskiff/driftctl/pkg/remote/deserializer"
|
||||
"github.com/cloudskiff/driftctl/pkg/resource"
|
||||
"github.com/cloudskiff/driftctl/pkg/resource/aws"
|
||||
awsdeserializer "github.com/cloudskiff/driftctl/pkg/resource/aws/deserializer"
|
||||
"github.com/cloudskiff/driftctl/pkg/terraform"
|
||||
)
|
||||
|
||||
type DynamoDBTableSupplier struct {
|
||||
reader terraform.ResourceReader
|
||||
deserializer deserializer.CTYDeserializer
|
||||
repository repository.DynamoDBRepository
|
||||
runner *terraform.ParallelResourceReader
|
||||
}
|
||||
|
||||
func NewDynamoDBTableSupplier(provider *TerraformProvider) *DynamoDBTableSupplier {
|
||||
return &DynamoDBTableSupplier{
|
||||
provider,
|
||||
awsdeserializer.NewDynamoDBTableDeserializer(),
|
||||
repository.NewDynamoDBRepository(provider.session),
|
||||
terraform.NewParallelResourceReader(provider.Runner().SubRunner()),
|
||||
}
|
||||
}
|
||||
|
||||
func (s DynamoDBTableSupplier) Resources() ([]resource.Resource, error) {
|
||||
tables, err := s.repository.ListAllTables()
|
||||
if err != nil {
|
||||
return nil, remoteerror.NewResourceEnumerationError(err, aws.AwsDynamodbTableResourceType)
|
||||
}
|
||||
|
||||
for _, table := range tables {
|
||||
table := table
|
||||
s.runner.Run(func() (cty.Value, error) {
|
||||
return s.readTable(table)
|
||||
})
|
||||
}
|
||||
|
||||
retrieve, err := s.runner.Wait()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.deserializer.Deserialize(retrieve)
|
||||
}
|
||||
|
||||
func (s DynamoDBTableSupplier) readTable(tableName *string) (cty.Value, error) {
|
||||
val, err := s.reader.ReadResource(terraform.ReadResourceArgs{
|
||||
ID: *tableName,
|
||||
Ty: aws.AwsDynamodbTableResourceType,
|
||||
Attributes: map[string]string{
|
||||
"table_name": *tableName,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
logrus.Error(err)
|
||||
return cty.NilVal, err
|
||||
}
|
||||
return *val, nil
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
package aws
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
|
||||
remoteerror "github.com/cloudskiff/driftctl/pkg/remote/error"
|
||||
|
||||
resourceaws "github.com/cloudskiff/driftctl/pkg/resource/aws"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
|
||||
"github.com/cloudskiff/driftctl/pkg/parallel"
|
||||
|
||||
awsdeserializer "github.com/cloudskiff/driftctl/pkg/resource/aws/deserializer"
|
||||
|
||||
"github.com/cloudskiff/driftctl/test/goldenfile"
|
||||
mocks2 "github.com/cloudskiff/driftctl/test/mocks"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
|
||||
"github.com/cloudskiff/driftctl/mocks"
|
||||
|
||||
"github.com/cloudskiff/driftctl/pkg/resource"
|
||||
"github.com/cloudskiff/driftctl/pkg/terraform"
|
||||
"github.com/cloudskiff/driftctl/test"
|
||||
)
|
||||
|
||||
func TestDynamoDBTableSupplier_Resources(t *testing.T) {
|
||||
cases := []struct {
|
||||
test string
|
||||
dirName string
|
||||
mocks func(client *mocks.DynamoDBRepository)
|
||||
err error
|
||||
}{
|
||||
{
|
||||
test: "no DynamoDB Table",
|
||||
dirName: "dynamodb_table_empty",
|
||||
mocks: func(client *mocks.DynamoDBRepository) {
|
||||
client.On("ListAllTables").Return([]*string{}, nil)
|
||||
},
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
test: "Multiple DynamoDB Table",
|
||||
dirName: "dynamodb_table_multiple",
|
||||
mocks: func(client *mocks.DynamoDBRepository) {
|
||||
client.On("ListAllTables").Return([]*string{
|
||||
aws.String("GameScores"),
|
||||
aws.String("example"),
|
||||
}, nil)
|
||||
},
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
test: "cannot list DynamoDB Table",
|
||||
dirName: "dynamodb_table_list",
|
||||
mocks: func(client *mocks.DynamoDBRepository) {
|
||||
client.On("ListAllTables").Return(nil, awserr.NewRequestFailure(awserr.New("AccessDeniedException", "", errors.New("")), 400, ""))
|
||||
},
|
||||
err: remoteerror.NewResourceEnumerationError(awserr.NewRequestFailure(awserr.New("AccessDeniedException", "", errors.New("")), 400, ""), resourceaws.AwsDynamodbTableResourceType),
|
||||
},
|
||||
}
|
||||
for _, c := range cases {
|
||||
shouldUpdate := c.dirName == *goldenfile.Update
|
||||
|
||||
providerLibrary := terraform.NewProviderLibrary()
|
||||
supplierLibrary := resource.NewSupplierLibrary()
|
||||
|
||||
if shouldUpdate {
|
||||
provider, err := NewTerraFormProvider()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
providerLibrary.AddProvider(terraform.AWS, provider)
|
||||
supplierLibrary.AddSupplier(NewDynamoDBTableSupplier(provider))
|
||||
}
|
||||
|
||||
t.Run(c.test, func(tt *testing.T) {
|
||||
fakeClient := mocks.DynamoDBRepository{}
|
||||
c.mocks(&fakeClient)
|
||||
provider := mocks2.NewMockedGoldenTFProvider(c.dirName, providerLibrary.Provider(terraform.AWS), shouldUpdate)
|
||||
dynamoDBTableDeserializer := awsdeserializer.NewDynamoDBTableDeserializer()
|
||||
s := &DynamoDBTableSupplier{
|
||||
provider,
|
||||
dynamoDBTableDeserializer,
|
||||
&fakeClient,
|
||||
terraform.NewParallelResourceReader(parallel.NewParallelRunner(context.TODO(), 10)),
|
||||
}
|
||||
got, err := s.Resources()
|
||||
assert.Equal(tt, c.err, err)
|
||||
|
||||
mock.AssertExpectationsForObjects(tt)
|
||||
test.CtyTestDiff(got, c.dirName, provider, dynamoDBTableDeserializer, shouldUpdate, tt)
|
||||
})
|
||||
}
|
||||
}
|
|
@ -62,6 +62,7 @@ func Init(alerter *alerter.Alerter, providerLibrary *terraform.ProviderLibrary,
|
|||
supplierLibrary.AddSupplier(NewSNSTopicSupplier(provider))
|
||||
supplierLibrary.AddSupplier(NewSNSTopicPolicySupplier(provider))
|
||||
supplierLibrary.AddSupplier(NewSNSTopicSubscriptionSupplier(provider))
|
||||
supplierLibrary.AddSupplier(NewDynamoDBTableSupplier(provider))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
package repository
|
||||
|
||||
import (
|
||||
"github.com/aws/aws-sdk-go/aws/session"
|
||||
"github.com/aws/aws-sdk-go/service/dynamodb"
|
||||
"github.com/aws/aws-sdk-go/service/dynamodb/dynamodbiface"
|
||||
)
|
||||
|
||||
type DynamoDBRepository interface {
|
||||
ListAllTables() ([]*string, error)
|
||||
}
|
||||
|
||||
type dynamoDBRepository struct {
|
||||
client dynamodbiface.DynamoDBAPI
|
||||
}
|
||||
|
||||
func NewDynamoDBRepository(session *session.Session) *dynamoDBRepository {
|
||||
return &dynamoDBRepository{
|
||||
dynamodb.New(session),
|
||||
}
|
||||
}
|
||||
|
||||
func (r *dynamoDBRepository) ListAllTables() ([]*string, error) {
|
||||
var tables []*string
|
||||
input := &dynamodb.ListTablesInput{}
|
||||
err := r.client.ListTablesPages(input, func(res *dynamodb.ListTablesOutput, lastPage bool) bool {
|
||||
tables = append(tables, res.TableNames...)
|
||||
return !lastPage
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return tables, nil
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
package repository
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/aws/aws-sdk-go/service/dynamodb"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
|
||||
"github.com/stretchr/testify/mock"
|
||||
|
||||
"github.com/cloudskiff/driftctl/mocks"
|
||||
"github.com/r3labs/diff/v2"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func Test_dynamoDBRepository_ListAllTopics(t *testing.T) {
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
mocks func(client *mocks.DynamodbClient)
|
||||
want []*string
|
||||
wantErr error
|
||||
}{
|
||||
{
|
||||
name: "List with 2 pages",
|
||||
mocks: func(client *mocks.DynamodbClient) {
|
||||
client.On("ListTablesPages",
|
||||
&dynamodb.ListTablesInput{},
|
||||
mock.MatchedBy(func(callback func(res *dynamodb.ListTablesOutput, lastPage bool) bool) bool {
|
||||
callback(&dynamodb.ListTablesOutput{
|
||||
TableNames: []*string{
|
||||
aws.String("1"),
|
||||
aws.String("2"),
|
||||
aws.String("3"),
|
||||
},
|
||||
}, false)
|
||||
callback(&dynamodb.ListTablesOutput{
|
||||
TableNames: []*string{
|
||||
aws.String("4"),
|
||||
aws.String("5"),
|
||||
aws.String("6"),
|
||||
},
|
||||
}, true)
|
||||
return true
|
||||
})).Return(nil)
|
||||
},
|
||||
want: []*string{
|
||||
aws.String("1"),
|
||||
aws.String("2"),
|
||||
aws.String("3"),
|
||||
aws.String("4"),
|
||||
aws.String("5"),
|
||||
aws.String("6"),
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
client := &mocks.DynamodbClient{}
|
||||
tt.mocks(client)
|
||||
r := &dynamoDBRepository{
|
||||
client: client,
|
||||
}
|
||||
got, err := r.ListAllTables()
|
||||
assert.Equal(t, tt.wantErr, err)
|
||||
changelog, err := diff.Diff(got, tt.want)
|
||||
assert.Nil(t, err)
|
||||
if len(changelog) > 0 {
|
||||
for _, change := range changelog {
|
||||
t.Errorf("%s: %s -> %s", strings.Join(change.Path, "."), change.From, change.To)
|
||||
}
|
||||
t.Fail()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
[]
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1 @@
|
|||
[]
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"Typ": "WyJvYmplY3QiLHsiYXJuIjoic3RyaW5nIiwiYXR0cmlidXRlIjpbInNldCIsWyJvYmplY3QiLHsibmFtZSI6InN0cmluZyIsInR5cGUiOiJzdHJpbmcifV1dLCJiaWxsaW5nX21vZGUiOiJzdHJpbmciLCJnbG9iYWxfc2Vjb25kYXJ5X2luZGV4IjpbInNldCIsWyJvYmplY3QiLHsiaGFzaF9rZXkiOiJzdHJpbmciLCJuYW1lIjoic3RyaW5nIiwibm9uX2tleV9hdHRyaWJ1dGVzIjpbInNldCIsInN0cmluZyJdLCJwcm9qZWN0aW9uX3R5cGUiOiJzdHJpbmciLCJyYW5nZV9rZXkiOiJzdHJpbmciLCJyZWFkX2NhcGFjaXR5IjoibnVtYmVyIiwid3JpdGVfY2FwYWNpdHkiOiJudW1iZXIifV1dLCJoYXNoX2tleSI6InN0cmluZyIsImlkIjoic3RyaW5nIiwibG9jYWxfc2Vjb25kYXJ5X2luZGV4IjpbInNldCIsWyJvYmplY3QiLHsibmFtZSI6InN0cmluZyIsIm5vbl9rZXlfYXR0cmlidXRlcyI6WyJsaXN0Iiwic3RyaW5nIl0sInByb2plY3Rpb25fdHlwZSI6InN0cmluZyIsInJhbmdlX2tleSI6InN0cmluZyJ9XV0sIm5hbWUiOiJzdHJpbmciLCJwb2ludF9pbl90aW1lX3JlY292ZXJ5IjpbImxpc3QiLFsib2JqZWN0Iix7ImVuYWJsZWQiOiJib29sIn1dXSwicmFuZ2Vfa2V5Ijoic3RyaW5nIiwicmVhZF9jYXBhY2l0eSI6Im51bWJlciIsInJlcGxpY2EiOlsic2V0IixbIm9iamVjdCIseyJyZWdpb25fbmFtZSI6InN0cmluZyJ9XV0sInNlcnZlcl9zaWRlX2VuY3J5cHRpb24iOlsibGlzdCIsWyJvYmplY3QiLHsiZW5hYmxlZCI6ImJvb2wiLCJrbXNfa2V5X2FybiI6InN0cmluZyJ9XV0sInN0cmVhbV9hcm4iOiJzdHJpbmciLCJzdHJlYW1fZW5hYmxlZCI6ImJvb2wiLCJzdHJlYW1fbGFiZWwiOiJzdHJpbmciLCJzdHJlYW1fdmlld190eXBlIjoic3RyaW5nIiwidGFncyI6WyJtYXAiLCJzdHJpbmciXSwidGltZW91dHMiOlsib2JqZWN0Iix7ImNyZWF0ZSI6InN0cmluZyIsImRlbGV0ZSI6InN0cmluZyIsInVwZGF0ZSI6InN0cmluZyJ9XSwidHRsIjpbImxpc3QiLFsib2JqZWN0Iix7ImF0dHJpYnV0ZV9uYW1lIjoic3RyaW5nIiwiZW5hYmxlZCI6ImJvb2wifV1dLCJ3cml0ZV9jYXBhY2l0eSI6Im51bWJlciJ9XQ==",
|
||||
"Val": "eyJhcm4iOiJhcm46YXdzOmR5bmFtb2RiOnVzLWVhc3QtMTo1MjY5NTQ5Mjk5MjM6dGFibGUvR2FtZVNjb3JlcyIsImF0dHJpYnV0ZSI6W3sibmFtZSI6IkdhbWVUaXRsZSIsInR5cGUiOiJTIn0seyJuYW1lIjoiVG9wU2NvcmUiLCJ0eXBlIjoiTiJ9LHsibmFtZSI6IlVzZXJJZCIsInR5cGUiOiJTIn1dLCJiaWxsaW5nX21vZGUiOiJQUk9WSVNJT05FRCIsImdsb2JhbF9zZWNvbmRhcnlfaW5kZXgiOlt7Imhhc2hfa2V5IjoiR2FtZVRpdGxlIiwibmFtZSI6IkdhbWVUaXRsZUluZGV4Iiwibm9uX2tleV9hdHRyaWJ1dGVzIjpbIlVzZXJJZCJdLCJwcm9qZWN0aW9uX3R5cGUiOiJJTkNMVURFIiwicmFuZ2Vfa2V5IjoiVG9wU2NvcmUiLCJyZWFkX2NhcGFjaXR5IjoxMCwid3JpdGVfY2FwYWNpdHkiOjEwfV0sImhhc2hfa2V5IjoiVXNlcklkIiwiaWQiOiJHYW1lU2NvcmVzIiwibG9jYWxfc2Vjb25kYXJ5X2luZGV4IjpbXSwibmFtZSI6IkdhbWVTY29yZXMiLCJwb2ludF9pbl90aW1lX3JlY292ZXJ5IjpbeyJlbmFibGVkIjpmYWxzZX1dLCJyYW5nZV9rZXkiOiJHYW1lVGl0bGUiLCJyZWFkX2NhcGFjaXR5IjoyMCwicmVwbGljYSI6W10sInNlcnZlcl9zaWRlX2VuY3J5cHRpb24iOltdLCJzdHJlYW1fYXJuIjoiIiwic3RyZWFtX2VuYWJsZWQiOmZhbHNlLCJzdHJlYW1fbGFiZWwiOiIiLCJzdHJlYW1fdmlld190eXBlIjoiIiwidGFncyI6eyJFbnZpcm9ubWVudCI6InByb2R1Y3Rpb24iLCJOYW1lIjoiZHluYW1vZGItdGFibGUtMSJ9LCJ0aW1lb3V0cyI6eyJjcmVhdGUiOm51bGwsImRlbGV0ZSI6bnVsbCwidXBkYXRlIjpudWxsfSwidHRsIjpbeyJhdHRyaWJ1dGVfbmFtZSI6IlRpbWVUb0V4aXN0IiwiZW5hYmxlZCI6dHJ1ZX1dLCJ3cml0ZV9jYXBhY2l0eSI6MjB9",
|
||||
"Err": null
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"Typ": "WyJvYmplY3QiLHsiYXJuIjoic3RyaW5nIiwiYXR0cmlidXRlIjpbInNldCIsWyJvYmplY3QiLHsibmFtZSI6InN0cmluZyIsInR5cGUiOiJzdHJpbmcifV1dLCJiaWxsaW5nX21vZGUiOiJzdHJpbmciLCJnbG9iYWxfc2Vjb25kYXJ5X2luZGV4IjpbInNldCIsWyJvYmplY3QiLHsiaGFzaF9rZXkiOiJzdHJpbmciLCJuYW1lIjoic3RyaW5nIiwibm9uX2tleV9hdHRyaWJ1dGVzIjpbInNldCIsInN0cmluZyJdLCJwcm9qZWN0aW9uX3R5cGUiOiJzdHJpbmciLCJyYW5nZV9rZXkiOiJzdHJpbmciLCJyZWFkX2NhcGFjaXR5IjoibnVtYmVyIiwid3JpdGVfY2FwYWNpdHkiOiJudW1iZXIifV1dLCJoYXNoX2tleSI6InN0cmluZyIsImlkIjoic3RyaW5nIiwibG9jYWxfc2Vjb25kYXJ5X2luZGV4IjpbInNldCIsWyJvYmplY3QiLHsibmFtZSI6InN0cmluZyIsIm5vbl9rZXlfYXR0cmlidXRlcyI6WyJsaXN0Iiwic3RyaW5nIl0sInByb2plY3Rpb25fdHlwZSI6InN0cmluZyIsInJhbmdlX2tleSI6InN0cmluZyJ9XV0sIm5hbWUiOiJzdHJpbmciLCJwb2ludF9pbl90aW1lX3JlY292ZXJ5IjpbImxpc3QiLFsib2JqZWN0Iix7ImVuYWJsZWQiOiJib29sIn1dXSwicmFuZ2Vfa2V5Ijoic3RyaW5nIiwicmVhZF9jYXBhY2l0eSI6Im51bWJlciIsInJlcGxpY2EiOlsic2V0IixbIm9iamVjdCIseyJyZWdpb25fbmFtZSI6InN0cmluZyJ9XV0sInNlcnZlcl9zaWRlX2VuY3J5cHRpb24iOlsibGlzdCIsWyJvYmplY3QiLHsiZW5hYmxlZCI6ImJvb2wiLCJrbXNfa2V5X2FybiI6InN0cmluZyJ9XV0sInN0cmVhbV9hcm4iOiJzdHJpbmciLCJzdHJlYW1fZW5hYmxlZCI6ImJvb2wiLCJzdHJlYW1fbGFiZWwiOiJzdHJpbmciLCJzdHJlYW1fdmlld190eXBlIjoic3RyaW5nIiwidGFncyI6WyJtYXAiLCJzdHJpbmciXSwidGltZW91dHMiOlsib2JqZWN0Iix7ImNyZWF0ZSI6InN0cmluZyIsImRlbGV0ZSI6InN0cmluZyIsInVwZGF0ZSI6InN0cmluZyJ9XSwidHRsIjpbImxpc3QiLFsib2JqZWN0Iix7ImF0dHJpYnV0ZV9uYW1lIjoic3RyaW5nIiwiZW5hYmxlZCI6ImJvb2wifV1dLCJ3cml0ZV9jYXBhY2l0eSI6Im51bWJlciJ9XQ==",
|
||||
"Val": "eyJhcm4iOiJhcm46YXdzOmR5bmFtb2RiOnVzLWVhc3QtMTo1MjY5NTQ5Mjk5MjM6dGFibGUvZXhhbXBsZSIsImF0dHJpYnV0ZSI6W3sibmFtZSI6IlRlc3RUYWJsZUhhc2hLZXkiLCJ0eXBlIjoiUyJ9XSwiYmlsbGluZ19tb2RlIjoiUEFZX1BFUl9SRVFVRVNUIiwiZ2xvYmFsX3NlY29uZGFyeV9pbmRleCI6W10sImhhc2hfa2V5IjoiVGVzdFRhYmxlSGFzaEtleSIsImlkIjoiZXhhbXBsZSIsImxvY2FsX3NlY29uZGFyeV9pbmRleCI6W10sIm5hbWUiOiJleGFtcGxlIiwicG9pbnRfaW5fdGltZV9yZWNvdmVyeSI6W3siZW5hYmxlZCI6ZmFsc2V9XSwicmFuZ2Vfa2V5IjpudWxsLCJyZWFkX2NhcGFjaXR5IjowLCJyZXBsaWNhIjpbeyJyZWdpb25fbmFtZSI6InVzLWVhc3QtMiJ9XSwic2VydmVyX3NpZGVfZW5jcnlwdGlvbiI6W10sInN0cmVhbV9hcm4iOiJhcm46YXdzOmR5bmFtb2RiOnVzLWVhc3QtMTo1MjY5NTQ5Mjk5MjM6dGFibGUvZXhhbXBsZS9zdHJlYW0vMjAyMS0wMi0xMVQwOTo1MDoyMC43NTAiLCJzdHJlYW1fZW5hYmxlZCI6dHJ1ZSwic3RyZWFtX2xhYmVsIjoiMjAyMS0wMi0xMVQwOTo1MDoyMC43NTAiLCJzdHJlYW1fdmlld190eXBlIjoiTkVXX0FORF9PTERfSU1BR0VTIiwidGFncyI6e30sInRpbWVvdXRzIjp7ImNyZWF0ZSI6bnVsbCwiZGVsZXRlIjpudWxsLCJ1cGRhdGUiOm51bGx9LCJ0dGwiOlt7ImF0dHJpYnV0ZV9uYW1lIjoiIiwiZW5hYmxlZCI6ZmFsc2V9XSwid3JpdGVfY2FwYWNpdHkiOjB9",
|
||||
"Err": null
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
[
|
||||
{
|
||||
"arn": "arn:aws:dynamodb:us-east-1:526954929923:table/GameScores",
|
||||
"attribute": [
|
||||
{
|
||||
"name": "GameTitle",
|
||||
"type": "S"
|
||||
},
|
||||
{
|
||||
"name": "TopScore",
|
||||
"type": "N"
|
||||
},
|
||||
{
|
||||
"name": "UserId",
|
||||
"type": "S"
|
||||
}
|
||||
],
|
||||
"billing_mode": "PROVISIONED",
|
||||
"global_secondary_index": [
|
||||
{
|
||||
"hash_key": "GameTitle",
|
||||
"name": "GameTitleIndex",
|
||||
"non_key_attributes": [
|
||||
"UserId"
|
||||
],
|
||||
"projection_type": "INCLUDE",
|
||||
"range_key": "TopScore",
|
||||
"read_capacity": 10,
|
||||
"write_capacity": 10
|
||||
}
|
||||
],
|
||||
"hash_key": "UserId",
|
||||
"id": "GameScores",
|
||||
"local_secondary_index": [],
|
||||
"name": "GameScores",
|
||||
"point_in_time_recovery": [
|
||||
{
|
||||
"enabled": false
|
||||
}
|
||||
],
|
||||
"range_key": "GameTitle",
|
||||
"read_capacity": 20,
|
||||
"replica": [],
|
||||
"server_side_encryption": [],
|
||||
"stream_arn": "",
|
||||
"stream_enabled": false,
|
||||
"stream_label": "",
|
||||
"stream_view_type": "",
|
||||
"tags": {
|
||||
"Environment": "production",
|
||||
"Name": "dynamodb-table-1"
|
||||
},
|
||||
"timeouts": {
|
||||
"create": null,
|
||||
"delete": null,
|
||||
"update": null
|
||||
},
|
||||
"ttl": [
|
||||
{
|
||||
"attribute_name": "TimeToExist",
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"write_capacity": 20
|
||||
},
|
||||
{
|
||||
"arn": "arn:aws:dynamodb:us-east-1:526954929923:table/example",
|
||||
"attribute": [
|
||||
{
|
||||
"name": "TestTableHashKey",
|
||||
"type": "S"
|
||||
}
|
||||
],
|
||||
"billing_mode": "PAY_PER_REQUEST",
|
||||
"global_secondary_index": [],
|
||||
"hash_key": "TestTableHashKey",
|
||||
"id": "example",
|
||||
"local_secondary_index": [],
|
||||
"name": "example",
|
||||
"point_in_time_recovery": [
|
||||
{
|
||||
"enabled": false
|
||||
}
|
||||
],
|
||||
"range_key": null,
|
||||
"read_capacity": 0,
|
||||
"replica": [
|
||||
{
|
||||
"region_name": "us-east-2"
|
||||
}
|
||||
],
|
||||
"server_side_encryption": [],
|
||||
"stream_arn": "arn:aws:dynamodb:us-east-1:526954929923:table/example/stream/2021-02-11T09:50:20.750",
|
||||
"stream_enabled": true,
|
||||
"stream_label": "2021-02-11T09:50:20.750",
|
||||
"stream_view_type": "NEW_AND_OLD_IMAGES",
|
||||
"tags": {},
|
||||
"timeouts": {
|
||||
"create": null,
|
||||
"delete": null,
|
||||
"update": null
|
||||
},
|
||||
"ttl": [
|
||||
{
|
||||
"attribute_name": "",
|
||||
"enabled": false
|
||||
}
|
||||
],
|
||||
"write_capacity": 0
|
||||
}
|
||||
]
|
File diff suppressed because it is too large
Load Diff
|
@ -2,12 +2,14 @@ package remote
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
remoteerror "github.com/cloudskiff/driftctl/pkg/remote/error"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/cloudskiff/driftctl/pkg/alerter"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func HandleResourceEnumerationError(err error, alertr *alerter.Alerter) error {
|
||||
|
@ -21,7 +23,7 @@ func HandleResourceEnumerationError(err error, alertr *alerter.Alerter) error {
|
|||
return err
|
||||
}
|
||||
|
||||
if reqerr.StatusCode() == 403 {
|
||||
if reqerr.StatusCode() == 403 || (reqerr.StatusCode() == 400 && strings.Contains(reqerr.Code(), "AccessDenied")) {
|
||||
message := fmt.Sprintf("Ignoring %s from drift calculation: Listing %s is forbidden.", listError.SupplierType(), listError.ListedTypeError())
|
||||
logrus.Debugf(message)
|
||||
alertr.SendAlert(listError.SupplierType(), alerter.Alert{
|
||||
|
|
|
@ -23,20 +23,26 @@ func TestHandleListAwsError(t *testing.T) {
|
|||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "Handled error",
|
||||
err: remoteerror.NewResourceEnumerationError(awserr.NewRequestFailure(nil, 403, ""), resourceaws.AwsVpcResourceType),
|
||||
name: "Handled error 403",
|
||||
err: remoteerror.NewResourceEnumerationError(awserr.NewRequestFailure(awserr.New("", "", errors.New("")), 403, ""), resourceaws.AwsVpcResourceType),
|
||||
wantAlerts: alerter.Alerts{"aws_vpc": []alerter.Alert{alerter.Alert{Message: "Ignoring aws_vpc from drift calculation: Listing aws_vpc is forbidden.", ShouldIgnoreResource: true}}},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "Handled error AccessDenied",
|
||||
err: remoteerror.NewResourceEnumerationError(awserr.NewRequestFailure(awserr.New("AccessDeniedException", "", errors.New("")), 403, ""), resourceaws.AwsDynamodbTableResourceType),
|
||||
wantAlerts: alerter.Alerts{"aws_dynamodb_table": []alerter.Alert{alerter.Alert{Message: "Ignoring aws_dynamodb_table from drift calculation: Listing aws_dynamodb_table is forbidden.", ShouldIgnoreResource: true}}},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "Not Handled error code",
|
||||
err: remoteerror.NewResourceEnumerationError(awserr.NewRequestFailure(nil, 404, ""), resourceaws.AwsVpcResourceType),
|
||||
err: remoteerror.NewResourceEnumerationError(awserr.NewRequestFailure(awserr.New("", "", errors.New("")), 404, ""), resourceaws.AwsVpcResourceType),
|
||||
wantAlerts: map[string][]alerter.Alert{},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "Not Handled supplier error",
|
||||
err: remoteerror.NewSupplierError(awserr.NewRequestFailure(nil, 403, ""), map[string]string{}, resourceaws.AwsVpcResourceType),
|
||||
err: remoteerror.NewSupplierError(awserr.NewRequestFailure(awserr.New("", "", errors.New("")), 403, ""), map[string]string{}, resourceaws.AwsVpcResourceType),
|
||||
wantAlerts: map[string][]alerter.Alert{},
|
||||
wantErr: true,
|
||||
},
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
// GENERATED, DO NOT EDIT THIS FILE
|
||||
package aws
|
||||
|
||||
const AwsDynamodbTableResourceType = "aws_dynamodb_table"
|
||||
|
||||
type AwsDynamodbTable struct {
|
||||
Arn *string `cty:"arn" computed:"true"`
|
||||
BillingMode *string `cty:"billing_mode"`
|
||||
HashKey *string `cty:"hash_key"`
|
||||
Id string `cty:"id" computed:"true"`
|
||||
Name *string `cty:"name"`
|
||||
RangeKey *string `cty:"range_key"`
|
||||
ReadCapacity *int `cty:"read_capacity"`
|
||||
StreamArn *string `cty:"stream_arn" computed:"true"`
|
||||
StreamEnabled *bool `cty:"stream_enabled"`
|
||||
StreamLabel *string `cty:"stream_label" computed:"true"`
|
||||
StreamViewType *string `cty:"stream_view_type" computed:"true"`
|
||||
Tags map[string]string `cty:"tags"`
|
||||
WriteCapacity *int `cty:"write_capacity"`
|
||||
Attribute *[]struct {
|
||||
Name *string `cty:"name"`
|
||||
Type *string `cty:"type"`
|
||||
} `cty:"attribute"`
|
||||
GlobalSecondaryIndex *[]struct {
|
||||
HashKey *string `cty:"hash_key"`
|
||||
Name *string `cty:"name"`
|
||||
NonKeyAttributes []string `cty:"non_key_attributes"`
|
||||
ProjectionType *string `cty:"projection_type"`
|
||||
RangeKey *string `cty:"range_key"`
|
||||
ReadCapacity *int `cty:"read_capacity"`
|
||||
WriteCapacity *int `cty:"write_capacity"`
|
||||
} `cty:"global_secondary_index"`
|
||||
LocalSecondaryIndex *[]struct {
|
||||
Name *string `cty:"name"`
|
||||
NonKeyAttributes []string `cty:"non_key_attributes"`
|
||||
ProjectionType *string `cty:"projection_type"`
|
||||
RangeKey *string `cty:"range_key"`
|
||||
} `cty:"local_secondary_index"`
|
||||
PointInTimeRecovery *[]struct {
|
||||
Enabled *bool `cty:"enabled"`
|
||||
} `cty:"point_in_time_recovery"`
|
||||
Replica *[]struct {
|
||||
RegionName *string `cty:"region_name"`
|
||||
} `cty:"replica"`
|
||||
ServerSideEncryption *[]struct {
|
||||
Enabled *bool `cty:"enabled"`
|
||||
KmsKeyArn *string `cty:"kms_key_arn" computed:"true"`
|
||||
} `cty:"server_side_encryption"`
|
||||
Timeouts *struct {
|
||||
Create *string `cty:"create"`
|
||||
Delete *string `cty:"delete"`
|
||||
Update *string `cty:"update"`
|
||||
} `cty:"timeouts" diff:"-"`
|
||||
Ttl *[]struct {
|
||||
AttributeName *string `cty:"attribute_name"`
|
||||
Enabled *bool `cty:"enabled"`
|
||||
} `cty:"ttl"`
|
||||
}
|
||||
|
||||
func (r *AwsDynamodbTable) TerraformId() string {
|
||||
return r.Id
|
||||
}
|
||||
|
||||
func (r *AwsDynamodbTable) TerraformType() string {
|
||||
return AwsDynamodbTableResourceType
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package aws_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/cloudskiff/driftctl/test/acceptance"
|
||||
)
|
||||
|
||||
func TestAcc_AwsDynamoDBTable(t *testing.T) {
|
||||
acceptance.Run(t, acceptance.AccTestCase{
|
||||
Path: "./testdata/acc/aws_dynamodb_table",
|
||||
Args: []string{"scan", "--filter", "Type=='aws_dynamodb_table'"},
|
||||
Checks: []acceptance.AccCheck{
|
||||
{
|
||||
Env: map[string]string{
|
||||
"AWS_REGION": "us-east-1",
|
||||
},
|
||||
Check: func(result *acceptance.ScanResult, stdout string, err error) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
result.AssertInfrastructureIsInSync()
|
||||
result.AssertManagedCount(2)
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
package deserializer
|
||||
|
||||
import (
|
||||
"github.com/cloudskiff/driftctl/pkg/resource"
|
||||
resourceaws "github.com/cloudskiff/driftctl/pkg/resource/aws"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
"github.com/zclconf/go-cty/cty/gocty"
|
||||
)
|
||||
|
||||
type DynamoDBTableDeserializer struct {
|
||||
}
|
||||
|
||||
func NewDynamoDBTableDeserializer() *DynamoDBTableDeserializer {
|
||||
return &DynamoDBTableDeserializer{}
|
||||
}
|
||||
|
||||
func (s *DynamoDBTableDeserializer) HandledType() resource.ResourceType {
|
||||
return resourceaws.AwsDynamodbTableResourceType
|
||||
}
|
||||
|
||||
func (s DynamoDBTableDeserializer) Deserialize(rawList []cty.Value) ([]resource.Resource, error) {
|
||||
resources := make([]resource.Resource, 0)
|
||||
for _, rawResource := range rawList {
|
||||
rawResource := rawResource
|
||||
resource, err := decodeDynamoDBTable(&rawResource)
|
||||
if err != nil {
|
||||
logrus.Warnf("Error when deserializing resource %+v : %+v", rawResource, err)
|
||||
return nil, err
|
||||
}
|
||||
resources = append(resources, resource)
|
||||
}
|
||||
return resources, nil
|
||||
}
|
||||
|
||||
func decodeDynamoDBTable(raw *cty.Value) (*resourceaws.AwsDynamodbTable, error) {
|
||||
var decoded resourceaws.AwsDynamodbTable
|
||||
if err := gocty.FromCtyValue(*raw, &decoded); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &decoded, nil
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
# This file is maintained automatically by "terraform init".
|
||||
# Manual edits may be lost in future updates.
|
||||
|
||||
provider "registry.terraform.io/hashicorp/aws" {
|
||||
version = "3.27.0"
|
||||
hashes = [
|
||||
"h1:ccxtk7jAtmBPvAEXswOEYJcyp5jTD9QlQeg8GEzYmxQ=",
|
||||
"zh:2986eb5a1ffbb0336c6390aad533b62efc832aa8aa5460d523e1f2daa4f42f79",
|
||||
"zh:825317cdb80860833125a856c0befc877cba22d41c631c5a7ca22400693d4356",
|
||||
"zh:a47aad668cc74058f508c56c5407cd715dbb9b6389aa68d37543e897895db43f",
|
||||
"zh:c0011502d0eb4637918127c3987a8cc07a015ea00f74f4956fd111c736286a4d",
|
||||
"zh:d5088ab51043bb2239132f4ed3760292b6aa4f7296232e4b8017f8c5c34f051a",
|
||||
"zh:d893658e983eb17a23a8124c79a910cc729cb1d751d5509b8e756101c828ad91",
|
||||
"zh:dcc4384ee79ea9492c87eb01e664f7f6b1f1d156471476f30b28336c9d9a4aec",
|
||||
"zh:e4abfaf013f31791cd029af7b6f989f73e3efca28fe2917057b428d051c4085f",
|
||||
"zh:f2a4d9446d23afe2a42421e7d5f902d34451fb31b7787b5e3aef95c08fec5ced",
|
||||
"zh:f54a6af10b077db9dc11556c27f59ba5c60e1b2ba96fe3aa9cd90d8c67d980f6",
|
||||
]
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
provider "aws" {
|
||||
region = "us-east-1"
|
||||
}
|
||||
|
||||
resource "aws_dynamodb_table" "basic-dynamodb-table" {
|
||||
name = "GameScores"
|
||||
billing_mode = "PROVISIONED"
|
||||
read_capacity = 20
|
||||
write_capacity = 20
|
||||
hash_key = "UserId"
|
||||
range_key = "GameTitle"
|
||||
|
||||
attribute {
|
||||
name = "UserId"
|
||||
type = "S"
|
||||
}
|
||||
|
||||
attribute {
|
||||
name = "GameTitle"
|
||||
type = "S"
|
||||
}
|
||||
|
||||
attribute {
|
||||
name = "TopScore"
|
||||
type = "N"
|
||||
}
|
||||
|
||||
ttl {
|
||||
attribute_name = "TimeToExist"
|
||||
enabled = false
|
||||
}
|
||||
|
||||
global_secondary_index {
|
||||
name = "GameTitleIndex"
|
||||
hash_key = "GameTitle"
|
||||
range_key = "TopScore"
|
||||
write_capacity = 10
|
||||
read_capacity = 10
|
||||
projection_type = "INCLUDE"
|
||||
non_key_attributes = ["UserId"]
|
||||
}
|
||||
|
||||
tags = {
|
||||
Name = "dynamodb-table-1"
|
||||
Environment = "production"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_dynamodb_table" "example" {
|
||||
name = "example"
|
||||
hash_key = "TestTableHashKey"
|
||||
billing_mode = "PAY_PER_REQUEST"
|
||||
stream_enabled = true
|
||||
stream_view_type = "NEW_AND_OLD_IMAGES"
|
||||
|
||||
attribute {
|
||||
name = "TestTableHashKey"
|
||||
type = "S"
|
||||
}
|
||||
|
||||
replica {
|
||||
region_name = "us-east-2"
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue