Merge branch 'main' into add_github_branch_protection

main
Elie 2021-03-02 15:47:18 +01:00 committed by GitHub
commit 1c34d869ed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 687776 additions and 5 deletions

View File

@ -105,8 +105,10 @@ As AWS documentation recommends, the below policy is granting only the permissio
"kms:ListAliases",
"kms:ListKeys",
"kms:ListResourceTags",
"lambda:GetEventSourceMapping",
"lambda:GetFunction",
"lambda:GetFunctionCodeSigningConfig",
"lambda:ListEventSourceMappings",
"lambda:ListFunctions",
"lambda:ListVersionsByFunction",
"rds:DescribeDBInstances",
@ -187,7 +189,7 @@ As AWS documentation recommends, the below policy is granting only the permissio
- [x] aws_lambda_function
- [ ] aws_lambda_alias
- [ ] aws_lambda_event_source_mapping
- [x] aws_lambda_event_source_mapping
- [ ] aws_lambda_function_event_invoke_config
- [ ] aws_lambda_layer_version
- [ ] aws_lambda_permission

View File

@ -58,6 +58,7 @@ func Deserializers() []deserializer.CTYDeserializer {
awsdeserializer.NewCloudfrontDistributionDeserializer(),
awsdeserializer.NewKMSKeyDeserializer(),
awsdeserializer.NewKMSAliasDeserializer(),
awsdeserializer.NewLambdaEventSourceMappingDeserializer(),
ghdeserializer.NewGithubRepositoryDeserializer(),
ghdeserializer.NewGithubTeamDeserializer(),

View File

@ -85,6 +85,7 @@ func TestTerraformStateReader_AWS_Resources(t *testing.T) {
{name: "Cloudfront distribution", dirName: "cloudfront_distribution", wantErr: false},
{name: "KMS key", dirName: "kms_key", wantErr: false},
{name: "KMS alias", dirName: "kms_alias", wantErr: false},
{name: "lambda event source mapping", dirName: "aws_lambda_event_source_mapping", wantErr: false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {

View File

@ -0,0 +1,44 @@
[
{
"BatchSize": 1,
"BisectBatchOnFunctionError": false,
"Enabled": true,
"EventSourceArn": "arn:aws:sqs:us-east-1:526954929923:queue1",
"FunctionArn": "arn:aws:lambda:us-east-1:526954929923:function:lambda_function_name",
"FunctionName": "arn:aws:lambda:us-east-1:526954929923:function:lambda_function_name",
"Id": "13ff66f8-37eb-4ad6-a0a8-594fea72df4f",
"LastModified": "2021-03-01T14:09:25Z",
"LastProcessingResult": "",
"MaximumBatchingWindowInSeconds": 0,
"MaximumRecordAgeInSeconds": 0,
"MaximumRetryAttempts": 0,
"ParallelizationFactor": 0,
"StartingPosition": null,
"StartingPositionTimestamp": null,
"State": "Enabled",
"StateTransitionReason": "USER_INITIATED",
"Uuid": "13ff66f8-37eb-4ad6-a0a8-594fea72df4f",
"DestinationConfig": []
},
{
"BatchSize": 1,
"BisectBatchOnFunctionError": false,
"Enabled": true,
"EventSourceArn": "arn:aws:sqs:us-east-1:526954929923:queue2",
"FunctionArn": "arn:aws:lambda:us-east-1:526954929923:function:lambda_function_name",
"FunctionName": "arn:aws:lambda:us-east-1:526954929923:function:lambda_function_name",
"Id": "4ad7e2b3-79e9-4713-9d9d-5af2c01d9058",
"LastModified": "2021-03-01T14:09:25Z",
"LastProcessingResult": "",
"MaximumBatchingWindowInSeconds": 0,
"MaximumRecordAgeInSeconds": 0,
"MaximumRetryAttempts": 0,
"ParallelizationFactor": 0,
"StartingPosition": null,
"StartingPositionTimestamp": null,
"State": "Enabled",
"StateTransitionReason": "USER_INITIATED",
"Uuid": "4ad7e2b3-79e9-4713-9d9d-5af2c01d9058",
"DestinationConfig": []
}
]

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,87 @@
{
"version": 4,
"terraform_version": "0.14.5",
"serial": 119,
"lineage": "30081725-54a2-ce02-6ff5-45c4d961c652",
"outputs": {},
"resources": [
{
"mode": "managed",
"type": "aws_lambda_event_source_mapping",
"name": "sqs1",
"provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
"instances": [
{
"schema_version": 0,
"attributes": {
"batch_size": 1,
"bisect_batch_on_function_error": false,
"destination_config": [],
"enabled": true,
"event_source_arn": "arn:aws:sqs:us-east-1:526954929923:queue1",
"function_arn": "arn:aws:lambda:us-east-1:526954929923:function:lambda_function_name",
"function_name": "arn:aws:lambda:us-east-1:526954929923:function:lambda_function_name",
"id": "13ff66f8-37eb-4ad6-a0a8-594fea72df4f",
"last_modified": "2021-03-01T14:09:25Z",
"last_processing_result": "",
"maximum_batching_window_in_seconds": 0,
"maximum_record_age_in_seconds": 0,
"maximum_retry_attempts": 0,
"parallelization_factor": 0,
"starting_position": null,
"starting_position_timestamp": null,
"state": "Enabled",
"state_transition_reason": "USER_INITIATED",
"uuid": "13ff66f8-37eb-4ad6-a0a8-594fea72df4f"
},
"sensitive_attributes": [],
"private": "bnVsbA==",
"dependencies": [
"aws_iam_role.iam_for_lambda",
"aws_lambda_function.test_lambda",
"aws_sqs_queue.queue1"
]
}
]
},
{
"mode": "managed",
"type": "aws_lambda_event_source_mapping",
"name": "sqs2",
"provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
"instances": [
{
"schema_version": 0,
"attributes": {
"batch_size": 1,
"bisect_batch_on_function_error": false,
"destination_config": [],
"enabled": true,
"event_source_arn": "arn:aws:sqs:us-east-1:526954929923:queue2",
"function_arn": "arn:aws:lambda:us-east-1:526954929923:function:lambda_function_name",
"function_name": "arn:aws:lambda:us-east-1:526954929923:function:lambda_function_name",
"id": "4ad7e2b3-79e9-4713-9d9d-5af2c01d9058",
"last_modified": "2021-03-01T14:09:25Z",
"last_processing_result": "",
"maximum_batching_window_in_seconds": 0,
"maximum_record_age_in_seconds": 0,
"maximum_retry_attempts": 0,
"parallelization_factor": 0,
"starting_position": null,
"starting_position_timestamp": null,
"state": "Enabled",
"state_transition_reason": "USER_INITIATED",
"uuid": "4ad7e2b3-79e9-4713-9d9d-5af2c01d9058"
},
"sensitive_attributes": [],
"private": "bnVsbA==",
"dependencies": [
"aws_iam_role.iam_for_lambda",
"aws_lambda_function.test_lambda",
"aws_sqs_queue.queue2"
]
}
]
}
]
}

View File

@ -73,6 +73,7 @@ func Init(alerter *alerter.Alerter, providerLibrary *terraform.ProviderLibrary,
supplierLibrary.AddSupplier(NewCloudfrontDistributionSupplier(provider))
supplierLibrary.AddSupplier(NewKMSKeySupplier(provider))
supplierLibrary.AddSupplier(NewKMSAliasSupplier(provider))
supplierLibrary.AddSupplier(NewLambdaEventSourceMappingSupplier(provider))
return nil
}

View File

@ -0,0 +1,65 @@
package aws
import (
"github.com/aws/aws-sdk-go/service/lambda"
"github.com/cloudskiff/driftctl/pkg/remote/aws/repository"
"github.com/cloudskiff/driftctl/pkg/remote/deserializer"
remoteerror "github.com/cloudskiff/driftctl/pkg/remote/error"
"github.com/cloudskiff/driftctl/pkg/resource"
resourceaws "github.com/cloudskiff/driftctl/pkg/resource/aws"
awsdeserializer "github.com/cloudskiff/driftctl/pkg/resource/aws/deserializer"
"github.com/cloudskiff/driftctl/pkg/terraform"
"github.com/sirupsen/logrus"
"github.com/zclconf/go-cty/cty"
)
type LambdaEventSourceMappingSupplier struct {
reader terraform.ResourceReader
deserializer deserializer.CTYDeserializer
client repository.LambdaRepository
runner *terraform.ParallelResourceReader
}
func NewLambdaEventSourceMappingSupplier(provider *AWSTerraformProvider) *LambdaEventSourceMappingSupplier {
return &LambdaEventSourceMappingSupplier{
provider,
awsdeserializer.NewLambdaEventSourceMappingDeserializer(),
repository.NewLambdaRepository(provider.session),
terraform.NewParallelResourceReader(provider.Runner().SubRunner()),
}
}
func (s LambdaEventSourceMappingSupplier) Resources() ([]resource.Resource, error) {
functions, err := s.client.ListAllLambdaEventSourceMappings()
if err != nil {
return nil, remoteerror.NewResourceEnumerationError(err, resourceaws.AwsLambdaEventSourceMappingResourceType)
}
var results []cty.Value
for _, function := range functions {
fun := *function
s.runner.Run(func() (cty.Value, error) {
return s.readLambdaEventSourceMapping(fun)
})
}
results, err = s.runner.Wait()
if err != nil {
return nil, err
}
return s.deserializer.Deserialize(results)
}
func (s LambdaEventSourceMappingSupplier) readLambdaEventSourceMapping(sourceMappingConfig lambda.EventSourceMappingConfiguration) (cty.Value, error) {
resFunction, err := s.reader.ReadResource(
terraform.ReadResourceArgs{
Ty: resourceaws.AwsLambdaEventSourceMappingResourceType,
ID: *sourceMappingConfig.UUID,
},
)
if err != nil {
logrus.Warnf("Error reading %s: %+v", resourceaws.AwsLambdaEventSourceMappingResourceType, err)
return cty.NilVal, err
}
return *resFunction, nil
}

View File

@ -0,0 +1,105 @@
package aws
import (
"context"
"testing"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/service/lambda"
"github.com/cloudskiff/driftctl/pkg/parallel"
"github.com/cloudskiff/driftctl/pkg/remote/aws/repository"
remoteerror "github.com/cloudskiff/driftctl/pkg/remote/error"
"github.com/cloudskiff/driftctl/pkg/resource"
resourceaws "github.com/cloudskiff/driftctl/pkg/resource/aws"
awsdeserializer "github.com/cloudskiff/driftctl/pkg/resource/aws/deserializer"
"github.com/cloudskiff/driftctl/pkg/terraform"
"github.com/cloudskiff/driftctl/test"
"github.com/cloudskiff/driftctl/test/goldenfile"
"github.com/cloudskiff/driftctl/test/mocks"
"github.com/stretchr/testify/assert"
)
func TestEventLambdaSourceMappingSupplier_Resources(t *testing.T) {
tests := []struct {
test string
dirName string
mocks func(repo *repository.MockLambdaRepository)
err error
}{
{
test: "no EventSourceMapping",
dirName: "lambda_source_mapping_empty",
mocks: func(repo *repository.MockLambdaRepository) {
repo.On("ListAllLambdaEventSourceMappings").Return([]*lambda.EventSourceMappingConfiguration{}, nil)
},
err: nil,
},
{
test: "with 2 sqs EventSourceMapping",
dirName: "lambda_source_mapping_sqs_multiple",
mocks: func(repo *repository.MockLambdaRepository) {
repo.On("ListAllLambdaEventSourceMappings").Return([]*lambda.EventSourceMappingConfiguration{
{
UUID: aws.String("13ff66f8-37eb-4ad6-a0a8-594fea72df4f"),
},
{
UUID: aws.String("4ad7e2b3-79e9-4713-9d9d-5af2c01d9058"),
},
}, nil)
},
err: nil,
},
{
test: "with dynamo EventSourceMapping",
dirName: "lambda_source_mapping_dynamo_multiple",
mocks: func(repo *repository.MockLambdaRepository) {
repo.On("ListAllLambdaEventSourceMappings").Return([]*lambda.EventSourceMappingConfiguration{
{
UUID: aws.String("1aa9c4a0-060b-41c1-a9ae-dc304ebcdb00"),
},
}, nil)
},
err: nil,
},
{
test: "cannot list lambda functions",
dirName: "lambda_function_empty",
mocks: func(repo *repository.MockLambdaRepository) {
repo.On("ListAllLambdaEventSourceMappings").Return([]*lambda.EventSourceMappingConfiguration{}, awserr.NewRequestFailure(nil, 403, ""))
},
err: remoteerror.NewResourceEnumerationError(awserr.NewRequestFailure(nil, 403, ""), resourceaws.AwsLambdaEventSourceMappingResourceType),
},
}
for _, tt := range tests {
shouldUpdate := tt.dirName == *goldenfile.Update
providerLibrary := terraform.NewProviderLibrary()
supplierLibrary := resource.NewSupplierLibrary()
if shouldUpdate {
provider, err := InitTestAwsProvider(providerLibrary)
if err != nil {
t.Fatal(err)
}
supplierLibrary.AddSupplier(NewLambdaEventSourceMappingSupplier(provider))
}
t.Run(tt.test, func(t *testing.T) {
provider := mocks.NewMockedGoldenTFProvider(tt.dirName, providerLibrary.Provider(terraform.AWS), shouldUpdate)
deserializer := awsdeserializer.NewLambdaEventSourceMappingDeserializer()
client := &repository.MockLambdaRepository{}
tt.mocks(client)
s := &LambdaEventSourceMappingSupplier{
provider,
deserializer,
client,
terraform.NewParallelResourceReader(parallel.NewParallelRunner(context.TODO(), 10)),
}
got, err := s.Resources()
assert.Equal(t, tt.err, err)
test.CtyTestDiff(got, tt.dirName, provider, deserializer, shouldUpdate, t)
})
}
}

View File

@ -1,16 +1,14 @@
package aws
import (
"github.com/aws/aws-sdk-go/service/lambda"
"github.com/cloudskiff/driftctl/pkg/remote/aws/repository"
remoteerror "github.com/cloudskiff/driftctl/pkg/remote/error"
"github.com/cloudskiff/driftctl/pkg/remote/deserializer"
remoteerror "github.com/cloudskiff/driftctl/pkg/remote/error"
"github.com/cloudskiff/driftctl/pkg/resource"
resourceaws "github.com/cloudskiff/driftctl/pkg/resource/aws"
awsdeserializer "github.com/cloudskiff/driftctl/pkg/resource/aws/deserializer"
"github.com/cloudskiff/driftctl/pkg/terraform"
"github.com/aws/aws-sdk-go/service/lambda"
"github.com/sirupsen/logrus"
"github.com/zclconf/go-cty/cty"
)

View File

@ -12,6 +12,7 @@ type LambdaClient interface {
type LambdaRepository interface {
ListAllLambdaFunctions() ([]*lambda.FunctionConfiguration, error)
ListAllLambdaEventSourceMappings() ([]*lambda.EventSourceMappingConfiguration, error)
}
type lambdaRepository struct {
@ -36,3 +37,16 @@ func (r *lambdaRepository) ListAllLambdaFunctions() ([]*lambda.FunctionConfigura
}
return functions, nil
}
func (r *lambdaRepository) ListAllLambdaEventSourceMappings() ([]*lambda.EventSourceMappingConfiguration, error) {
var eventSourceMappingConfigurations []*lambda.EventSourceMappingConfiguration
input := &lambda.ListEventSourceMappingsInput{}
err := r.client.ListEventSourceMappingsPages(input, func(res *lambda.ListEventSourceMappingsOutput, lastPage bool) bool {
eventSourceMappingConfigurations = append(eventSourceMappingConfigurations, res.EventSourceMappings...)
return !lastPage
})
if err != nil {
return nil, err
}
return eventSourceMappingConfigurations, nil
}

View File

@ -78,3 +78,69 @@ func Test_lambdaRepository_ListAllLambdaFunctions(t *testing.T) {
})
}
}
func Test_lambdaRepository_ListAllLambdaEventSourceMappings(t *testing.T) {
tests := []struct {
name string
mocks func(mock *MockLambdaClient)
want []*lambda.EventSourceMappingConfiguration
wantErr error
}{
{
name: "List with 2 pages",
mocks: func(client *MockLambdaClient) {
client.On("ListEventSourceMappingsPages",
&lambda.ListEventSourceMappingsInput{},
mock.MatchedBy(func(callback func(res *lambda.ListEventSourceMappingsOutput, lastPage bool) bool) bool {
callback(&lambda.ListEventSourceMappingsOutput{
EventSourceMappings: []*lambda.EventSourceMappingConfiguration{
{UUID: aws.String("1")},
{UUID: aws.String("2")},
{UUID: aws.String("3")},
{UUID: aws.String("4")},
},
}, false)
callback(&lambda.ListEventSourceMappingsOutput{
EventSourceMappings: []*lambda.EventSourceMappingConfiguration{
{UUID: aws.String("5")},
{UUID: aws.String("6")},
{UUID: aws.String("7")},
{UUID: aws.String("8")},
},
}, true)
return true
})).Return(nil)
},
want: []*lambda.EventSourceMappingConfiguration{
{UUID: aws.String("1")},
{UUID: aws.String("2")},
{UUID: aws.String("3")},
{UUID: aws.String("4")},
{UUID: aws.String("5")},
{UUID: aws.String("6")},
{UUID: aws.String("7")},
{UUID: aws.String("8")},
},
wantErr: nil,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
client := &MockLambdaClient{}
tt.mocks(client)
r := &lambdaRepository{
client: client,
}
got, err := r.ListAllLambdaEventSourceMappings()
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()
}
})
}
}

