Iam cloudformation update, singificant cloudformation refactoring (#3218)
* IAM User Cloudformation Enhancements: update, delete, getatt. * AWS::IAM::Policy Support * Added unit tests for AWS:IAM:Policy for roles and groups. Fixed bug related to groups. * AWS:IAM:AccessKey CloudFormation support. * Refactor of CloudFormation parsing.py methods to simplify and standardize how they call to the models. Adjusted some models accordingly. * Further model CloudFormation support changes to align with revised CloudFormation logic. Mostly avoidance of getting resoure name from properties. * Support for Kinesis Stream RetentionPeriodHours param. * Kinesis Stream Cloudformation Tag Support. * Added omitted 'region' param to boto3.client() calls in new tests. Co-authored-by: Joseph Weitekamp <jweite@amazon.com>
This commit is contained in:
parent
3b06ce689e
commit
49d92861c0
25 changed files with 1912 additions and 318 deletions
|
|
@ -2,7 +2,6 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
import datetime
|
||||
import os
|
||||
import sys
|
||||
|
||||
from boto3 import Session
|
||||
|
|
@ -11,7 +10,6 @@ from six.moves.urllib.error import HTTPError
|
|||
from functools import wraps
|
||||
from gzip import GzipFile
|
||||
from io import BytesIO
|
||||
import mimetypes
|
||||
import zlib
|
||||
import pickle
|
||||
import uuid
|
||||
|
|
@ -36,7 +34,7 @@ from nose.tools import assert_raises
|
|||
|
||||
import sure # noqa
|
||||
|
||||
from moto import settings, mock_s3, mock_s3_deprecated, mock_config, mock_cloudformation
|
||||
from moto import settings, mock_s3, mock_s3_deprecated, mock_config
|
||||
import moto.s3.models as s3model
|
||||
from moto.core.exceptions import InvalidNextTokenException
|
||||
from moto.core.utils import py2_strip_unicode_keys
|
||||
|
|
@ -4686,142 +4684,3 @@ def test_presigned_put_url_with_custom_headers():
|
|||
|
||||
s3.delete_object(Bucket=bucket, Key=key)
|
||||
s3.delete_bucket(Bucket=bucket)
|
||||
|
||||
|
||||
@mock_s3
|
||||
@mock_cloudformation
|
||||
def test_s3_bucket_cloudformation_basic():
|
||||
s3 = boto3.client("s3", region_name="us-east-1")
|
||||
cf = boto3.client("cloudformation", region_name="us-east-1")
|
||||
|
||||
template = {
|
||||
"AWSTemplateFormatVersion": "2010-09-09",
|
||||
"Resources": {"testInstance": {"Type": "AWS::S3::Bucket", "Properties": {},}},
|
||||
"Outputs": {"Bucket": {"Value": {"Ref": "testInstance"}}},
|
||||
}
|
||||
template_json = json.dumps(template)
|
||||
stack_id = cf.create_stack(StackName="test_stack", TemplateBody=template_json)[
|
||||
"StackId"
|
||||
]
|
||||
stack_description = cf.describe_stacks(StackName="test_stack")["Stacks"][0]
|
||||
|
||||
s3.head_bucket(Bucket=stack_description["Outputs"][0]["OutputValue"])
|
||||
|
||||
|
||||
@mock_s3
|
||||
@mock_cloudformation
|
||||
def test_s3_bucket_cloudformation_with_properties():
|
||||
s3 = boto3.client("s3", region_name="us-east-1")
|
||||
cf = boto3.client("cloudformation", region_name="us-east-1")
|
||||
|
||||
bucket_name = "MyBucket"
|
||||
template = {
|
||||
"AWSTemplateFormatVersion": "2010-09-09",
|
||||
"Resources": {
|
||||
"testInstance": {
|
||||
"Type": "AWS::S3::Bucket",
|
||||
"Properties": {
|
||||
"BucketName": bucket_name,
|
||||
"BucketEncryption": {
|
||||
"ServerSideEncryptionConfiguration": [
|
||||
{
|
||||
"ServerSideEncryptionByDefault": {
|
||||
"SSEAlgorithm": "AES256"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
"Outputs": {"Bucket": {"Value": {"Ref": "testInstance"}}},
|
||||
}
|
||||
template_json = json.dumps(template)
|
||||
stack_id = cf.create_stack(StackName="test_stack", TemplateBody=template_json)[
|
||||
"StackId"
|
||||
]
|
||||
stack_description = cf.describe_stacks(StackName="test_stack")["Stacks"][0]
|
||||
s3.head_bucket(Bucket=bucket_name)
|
||||
|
||||
encryption = s3.get_bucket_encryption(Bucket=bucket_name)
|
||||
encryption["ServerSideEncryptionConfiguration"]["Rules"][0][
|
||||
"ApplyServerSideEncryptionByDefault"
|
||||
]["SSEAlgorithm"].should.equal("AES256")
|
||||
|
||||
|
||||
@mock_s3
|
||||
@mock_cloudformation
|
||||
def test_s3_bucket_cloudformation_update_no_interruption():
|
||||
s3 = boto3.client("s3", region_name="us-east-1")
|
||||
cf = boto3.client("cloudformation", region_name="us-east-1")
|
||||
|
||||
template = {
|
||||
"AWSTemplateFormatVersion": "2010-09-09",
|
||||
"Resources": {"testInstance": {"Type": "AWS::S3::Bucket"}},
|
||||
"Outputs": {"Bucket": {"Value": {"Ref": "testInstance"}}},
|
||||
}
|
||||
template_json = json.dumps(template)
|
||||
cf.create_stack(StackName="test_stack", TemplateBody=template_json)
|
||||
stack_description = cf.describe_stacks(StackName="test_stack")["Stacks"][0]
|
||||
s3.head_bucket(Bucket=stack_description["Outputs"][0]["OutputValue"])
|
||||
|
||||
template = {
|
||||
"AWSTemplateFormatVersion": "2010-09-09",
|
||||
"Resources": {
|
||||
"testInstance": {
|
||||
"Type": "AWS::S3::Bucket",
|
||||
"Properties": {
|
||||
"BucketEncryption": {
|
||||
"ServerSideEncryptionConfiguration": [
|
||||
{
|
||||
"ServerSideEncryptionByDefault": {
|
||||
"SSEAlgorithm": "AES256"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
"Outputs": {"Bucket": {"Value": {"Ref": "testInstance"}}},
|
||||
}
|
||||
template_json = json.dumps(template)
|
||||
cf.update_stack(StackName="test_stack", TemplateBody=template_json)
|
||||
encryption = s3.get_bucket_encryption(
|
||||
Bucket=stack_description["Outputs"][0]["OutputValue"]
|
||||
)
|
||||
encryption["ServerSideEncryptionConfiguration"]["Rules"][0][
|
||||
"ApplyServerSideEncryptionByDefault"
|
||||
]["SSEAlgorithm"].should.equal("AES256")
|
||||
|
||||
|
||||
@mock_s3
|
||||
@mock_cloudformation
|
||||
def test_s3_bucket_cloudformation_update_replacement():
|
||||
s3 = boto3.client("s3", region_name="us-east-1")
|
||||
cf = boto3.client("cloudformation", region_name="us-east-1")
|
||||
|
||||
template = {
|
||||
"AWSTemplateFormatVersion": "2010-09-09",
|
||||
"Resources": {"testInstance": {"Type": "AWS::S3::Bucket"}},
|
||||
"Outputs": {"Bucket": {"Value": {"Ref": "testInstance"}}},
|
||||
}
|
||||
template_json = json.dumps(template)
|
||||
cf.create_stack(StackName="test_stack", TemplateBody=template_json)
|
||||
stack_description = cf.describe_stacks(StackName="test_stack")["Stacks"][0]
|
||||
s3.head_bucket(Bucket=stack_description["Outputs"][0]["OutputValue"])
|
||||
|
||||
template = {
|
||||
"AWSTemplateFormatVersion": "2010-09-09",
|
||||
"Resources": {
|
||||
"testInstance": {
|
||||
"Type": "AWS::S3::Bucket",
|
||||
"Properties": {"BucketName": "MyNewBucketName"},
|
||||
}
|
||||
},
|
||||
"Outputs": {"Bucket": {"Value": {"Ref": "testInstance"}}},
|
||||
}
|
||||
template_json = json.dumps(template)
|
||||
cf.update_stack(StackName="test_stack", TemplateBody=template_json)
|
||||
stack_description = cf.describe_stacks(StackName="test_stack")["Stacks"][0]
|
||||
s3.head_bucket(Bucket=stack_description["Outputs"][0]["OutputValue"])
|
||||
|
|
|
|||
145
tests/test_s3/test_s3_cloudformation.py
Normal file
145
tests/test_s3/test_s3_cloudformation.py
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
import json
|
||||
import boto3
|
||||
|
||||
import sure # noqa
|
||||
|
||||
from moto import mock_s3, mock_cloudformation
|
||||
|
||||
|
||||
@mock_s3
|
||||
@mock_cloudformation
|
||||
def test_s3_bucket_cloudformation_basic():
|
||||
s3 = boto3.client("s3", region_name="us-east-1")
|
||||
cf = boto3.client("cloudformation", region_name="us-east-1")
|
||||
|
||||
template = {
|
||||
"AWSTemplateFormatVersion": "2010-09-09",
|
||||
"Resources": {"testInstance": {"Type": "AWS::S3::Bucket", "Properties": {},}},
|
||||
"Outputs": {"Bucket": {"Value": {"Ref": "testInstance"}}},
|
||||
}
|
||||
template_json = json.dumps(template)
|
||||
stack_id = cf.create_stack(StackName="test_stack", TemplateBody=template_json)[
|
||||
"StackId"
|
||||
]
|
||||
stack_description = cf.describe_stacks(StackName="test_stack")["Stacks"][0]
|
||||
|
||||
s3.head_bucket(Bucket=stack_description["Outputs"][0]["OutputValue"])
|
||||
|
||||
|
||||
@mock_s3
|
||||
@mock_cloudformation
|
||||
def test_s3_bucket_cloudformation_with_properties():
|
||||
s3 = boto3.client("s3", region_name="us-east-1")
|
||||
cf = boto3.client("cloudformation", region_name="us-east-1")
|
||||
|
||||
bucket_name = "MyBucket"
|
||||
template = {
|
||||
"AWSTemplateFormatVersion": "2010-09-09",
|
||||
"Resources": {
|
||||
"testInstance": {
|
||||
"Type": "AWS::S3::Bucket",
|
||||
"Properties": {
|
||||
"BucketName": bucket_name,
|
||||
"BucketEncryption": {
|
||||
"ServerSideEncryptionConfiguration": [
|
||||
{
|
||||
"ServerSideEncryptionByDefault": {
|
||||
"SSEAlgorithm": "AES256"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
"Outputs": {"Bucket": {"Value": {"Ref": "testInstance"}}},
|
||||
}
|
||||
template_json = json.dumps(template)
|
||||
stack_id = cf.create_stack(StackName="test_stack", TemplateBody=template_json)[
|
||||
"StackId"
|
||||
]
|
||||
stack_description = cf.describe_stacks(StackName="test_stack")["Stacks"][0]
|
||||
s3.head_bucket(Bucket=bucket_name)
|
||||
|
||||
encryption = s3.get_bucket_encryption(Bucket=bucket_name)
|
||||
encryption["ServerSideEncryptionConfiguration"]["Rules"][0][
|
||||
"ApplyServerSideEncryptionByDefault"
|
||||
]["SSEAlgorithm"].should.equal("AES256")
|
||||
|
||||
|
||||
@mock_s3
|
||||
@mock_cloudformation
|
||||
def test_s3_bucket_cloudformation_update_no_interruption():
|
||||
s3 = boto3.client("s3", region_name="us-east-1")
|
||||
cf = boto3.client("cloudformation", region_name="us-east-1")
|
||||
|
||||
template = {
|
||||
"AWSTemplateFormatVersion": "2010-09-09",
|
||||
"Resources": {"testInstance": {"Type": "AWS::S3::Bucket"}},
|
||||
"Outputs": {"Bucket": {"Value": {"Ref": "testInstance"}}},
|
||||
}
|
||||
template_json = json.dumps(template)
|
||||
cf.create_stack(StackName="test_stack", TemplateBody=template_json)
|
||||
stack_description = cf.describe_stacks(StackName="test_stack")["Stacks"][0]
|
||||
s3.head_bucket(Bucket=stack_description["Outputs"][0]["OutputValue"])
|
||||
|
||||
template = {
|
||||
"AWSTemplateFormatVersion": "2010-09-09",
|
||||
"Resources": {
|
||||
"testInstance": {
|
||||
"Type": "AWS::S3::Bucket",
|
||||
"Properties": {
|
||||
"BucketEncryption": {
|
||||
"ServerSideEncryptionConfiguration": [
|
||||
{
|
||||
"ServerSideEncryptionByDefault": {
|
||||
"SSEAlgorithm": "AES256"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
"Outputs": {"Bucket": {"Value": {"Ref": "testInstance"}}},
|
||||
}
|
||||
template_json = json.dumps(template)
|
||||
cf.update_stack(StackName="test_stack", TemplateBody=template_json)
|
||||
encryption = s3.get_bucket_encryption(
|
||||
Bucket=stack_description["Outputs"][0]["OutputValue"]
|
||||
)
|
||||
encryption["ServerSideEncryptionConfiguration"]["Rules"][0][
|
||||
"ApplyServerSideEncryptionByDefault"
|
||||
]["SSEAlgorithm"].should.equal("AES256")
|
||||
|
||||
|
||||
@mock_s3
|
||||
@mock_cloudformation
|
||||
def test_s3_bucket_cloudformation_update_replacement():
|
||||
s3 = boto3.client("s3", region_name="us-east-1")
|
||||
cf = boto3.client("cloudformation", region_name="us-east-1")
|
||||
|
||||
template = {
|
||||
"AWSTemplateFormatVersion": "2010-09-09",
|
||||
"Resources": {"testInstance": {"Type": "AWS::S3::Bucket"}},
|
||||
"Outputs": {"Bucket": {"Value": {"Ref": "testInstance"}}},
|
||||
}
|
||||
template_json = json.dumps(template)
|
||||
cf.create_stack(StackName="test_stack", TemplateBody=template_json)
|
||||
stack_description = cf.describe_stacks(StackName="test_stack")["Stacks"][0]
|
||||
s3.head_bucket(Bucket=stack_description["Outputs"][0]["OutputValue"])
|
||||
|
||||
template = {
|
||||
"AWSTemplateFormatVersion": "2010-09-09",
|
||||
"Resources": {
|
||||
"testInstance": {
|
||||
"Type": "AWS::S3::Bucket",
|
||||
"Properties": {"BucketName": "MyNewBucketName"},
|
||||
}
|
||||
},
|
||||
"Outputs": {"Bucket": {"Value": {"Ref": "testInstance"}}},
|
||||
}
|
||||
template_json = json.dumps(template)
|
||||
cf.update_stack(StackName="test_stack", TemplateBody=template_json)
|
||||
stack_description = cf.describe_stacks(StackName="test_stack")["Stacks"][0]
|
||||
s3.head_bucket(Bucket=stack_description["Outputs"][0]["OutputValue"])
|
||||
Loading…
Add table
Add a link
Reference in a new issue