support to create dynamodb resource by cloudformation (#2219)

* support to create dynamodb resource by cloudformation
This commit is contained in:
Koudai Aono 2019-05-25 18:16:33 +09:00 committed by Terry Cain
parent cb72d1d00e
commit a61124f774
3 changed files with 153 additions and 2 deletions

View File

@ -12,7 +12,7 @@ from moto.batch import models as batch_models
from moto.cloudwatch import models as cloudwatch_models
from moto.cognitoidentity import models as cognitoidentity_models
from moto.datapipeline import models as datapipeline_models
from moto.dynamodb import models as dynamodb_models
from moto.dynamodb2 import models as dynamodb2_models
from moto.ec2 import models as ec2_models
from moto.ecs import models as ecs_models
from moto.elb import models as elb_models
@ -37,7 +37,7 @@ MODEL_MAP = {
"AWS::Batch::JobDefinition": batch_models.JobDefinition,
"AWS::Batch::JobQueue": batch_models.JobQueue,
"AWS::Batch::ComputeEnvironment": batch_models.ComputeEnvironment,
"AWS::DynamoDB::Table": dynamodb_models.Table,
"AWS::DynamoDB::Table": dynamodb2_models.Table,
"AWS::Kinesis::Stream": kinesis_models.Stream,
"AWS::Lambda::EventSourceMapping": lambda_models.EventSourceMapping,
"AWS::Lambda::Function": lambda_models.LambdaFunction,

View File

@ -417,6 +417,25 @@ class Table(BaseModel):
}
self.set_stream_specification(streams)
@classmethod
def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):
properties = cloudformation_json['Properties']
params = {}
if 'KeySchema' in properties:
params['schema'] = properties['KeySchema']
if 'AttributeDefinitions' in properties:
params['attr'] = properties['AttributeDefinitions']
if 'GlobalSecondaryIndexes' in properties:
params['global_indexes'] = properties['GlobalSecondaryIndexes']
if 'ProvisionedThroughput' in properties:
params['throughput'] = properties['ProvisionedThroughput']
if 'LocalSecondaryIndexes' in properties:
params['indexes'] = properties['LocalSecondaryIndexes']
table = dynamodb_backends[region_name].create_table(name=properties['TableName'], **params)
return table
def _generate_arn(self, name):
return 'arn:aws:dynamodb:us-east-1:123456789011:table/' + name

View File

@ -2,6 +2,8 @@ from __future__ import unicode_literals
import json
import base64
from decimal import Decimal
import boto
import boto.cloudformation
import boto.datapipeline
@ -22,6 +24,7 @@ from moto import (
mock_cloudformation,
mock_cloudformation_deprecated,
mock_datapipeline_deprecated,
mock_dynamodb2,
mock_ec2,
mock_ec2_deprecated,
mock_elb,
@ -39,6 +42,7 @@ from moto import (
mock_sqs,
mock_sqs_deprecated,
mock_elbv2)
from moto.dynamodb2.models import Table
from .fixtures import (
ec2_classic_eip,
@ -2433,3 +2437,131 @@ def test_stack_elbv2_resources_integration():
dns['OutputValue'].should.equal(load_balancers[0]['DNSName'])
name['OutputValue'].should.equal(load_balancers[0]['LoadBalancerName'])
@mock_dynamodb2
@mock_cloudformation
def test_stack_dynamodb_resources_integration():
dynamodb_template = {
"AWSTemplateFormatVersion": "2010-09-09",
"Resources": {
"myDynamoDBTable": {
"Type": "AWS::DynamoDB::Table",
"Properties": {
"AttributeDefinitions": [
{
"AttributeName": "Album",
"AttributeType": "S"
},
{
"AttributeName": "Artist",
"AttributeType": "S"
},
{
"AttributeName": "Sales",
"AttributeType": "N"
},
{
"AttributeName": "NumberOfSongs",
"AttributeType": "N"
}
],
"KeySchema": [
{
"AttributeName": "Album",
"KeyType": "HASH"
},
{
"AttributeName": "Artist",
"KeyType": "RANGE"
}
],
"ProvisionedThroughput": {
"ReadCapacityUnits": "5",
"WriteCapacityUnits": "5"
},
"TableName": "myTableName",
"GlobalSecondaryIndexes": [{
"IndexName": "myGSI",
"KeySchema": [
{
"AttributeName": "Sales",
"KeyType": "HASH"
},
{
"AttributeName": "Artist",
"KeyType": "RANGE"
}
],
"Projection": {
"NonKeyAttributes": ["Album","NumberOfSongs"],
"ProjectionType": "INCLUDE"
},
"ProvisionedThroughput": {
"ReadCapacityUnits": "5",
"WriteCapacityUnits": "5"
}
},
{
"IndexName": "myGSI2",
"KeySchema": [
{
"AttributeName": "NumberOfSongs",
"KeyType": "HASH"
},
{
"AttributeName": "Sales",
"KeyType": "RANGE"
}
],
"Projection": {
"NonKeyAttributes": ["Album","Artist"],
"ProjectionType": "INCLUDE"
},
"ProvisionedThroughput": {
"ReadCapacityUnits": "5",
"WriteCapacityUnits": "5"
}
}],
"LocalSecondaryIndexes":[{
"IndexName": "myLSI",
"KeySchema": [
{
"AttributeName": "Album",
"KeyType": "HASH"
},
{
"AttributeName": "Sales",
"KeyType": "RANGE"
}
],
"Projection": {
"NonKeyAttributes": ["Artist","NumberOfSongs"],
"ProjectionType": "INCLUDE"
}
}]
}
}
}
}
dynamodb_template_json = json.dumps(dynamodb_template)
cfn_conn = boto3.client('cloudformation', 'us-east-1')
cfn_conn.create_stack(
StackName='dynamodb_stack',
TemplateBody=dynamodb_template_json,
)
dynamodb_conn = boto3.resource('dynamodb', region_name='us-east-1')
table = dynamodb_conn.Table('myTableName')
table.name.should.equal('myTableName')
table.put_item(Item={"Album": "myAlbum", "Artist": "myArtist", "Sales": 10, "NumberOfSongs": 5})
response = table.get_item(Key={"Album": "myAlbum", "Artist": "myArtist"})
response['Item']['Album'].should.equal('myAlbum')
response['Item']['Sales'].should.equal(Decimal('10'))
response['Item']['NumberOfSongs'].should.equal(Decimal('5'))
response['Item']['Album'].should.equal('myAlbum')