View File

@ -12,6 +12,29 @@ type MockLambdaRepository struct {
mock.Mock
}
// ListAllLambdaEventSourceMappings provides a mock function with given fields:
func (_m *MockLambdaRepository) ListAllLambdaEventSourceMappings() ([]*lambda.EventSourceMappingConfiguration, error) {
ret := _m.Called()
var r0 []*lambda.EventSourceMappingConfiguration
if rf, ok := ret.Get(0).(func() []*lambda.EventSourceMappingConfiguration); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]*lambda.EventSourceMappingConfiguration)
}
}
var r1 error
if rf, ok := ret.Get(1).(func() error); ok {
r1 = rf()
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// ListAllLambdaFunctions provides a mock function with given fields:
func (_m *MockLambdaRepository) ListAllLambdaFunctions() ([]*lambda.FunctionConfiguration, error) {
ret := _m.Called()

View File

@ -0,0 +1,5 @@
{
"Typ": "WyJvYmplY3QiLHsiYmF0Y2hfc2l6ZSI6Im51bWJlciIsImJpc2VjdF9iYXRjaF9vbl9mdW5jdGlvbl9lcnJvciI6ImJvb2wiLCJkZXN0aW5hdGlvbl9jb25maWciOlsibGlzdCIsWyJvYmplY3QiLHsib25fZmFpbHVyZSI6WyJsaXN0IixbIm9iamVjdCIseyJkZXN0aW5hdGlvbl9hcm4iOiJzdHJpbmcifV1dfV1dLCJlbmFibGVkIjoiYm9vbCIsImV2ZW50X3NvdXJjZV9hcm4iOiJzdHJpbmciLCJmdW5jdGlvbl9hcm4iOiJzdHJpbmciLCJmdW5jdGlvbl9uYW1lIjoic3RyaW5nIiwiaWQiOiJzdHJpbmciLCJsYXN0X21vZGlmaWVkIjoic3RyaW5nIiwibGFzdF9wcm9jZXNzaW5nX3Jlc3VsdCI6InN0cmluZyIsIm1heGltdW1fYmF0Y2hpbmdfd2luZG93X2luX3NlY29uZHMiOiJudW1iZXIiLCJtYXhpbXVtX3JlY29yZF9hZ2VfaW5fc2Vjb25kcyI6Im51bWJlciIsIm1heGltdW1fcmV0cnlfYXR0ZW1wdHMiOiJudW1iZXIiLCJwYXJhbGxlbGl6YXRpb25fZmFjdG9yIjoibnVtYmVyIiwic3RhcnRpbmdfcG9zaXRpb24iOiJzdHJpbmciLCJzdGFydGluZ19wb3NpdGlvbl90aW1lc3RhbXAiOiJzdHJpbmciLCJzdGF0ZSI6InN0cmluZyIsInN0YXRlX3RyYW5zaXRpb25fcmVhc29uIjoic3RyaW5nIiwidXVpZCI6InN0cmluZyJ9XQ==",
"Val": "eyJiYXRjaF9zaXplIjoxMDAsImJpc2VjdF9iYXRjaF9vbl9mdW5jdGlvbl9lcnJvciI6ZmFsc2UsImRlc3RpbmF0aW9uX2NvbmZpZyI6W10sImVuYWJsZWQiOnRydWUsImV2ZW50X3NvdXJjZV9hcm4iOiJhcm46YXdzOmR5bmFtb2RiOnVzLWVhc3QtMTo1MjY5NTQ5Mjk5MjM6dGFibGUvZXhhbXBsZS9zdHJlYW0vMjAyMS0wMy0wMVQxNDoxNDozMi4yODEiLCJmdW5jdGlvbl9hcm4iOiJhcm46YXdzOmxhbWJkYTp1cy1lYXN0LTE6NTI2OTU0OTI5OTIzOmZ1bmN0aW9uOmxhbWJkYV9mdW5jdGlvbl9uYW1lIiwiZnVuY3Rpb25fbmFtZSI6ImFybjphd3M6bGFtYmRhOnVzLWVhc3QtMTo1MjY5NTQ5Mjk5MjM6ZnVuY3Rpb246bGFtYmRhX2Z1bmN0aW9uX25hbWUiLCJpZCI6IjFhYTljNGEwLTA2MGItNDFjMS1hOWFlLWRjMzA0ZWJjZGIwMCIsImxhc3RfbW9kaWZpZWQiOiIyMDIxLTAzLTAxVDE1OjAzOjAwWiIsImxhc3RfcHJvY2Vzc2luZ19yZXN1bHQiOiJObyByZWNvcmRzIHByb2Nlc3NlZCIsIm1heGltdW1fYmF0Y2hpbmdfd2luZG93X2luX3NlY29uZHMiOjAsIm1heGltdW1fcmVjb3JkX2FnZV9pbl9zZWNvbmRzIjotMSwibWF4aW11bV9yZXRyeV9hdHRlbXB0cyI6LTEsInBhcmFsbGVsaXphdGlvbl9mYWN0b3IiOjEsInN0YXJ0aW5nX3Bvc2l0aW9uIjpudWxsLCJzdGFydGluZ19wb3NpdGlvbl90aW1lc3RhbXAiOm51bGwsInN0YXRlIjoiRW5hYmxlZCIsInN0YXRlX3RyYW5zaXRpb25fcmVhc29uIjoiVXNlciBhY3Rpb24iLCJ1dWlkIjoiMWFhOWM0YTAtMDYwYi00MWMxLWE5YWUtZGMzMDRlYmNkYjAwIn0=",
"Err": null
}

View File

@ -0,0 +1,23 @@
[
{
"batch_size": 100,
"bisect_batch_on_function_error": false,
"destination_config": [],
"enabled": true,
"event_source_arn": "arn:aws:dynamodb:us-east-1:526954929923:table/example/stream/2021-03-01T14:14:32.281",
"function_arn": "arn:aws:lambda:us-east-1:526954929923:function:lambda_function_name",
"function_name": "arn:aws:lambda:us-east-1:526954929923:function:lambda_function_name",
"id": "1aa9c4a0-060b-41c1-a9ae-dc304ebcdb00",
"last_modified": "2021-03-01T15:03:00Z",
"last_processing_result": "No records processed",
"maximum_batching_window_in_seconds": 0,
"maximum_record_age_in_seconds": -1,
"maximum_retry_attempts": -1,
"parallelization_factor": 1,
"starting_position": null,
"starting_position_timestamp": null,
"state": "Enabled",
"state_transition_reason": "User action",
"uuid": "1aa9c4a0-060b-41c1-a9ae-dc304ebcdb00"
}
]

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@
[]

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,5 @@
{
"Typ": "WyJvYmplY3QiLHsiYmF0Y2hfc2l6ZSI6Im51bWJlciIsImJpc2VjdF9iYXRjaF9vbl9mdW5jdGlvbl9lcnJvciI6ImJvb2wiLCJkZXN0aW5hdGlvbl9jb25maWciOlsibGlzdCIsWyJvYmplY3QiLHsib25fZmFpbHVyZSI6WyJsaXN0IixbIm9iamVjdCIseyJkZXN0aW5hdGlvbl9hcm4iOiJzdHJpbmcifV1dfV1dLCJlbmFibGVkIjoiYm9vbCIsImV2ZW50X3NvdXJjZV9hcm4iOiJzdHJpbmciLCJmdW5jdGlvbl9hcm4iOiJzdHJpbmciLCJmdW5jdGlvbl9uYW1lIjoic3RyaW5nIiwiaWQiOiJzdHJpbmciLCJsYXN0X21vZGlmaWVkIjoic3RyaW5nIiwibGFzdF9wcm9jZXNzaW5nX3Jlc3VsdCI6InN0cmluZyIsIm1heGltdW1fYmF0Y2hpbmdfd2luZG93X2luX3NlY29uZHMiOiJudW1iZXIiLCJtYXhpbXVtX3JlY29yZF9hZ2VfaW5fc2Vjb25kcyI6Im51bWJlciIsIm1heGltdW1fcmV0cnlfYXR0ZW1wdHMiOiJudW1iZXIiLCJwYXJhbGxlbGl6YXRpb25fZmFjdG9yIjoibnVtYmVyIiwic3RhcnRpbmdfcG9zaXRpb24iOiJzdHJpbmciLCJzdGFydGluZ19wb3NpdGlvbl90aW1lc3RhbXAiOiJzdHJpbmciLCJzdGF0ZSI6InN0cmluZyIsInN0YXRlX3RyYW5zaXRpb25fcmVhc29uIjoic3RyaW5nIiwidXVpZCI6InN0cmluZyJ9XQ==",
"Val": "eyJiYXRjaF9zaXplIjoxLCJiaXNlY3RfYmF0Y2hfb25fZnVuY3Rpb25fZXJyb3IiOmZhbHNlLCJkZXN0aW5hdGlvbl9jb25maWciOltdLCJlbmFibGVkIjp0cnVlLCJldmVudF9zb3VyY2VfYXJuIjoiYXJuOmF3czpzcXM6dXMtZWFzdC0xOjUyNjk1NDkyOTkyMzpxdWV1ZTEiLCJmdW5jdGlvbl9hcm4iOiJhcm46YXdzOmxhbWJkYTp1cy1lYXN0LTE6NTI2OTU0OTI5OTIzOmZ1bmN0aW9uOmxhbWJkYV9mdW5jdGlvbl9uYW1lIiwiZnVuY3Rpb25fbmFtZSI6ImFybjphd3M6bGFtYmRhOnVzLWVhc3QtMTo1MjY5NTQ5Mjk5MjM6ZnVuY3Rpb246bGFtYmRhX2Z1bmN0aW9uX25hbWUiLCJpZCI6IjEzZmY2NmY4LTM3ZWItNGFkNi1hMGE4LTU5NGZlYTcyZGY0ZiIsImxhc3RfbW9kaWZpZWQiOiIyMDIxLTAzLTAxVDE0OjA5OjI1WiIsImxhc3RfcHJvY2Vzc2luZ19yZXN1bHQiOiIiLCJtYXhpbXVtX2JhdGNoaW5nX3dpbmRvd19pbl9zZWNvbmRzIjowLCJtYXhpbXVtX3JlY29yZF9hZ2VfaW5fc2Vjb25kcyI6MCwibWF4aW11bV9yZXRyeV9hdHRlbXB0cyI6MCwicGFyYWxsZWxpemF0aW9uX2ZhY3RvciI6MCwic3RhcnRpbmdfcG9zaXRpb24iOm51bGwsInN0YXJ0aW5nX3Bvc2l0aW9uX3RpbWVzdGFtcCI6bnVsbCwic3RhdGUiOiJFbmFibGVkIiwic3RhdGVfdHJhbnNpdGlvbl9yZWFzb24iOiJVU0VSX0lOSVRJQVRFRCIsInV1aWQiOiIxM2ZmNjZmOC0zN2ViLTRhZDYtYTBhOC01OTRmZWE3MmRmNGYifQ==",
"Err": null
}

View File

@ -0,0 +1,5 @@
{
"Typ": "WyJvYmplY3QiLHsiYmF0Y2hfc2l6ZSI6Im51bWJlciIsImJpc2VjdF9iYXRjaF9vbl9mdW5jdGlvbl9lcnJvciI6ImJvb2wiLCJkZXN0aW5hdGlvbl9jb25maWciOlsibGlzdCIsWyJvYmplY3QiLHsib25fZmFpbHVyZSI6WyJsaXN0IixbIm9iamVjdCIseyJkZXN0aW5hdGlvbl9hcm4iOiJzdHJpbmcifV1dfV1dLCJlbmFibGVkIjoiYm9vbCIsImV2ZW50X3NvdXJjZV9hcm4iOiJzdHJpbmciLCJmdW5jdGlvbl9hcm4iOiJzdHJpbmciLCJmdW5jdGlvbl9uYW1lIjoic3RyaW5nIiwiaWQiOiJzdHJpbmciLCJsYXN0X21vZGlmaWVkIjoic3RyaW5nIiwibGFzdF9wcm9jZXNzaW5nX3Jlc3VsdCI6InN0cmluZyIsIm1heGltdW1fYmF0Y2hpbmdfd2luZG93X2luX3NlY29uZHMiOiJudW1iZXIiLCJtYXhpbXVtX3JlY29yZF9hZ2VfaW5fc2Vjb25kcyI6Im51bWJlciIsIm1heGltdW1fcmV0cnlfYXR0ZW1wdHMiOiJudW1iZXIiLCJwYXJhbGxlbGl6YXRpb25fZmFjdG9yIjoibnVtYmVyIiwic3RhcnRpbmdfcG9zaXRpb24iOiJzdHJpbmciLCJzdGFydGluZ19wb3NpdGlvbl90aW1lc3RhbXAiOiJzdHJpbmciLCJzdGF0ZSI6InN0cmluZyIsInN0YXRlX3RyYW5zaXRpb25fcmVhc29uIjoic3RyaW5nIiwidXVpZCI6InN0cmluZyJ9XQ==",
"Val": "eyJiYXRjaF9zaXplIjoxLCJiaXNlY3RfYmF0Y2hfb25fZnVuY3Rpb25fZXJyb3IiOmZhbHNlLCJkZXN0aW5hdGlvbl9jb25maWciOltdLCJlbmFibGVkIjp0cnVlLCJldmVudF9zb3VyY2VfYXJuIjoiYXJuOmF3czpzcXM6dXMtZWFzdC0xOjUyNjk1NDkyOTkyMzpxdWV1ZTIiLCJmdW5jdGlvbl9hcm4iOiJhcm46YXdzOmxhbWJkYTp1cy1lYXN0LTE6NTI2OTU0OTI5OTIzOmZ1bmN0aW9uOmxhbWJkYV9mdW5jdGlvbl9uYW1lIiwiZnVuY3Rpb25fbmFtZSI6ImFybjphd3M6bGFtYmRhOnVzLWVhc3QtMTo1MjY5NTQ5Mjk5MjM6ZnVuY3Rpb246bGFtYmRhX2Z1bmN0aW9uX25hbWUiLCJpZCI6IjRhZDdlMmIzLTc5ZTktNDcxMy05ZDlkLTVhZjJjMDFkOTA1OCIsImxhc3RfbW9kaWZpZWQiOiIyMDIxLTAzLTAxVDE0OjA5OjI1WiIsImxhc3RfcHJvY2Vzc2luZ19yZXN1bHQiOiIiLCJtYXhpbXVtX2JhdGNoaW5nX3dpbmRvd19pbl9zZWNvbmRzIjowLCJtYXhpbXVtX3JlY29yZF9hZ2VfaW5fc2Vjb25kcyI6MCwibWF4aW11bV9yZXRyeV9hdHRlbXB0cyI6MCwicGFyYWxsZWxpemF0aW9uX2ZhY3RvciI6MCwic3RhcnRpbmdfcG9zaXRpb24iOm51bGwsInN0YXJ0aW5nX3Bvc2l0aW9uX3RpbWVzdGFtcCI6bnVsbCwic3RhdGUiOiJFbmFibGVkIiwic3RhdGVfdHJhbnNpdGlvbl9yZWFzb24iOiJVU0VSX0lOSVRJQVRFRCIsInV1aWQiOiI0YWQ3ZTJiMy03OWU5LTQ3MTMtOWQ5ZC01YWYyYzAxZDkwNTgifQ==",
"Err": null
}

View File

@ -0,0 +1,44 @@
[
{
"batch_size": 1,
"bisect_batch_on_function_error": false,
"destination_config": [],
"enabled": true,
"event_source_arn": "arn:aws:sqs:us-east-1:526954929923:queue2",
"function_arn": "arn:aws:lambda:us-east-1:526954929923:function:lambda_function_name",
"function_name": "arn:aws:lambda:us-east-1:526954929923:function:lambda_function_name",
"id": "4ad7e2b3-79e9-4713-9d9d-5af2c01d9058",
"last_modified": "2021-03-01T14:09:25Z",
"last_processing_result": "",
"maximum_batching_window_in_seconds": 0,
"maximum_record_age_in_seconds": 0,
"maximum_retry_attempts": 0,
"parallelization_factor": 0,
"starting_position": null,
"starting_position_timestamp": null,
"state": "Enabled",
"state_transition_reason": "USER_INITIATED",
"uuid": "4ad7e2b3-79e9-4713-9d9d-5af2c01d9058"
},
{
"batch_size": 1,
"bisect_batch_on_function_error": false,
"destination_config": [],
"enabled": true,
"event_source_arn": "arn:aws:sqs:us-east-1:526954929923:queue1",
"function_arn": "arn:aws:lambda:us-east-1:526954929923:function:lambda_function_name",
"function_name": "arn:aws:lambda:us-east-1:526954929923:function:lambda_function_name",
"id": "13ff66f8-37eb-4ad6-a0a8-594fea72df4f",
"last_modified": "2021-03-01T14:09:25Z",
"last_processing_result": "",
"maximum_batching_window_in_seconds": 0,
"maximum_record_age_in_seconds": 0,
"maximum_retry_attempts": 0,
"parallelization_factor": 0,
"starting_position": null,
"starting_position_timestamp": null,
"state": "Enabled",
"state_transition_reason": "USER_INITIATED",
"uuid": "13ff66f8-37eb-4ad6-a0a8-594fea72df4f"
}
]

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,38 @@
// GENERATED, DO NOT EDIT THIS FILE
package aws
const AwsLambdaEventSourceMappingResourceType = "aws_lambda_event_source_mapping"
type AwsLambdaEventSourceMapping struct {
BatchSize *int `cty:"batch_size"`
BisectBatchOnFunctionError *bool `cty:"bisect_batch_on_function_error"`
Enabled *bool `cty:"enabled"`
EventSourceArn *string `cty:"event_source_arn"`
FunctionArn *string `cty:"function_arn" computed:"true"`
FunctionName *string `cty:"function_name"`
Id string `cty:"id" computed:"true"`
LastModified *string `cty:"last_modified" computed:"true" diff:"-"`
LastProcessingResult *string `cty:"last_processing_result" computed:"true" diff:"-"`
MaximumBatchingWindowInSeconds *int `cty:"maximum_batching_window_in_seconds"`
MaximumRecordAgeInSeconds *int `cty:"maximum_record_age_in_seconds" computed:"true"`
MaximumRetryAttempts *int `cty:"maximum_retry_attempts" computed:"true"`
ParallelizationFactor *int `cty:"parallelization_factor" computed:"true"`
StartingPosition *string `cty:"starting_position" diff:"-"`
StartingPositionTimestamp *string `cty:"starting_position_timestamp" diff:"-"`
State *string `cty:"state" computed:"true" diff:"-"`
StateTransitionReason *string `cty:"state_transition_reason" computed:"true" diff:"-"`
Uuid *string `cty:"uuid" computed:"true"`
DestinationConfig *[]struct {
OnFailure *[]struct {
DestinationArn *string `cty:"destination_arn"`
} `cty:"on_failure"`
} `cty:"destination_config"`
}
func (r *AwsLambdaEventSourceMapping) TerraformId() string {
return r.Id
}
func (r *AwsLambdaEventSourceMapping) TerraformType() string {
return AwsLambdaEventSourceMappingResourceType
}

View File

@ -0,0 +1,11 @@
// GENERATED, DO NOT EDIT THIS FILE
package aws
import "fmt"
func (r *AwsLambdaEventSourceMapping) String() string {
if r.EventSourceArn == nil || *r.EventSourceArn == "" || r.FunctionName == nil || *r.FunctionName == "" {
return r.Id
}
return fmt.Sprintf("Source: %s Dest: %s", *r.EventSourceArn, *r.FunctionName)
}

View File

@ -0,0 +1,28 @@
package aws_test
import (
"testing"
"github.com/cloudskiff/driftctl/test/acceptance"
)
func TestAcc_AwsLambdaEventSourceMapping(t *testing.T) {
acceptance.Run(t, acceptance.AccTestCase{
Paths: []string{"./testdata/acc/aws_lambda_event_source_mapping"},
Args: []string{"scan", "--filter", "Type=='aws_lambda_event_source_mapping'"},
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(3)
},
},
},
})
}

View File

@ -0,0 +1,38 @@
package deserializer
import (
"github.com/cloudskiff/driftctl/pkg/resource"
"github.com/cloudskiff/driftctl/pkg/resource/aws"
"github.com/zclconf/go-cty/cty"
"github.com/zclconf/go-cty/cty/gocty"
)
type LambdaEventSourceMappingTopicDeserializer struct {
}
func NewLambdaEventSourceMappingDeserializer() *LambdaEventSourceMappingTopicDeserializer {
return &LambdaEventSourceMappingTopicDeserializer{}
}
func (s *LambdaEventSourceMappingTopicDeserializer) HandledType() resource.ResourceType {
return aws.AwsLambdaEventSourceMappingResourceType
}
func (s LambdaEventSourceMappingTopicDeserializer) Deserialize(values []cty.Value) ([]resource.Resource, error) {
decoded := make([]resource.Resource, 0)
for _, value := range values {
eventSourceMapping, err := decodeLambdaEventSourceMapping(value)
if err != nil {
return nil, err
}
decoded = append(decoded, eventSourceMapping)
}
return decoded, nil
}
func decodeLambdaEventSourceMapping(value cty.Value) (resource.Resource, error) {
var eventSourceMapping aws.AwsLambdaEventSourceMapping
err := gocty.FromCtyValue(value, &eventSourceMapping)
return &eventSourceMapping, err
}

View File

@ -0,0 +1,20 @@
# This file is maintained automatically by "terraform init".
# Manual edits may be lost in future updates.
provider "registry.terraform.io/hashicorp/aws" {
version = "3.30.0"
hashes = [
"h1:z9kdXY2A/+dIZrPy9hNlg/B5I/AuETQsp0jz9EgprIQ=",
"zh:01f562a6a31fe46a8ca74804f360e3452b26f71abc549ce1f0ab5a8af2484cdf",
"zh:25bacc5ed725051f0ab1f7d575e45c901e5b8e1d50da4156a31dda92b2b7e481",
"zh:349b79979d9169db614d8ebd1bc2e0caeb7a38dc816e261b8b2b4b5204615519",
"zh:5e41446acc54c6fc15e82c3fa14b72174b30eba81e0711ede297e5620c55a628",
"zh:68ad98f6d612bdc35a65d48950abc8e75c69decb49db28258ce8eeb5458586b7",
"zh:704603d65e8bac17d203b57c2db142c3134a91076e1b4a31c40f75eb3257dde8",
"zh:a362c700032b2db047d16007d52f28b3f216d32671b6b355d23bdaa082c66a4b",
"zh:bd197797b41268de3c93cad02b7c655dc0c4d8661abb37544ca049e6b1eccae6",
"zh:deb12ef0e3396a71d485977ddc14b695775f7937097ebf2b2f53ed348a4365e7",
"zh:ec8a7d0f02738f290107d39bf401d68ddce82a95cd9d998003f7e04b3a196411",
"zh:ffcc43b6c5e7f26c55e2a8c539d7370fca8042722400a3e06bdce4240bd7088a",
]
}

View File

@ -0,0 +1,118 @@
provider "aws" {
region = "us-east-1"
}
resource "aws_sqs_queue" "queue1" {
name = "queue1"
delay_seconds = 90
max_message_size = 2048
message_retention_seconds = 86400
receive_wait_time_seconds = 10
}
resource "aws_sqs_queue" "queue2" {
name = "queue2"
delay_seconds = 90
max_message_size = 2048
message_retention_seconds = 86400
receive_wait_time_seconds = 10
}
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"
}
}
resource "aws_iam_role" "iam_for_lambda" {
name = "iam_for_lambda"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
}
resource "aws_iam_policy" "policy" {
name = "policy"
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"sqs:ReceiveMessage",
"sqs:DeleteMessage",
"sqs:GetQueueAttributes",
"dynamodb:GetRecords",
"dynamodb:GetShardIterator",
"dynamodb:DescribeStream",
"dynamodb:ListShards",
"dynamodb:ListStreams"
],
"Resource": "*"
}
]
}
EOF
}
resource "aws_iam_policy_attachment" "policy_attachment" {
name = "attachment"
roles = [aws_iam_role.iam_for_lambda.name]
policy_arn = aws_iam_policy.policy.arn
}
resource "aws_lambda_function" "test_lambda" {
filename = "function.zip"
function_name = "lambda_function_name"
role = aws_iam_role.iam_for_lambda.arn
handler = "exports.test"
runtime = "nodejs12.x"
environment {
variables = {
foo = "bar"
}
}
}
resource "aws_lambda_event_source_mapping" "sqs1" {
event_source_arn = aws_sqs_queue.queue1.arn
enabled = true
function_name = aws_lambda_function.test_lambda.arn
batch_size = 1
}
resource "aws_lambda_event_source_mapping" "sqs2" {
event_source_arn = aws_sqs_queue.queue2.arn
enabled = true
function_name = aws_lambda_function.test_lambda.arn
batch_size = 1
}
resource "aws_lambda_event_source_mapping" "dynamo" {
event_source_arn = aws_dynamodb_table.example.stream_arn
function_name = aws_lambda_function.test_lambda.arn
starting_position = "LATEST"
}