Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Stephan 2019-05-28 08:55:50 +02:00
commit d0de38601d
110 changed files with 22566 additions and 20240 deletions

View file

@ -32,7 +32,7 @@ def test_create_autoscaling_group():
group = AutoScalingGroup(
name='tester_group',
availability_zones=['us-east-1c', 'us-east-1b'],
availability_zones=['us-east-1a', 'us-east-1b'],
default_cooldown=60,
desired_capacity=2,
health_check_period=100,
@ -42,7 +42,10 @@ def test_create_autoscaling_group():
launch_config=config,
load_balancers=["test_lb"],
placement_group="test_placement",
vpc_zone_identifier=mocked_networking['subnet1'],
vpc_zone_identifier="{subnet1},{subnet2}".format(
subnet1=mocked_networking['subnet1'],
subnet2=mocked_networking['subnet2'],
),
termination_policies=["OldestInstance", "NewestInstance"],
tags=[Tag(
resource_id='tester_group',
@ -57,12 +60,15 @@ def test_create_autoscaling_group():
group = conn.get_all_groups()[0]
group.name.should.equal('tester_group')
set(group.availability_zones).should.equal(
set(['us-east-1c', 'us-east-1b']))
set(['us-east-1a', 'us-east-1b']))
group.desired_capacity.should.equal(2)
group.max_size.should.equal(2)
group.min_size.should.equal(2)
group.instances.should.have.length_of(2)
group.vpc_zone_identifier.should.equal(mocked_networking['subnet1'])
group.vpc_zone_identifier.should.equal("{subnet1},{subnet2}".format(
subnet1=mocked_networking['subnet1'],
subnet2=mocked_networking['subnet2'],
))
group.launch_config_name.should.equal('tester')
group.default_cooldown.should.equal(60)
group.health_check_period.should.equal(100)
@ -109,7 +115,7 @@ def test_create_autoscaling_groups_defaults():
group.launch_config_name.should.equal('tester')
# Defaults
list(group.availability_zones).should.equal([])
list(group.availability_zones).should.equal(['us-east-1a']) # subnet1
group.desired_capacity.should.equal(2)
group.vpc_zone_identifier.should.equal(mocked_networking['subnet1'])
group.default_cooldown.should.equal(300)
@ -217,7 +223,6 @@ def test_autoscaling_update():
group = AutoScalingGroup(
name='tester_group',
availability_zones=['us-east-1c', 'us-east-1b'],
desired_capacity=2,
max_size=2,
min_size=2,
@ -227,13 +232,16 @@ def test_autoscaling_update():
conn.create_auto_scaling_group(group)
group = conn.get_all_groups()[0]
group.availability_zones.should.equal(['us-east-1a'])
group.vpc_zone_identifier.should.equal(mocked_networking['subnet1'])
group.vpc_zone_identifier = 'subnet-5678efgh'
group.availability_zones = ['us-east-1b']
group.vpc_zone_identifier = mocked_networking['subnet2']
group.update()
group = conn.get_all_groups()[0]
group.vpc_zone_identifier.should.equal('subnet-5678efgh')
group.availability_zones.should.equal(['us-east-1b'])
group.vpc_zone_identifier.should.equal(mocked_networking['subnet2'])
@mock_autoscaling_deprecated
@ -249,7 +257,7 @@ def test_autoscaling_tags_update():
group = AutoScalingGroup(
name='tester_group',
availability_zones=['us-east-1c', 'us-east-1b'],
availability_zones=['us-east-1a'],
desired_capacity=2,
max_size=2,
min_size=2,
@ -309,7 +317,7 @@ def test_autoscaling_group_delete():
@mock_autoscaling_deprecated
def test_autoscaling_group_describe_instances():
mocked_networking = setup_networking_deprecated()
conn = boto.connect_autoscale()
conn = boto.ec2.autoscale.connect_to_region('us-east-1')
config = LaunchConfiguration(
name='tester',
image_id='ami-abcd1234',
@ -332,7 +340,7 @@ def test_autoscaling_group_describe_instances():
instances[0].health_status.should.equal('Healthy')
autoscale_instance_ids = [instance.instance_id for instance in instances]
ec2_conn = boto.connect_ec2()
ec2_conn = boto.ec2.connect_to_region('us-east-1')
reservations = ec2_conn.get_all_instances()
instances = reservations[0].instances
instances.should.have.length_of(2)
@ -355,7 +363,7 @@ def test_set_desired_capacity_up():
group = AutoScalingGroup(
name='tester_group',
availability_zones=['us-east-1c', 'us-east-1b'],
availability_zones=['us-east-1a'],
desired_capacity=2,
max_size=2,
min_size=2,
@ -391,7 +399,7 @@ def test_set_desired_capacity_down():
group = AutoScalingGroup(
name='tester_group',
availability_zones=['us-east-1c', 'us-east-1b'],
availability_zones=['us-east-1a'],
desired_capacity=2,
max_size=2,
min_size=2,
@ -427,7 +435,7 @@ def test_set_desired_capacity_the_same():
group = AutoScalingGroup(
name='tester_group',
availability_zones=['us-east-1c', 'us-east-1b'],
availability_zones=['us-east-1a'],
desired_capacity=2,
max_size=2,
min_size=2,
@ -543,6 +551,7 @@ def test_describe_load_balancers():
)
response = client.describe_load_balancers(AutoScalingGroupName='test_asg')
assert response['ResponseMetadata']['RequestId']
list(response['LoadBalancers']).should.have.length_of(1)
response['LoadBalancers'][0]['LoadBalancerName'].should.equal('my-lb')
@ -738,8 +747,12 @@ def test_describe_autoscaling_groups_boto3():
response['ResponseMetadata']['HTTPStatusCode'].should.equal(200)
group = response['AutoScalingGroups'][0]
group['AutoScalingGroupName'].should.equal('test_asg')
group['AvailabilityZones'].should.equal(['us-east-1a'])
group['VPCZoneIdentifier'].should.equal(mocked_networking['subnet1'])
group['NewInstancesProtectedFromScaleIn'].should.equal(True)
group['Instances'][0]['ProtectedFromScaleIn'].should.equal(True)
for instance in group['Instances']:
instance['AvailabilityZone'].should.equal('us-east-1a')
instance['ProtectedFromScaleIn'].should.equal(True)
@mock_autoscaling
@ -770,6 +783,7 @@ def test_describe_autoscaling_instances_boto3():
response = client.describe_auto_scaling_instances(InstanceIds=instance_ids)
for instance in response['AutoScalingInstances']:
instance['AutoScalingGroupName'].should.equal('test_asg')
instance['AvailabilityZone'].should.equal('us-east-1a')
instance['ProtectedFromScaleIn'].should.equal(True)
@ -793,6 +807,10 @@ def test_update_autoscaling_group_boto3():
_ = client.update_auto_scaling_group(
AutoScalingGroupName='test_asg',
MinSize=1,
VPCZoneIdentifier="{subnet1},{subnet2}".format(
subnet1=mocked_networking['subnet1'],
subnet2=mocked_networking['subnet2'],
),
NewInstancesProtectedFromScaleIn=False,
)
@ -801,6 +819,7 @@ def test_update_autoscaling_group_boto3():
)
group = response['AutoScalingGroups'][0]
group['MinSize'].should.equal(1)
set(group['AvailabilityZones']).should.equal({'us-east-1a', 'us-east-1b'})
group['NewInstancesProtectedFromScaleIn'].should.equal(False)

View file

@ -106,7 +106,7 @@ def test_detach_all_target_groups():
MaxSize=INSTANCE_COUNT,
DesiredCapacity=INSTANCE_COUNT,
TargetGroupARNs=[target_group_arn],
VPCZoneIdentifier=mocked_networking['vpc'])
VPCZoneIdentifier=mocked_networking['subnet1'])
response = client.describe_load_balancer_target_groups(
AutoScalingGroupName='test_asg')

View file

@ -1,5 +1,6 @@
import boto
import boto3
from boto import vpc as boto_vpc
from moto import mock_ec2, mock_ec2_deprecated
@ -19,9 +20,14 @@ def setup_networking():
@mock_ec2_deprecated
def setup_networking_deprecated():
conn = boto.connect_vpc()
conn = boto_vpc.connect_to_region('us-east-1')
vpc = conn.create_vpc("10.11.0.0/16")
subnet1 = conn.create_subnet(vpc.id, "10.11.1.0/24")
subnet2 = conn.create_subnet(vpc.id, "10.11.2.0/24")
subnet1 = conn.create_subnet(
vpc.id,
"10.11.1.0/24",
availability_zone='us-east-1a')
subnet2 = conn.create_subnet(
vpc.id,
"10.11.2.0/24",
availability_zone='us-east-1b')
return {'vpc': vpc.id, 'subnet1': subnet1.id, 'subnet2': subnet2.id}

View file

@ -282,7 +282,7 @@ def test_create_function_from_aws_bucket():
result.pop('LastModified')
result.should.equal({
'FunctionName': 'testFunction',
'FunctionArn': 'arn:aws:lambda:{}:123456789012:function:testFunction:$LATEST'.format(_lambda_region),
'FunctionArn': 'arn:aws:lambda:{}:123456789012:function:testFunction'.format(_lambda_region),
'Runtime': 'python2.7',
'Role': 'test-iam-role',
'Handler': 'lambda_function.lambda_handler',
@ -291,7 +291,7 @@ def test_create_function_from_aws_bucket():
'Description': 'test lambda function',
'Timeout': 3,
'MemorySize': 128,
'Version': '$LATEST',
'Version': '1',
'VpcConfig': {
"SecurityGroupIds": ["sg-123abc"],
"SubnetIds": ["subnet-123abc"],
@ -327,7 +327,7 @@ def test_create_function_from_zipfile():
result.should.equal({
'FunctionName': 'testFunction',
'FunctionArn': 'arn:aws:lambda:{}:123456789012:function:testFunction:$LATEST'.format(_lambda_region),
'FunctionArn': 'arn:aws:lambda:{}:123456789012:function:testFunction'.format(_lambda_region),
'Runtime': 'python2.7',
'Role': 'test-iam-role',
'Handler': 'lambda_function.lambda_handler',
@ -336,7 +336,7 @@ def test_create_function_from_zipfile():
'Timeout': 3,
'MemorySize': 128,
'CodeSha256': hashlib.sha256(zip_content).hexdigest(),
'Version': '$LATEST',
'Version': '1',
'VpcConfig': {
"SecurityGroupIds": [],
"SubnetIds": [],
@ -398,6 +398,8 @@ def test_get_function():
# Test get function with
result = conn.get_function(FunctionName='testFunction', Qualifier='$LATEST')
result['Configuration']['Version'].should.equal('$LATEST')
result['Configuration']['FunctionArn'].should.equal('arn:aws:lambda:us-west-2:123456789012:function:testFunction:$LATEST')
# Test get function when can't find function name
with assert_raises(ClientError):
@ -464,7 +466,7 @@ def test_publish():
Description='test lambda function',
Timeout=3,
MemorySize=128,
Publish=True,
Publish=False,
)
function_list = conn.list_functions()
@ -485,7 +487,7 @@ def test_publish():
function_list = conn.list_functions()
function_list['Functions'].should.have.length_of(1)
function_list['Functions'][0]['FunctionArn'].should.contain('testFunction:$LATEST')
function_list['Functions'][0]['FunctionArn'].should.contain('testFunction')
@mock_lambda
@ -528,7 +530,7 @@ def test_list_create_list_get_delete_list():
"CodeSha256": hashlib.sha256(zip_content).hexdigest(),
"CodeSize": len(zip_content),
"Description": "test lambda function",
"FunctionArn": 'arn:aws:lambda:{}:123456789012:function:testFunction:$LATEST'.format(_lambda_region),
"FunctionArn": 'arn:aws:lambda:{}:123456789012:function:testFunction'.format(_lambda_region),
"FunctionName": "testFunction",
"Handler": "lambda_function.lambda_handler",
"MemorySize": 128,
@ -701,7 +703,7 @@ def test_invoke_async_function():
)
success_result = conn.invoke_async(
FunctionName='testFunction',
FunctionName='testFunction',
InvokeArgs=json.dumps({'test': 'event'})
)
@ -741,7 +743,7 @@ def test_get_function_created_with_zipfile():
"CodeSha256": hashlib.sha256(zip_content).hexdigest(),
"CodeSize": len(zip_content),
"Description": "test lambda function",
"FunctionArn": 'arn:aws:lambda:{}:123456789012:function:testFunction:$LATEST'.format(_lambda_region),
"FunctionArn": 'arn:aws:lambda:{}:123456789012:function:testFunction'.format(_lambda_region),
"FunctionName": "testFunction",
"Handler": "lambda_function.handler",
"MemorySize": 128,
@ -842,7 +844,7 @@ def test_list_versions_by_function():
conn.create_function(
FunctionName='testFunction',
Runtime='python2.7',
Role='test-iam-role',
Role='arn:aws:iam::123456789012:role/test-iam-role',
Handler='lambda_function.lambda_handler',
Code={
'S3Bucket': 'test-bucket',
@ -857,8 +859,28 @@ def test_list_versions_by_function():
res = conn.publish_version(FunctionName='testFunction')
assert res['ResponseMetadata']['HTTPStatusCode'] == 201
versions = conn.list_versions_by_function(FunctionName='testFunction')
assert len(versions['Versions']) == 3
assert versions['Versions'][0]['FunctionArn'] == 'arn:aws:lambda:us-west-2:123456789012:function:testFunction:$LATEST'
assert versions['Versions'][1]['FunctionArn'] == 'arn:aws:lambda:us-west-2:123456789012:function:testFunction:1'
assert versions['Versions'][2]['FunctionArn'] == 'arn:aws:lambda:us-west-2:123456789012:function:testFunction:2'
conn.create_function(
FunctionName='testFunction_2',
Runtime='python2.7',
Role='arn:aws:iam::123456789012:role/test-iam-role',
Handler='lambda_function.lambda_handler',
Code={
'S3Bucket': 'test-bucket',
'S3Key': 'test.zip',
},
Description='test lambda function',
Timeout=3,
MemorySize=128,
Publish=False,
)
versions = conn.list_versions_by_function(FunctionName='testFunction_2')
assert len(versions['Versions']) == 1
assert versions['Versions'][0]['FunctionArn'] == 'arn:aws:lambda:us-west-2:123456789012:function:testFunction_2:$LATEST'
@mock_lambda

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,
@ -2085,7 +2089,7 @@ def test_stack_kms():
def test_stack_spot_fleet():
conn = boto3.client('ec2', 'us-east-1')
vpc = conn.create_vpc(CidrBlock="10.0.0.0/8")['Vpc']
vpc = conn.create_vpc(CidrBlock="10.0.0.0/16")['Vpc']
subnet = conn.create_subnet(
VpcId=vpc['VpcId'], CidrBlock='10.0.0.0/16', AvailabilityZone='us-east-1a')['Subnet']
subnet_id = subnet['SubnetId']
@ -2169,7 +2173,7 @@ def test_stack_spot_fleet():
def test_stack_spot_fleet_should_figure_out_default_price():
conn = boto3.client('ec2', 'us-east-1')
vpc = conn.create_vpc(CidrBlock="10.0.0.0/8")['Vpc']
vpc = conn.create_vpc(CidrBlock="10.0.0.0/16")['Vpc']
subnet = conn.create_subnet(
VpcId=vpc['VpcId'], CidrBlock='10.0.0.0/16', AvailabilityZone='us-east-1a')['Subnet']
subnet_id = subnet['SubnetId']
@ -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')

View file

@ -83,6 +83,18 @@ get_availability_zones_output = {
}
}
parameters = {
"Parameters": {
"Param": {
"Type": "String",
},
"NoEchoParam": {
"Type": "String",
"NoEcho": True
}
}
}
split_select_template = {
"AWSTemplateFormatVersion": "2010-09-09",
"Resources": {
@ -157,6 +169,9 @@ get_attribute_outputs_template = dict(
get_availability_zones_template = dict(
list(dummy_template.items()) + list(get_availability_zones_output.items()))
parameters_template = dict(
list(dummy_template.items()) + list(parameters.items()))
dummy_template_json = json.dumps(dummy_template)
name_type_template_json = json.dumps(name_type_template)
output_type_template_json = json.dumps(outputs_template)
@ -165,6 +180,7 @@ get_attribute_outputs_template_json = json.dumps(
get_attribute_outputs_template)
get_availability_zones_template_json = json.dumps(
get_availability_zones_template)
parameters_template_json = json.dumps(parameters_template)
split_select_template_json = json.dumps(split_select_template)
sub_template_json = json.dumps(sub_template)
export_value_template_json = json.dumps(export_value_template)
@ -290,6 +306,18 @@ def test_parse_stack_with_bad_get_attribute_outputs():
"test_id", "test_stack", bad_output_template_json, {}, "us-west-1").should.throw(ValidationError)
def test_parse_stack_with_parameters():
stack = FakeStack(
stack_id="test_id",
name="test_stack",
template=parameters_template_json,
parameters={"Param": "visible value", "NoEchoParam": "hidden value"},
region_name='us-west-1')
stack.resource_map.no_echo_parameter_keys.should.have("NoEchoParam")
stack.resource_map.no_echo_parameter_keys.should_not.have("Param")
def test_parse_equals_condition():
parse_condition(
condition={"Fn::Equals": [{"Ref": "EnvType"}, "prod"]},

View file

@ -1162,3 +1162,53 @@ def test_confirm_forgot_password():
ConfirmationCode=str(uuid.uuid4()),
Password=str(uuid.uuid4()),
)
@mock_cognitoidp
def test_admin_update_user_attributes():
conn = boto3.client("cognito-idp", "us-west-2")
username = str(uuid.uuid4())
user_pool_id = conn.create_user_pool(PoolName=str(uuid.uuid4()))["UserPool"]["Id"]
conn.admin_create_user(
UserPoolId=user_pool_id,
Username=username,
UserAttributes=[
{
'Name': 'family_name',
'Value': 'Doe',
},
{
'Name': 'given_name',
'Value': 'John',
}
]
)
conn.admin_update_user_attributes(
UserPoolId=user_pool_id,
Username=username,
UserAttributes=[
{
'Name': 'family_name',
'Value': 'Doe',
},
{
'Name': 'given_name',
'Value': 'Jane',
}
]
)
user = conn.admin_get_user(
UserPoolId=user_pool_id,
Username=username
)
attributes = user['UserAttributes']
attributes.should.be.a(list)
for attr in attributes:
val = attr['Value']
if attr['Name'] == 'family_name':
val.should.equal('Doe')
elif attr['Name'] == 'given_name':
val.should.equal('Jane')

View file

@ -1,81 +1,89 @@
from __future__ import unicode_literals
import sure # noqa
from moto.core.responses import AWSServiceSpec
from moto.core.responses import flatten_json_request_body
def test_flatten_json_request_body():
spec = AWSServiceSpec(
'data/emr/2009-03-31/service-2.json').input_spec('RunJobFlow')
body = {
'Name': 'cluster',
'Instances': {
'Ec2KeyName': 'ec2key',
'InstanceGroups': [
{'InstanceRole': 'MASTER',
'InstanceType': 'm1.small'},
{'InstanceRole': 'CORE',
'InstanceType': 'm1.medium'},
],
'Placement': {'AvailabilityZone': 'us-east-1'},
},
'Steps': [
{'HadoopJarStep': {
'Properties': [
{'Key': 'k1', 'Value': 'v1'},
{'Key': 'k2', 'Value': 'v2'}
],
'Args': ['arg1', 'arg2']}},
],
'Configurations': [
{'Classification': 'class',
'Properties': {'propkey1': 'propkey1',
'propkey2': 'propkey2'}},
{'Classification': 'anotherclass',
'Properties': {'propkey3': 'propkey3'}},
]
}
flat = flatten_json_request_body('', body, spec)
flat['Name'].should.equal(body['Name'])
flat['Instances.Ec2KeyName'].should.equal(body['Instances']['Ec2KeyName'])
for idx in range(2):
flat['Instances.InstanceGroups.member.' + str(idx + 1) + '.InstanceRole'].should.equal(
body['Instances']['InstanceGroups'][idx]['InstanceRole'])
flat['Instances.InstanceGroups.member.' + str(idx + 1) + '.InstanceType'].should.equal(
body['Instances']['InstanceGroups'][idx]['InstanceType'])
flat['Instances.Placement.AvailabilityZone'].should.equal(
body['Instances']['Placement']['AvailabilityZone'])
for idx in range(1):
prefix = 'Steps.member.' + str(idx + 1) + '.HadoopJarStep'
step = body['Steps'][idx]['HadoopJarStep']
i = 0
while prefix + '.Properties.member.' + str(i + 1) + '.Key' in flat:
flat[prefix + '.Properties.member.' +
str(i + 1) + '.Key'].should.equal(step['Properties'][i]['Key'])
flat[prefix + '.Properties.member.' +
str(i + 1) + '.Value'].should.equal(step['Properties'][i]['Value'])
i += 1
i = 0
while prefix + '.Args.member.' + str(i + 1) in flat:
flat[prefix + '.Args.member.' +
str(i + 1)].should.equal(step['Args'][i])
i += 1
for idx in range(2):
flat['Configurations.member.' + str(idx + 1) + '.Classification'].should.equal(
body['Configurations'][idx]['Classification'])
props = {}
i = 1
keyfmt = 'Configurations.member.{0}.Properties.entry.{1}'
key = keyfmt.format(idx + 1, i)
while key + '.key' in flat:
props[flat[key + '.key']] = flat[key + '.value']
i += 1
key = keyfmt.format(idx + 1, i)
props.should.equal(body['Configurations'][idx]['Properties'])
from __future__ import unicode_literals
import sure # noqa
from botocore.awsrequest import AWSPreparedRequest
from moto.core.responses import AWSServiceSpec, BaseResponse
from moto.core.responses import flatten_json_request_body
def test_flatten_json_request_body():
spec = AWSServiceSpec(
'data/emr/2009-03-31/service-2.json').input_spec('RunJobFlow')
body = {
'Name': 'cluster',
'Instances': {
'Ec2KeyName': 'ec2key',
'InstanceGroups': [
{'InstanceRole': 'MASTER',
'InstanceType': 'm1.small'},
{'InstanceRole': 'CORE',
'InstanceType': 'm1.medium'},
],
'Placement': {'AvailabilityZone': 'us-east-1'},
},
'Steps': [
{'HadoopJarStep': {
'Properties': [
{'Key': 'k1', 'Value': 'v1'},
{'Key': 'k2', 'Value': 'v2'}
],
'Args': ['arg1', 'arg2']}},
],
'Configurations': [
{'Classification': 'class',
'Properties': {'propkey1': 'propkey1',
'propkey2': 'propkey2'}},
{'Classification': 'anotherclass',
'Properties': {'propkey3': 'propkey3'}},
]
}
flat = flatten_json_request_body('', body, spec)
flat['Name'].should.equal(body['Name'])
flat['Instances.Ec2KeyName'].should.equal(body['Instances']['Ec2KeyName'])
for idx in range(2):
flat['Instances.InstanceGroups.member.' + str(idx + 1) + '.InstanceRole'].should.equal(
body['Instances']['InstanceGroups'][idx]['InstanceRole'])
flat['Instances.InstanceGroups.member.' + str(idx + 1) + '.InstanceType'].should.equal(
body['Instances']['InstanceGroups'][idx]['InstanceType'])
flat['Instances.Placement.AvailabilityZone'].should.equal(
body['Instances']['Placement']['AvailabilityZone'])
for idx in range(1):
prefix = 'Steps.member.' + str(idx + 1) + '.HadoopJarStep'
step = body['Steps'][idx]['HadoopJarStep']
i = 0
while prefix + '.Properties.member.' + str(i + 1) + '.Key' in flat:
flat[prefix + '.Properties.member.' +
str(i + 1) + '.Key'].should.equal(step['Properties'][i]['Key'])
flat[prefix + '.Properties.member.' +
str(i + 1) + '.Value'].should.equal(step['Properties'][i]['Value'])
i += 1
i = 0
while prefix + '.Args.member.' + str(i + 1) in flat:
flat[prefix + '.Args.member.' +
str(i + 1)].should.equal(step['Args'][i])
i += 1
for idx in range(2):
flat['Configurations.member.' + str(idx + 1) + '.Classification'].should.equal(
body['Configurations'][idx]['Classification'])
props = {}
i = 1
keyfmt = 'Configurations.member.{0}.Properties.entry.{1}'
key = keyfmt.format(idx + 1, i)
while key + '.key' in flat:
props[flat[key + '.key']] = flat[key + '.value']
i += 1
key = keyfmt.format(idx + 1, i)
props.should.equal(body['Configurations'][idx]['Properties'])
def test_parse_qs_unicode_decode_error():
body = b'{"key": "%D0"}, "C": "#0 = :0"}'
request = AWSPreparedRequest('GET', 'http://request', {'foo': 'bar'}, body, False)
BaseResponse().setup_class(request, request.url, request.headers)

View file

@ -949,6 +949,33 @@ def test_bad_scan_filter():
raise RuntimeError('Should of raised ResourceInUseException')
@mock_dynamodb2
def test_create_table_pay_per_request():
client = boto3.client('dynamodb', region_name='us-east-1')
client.create_table(
TableName='test1',
AttributeDefinitions=[{'AttributeName': 'client', 'AttributeType': 'S'}, {'AttributeName': 'app', 'AttributeType': 'S'}],
KeySchema=[{'AttributeName': 'client', 'KeyType': 'HASH'}, {'AttributeName': 'app', 'KeyType': 'RANGE'}],
BillingMode="PAY_PER_REQUEST"
)
@mock_dynamodb2
def test_create_table_error_pay_per_request_with_provisioned_param():
client = boto3.client('dynamodb', region_name='us-east-1')
try:
client.create_table(
TableName='test1',
AttributeDefinitions=[{'AttributeName': 'client', 'AttributeType': 'S'}, {'AttributeName': 'app', 'AttributeType': 'S'}],
KeySchema=[{'AttributeName': 'client', 'KeyType': 'HASH'}, {'AttributeName': 'app', 'KeyType': 'RANGE'}],
ProvisionedThroughput={'ReadCapacityUnits': 123, 'WriteCapacityUnits': 123},
BillingMode="PAY_PER_REQUEST"
)
except ClientError as err:
err.response['Error']['Code'].should.equal('ValidationException')
@mock_dynamodb2
def test_duplicate_create():
client = boto3.client('dynamodb', region_name='us-east-1')
@ -1504,6 +1531,7 @@ def test_dynamodb_streams_2():
}
assert 'LatestStreamLabel' in resp['TableDescription']
assert 'LatestStreamArn' in resp['TableDescription']
@mock_dynamodb2
def test_condition_expressions():
@ -1669,8 +1697,8 @@ def test_query_gsi_with_range_key():
res = dynamodb.query(TableName='test', IndexName='test_gsi',
KeyConditionExpression='gsi_hash_key = :gsi_hash_key AND gsi_range_key = :gsi_range_key',
ExpressionAttributeValues={
':gsi_hash_key': {'S': 'key1'},
':gsi_range_key': {'S': 'range1'}
':gsi_hash_key': {'S': 'key1'},
':gsi_range_key': {'S': 'range1'}
})
res.should.have.key("Count").equal(1)
res.should.have.key("Items")
@ -1679,3 +1707,45 @@ def test_query_gsi_with_range_key():
'gsi_hash_key': {'S': 'key1'},
'gsi_range_key': {'S': 'range1'},
})
@mock_dynamodb2
def test_scan_by_non_exists_index():
dynamodb = boto3.client('dynamodb', region_name='us-east-1')
dynamodb.create_table(
TableName='test',
KeySchema=[{'AttributeName': 'id', 'KeyType': 'HASH'}],
AttributeDefinitions=[
{'AttributeName': 'id', 'AttributeType': 'S'},
{'AttributeName': 'gsi_col', 'AttributeType': 'S'}
],
ProvisionedThroughput={'ReadCapacityUnits': 1, 'WriteCapacityUnits': 1},
GlobalSecondaryIndexes=[
{
'IndexName': 'test_gsi',
'KeySchema': [
{
'AttributeName': 'gsi_col',
'KeyType': 'HASH'
},
],
'Projection': {
'ProjectionType': 'ALL',
},
'ProvisionedThroughput': {
'ReadCapacityUnits': 1,
'WriteCapacityUnits': 1
}
},
]
)
with assert_raises(ClientError) as ex:
dynamodb.scan(TableName='test', IndexName='non_exists_index')
ex.exception.response['Error']['Code'].should.equal('ValidationException')
ex.exception.response['ResponseMetadata']['HTTPStatusCode'].should.equal(400)
ex.exception.response['Error']['Message'].should.equal(
'The table does not have the specified index: non_exists_index'
)

File diff suppressed because it is too large Load diff

View file

@ -829,3 +829,77 @@ def test_scan_pagination():
results = page1['Items'] + page2['Items']
usernames = set([r['username'] for r in results])
usernames.should.equal(set(expected_usernames))
@mock_dynamodb2
def test_scan_by_index():
dynamodb = boto3.client('dynamodb', region_name='us-east-1')
dynamodb.create_table(
TableName='test',
KeySchema=[{'AttributeName': 'id', 'KeyType': 'HASH'}],
AttributeDefinitions=[
{'AttributeName': 'id', 'AttributeType': 'S'},
{'AttributeName': 'gsi_col', 'AttributeType': 'S'}
],
ProvisionedThroughput={'ReadCapacityUnits': 1, 'WriteCapacityUnits': 1},
GlobalSecondaryIndexes=[
{
'IndexName': 'test_gsi',
'KeySchema': [
{
'AttributeName': 'gsi_col',
'KeyType': 'HASH'
},
],
'Projection': {
'ProjectionType': 'ALL',
},
'ProvisionedThroughput': {
'ReadCapacityUnits': 1,
'WriteCapacityUnits': 1
}
},
]
)
dynamodb.put_item(
TableName='test',
Item={
'id': {'S': '1'},
'col1': {'S': 'val1'},
'gsi_col': {'S': 'gsi_val1'},
}
)
dynamodb.put_item(
TableName='test',
Item={
'id': {'S': '2'},
'col1': {'S': 'val2'},
'gsi_col': {'S': 'gsi_val2'},
}
)
dynamodb.put_item(
TableName='test',
Item={
'id': {'S': '3'},
'col1': {'S': 'val3'},
}
)
res = dynamodb.scan(TableName='test')
assert res['Count'] == 3
assert len(res['Items']) == 3
res = dynamodb.scan(TableName='test', IndexName='test_gsi')
assert res['Count'] == 2
assert len(res['Items']) == 2
res = dynamodb.scan(TableName='test', IndexName='test_gsi', Limit=1)
assert res['Count'] == 1
assert len(res['Items']) == 1
last_eval_key = res['LastEvaluatedKey']
assert last_eval_key['id']['S'] == '1'
assert last_eval_key['gsi_col']['S'] == 'gsi_val1'

View file

15
tests/test_ec2/helpers.py Normal file
View file

@ -0,0 +1,15 @@
import six
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import rsa
def rsa_check_private_key(private_key_material):
assert isinstance(private_key_material, six.string_types)
private_key = serialization.load_pem_private_key(
data=private_key_material.encode('ascii'),
backend=default_backend(),
password=None)
assert isinstance(private_key, rsa.RSAPrivateKey)

View file

@ -16,7 +16,7 @@ from moto import mock_ec2_deprecated, mock_ec2
@mock_ec2_deprecated
def test_create_and_delete_volume():
conn = boto.connect_ec2('the_key', 'the_secret')
conn = boto.ec2.connect_to_region("us-east-1")
volume = conn.create_volume(80, "us-east-1a")
all_volumes = conn.get_all_volumes()
@ -52,7 +52,7 @@ def test_create_and_delete_volume():
@mock_ec2_deprecated
def test_create_encrypted_volume_dryrun():
conn = boto.connect_ec2('the_key', 'the_secret')
conn = boto.ec2.connect_to_region("us-east-1")
with assert_raises(EC2ResponseError) as ex:
conn.create_volume(80, "us-east-1a", encrypted=True, dry_run=True)
ex.exception.error_code.should.equal('DryRunOperation')
@ -63,7 +63,7 @@ def test_create_encrypted_volume_dryrun():
@mock_ec2_deprecated
def test_create_encrypted_volume():
conn = boto.connect_ec2('the_key', 'the_secret')
conn = boto.ec2.connect_to_region("us-east-1")
volume = conn.create_volume(80, "us-east-1a", encrypted=True)
with assert_raises(EC2ResponseError) as ex:
@ -79,7 +79,7 @@ def test_create_encrypted_volume():
@mock_ec2_deprecated
def test_filter_volume_by_id():
conn = boto.connect_ec2('the_key', 'the_secret')
conn = boto.ec2.connect_to_region("us-east-1")
volume1 = conn.create_volume(80, "us-east-1a")
volume2 = conn.create_volume(36, "us-east-1b")
volume3 = conn.create_volume(20, "us-east-1c")
@ -99,7 +99,7 @@ def test_filter_volume_by_id():
@mock_ec2_deprecated
def test_volume_filters():
conn = boto.connect_ec2('the_key', 'the_secret')
conn = boto.ec2.connect_to_region("us-east-1")
reservation = conn.run_instances('ami-1234abcd')
instance = reservation.instances[0]
@ -196,7 +196,7 @@ def test_volume_filters():
@mock_ec2_deprecated
def test_volume_attach_and_detach():
conn = boto.connect_ec2('the_key', 'the_secret')
conn = boto.ec2.connect_to_region("us-east-1")
reservation = conn.run_instances('ami-1234abcd')
instance = reservation.instances[0]
volume = conn.create_volume(80, "us-east-1a")
@ -252,7 +252,7 @@ def test_volume_attach_and_detach():
@mock_ec2_deprecated
def test_create_snapshot():
conn = boto.connect_ec2('the_key', 'the_secret')
conn = boto.ec2.connect_to_region("us-east-1")
volume = conn.create_volume(80, "us-east-1a")
with assert_raises(EC2ResponseError) as ex:
@ -291,7 +291,7 @@ def test_create_snapshot():
@mock_ec2_deprecated
def test_create_encrypted_snapshot():
conn = boto.connect_ec2('the_key', 'the_secret')
conn = boto.ec2.connect_to_region("us-east-1")
volume = conn.create_volume(80, "us-east-1a", encrypted=True)
snapshot = volume.create_snapshot('a test snapshot')
snapshot.update()
@ -306,7 +306,7 @@ def test_create_encrypted_snapshot():
@mock_ec2_deprecated
def test_filter_snapshot_by_id():
conn = boto.connect_ec2('the_key', 'the_secret')
conn = boto.ec2.connect_to_region("us-east-1")
volume1 = conn.create_volume(36, "us-east-1a")
snap1 = volume1.create_snapshot('a test snapshot 1')
volume2 = conn.create_volume(42, 'us-east-1a')
@ -333,7 +333,7 @@ def test_filter_snapshot_by_id():
@mock_ec2_deprecated
def test_snapshot_filters():
conn = boto.connect_ec2('the_key', 'the_secret')
conn = boto.ec2.connect_to_region("us-east-1")
volume1 = conn.create_volume(20, "us-east-1a", encrypted=False)
volume2 = conn.create_volume(25, "us-east-1a", encrypted=True)
@ -394,12 +394,17 @@ def test_snapshot_filters():
set([snap.id for snap in snapshots_by_encrypted]
).should.equal({snapshot3.id})
snapshots_by_owner_id = conn.get_all_snapshots(
filters={'owner-id': '123456789012'})
set([snap.id for snap in snapshots_by_owner_id]
).should.equal({snapshot1.id, snapshot2.id, snapshot3.id})
@mock_ec2_deprecated
def test_snapshot_attribute():
import copy
conn = boto.connect_ec2('the_key', 'the_secret')
conn = boto.ec2.connect_to_region("us-east-1")
volume = conn.create_volume(80, "us-east-1a")
snapshot = volume.create_snapshot()
@ -502,7 +507,7 @@ def test_snapshot_attribute():
@mock_ec2_deprecated
def test_create_volume_from_snapshot():
conn = boto.connect_ec2('the_key', 'the_secret')
conn = boto.ec2.connect_to_region("us-east-1")
volume = conn.create_volume(80, "us-east-1a")
snapshot = volume.create_snapshot('a test snapshot')
@ -524,7 +529,7 @@ def test_create_volume_from_snapshot():
@mock_ec2_deprecated
def test_create_volume_from_encrypted_snapshot():
conn = boto.connect_ec2('the_key', 'the_secret')
conn = boto.ec2.connect_to_region("us-east-1")
volume = conn.create_volume(80, "us-east-1a", encrypted=True)
snapshot = volume.create_snapshot('a test snapshot')
@ -569,7 +574,7 @@ def test_modify_attribute_blockDeviceMapping():
@mock_ec2_deprecated
def test_volume_tag_escaping():
conn = boto.connect_ec2('the_key', 'the_secret')
conn = boto.ec2.connect_to_region("us-east-1")
vol = conn.create_volume(10, 'us-east-1a')
snapshot = conn.create_snapshot(vol.id, 'Desc')

View file

@ -42,7 +42,7 @@ def test_add_servers():
@freeze_time("2014-01-01 05:00:00")
@mock_ec2_deprecated
def test_instance_launch_and_terminate():
conn = boto.connect_ec2('the_key', 'the_secret')
conn = boto.ec2.connect_to_region("us-east-1")
with assert_raises(EC2ResponseError) as ex:
reservation = conn.run_instances('ami-1234abcd', dry_run=True)
@ -820,7 +820,7 @@ def test_run_instance_with_instance_type():
@mock_ec2_deprecated
def test_run_instance_with_default_placement():
conn = boto.connect_ec2('the_key', 'the_secret')
conn = boto.ec2.connect_to_region("us-east-1")
reservation = conn.run_instances('ami-1234abcd')
instance = reservation.instances[0]

View file

@ -1,151 +1,224 @@
from __future__ import unicode_literals
# Ensure 'assert_raises' context manager support for Python 2.6
import tests.backport_assert_raises
from nose.tools import assert_raises
import boto
import six
import sure # noqa
from boto.exception import EC2ResponseError
from moto import mock_ec2_deprecated
@mock_ec2_deprecated
def test_key_pairs_empty():
conn = boto.connect_ec2('the_key', 'the_secret')
assert len(conn.get_all_key_pairs()) == 0
@mock_ec2_deprecated
def test_key_pairs_invalid_id():
conn = boto.connect_ec2('the_key', 'the_secret')
with assert_raises(EC2ResponseError) as cm:
conn.get_all_key_pairs('foo')
cm.exception.code.should.equal('InvalidKeyPair.NotFound')
cm.exception.status.should.equal(400)
cm.exception.request_id.should_not.be.none
@mock_ec2_deprecated
def test_key_pairs_create():
conn = boto.connect_ec2('the_key', 'the_secret')
with assert_raises(EC2ResponseError) as ex:
kp = conn.create_key_pair('foo', dry_run=True)
ex.exception.error_code.should.equal('DryRunOperation')
ex.exception.status.should.equal(400)
ex.exception.message.should.equal(
'An error occurred (DryRunOperation) when calling the CreateKeyPair operation: Request would have succeeded, but DryRun flag is set')
kp = conn.create_key_pair('foo')
assert kp.material.startswith('---- BEGIN RSA PRIVATE KEY ----')
kps = conn.get_all_key_pairs()
assert len(kps) == 1
assert kps[0].name == 'foo'
@mock_ec2_deprecated
def test_key_pairs_create_two():
conn = boto.connect_ec2('the_key', 'the_secret')
kp = conn.create_key_pair('foo')
kp = conn.create_key_pair('bar')
assert kp.material.startswith('---- BEGIN RSA PRIVATE KEY ----')
kps = conn.get_all_key_pairs()
kps.should.have.length_of(2)
[i.name for i in kps].should.contain('foo')
[i.name for i in kps].should.contain('bar')
kps = conn.get_all_key_pairs('foo')
kps.should.have.length_of(1)
kps[0].name.should.equal('foo')
@mock_ec2_deprecated
def test_key_pairs_create_exist():
conn = boto.connect_ec2('the_key', 'the_secret')
kp = conn.create_key_pair('foo')
assert kp.material.startswith('---- BEGIN RSA PRIVATE KEY ----')
assert len(conn.get_all_key_pairs()) == 1
with assert_raises(EC2ResponseError) as cm:
conn.create_key_pair('foo')
cm.exception.code.should.equal('InvalidKeyPair.Duplicate')
cm.exception.status.should.equal(400)
cm.exception.request_id.should_not.be.none
@mock_ec2_deprecated
def test_key_pairs_delete_no_exist():
conn = boto.connect_ec2('the_key', 'the_secret')
assert len(conn.get_all_key_pairs()) == 0
r = conn.delete_key_pair('foo')
r.should.be.ok
@mock_ec2_deprecated
def test_key_pairs_delete_exist():
conn = boto.connect_ec2('the_key', 'the_secret')
conn.create_key_pair('foo')
with assert_raises(EC2ResponseError) as ex:
r = conn.delete_key_pair('foo', dry_run=True)
ex.exception.error_code.should.equal('DryRunOperation')
ex.exception.status.should.equal(400)
ex.exception.message.should.equal(
'An error occurred (DryRunOperation) when calling the DeleteKeyPair operation: Request would have succeeded, but DryRun flag is set')
r = conn.delete_key_pair('foo')
r.should.be.ok
assert len(conn.get_all_key_pairs()) == 0
@mock_ec2_deprecated
def test_key_pairs_import():
conn = boto.connect_ec2('the_key', 'the_secret')
with assert_raises(EC2ResponseError) as ex:
kp = conn.import_key_pair('foo', b'content', dry_run=True)
ex.exception.error_code.should.equal('DryRunOperation')
ex.exception.status.should.equal(400)
ex.exception.message.should.equal(
'An error occurred (DryRunOperation) when calling the ImportKeyPair operation: Request would have succeeded, but DryRun flag is set')
kp = conn.import_key_pair('foo', b'content')
assert kp.name == 'foo'
kps = conn.get_all_key_pairs()
assert len(kps) == 1
assert kps[0].name == 'foo'
@mock_ec2_deprecated
def test_key_pairs_import_exist():
conn = boto.connect_ec2('the_key', 'the_secret')
kp = conn.import_key_pair('foo', b'content')
assert kp.name == 'foo'
assert len(conn.get_all_key_pairs()) == 1
with assert_raises(EC2ResponseError) as cm:
conn.create_key_pair('foo')
cm.exception.code.should.equal('InvalidKeyPair.Duplicate')
cm.exception.status.should.equal(400)
cm.exception.request_id.should_not.be.none
@mock_ec2_deprecated
def test_key_pair_filters():
conn = boto.connect_ec2('the_key', 'the_secret')
_ = conn.create_key_pair('kpfltr1')
kp2 = conn.create_key_pair('kpfltr2')
kp3 = conn.create_key_pair('kpfltr3')
kp_by_name = conn.get_all_key_pairs(
filters={'key-name': 'kpfltr2'})
set([kp.name for kp in kp_by_name]
).should.equal(set([kp2.name]))
kp_by_name = conn.get_all_key_pairs(
filters={'fingerprint': kp3.fingerprint})
set([kp.name for kp in kp_by_name]
).should.equal(set([kp3.name]))
from __future__ import unicode_literals
# Ensure 'assert_raises' context manager support for Python 2.6
import tests.backport_assert_raises
from nose.tools import assert_raises
import boto
import sure # noqa
from boto.exception import EC2ResponseError
from moto import mock_ec2_deprecated
from .helpers import rsa_check_private_key
RSA_PUBLIC_KEY_OPENSSH = b"""\
ssh-rsa \
AAAAB3NzaC1yc2EAAAADAQABAAABAQDusXfgTE4eBP50NglSzCSEGnIL6+cr6m3H\
6cZANOQ+P1o/W4BdtcAL3sor4iGi7SOeJgo\8kweyMQrhrt6HaKGgromRiz37LQx\
4YIAcBi4Zd023mO/V7Rc2Chh18mWgLSmA6ng+j37ip6452zxtv0jHAz9pJolbKBp\
JzbZlPN45ZCTk9ck0fSVHRl6VRSSPQcpqi65XpRf+35zNOCGCc1mAOOTmw59Q2a6\
A3t8mL7r91aM5q6QOQm219lctFM8O7HRJnDgmhGpnjRwE1LyKktWTbgFZ4SNWU2X\
qusUO07jKuSxzPumXBeU+JEtx0J1tqZwJlpGt2R+0qN7nKnPl2+hx \
moto@github.com"""
RSA_PUBLIC_KEY_RFC4716 = b"""\
---- BEGIN SSH2 PUBLIC KEY ----
AAAAB3NzaC1yc2EAAAADAQABAAABAQDusXfgTE4eBP50NglSzCSEGnIL6+cr6m3H6cZANO
Q+P1o/W4BdtcAL3sor4iGi7SOeJgo8kweyMQrhrt6HaKGgromRiz37LQx4YIAcBi4Zd023
mO/V7Rc2Chh18mWgLSmA6ng+j37ip6452zxtv0jHAz9pJolbKBpJzbZlPN45ZCTk9ck0fS
VHRl6VRSSPQcpqi65XpRf+35zNOCGCc1mAOOTmw59Q2a6A3t8mL7r91aM5q6QOQm219lct
FM8O7HRJnDgmhGpnjRwE1LyKktWTbgFZ4SNWU2XqusUO07jKuSxzPumXBeU+JEtx0J1tqZ
wJlpGt2R+0qN7nKnPl2+hx
---- END SSH2 PUBLIC KEY ----
"""
RSA_PUBLIC_KEY_FINGERPRINT = "6a:49:07:1c:7e:bd:d2:bd:96:25:fe:b5:74:83:ae:fd"
DSA_PUBLIC_KEY_OPENSSH = b"""ssh-dss \
AAAAB3NzaC1kc3MAAACBAJ0aXctVwbN6VB81gpo8R7DUk8zXRjZvrkg8Y8vEGt63gklpNJNsLXtEUXkl5D4c0nD2FZO1rJNqFoe\
OQOCoGSfclHvt9w4yPl/lUEtb3Qtj1j80MInETHr19vaSunRk5R+M+8YH+LLcdYdz7MijuGey02mbi0H9K5nUIcuLMArVAAAAFQ\
D0RDvsObRWBlnaW8645obZBM86jwAAAIBNZwf3B4krIzAwVfkMHLDSdAvs7lOWE7o8SJLzr9t4a9HhYp9SLbMzJ815KWfidEYV2\
+s4ZaPCfcZ1GENFRbE8rixz5eMAjEUXEPMJkblDZTHzMsH96z2cOCQZ0vfOmgznsf18Uf725pqo9OqAioEsTJjX8jtI2qNPEBU0\
uhMSZQAAAIBBMGhDu5CWPUlS2QG7vzmzw81XasmHE/s2YPDRbolkriwlunpgwZhCscoQP8HFHY+DLUVvUb+GZwBmFt4l1uHl03b\
ffsm7UIHtCBYERr9Nx0u20ldfhkgB1lhaJb5o0ZJ3pmJ38KChfyHe5EUcqRdEFo89Mp72VI2Z6UHyL175RA== \
moto@github.com"""
@mock_ec2_deprecated
def test_key_pairs_empty():
conn = boto.connect_ec2('the_key', 'the_secret')
assert len(conn.get_all_key_pairs()) == 0
@mock_ec2_deprecated
def test_key_pairs_invalid_id():
conn = boto.connect_ec2('the_key', 'the_secret')
with assert_raises(EC2ResponseError) as cm:
conn.get_all_key_pairs('foo')
cm.exception.code.should.equal('InvalidKeyPair.NotFound')
cm.exception.status.should.equal(400)
cm.exception.request_id.should_not.be.none
@mock_ec2_deprecated
def test_key_pairs_create():
conn = boto.connect_ec2('the_key', 'the_secret')
with assert_raises(EC2ResponseError) as ex:
conn.create_key_pair('foo', dry_run=True)
ex.exception.error_code.should.equal('DryRunOperation')
ex.exception.status.should.equal(400)
ex.exception.message.should.equal(
'An error occurred (DryRunOperation) when calling the CreateKeyPair operation: Request would have succeeded, but DryRun flag is set')
kp = conn.create_key_pair('foo')
rsa_check_private_key(kp.material)
kps = conn.get_all_key_pairs()
assert len(kps) == 1
assert kps[0].name == 'foo'
@mock_ec2_deprecated
def test_key_pairs_create_two():
conn = boto.connect_ec2('the_key', 'the_secret')
kp1 = conn.create_key_pair('foo')
rsa_check_private_key(kp1.material)
kp2 = conn.create_key_pair('bar')
rsa_check_private_key(kp2.material)
assert kp1.material != kp2.material
kps = conn.get_all_key_pairs()
kps.should.have.length_of(2)
assert {i.name for i in kps} == {'foo', 'bar'}
kps = conn.get_all_key_pairs('foo')
kps.should.have.length_of(1)
kps[0].name.should.equal('foo')
@mock_ec2_deprecated
def test_key_pairs_create_exist():
conn = boto.connect_ec2('the_key', 'the_secret')
conn.create_key_pair('foo')
assert len(conn.get_all_key_pairs()) == 1
with assert_raises(EC2ResponseError) as cm:
conn.create_key_pair('foo')
cm.exception.code.should.equal('InvalidKeyPair.Duplicate')
cm.exception.status.should.equal(400)
cm.exception.request_id.should_not.be.none
@mock_ec2_deprecated
def test_key_pairs_delete_no_exist():
conn = boto.connect_ec2('the_key', 'the_secret')
assert len(conn.get_all_key_pairs()) == 0
r = conn.delete_key_pair('foo')
r.should.be.ok
@mock_ec2_deprecated
def test_key_pairs_delete_exist():
conn = boto.connect_ec2('the_key', 'the_secret')
conn.create_key_pair('foo')
with assert_raises(EC2ResponseError) as ex:
r = conn.delete_key_pair('foo', dry_run=True)
ex.exception.error_code.should.equal('DryRunOperation')
ex.exception.status.should.equal(400)
ex.exception.message.should.equal(
'An error occurred (DryRunOperation) when calling the DeleteKeyPair operation: Request would have succeeded, but DryRun flag is set')
r = conn.delete_key_pair('foo')
r.should.be.ok
assert len(conn.get_all_key_pairs()) == 0
@mock_ec2_deprecated
def test_key_pairs_import():
conn = boto.connect_ec2('the_key', 'the_secret')
with assert_raises(EC2ResponseError) as ex:
conn.import_key_pair('foo', RSA_PUBLIC_KEY_OPENSSH, dry_run=True)
ex.exception.error_code.should.equal('DryRunOperation')
ex.exception.status.should.equal(400)
ex.exception.message.should.equal(
'An error occurred (DryRunOperation) when calling the ImportKeyPair operation: Request would have succeeded, but DryRun flag is set')
kp1 = conn.import_key_pair('foo', RSA_PUBLIC_KEY_OPENSSH)
assert kp1.name == 'foo'
assert kp1.fingerprint == RSA_PUBLIC_KEY_FINGERPRINT
kp2 = conn.import_key_pair('foo2', RSA_PUBLIC_KEY_RFC4716)
assert kp2.name == 'foo2'
assert kp2.fingerprint == RSA_PUBLIC_KEY_FINGERPRINT
kps = conn.get_all_key_pairs()
assert len(kps) == 2
assert kps[0].name == kp1.name
assert kps[1].name == kp2.name
@mock_ec2_deprecated
def test_key_pairs_import_exist():
conn = boto.connect_ec2('the_key', 'the_secret')
kp = conn.import_key_pair('foo', RSA_PUBLIC_KEY_OPENSSH)
assert kp.name == 'foo'
assert len(conn.get_all_key_pairs()) == 1
with assert_raises(EC2ResponseError) as cm:
conn.create_key_pair('foo')
cm.exception.code.should.equal('InvalidKeyPair.Duplicate')
cm.exception.status.should.equal(400)
cm.exception.request_id.should_not.be.none
@mock_ec2_deprecated
def test_key_pairs_invalid():
conn = boto.connect_ec2('the_key', 'the_secret')
with assert_raises(EC2ResponseError) as ex:
conn.import_key_pair('foo', b'')
ex.exception.error_code.should.equal('InvalidKeyPair.Format')
ex.exception.status.should.equal(400)
ex.exception.message.should.equal(
'Key is not in valid OpenSSH public key format')
with assert_raises(EC2ResponseError) as ex:
conn.import_key_pair('foo', b'garbage')
ex.exception.error_code.should.equal('InvalidKeyPair.Format')
ex.exception.status.should.equal(400)
ex.exception.message.should.equal(
'Key is not in valid OpenSSH public key format')
with assert_raises(EC2ResponseError) as ex:
conn.import_key_pair('foo', DSA_PUBLIC_KEY_OPENSSH)
ex.exception.error_code.should.equal('InvalidKeyPair.Format')
ex.exception.status.should.equal(400)
ex.exception.message.should.equal(
'Key is not in valid OpenSSH public key format')
@mock_ec2_deprecated
def test_key_pair_filters():
conn = boto.connect_ec2('the_key', 'the_secret')
_ = conn.create_key_pair('kpfltr1')
kp2 = conn.create_key_pair('kpfltr2')
kp3 = conn.create_key_pair('kpfltr3')
kp_by_name = conn.get_all_key_pairs(
filters={'key-name': 'kpfltr2'})
set([kp.name for kp in kp_by_name]
).should.equal(set([kp2.name]))
kp_by_name = conn.get_all_key_pairs(
filters={'fingerprint': kp3.fingerprint})
set([kp.name for kp in kp_by_name]
).should.equal(set([kp3.name]))

View file

@ -2,6 +2,8 @@ from __future__ import unicode_literals
import boto
import boto3
import sure # noqa
from nose.tools import assert_raises
from botocore.exceptions import ClientError
from moto import mock_ec2_deprecated, mock_ec2
@ -28,7 +30,7 @@ def test_new_subnet_associates_with_default_network_acl():
conn = boto.connect_vpc('the_key', 'the secret')
vpc = conn.get_all_vpcs()[0]
subnet = conn.create_subnet(vpc.id, "10.0.0.0/18")
subnet = conn.create_subnet(vpc.id, "172.31.48.0/20")
all_network_acls = conn.get_all_network_acls()
all_network_acls.should.have.length_of(1)
@ -214,3 +216,37 @@ def test_default_network_acl_default_entries():
unique_entries.append(entry)
unique_entries.should.have.length_of(4)
@mock_ec2
def test_delete_default_network_acl_default_entry():
ec2 = boto3.resource('ec2', region_name='us-west-1')
default_network_acl = next(iter(ec2.network_acls.all()), None)
default_network_acl.is_default.should.be.ok
default_network_acl.entries.should.have.length_of(4)
first_default_network_acl_entry = default_network_acl.entries[0]
default_network_acl.delete_entry(Egress=first_default_network_acl_entry['Egress'],
RuleNumber=first_default_network_acl_entry['RuleNumber'])
default_network_acl.entries.should.have.length_of(3)
@mock_ec2
def test_duplicate_network_acl_entry():
ec2 = boto3.resource('ec2', region_name='us-west-1')
default_network_acl = next(iter(ec2.network_acls.all()), None)
default_network_acl.is_default.should.be.ok
rule_number = 200
egress = True
default_network_acl.create_entry(CidrBlock="0.0.0.0/0", Egress=egress, Protocol="-1", RuleAction="allow", RuleNumber=rule_number)
with assert_raises(ClientError) as ex:
default_network_acl.create_entry(CidrBlock="10.0.0.0/0", Egress=egress, Protocol="-1", RuleAction="deny", RuleNumber=rule_number)
str(ex.exception).should.equal(
"An error occurred (NetworkAclEntryAlreadyExists) when calling the CreateNetworkAclEntry "
"operation: The network acl entry identified by {} already exists.".format(rule_number))

View file

@ -1,148 +1,150 @@
from __future__ import unicode_literals
import boto.ec2
import boto.ec2.autoscale
import boto.ec2.elb
import sure
from moto import mock_ec2_deprecated, mock_autoscaling_deprecated, mock_elb_deprecated
from moto.ec2 import ec2_backends
def test_use_boto_regions():
boto_regions = {r.name for r in boto.ec2.regions()}
moto_regions = set(ec2_backends)
moto_regions.should.equal(boto_regions)
def add_servers_to_region(ami_id, count, region):
conn = boto.ec2.connect_to_region(region)
for index in range(count):
conn.run_instances(ami_id)
@mock_ec2_deprecated
def test_add_servers_to_a_single_region():
region = 'ap-northeast-1'
add_servers_to_region('ami-1234abcd', 1, region)
add_servers_to_region('ami-5678efgh', 1, region)
conn = boto.ec2.connect_to_region(region)
reservations = conn.get_all_instances()
len(reservations).should.equal(2)
reservations.sort(key=lambda x: x.instances[0].image_id)
reservations[0].instances[0].image_id.should.equal('ami-1234abcd')
reservations[1].instances[0].image_id.should.equal('ami-5678efgh')
@mock_ec2_deprecated
def test_add_servers_to_multiple_regions():
region1 = 'us-east-1'
region2 = 'ap-northeast-1'
add_servers_to_region('ami-1234abcd', 1, region1)
add_servers_to_region('ami-5678efgh', 1, region2)
us_conn = boto.ec2.connect_to_region(region1)
ap_conn = boto.ec2.connect_to_region(region2)
us_reservations = us_conn.get_all_instances()
ap_reservations = ap_conn.get_all_instances()
len(us_reservations).should.equal(1)
len(ap_reservations).should.equal(1)
us_reservations[0].instances[0].image_id.should.equal('ami-1234abcd')
ap_reservations[0].instances[0].image_id.should.equal('ami-5678efgh')
@mock_autoscaling_deprecated
@mock_elb_deprecated
def test_create_autoscaling_group():
elb_conn = boto.ec2.elb.connect_to_region('us-east-1')
elb_conn.create_load_balancer(
'us_test_lb', zones=[], listeners=[(80, 8080, 'http')])
elb_conn = boto.ec2.elb.connect_to_region('ap-northeast-1')
elb_conn.create_load_balancer(
'ap_test_lb', zones=[], listeners=[(80, 8080, 'http')])
us_conn = boto.ec2.autoscale.connect_to_region('us-east-1')
config = boto.ec2.autoscale.LaunchConfiguration(
name='us_tester',
image_id='ami-abcd1234',
instance_type='m1.small',
)
us_conn.create_launch_configuration(config)
group = boto.ec2.autoscale.AutoScalingGroup(
name='us_tester_group',
availability_zones=['us-east-1c'],
default_cooldown=60,
desired_capacity=2,
health_check_period=100,
health_check_type="EC2",
max_size=2,
min_size=2,
launch_config=config,
load_balancers=["us_test_lb"],
placement_group="us_test_placement",
vpc_zone_identifier='subnet-1234abcd',
termination_policies=["OldestInstance", "NewestInstance"],
)
us_conn.create_auto_scaling_group(group)
ap_conn = boto.ec2.autoscale.connect_to_region('ap-northeast-1')
config = boto.ec2.autoscale.LaunchConfiguration(
name='ap_tester',
image_id='ami-efgh5678',
instance_type='m1.small',
)
ap_conn.create_launch_configuration(config)
group = boto.ec2.autoscale.AutoScalingGroup(
name='ap_tester_group',
availability_zones=['ap-northeast-1a'],
default_cooldown=60,
desired_capacity=2,
health_check_period=100,
health_check_type="EC2",
max_size=2,
min_size=2,
launch_config=config,
load_balancers=["ap_test_lb"],
placement_group="ap_test_placement",
vpc_zone_identifier='subnet-5678efgh',
termination_policies=["OldestInstance", "NewestInstance"],
)
ap_conn.create_auto_scaling_group(group)
len(us_conn.get_all_groups()).should.equal(1)
len(ap_conn.get_all_groups()).should.equal(1)
us_group = us_conn.get_all_groups()[0]
us_group.name.should.equal('us_tester_group')
list(us_group.availability_zones).should.equal(['us-east-1c'])
us_group.desired_capacity.should.equal(2)
us_group.max_size.should.equal(2)
us_group.min_size.should.equal(2)
us_group.vpc_zone_identifier.should.equal('subnet-1234abcd')
us_group.launch_config_name.should.equal('us_tester')
us_group.default_cooldown.should.equal(60)
us_group.health_check_period.should.equal(100)
us_group.health_check_type.should.equal("EC2")
list(us_group.load_balancers).should.equal(["us_test_lb"])
us_group.placement_group.should.equal("us_test_placement")
list(us_group.termination_policies).should.equal(
["OldestInstance", "NewestInstance"])
ap_group = ap_conn.get_all_groups()[0]
ap_group.name.should.equal('ap_tester_group')
list(ap_group.availability_zones).should.equal(['ap-northeast-1a'])
ap_group.desired_capacity.should.equal(2)
ap_group.max_size.should.equal(2)
ap_group.min_size.should.equal(2)
ap_group.vpc_zone_identifier.should.equal('subnet-5678efgh')
ap_group.launch_config_name.should.equal('ap_tester')
ap_group.default_cooldown.should.equal(60)
ap_group.health_check_period.should.equal(100)
ap_group.health_check_type.should.equal("EC2")
list(ap_group.load_balancers).should.equal(["ap_test_lb"])
ap_group.placement_group.should.equal("ap_test_placement")
list(ap_group.termination_policies).should.equal(
["OldestInstance", "NewestInstance"])
from __future__ import unicode_literals
import boto.ec2
import boto.ec2.autoscale
import boto.ec2.elb
import sure
from moto import mock_ec2_deprecated, mock_autoscaling_deprecated, mock_elb_deprecated
from moto.ec2 import ec2_backends
def test_use_boto_regions():
boto_regions = {r.name for r in boto.ec2.regions()}
moto_regions = set(ec2_backends)
moto_regions.should.equal(boto_regions)
def add_servers_to_region(ami_id, count, region):
conn = boto.ec2.connect_to_region(region)
for index in range(count):
conn.run_instances(ami_id)
@mock_ec2_deprecated
def test_add_servers_to_a_single_region():
region = 'ap-northeast-1'
add_servers_to_region('ami-1234abcd', 1, region)
add_servers_to_region('ami-5678efgh', 1, region)
conn = boto.ec2.connect_to_region(region)
reservations = conn.get_all_instances()
len(reservations).should.equal(2)
reservations.sort(key=lambda x: x.instances[0].image_id)
reservations[0].instances[0].image_id.should.equal('ami-1234abcd')
reservations[1].instances[0].image_id.should.equal('ami-5678efgh')
@mock_ec2_deprecated
def test_add_servers_to_multiple_regions():
region1 = 'us-east-1'
region2 = 'ap-northeast-1'
add_servers_to_region('ami-1234abcd', 1, region1)
add_servers_to_region('ami-5678efgh', 1, region2)
us_conn = boto.ec2.connect_to_region(region1)
ap_conn = boto.ec2.connect_to_region(region2)
us_reservations = us_conn.get_all_instances()
ap_reservations = ap_conn.get_all_instances()
len(us_reservations).should.equal(1)
len(ap_reservations).should.equal(1)
us_reservations[0].instances[0].image_id.should.equal('ami-1234abcd')
ap_reservations[0].instances[0].image_id.should.equal('ami-5678efgh')
@mock_autoscaling_deprecated
@mock_elb_deprecated
def test_create_autoscaling_group():
elb_conn = boto.ec2.elb.connect_to_region('us-east-1')
elb_conn.create_load_balancer(
'us_test_lb', zones=[], listeners=[(80, 8080, 'http')])
elb_conn = boto.ec2.elb.connect_to_region('ap-northeast-1')
elb_conn.create_load_balancer(
'ap_test_lb', zones=[], listeners=[(80, 8080, 'http')])
us_conn = boto.ec2.autoscale.connect_to_region('us-east-1')
config = boto.ec2.autoscale.LaunchConfiguration(
name='us_tester',
image_id='ami-abcd1234',
instance_type='m1.small',
)
x = us_conn.create_launch_configuration(config)
us_subnet_id = list(ec2_backends['us-east-1'].subnets['us-east-1c'].keys())[0]
ap_subnet_id = list(ec2_backends['ap-northeast-1'].subnets['ap-northeast-1a'].keys())[0]
group = boto.ec2.autoscale.AutoScalingGroup(
name='us_tester_group',
availability_zones=['us-east-1c'],
default_cooldown=60,
desired_capacity=2,
health_check_period=100,
health_check_type="EC2",
max_size=2,
min_size=2,
launch_config=config,
load_balancers=["us_test_lb"],
placement_group="us_test_placement",
vpc_zone_identifier=us_subnet_id,
termination_policies=["OldestInstance", "NewestInstance"],
)
us_conn.create_auto_scaling_group(group)
ap_conn = boto.ec2.autoscale.connect_to_region('ap-northeast-1')
config = boto.ec2.autoscale.LaunchConfiguration(
name='ap_tester',
image_id='ami-efgh5678',
instance_type='m1.small',
)
ap_conn.create_launch_configuration(config)
group = boto.ec2.autoscale.AutoScalingGroup(
name='ap_tester_group',
availability_zones=['ap-northeast-1a'],
default_cooldown=60,
desired_capacity=2,
health_check_period=100,
health_check_type="EC2",
max_size=2,
min_size=2,
launch_config=config,
load_balancers=["ap_test_lb"],
placement_group="ap_test_placement",
vpc_zone_identifier=ap_subnet_id,
termination_policies=["OldestInstance", "NewestInstance"],
)
ap_conn.create_auto_scaling_group(group)
len(us_conn.get_all_groups()).should.equal(1)
len(ap_conn.get_all_groups()).should.equal(1)
us_group = us_conn.get_all_groups()[0]
us_group.name.should.equal('us_tester_group')
list(us_group.availability_zones).should.equal(['us-east-1c'])
us_group.desired_capacity.should.equal(2)
us_group.max_size.should.equal(2)
us_group.min_size.should.equal(2)
us_group.vpc_zone_identifier.should.equal(us_subnet_id)
us_group.launch_config_name.should.equal('us_tester')
us_group.default_cooldown.should.equal(60)
us_group.health_check_period.should.equal(100)
us_group.health_check_type.should.equal("EC2")
list(us_group.load_balancers).should.equal(["us_test_lb"])
us_group.placement_group.should.equal("us_test_placement")
list(us_group.termination_policies).should.equal(
["OldestInstance", "NewestInstance"])
ap_group = ap_conn.get_all_groups()[0]
ap_group.name.should.equal('ap_tester_group')
list(ap_group.availability_zones).should.equal(['ap-northeast-1a'])
ap_group.desired_capacity.should.equal(2)
ap_group.max_size.should.equal(2)
ap_group.min_size.should.equal(2)
ap_group.vpc_zone_identifier.should.equal(ap_subnet_id)
ap_group.launch_config_name.should.equal('ap_tester')
ap_group.default_cooldown.should.equal(60)
ap_group.health_check_period.should.equal(100)
ap_group.health_check_type.should.equal("EC2")
list(ap_group.load_balancers).should.equal(["ap_test_lb"])
ap_group.placement_group.should.equal("ap_test_placement")
list(ap_group.termination_policies).should.equal(
["OldestInstance", "NewestInstance"])

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -7,7 +7,7 @@ from moto import mock_ec2
def get_subnet_id(conn):
vpc = conn.create_vpc(CidrBlock="10.0.0.0/8")['Vpc']
vpc = conn.create_vpc(CidrBlock="10.0.0.0/16")['Vpc']
subnet = conn.create_subnet(
VpcId=vpc['VpcId'], CidrBlock='10.0.0.0/16', AvailabilityZone='us-east-1a')['Subnet']
subnet_id = subnet['SubnetId']

View file

@ -1,268 +1,268 @@
from __future__ import unicode_literals
from nose.tools import assert_raises
import datetime
import boto
import boto3
from boto.exception import EC2ResponseError
from botocore.exceptions import ClientError
import pytz
import sure # noqa
from moto import mock_ec2, mock_ec2_deprecated
from moto.backends import get_model
from moto.core.utils import iso_8601_datetime_with_milliseconds
@mock_ec2
def test_request_spot_instances():
conn = boto3.client('ec2', 'us-east-1')
vpc = conn.create_vpc(CidrBlock="10.0.0.0/8")['Vpc']
subnet = conn.create_subnet(
VpcId=vpc['VpcId'], CidrBlock='10.0.0.0/16', AvailabilityZone='us-east-1a')['Subnet']
subnet_id = subnet['SubnetId']
conn.create_security_group(GroupName='group1', Description='description')
conn.create_security_group(GroupName='group2', Description='description')
start_dt = datetime.datetime(2013, 1, 1).replace(tzinfo=pytz.utc)
end_dt = datetime.datetime(2013, 1, 2).replace(tzinfo=pytz.utc)
start = iso_8601_datetime_with_milliseconds(start_dt)
end = iso_8601_datetime_with_milliseconds(end_dt)
with assert_raises(ClientError) as ex:
request = conn.request_spot_instances(
SpotPrice="0.5", InstanceCount=1, Type='one-time',
ValidFrom=start, ValidUntil=end, LaunchGroup="the-group",
AvailabilityZoneGroup='my-group',
LaunchSpecification={
"ImageId": 'ami-abcd1234',
"KeyName": "test",
"SecurityGroups": ['group1', 'group2'],
"UserData": "some test data",
"InstanceType": 'm1.small',
"Placement": {
"AvailabilityZone": 'us-east-1c',
},
"KernelId": "test-kernel",
"RamdiskId": "test-ramdisk",
"Monitoring": {
"Enabled": True,
},
"SubnetId": subnet_id,
},
DryRun=True,
)
ex.exception.response['Error']['Code'].should.equal('DryRunOperation')
ex.exception.response['ResponseMetadata'][
'HTTPStatusCode'].should.equal(400)
ex.exception.response['Error']['Message'].should.equal(
'An error occurred (DryRunOperation) when calling the RequestSpotInstance operation: Request would have succeeded, but DryRun flag is set')
request = conn.request_spot_instances(
SpotPrice="0.5", InstanceCount=1, Type='one-time',
ValidFrom=start, ValidUntil=end, LaunchGroup="the-group",
AvailabilityZoneGroup='my-group',
LaunchSpecification={
"ImageId": 'ami-abcd1234',
"KeyName": "test",
"SecurityGroups": ['group1', 'group2'],
"UserData": "some test data",
"InstanceType": 'm1.small',
"Placement": {
"AvailabilityZone": 'us-east-1c',
},
"KernelId": "test-kernel",
"RamdiskId": "test-ramdisk",
"Monitoring": {
"Enabled": True,
},
"SubnetId": subnet_id,
},
)
requests = conn.describe_spot_instance_requests()['SpotInstanceRequests']
requests.should.have.length_of(1)
request = requests[0]
request['State'].should.equal("open")
request['SpotPrice'].should.equal("0.5")
request['Type'].should.equal('one-time')
request['ValidFrom'].should.equal(start_dt)
request['ValidUntil'].should.equal(end_dt)
request['LaunchGroup'].should.equal("the-group")
request['AvailabilityZoneGroup'].should.equal('my-group')
launch_spec = request['LaunchSpecification']
security_group_names = [group['GroupName']
for group in launch_spec['SecurityGroups']]
set(security_group_names).should.equal(set(['group1', 'group2']))
launch_spec['ImageId'].should.equal('ami-abcd1234')
launch_spec['KeyName'].should.equal("test")
launch_spec['InstanceType'].should.equal('m1.small')
launch_spec['KernelId'].should.equal("test-kernel")
launch_spec['RamdiskId'].should.equal("test-ramdisk")
launch_spec['SubnetId'].should.equal(subnet_id)
@mock_ec2
def test_request_spot_instances_default_arguments():
"""
Test that moto set the correct default arguments
"""
conn = boto3.client('ec2', 'us-east-1')
request = conn.request_spot_instances(
SpotPrice="0.5",
LaunchSpecification={
"ImageId": 'ami-abcd1234',
}
)
requests = conn.describe_spot_instance_requests()['SpotInstanceRequests']
requests.should.have.length_of(1)
request = requests[0]
request['State'].should.equal("open")
request['SpotPrice'].should.equal("0.5")
request['Type'].should.equal('one-time')
request.shouldnt.contain('ValidFrom')
request.shouldnt.contain('ValidUntil')
request.shouldnt.contain('LaunchGroup')
request.shouldnt.contain('AvailabilityZoneGroup')
launch_spec = request['LaunchSpecification']
security_group_names = [group['GroupName']
for group in launch_spec['SecurityGroups']]
security_group_names.should.equal(["default"])
launch_spec['ImageId'].should.equal('ami-abcd1234')
request.shouldnt.contain('KeyName')
launch_spec['InstanceType'].should.equal('m1.small')
request.shouldnt.contain('KernelId')
request.shouldnt.contain('RamdiskId')
request.shouldnt.contain('SubnetId')
@mock_ec2_deprecated
def test_cancel_spot_instance_request():
conn = boto.connect_ec2()
conn.request_spot_instances(
price=0.5, image_id='ami-abcd1234',
)
requests = conn.get_all_spot_instance_requests()
requests.should.have.length_of(1)
with assert_raises(EC2ResponseError) as ex:
conn.cancel_spot_instance_requests([requests[0].id], dry_run=True)
ex.exception.error_code.should.equal('DryRunOperation')
ex.exception.status.should.equal(400)
ex.exception.message.should.equal(
'An error occurred (DryRunOperation) when calling the CancelSpotInstance operation: Request would have succeeded, but DryRun flag is set')
conn.cancel_spot_instance_requests([requests[0].id])
requests = conn.get_all_spot_instance_requests()
requests.should.have.length_of(0)
@mock_ec2_deprecated
def test_request_spot_instances_fulfilled():
"""
Test that moto correctly fullfills a spot instance request
"""
conn = boto.ec2.connect_to_region("us-east-1")
request = conn.request_spot_instances(
price=0.5, image_id='ami-abcd1234',
)
requests = conn.get_all_spot_instance_requests()
requests.should.have.length_of(1)
request = requests[0]
request.state.should.equal("open")
get_model('SpotInstanceRequest', 'us-east-1')[0].state = 'active'
requests = conn.get_all_spot_instance_requests()
requests.should.have.length_of(1)
request = requests[0]
request.state.should.equal("active")
@mock_ec2_deprecated
def test_tag_spot_instance_request():
"""
Test that moto correctly tags a spot instance request
"""
conn = boto.connect_ec2()
request = conn.request_spot_instances(
price=0.5, image_id='ami-abcd1234',
)
request[0].add_tag('tag1', 'value1')
request[0].add_tag('tag2', 'value2')
requests = conn.get_all_spot_instance_requests()
requests.should.have.length_of(1)
request = requests[0]
tag_dict = dict(request.tags)
tag_dict.should.equal({'tag1': 'value1', 'tag2': 'value2'})
@mock_ec2_deprecated
def test_get_all_spot_instance_requests_filtering():
"""
Test that moto correctly filters spot instance requests
"""
conn = boto.connect_ec2()
request1 = conn.request_spot_instances(
price=0.5, image_id='ami-abcd1234',
)
request2 = conn.request_spot_instances(
price=0.5, image_id='ami-abcd1234',
)
conn.request_spot_instances(
price=0.5, image_id='ami-abcd1234',
)
request1[0].add_tag('tag1', 'value1')
request1[0].add_tag('tag2', 'value2')
request2[0].add_tag('tag1', 'value1')
request2[0].add_tag('tag2', 'wrong')
requests = conn.get_all_spot_instance_requests(filters={'state': 'active'})
requests.should.have.length_of(0)
requests = conn.get_all_spot_instance_requests(filters={'state': 'open'})
requests.should.have.length_of(3)
requests = conn.get_all_spot_instance_requests(
filters={'tag:tag1': 'value1'})
requests.should.have.length_of(2)
requests = conn.get_all_spot_instance_requests(
filters={'tag:tag1': 'value1', 'tag:tag2': 'value2'})
requests.should.have.length_of(1)
@mock_ec2_deprecated
def test_request_spot_instances_setting_instance_id():
conn = boto.ec2.connect_to_region("us-east-1")
request = conn.request_spot_instances(
price=0.5, image_id='ami-abcd1234')
req = get_model('SpotInstanceRequest', 'us-east-1')[0]
req.state = 'active'
req.instance_id = 'i-12345678'
request = conn.get_all_spot_instance_requests()[0]
assert request.state == 'active'
assert request.instance_id == 'i-12345678'
from __future__ import unicode_literals
from nose.tools import assert_raises
import datetime
import boto
import boto3
from boto.exception import EC2ResponseError
from botocore.exceptions import ClientError
import pytz
import sure # noqa
from moto import mock_ec2, mock_ec2_deprecated
from moto.backends import get_model
from moto.core.utils import iso_8601_datetime_with_milliseconds
@mock_ec2
def test_request_spot_instances():
conn = boto3.client('ec2', 'us-east-1')
vpc = conn.create_vpc(CidrBlock="10.0.0.0/16")['Vpc']
subnet = conn.create_subnet(
VpcId=vpc['VpcId'], CidrBlock='10.0.0.0/16', AvailabilityZone='us-east-1a')['Subnet']
subnet_id = subnet['SubnetId']
conn.create_security_group(GroupName='group1', Description='description')
conn.create_security_group(GroupName='group2', Description='description')
start_dt = datetime.datetime(2013, 1, 1).replace(tzinfo=pytz.utc)
end_dt = datetime.datetime(2013, 1, 2).replace(tzinfo=pytz.utc)
start = iso_8601_datetime_with_milliseconds(start_dt)
end = iso_8601_datetime_with_milliseconds(end_dt)
with assert_raises(ClientError) as ex:
request = conn.request_spot_instances(
SpotPrice="0.5", InstanceCount=1, Type='one-time',
ValidFrom=start, ValidUntil=end, LaunchGroup="the-group",
AvailabilityZoneGroup='my-group',
LaunchSpecification={
"ImageId": 'ami-abcd1234',
"KeyName": "test",
"SecurityGroups": ['group1', 'group2'],
"UserData": "some test data",
"InstanceType": 'm1.small',
"Placement": {
"AvailabilityZone": 'us-east-1c',
},
"KernelId": "test-kernel",
"RamdiskId": "test-ramdisk",
"Monitoring": {
"Enabled": True,
},
"SubnetId": subnet_id,
},
DryRun=True,
)
ex.exception.response['Error']['Code'].should.equal('DryRunOperation')
ex.exception.response['ResponseMetadata'][
'HTTPStatusCode'].should.equal(400)
ex.exception.response['Error']['Message'].should.equal(
'An error occurred (DryRunOperation) when calling the RequestSpotInstance operation: Request would have succeeded, but DryRun flag is set')
request = conn.request_spot_instances(
SpotPrice="0.5", InstanceCount=1, Type='one-time',
ValidFrom=start, ValidUntil=end, LaunchGroup="the-group",
AvailabilityZoneGroup='my-group',
LaunchSpecification={
"ImageId": 'ami-abcd1234',
"KeyName": "test",
"SecurityGroups": ['group1', 'group2'],
"UserData": "some test data",
"InstanceType": 'm1.small',
"Placement": {
"AvailabilityZone": 'us-east-1c',
},
"KernelId": "test-kernel",
"RamdiskId": "test-ramdisk",
"Monitoring": {
"Enabled": True,
},
"SubnetId": subnet_id,
},
)
requests = conn.describe_spot_instance_requests()['SpotInstanceRequests']
requests.should.have.length_of(1)
request = requests[0]
request['State'].should.equal("open")
request['SpotPrice'].should.equal("0.5")
request['Type'].should.equal('one-time')
request['ValidFrom'].should.equal(start_dt)
request['ValidUntil'].should.equal(end_dt)
request['LaunchGroup'].should.equal("the-group")
request['AvailabilityZoneGroup'].should.equal('my-group')
launch_spec = request['LaunchSpecification']
security_group_names = [group['GroupName']
for group in launch_spec['SecurityGroups']]
set(security_group_names).should.equal(set(['group1', 'group2']))
launch_spec['ImageId'].should.equal('ami-abcd1234')
launch_spec['KeyName'].should.equal("test")
launch_spec['InstanceType'].should.equal('m1.small')
launch_spec['KernelId'].should.equal("test-kernel")
launch_spec['RamdiskId'].should.equal("test-ramdisk")
launch_spec['SubnetId'].should.equal(subnet_id)
@mock_ec2
def test_request_spot_instances_default_arguments():
"""
Test that moto set the correct default arguments
"""
conn = boto3.client('ec2', 'us-east-1')
request = conn.request_spot_instances(
SpotPrice="0.5",
LaunchSpecification={
"ImageId": 'ami-abcd1234',
}
)
requests = conn.describe_spot_instance_requests()['SpotInstanceRequests']
requests.should.have.length_of(1)
request = requests[0]
request['State'].should.equal("open")
request['SpotPrice'].should.equal("0.5")
request['Type'].should.equal('one-time')
request.shouldnt.contain('ValidFrom')
request.shouldnt.contain('ValidUntil')
request.shouldnt.contain('LaunchGroup')
request.shouldnt.contain('AvailabilityZoneGroup')
launch_spec = request['LaunchSpecification']
security_group_names = [group['GroupName']
for group in launch_spec['SecurityGroups']]
security_group_names.should.equal(["default"])
launch_spec['ImageId'].should.equal('ami-abcd1234')
request.shouldnt.contain('KeyName')
launch_spec['InstanceType'].should.equal('m1.small')
request.shouldnt.contain('KernelId')
request.shouldnt.contain('RamdiskId')
request.shouldnt.contain('SubnetId')
@mock_ec2_deprecated
def test_cancel_spot_instance_request():
conn = boto.connect_ec2()
conn.request_spot_instances(
price=0.5, image_id='ami-abcd1234',
)
requests = conn.get_all_spot_instance_requests()
requests.should.have.length_of(1)
with assert_raises(EC2ResponseError) as ex:
conn.cancel_spot_instance_requests([requests[0].id], dry_run=True)
ex.exception.error_code.should.equal('DryRunOperation')
ex.exception.status.should.equal(400)
ex.exception.message.should.equal(
'An error occurred (DryRunOperation) when calling the CancelSpotInstance operation: Request would have succeeded, but DryRun flag is set')
conn.cancel_spot_instance_requests([requests[0].id])
requests = conn.get_all_spot_instance_requests()
requests.should.have.length_of(0)
@mock_ec2_deprecated
def test_request_spot_instances_fulfilled():
"""
Test that moto correctly fullfills a spot instance request
"""
conn = boto.ec2.connect_to_region("us-east-1")
request = conn.request_spot_instances(
price=0.5, image_id='ami-abcd1234',
)
requests = conn.get_all_spot_instance_requests()
requests.should.have.length_of(1)
request = requests[0]
request.state.should.equal("open")
get_model('SpotInstanceRequest', 'us-east-1')[0].state = 'active'
requests = conn.get_all_spot_instance_requests()
requests.should.have.length_of(1)
request = requests[0]
request.state.should.equal("active")
@mock_ec2_deprecated
def test_tag_spot_instance_request():
"""
Test that moto correctly tags a spot instance request
"""
conn = boto.connect_ec2()
request = conn.request_spot_instances(
price=0.5, image_id='ami-abcd1234',
)
request[0].add_tag('tag1', 'value1')
request[0].add_tag('tag2', 'value2')
requests = conn.get_all_spot_instance_requests()
requests.should.have.length_of(1)
request = requests[0]
tag_dict = dict(request.tags)
tag_dict.should.equal({'tag1': 'value1', 'tag2': 'value2'})
@mock_ec2_deprecated
def test_get_all_spot_instance_requests_filtering():
"""
Test that moto correctly filters spot instance requests
"""
conn = boto.connect_ec2()
request1 = conn.request_spot_instances(
price=0.5, image_id='ami-abcd1234',
)
request2 = conn.request_spot_instances(
price=0.5, image_id='ami-abcd1234',
)
conn.request_spot_instances(
price=0.5, image_id='ami-abcd1234',
)
request1[0].add_tag('tag1', 'value1')
request1[0].add_tag('tag2', 'value2')
request2[0].add_tag('tag1', 'value1')
request2[0].add_tag('tag2', 'wrong')
requests = conn.get_all_spot_instance_requests(filters={'state': 'active'})
requests.should.have.length_of(0)
requests = conn.get_all_spot_instance_requests(filters={'state': 'open'})
requests.should.have.length_of(3)
requests = conn.get_all_spot_instance_requests(
filters={'tag:tag1': 'value1'})
requests.should.have.length_of(2)
requests = conn.get_all_spot_instance_requests(
filters={'tag:tag1': 'value1', 'tag:tag2': 'value2'})
requests.should.have.length_of(1)
@mock_ec2_deprecated
def test_request_spot_instances_setting_instance_id():
conn = boto.ec2.connect_to_region("us-east-1")
request = conn.request_spot_instances(
price=0.5, image_id='ami-abcd1234')
req = get_model('SpotInstanceRequest', 'us-east-1')[0]
req.state = 'active'
req.instance_id = 'i-12345678'
request = conn.get_all_spot_instance_requests()[0]
assert request.state == 'active'
assert request.instance_id == 'i-12345678'

View file

@ -1,291 +1,340 @@
from __future__ import unicode_literals
# Ensure 'assert_raises' context manager support for Python 2.6
import tests.backport_assert_raises # noqa
from nose.tools import assert_raises
import boto3
import boto
import boto.vpc
from boto.exception import EC2ResponseError
from botocore.exceptions import ParamValidationError
import json
import sure # noqa
from moto import mock_cloudformation_deprecated, mock_ec2, mock_ec2_deprecated
@mock_ec2_deprecated
def test_subnets():
ec2 = boto.connect_ec2('the_key', 'the_secret')
conn = boto.connect_vpc('the_key', 'the_secret')
vpc = conn.create_vpc("10.0.0.0/16")
subnet = conn.create_subnet(vpc.id, "10.0.0.0/18")
all_subnets = conn.get_all_subnets()
all_subnets.should.have.length_of(1 + len(ec2.get_all_zones()))
conn.delete_subnet(subnet.id)
all_subnets = conn.get_all_subnets()
all_subnets.should.have.length_of(0 + len(ec2.get_all_zones()))
with assert_raises(EC2ResponseError) as cm:
conn.delete_subnet(subnet.id)
cm.exception.code.should.equal('InvalidSubnetID.NotFound')
cm.exception.status.should.equal(400)
cm.exception.request_id.should_not.be.none
@mock_ec2_deprecated
def test_subnet_create_vpc_validation():
conn = boto.connect_vpc('the_key', 'the_secret')
with assert_raises(EC2ResponseError) as cm:
conn.create_subnet("vpc-abcd1234", "10.0.0.0/18")
cm.exception.code.should.equal('InvalidVpcID.NotFound')
cm.exception.status.should.equal(400)
cm.exception.request_id.should_not.be.none
@mock_ec2_deprecated
def test_subnet_tagging():
conn = boto.connect_vpc('the_key', 'the_secret')
vpc = conn.create_vpc("10.0.0.0/16")
subnet = conn.create_subnet(vpc.id, "10.0.0.0/18")
subnet.add_tag("a key", "some value")
tag = conn.get_all_tags()[0]
tag.name.should.equal("a key")
tag.value.should.equal("some value")
# Refresh the subnet
subnet = conn.get_all_subnets(subnet_ids=[subnet.id])[0]
subnet.tags.should.have.length_of(1)
subnet.tags["a key"].should.equal("some value")
@mock_ec2_deprecated
def test_subnet_should_have_proper_availability_zone_set():
conn = boto.vpc.connect_to_region('us-west-1')
vpcA = conn.create_vpc("10.0.0.0/16")
subnetA = conn.create_subnet(
vpcA.id, "10.0.0.0/24", availability_zone='us-west-1b')
subnetA.availability_zone.should.equal('us-west-1b')
@mock_ec2
def test_default_subnet():
ec2 = boto3.resource('ec2', region_name='us-west-1')
default_vpc = list(ec2.vpcs.all())[0]
default_vpc.cidr_block.should.equal('172.31.0.0/16')
default_vpc.reload()
default_vpc.is_default.should.be.ok
subnet = ec2.create_subnet(
VpcId=default_vpc.id, CidrBlock='172.31.0.0/20', AvailabilityZone='us-west-1a')
subnet.reload()
subnet.map_public_ip_on_launch.shouldnt.be.ok
@mock_ec2_deprecated
def test_non_default_subnet():
vpc_cli = boto.vpc.connect_to_region('us-west-1')
# Create the non default VPC
vpc = vpc_cli.create_vpc("10.0.0.0/16")
vpc.is_default.shouldnt.be.ok
subnet = vpc_cli.create_subnet(vpc.id, "10.0.0.0/24")
subnet = vpc_cli.get_all_subnets(subnet_ids=[subnet.id])[0]
subnet.mapPublicIpOnLaunch.should.equal('false')
@mock_ec2
def test_boto3_non_default_subnet():
ec2 = boto3.resource('ec2', region_name='us-west-1')
# Create the non default VPC
vpc = ec2.create_vpc(CidrBlock='10.0.0.0/16')
vpc.reload()
vpc.is_default.shouldnt.be.ok
subnet = ec2.create_subnet(
VpcId=vpc.id, CidrBlock='10.0.0.0/24', AvailabilityZone='us-west-1a')
subnet.reload()
subnet.map_public_ip_on_launch.shouldnt.be.ok
@mock_ec2
def test_modify_subnet_attribute():
ec2 = boto3.resource('ec2', region_name='us-west-1')
client = boto3.client('ec2', region_name='us-west-1')
# Get the default VPC
vpc = list(ec2.vpcs.all())[0]
subnet = ec2.create_subnet(
VpcId=vpc.id, CidrBlock='10.0.0.0/24', AvailabilityZone='us-west-1a')
# 'map_public_ip_on_launch' is set when calling 'DescribeSubnets' action
subnet.reload()
# For non default subnet, attribute value should be 'False'
subnet.map_public_ip_on_launch.shouldnt.be.ok
client.modify_subnet_attribute(
SubnetId=subnet.id, MapPublicIpOnLaunch={'Value': False})
subnet.reload()
subnet.map_public_ip_on_launch.shouldnt.be.ok
client.modify_subnet_attribute(
SubnetId=subnet.id, MapPublicIpOnLaunch={'Value': True})
subnet.reload()
subnet.map_public_ip_on_launch.should.be.ok
@mock_ec2
def test_modify_subnet_attribute_validation():
ec2 = boto3.resource('ec2', region_name='us-west-1')
client = boto3.client('ec2', region_name='us-west-1')
vpc = ec2.create_vpc(CidrBlock='10.0.0.0/16')
subnet = ec2.create_subnet(
VpcId=vpc.id, CidrBlock='10.0.0.0/24', AvailabilityZone='us-west-1a')
with assert_raises(ParamValidationError):
client.modify_subnet_attribute(
SubnetId=subnet.id, MapPublicIpOnLaunch={'Value': 'invalid'})
@mock_ec2_deprecated
def test_subnet_get_by_id():
ec2 = boto.ec2.connect_to_region('us-west-1')
conn = boto.vpc.connect_to_region('us-west-1')
vpcA = conn.create_vpc("10.0.0.0/16")
subnetA = conn.create_subnet(
vpcA.id, "10.0.0.0/24", availability_zone='us-west-1a')
vpcB = conn.create_vpc("10.0.0.0/16")
subnetB1 = conn.create_subnet(
vpcB.id, "10.0.0.0/24", availability_zone='us-west-1a')
subnetB2 = conn.create_subnet(
vpcB.id, "10.0.1.0/24", availability_zone='us-west-1b')
subnets_by_id = conn.get_all_subnets(subnet_ids=[subnetA.id, subnetB1.id])
subnets_by_id.should.have.length_of(2)
subnets_by_id = tuple(map(lambda s: s.id, subnets_by_id))
subnetA.id.should.be.within(subnets_by_id)
subnetB1.id.should.be.within(subnets_by_id)
with assert_raises(EC2ResponseError) as cm:
conn.get_all_subnets(subnet_ids=['subnet-does_not_exist'])
cm.exception.code.should.equal('InvalidSubnetID.NotFound')
cm.exception.status.should.equal(400)
cm.exception.request_id.should_not.be.none
@mock_ec2_deprecated
def test_get_subnets_filtering():
ec2 = boto.ec2.connect_to_region('us-west-1')
conn = boto.vpc.connect_to_region('us-west-1')
vpcA = conn.create_vpc("10.0.0.0/16")
subnetA = conn.create_subnet(
vpcA.id, "10.0.0.0/24", availability_zone='us-west-1a')
vpcB = conn.create_vpc("10.0.0.0/16")
subnetB1 = conn.create_subnet(
vpcB.id, "10.0.0.0/24", availability_zone='us-west-1a')
subnetB2 = conn.create_subnet(
vpcB.id, "10.0.1.0/24", availability_zone='us-west-1b')
all_subnets = conn.get_all_subnets()
all_subnets.should.have.length_of(3 + len(ec2.get_all_zones()))
# Filter by VPC ID
subnets_by_vpc = conn.get_all_subnets(filters={'vpc-id': vpcB.id})
subnets_by_vpc.should.have.length_of(2)
set([subnet.id for subnet in subnets_by_vpc]).should.equal(
set([subnetB1.id, subnetB2.id]))
# Filter by CIDR variations
subnets_by_cidr1 = conn.get_all_subnets(filters={'cidr': "10.0.0.0/24"})
subnets_by_cidr1.should.have.length_of(2)
set([subnet.id for subnet in subnets_by_cidr1]
).should.equal(set([subnetA.id, subnetB1.id]))
subnets_by_cidr2 = conn.get_all_subnets(
filters={'cidr-block': "10.0.0.0/24"})
subnets_by_cidr2.should.have.length_of(2)
set([subnet.id for subnet in subnets_by_cidr2]
).should.equal(set([subnetA.id, subnetB1.id]))
subnets_by_cidr3 = conn.get_all_subnets(
filters={'cidrBlock': "10.0.0.0/24"})
subnets_by_cidr3.should.have.length_of(2)
set([subnet.id for subnet in subnets_by_cidr3]
).should.equal(set([subnetA.id, subnetB1.id]))
# Filter by VPC ID and CIDR
subnets_by_vpc_and_cidr = conn.get_all_subnets(
filters={'vpc-id': vpcB.id, 'cidr': "10.0.0.0/24"})
subnets_by_vpc_and_cidr.should.have.length_of(1)
set([subnet.id for subnet in subnets_by_vpc_and_cidr]
).should.equal(set([subnetB1.id]))
# Filter by subnet ID
subnets_by_id = conn.get_all_subnets(filters={'subnet-id': subnetA.id})
subnets_by_id.should.have.length_of(1)
set([subnet.id for subnet in subnets_by_id]).should.equal(set([subnetA.id]))
# Filter by availabilityZone
subnets_by_az = conn.get_all_subnets(
filters={'availabilityZone': 'us-west-1a', 'vpc-id': vpcB.id})
subnets_by_az.should.have.length_of(1)
set([subnet.id for subnet in subnets_by_az]
).should.equal(set([subnetB1.id]))
# Filter by defaultForAz
subnets_by_az = conn.get_all_subnets(filters={'defaultForAz': "true"})
subnets_by_az.should.have.length_of(len(conn.get_all_zones()))
# Unsupported filter
conn.get_all_subnets.when.called_with(
filters={'not-implemented-filter': 'foobar'}).should.throw(NotImplementedError)
@mock_ec2_deprecated
@mock_cloudformation_deprecated
def test_subnet_tags_through_cloudformation():
vpc_conn = boto.vpc.connect_to_region('us-west-1')
vpc = vpc_conn.create_vpc("10.0.0.0/16")
subnet_template = {
"AWSTemplateFormatVersion": "2010-09-09",
"Resources": {
"testSubnet": {
"Type": "AWS::EC2::Subnet",
"Properties": {
"VpcId": vpc.id,
"CidrBlock": "10.0.0.0/24",
"AvailabilityZone": "us-west-1b",
"Tags": [{
"Key": "foo",
"Value": "bar",
}, {
"Key": "blah",
"Value": "baz",
}]
}
}
}
}
cf_conn = boto.cloudformation.connect_to_region("us-west-1")
template_json = json.dumps(subnet_template)
cf_conn.create_stack(
"test_stack",
template_body=template_json,
)
subnet = vpc_conn.get_all_subnets(filters={'cidrBlock': '10.0.0.0/24'})[0]
subnet.tags["foo"].should.equal("bar")
subnet.tags["blah"].should.equal("baz")
from __future__ import unicode_literals
# Ensure 'assert_raises' context manager support for Python 2.6
import tests.backport_assert_raises # noqa
from nose.tools import assert_raises
import boto3
import boto
import boto.vpc
from boto.exception import EC2ResponseError
from botocore.exceptions import ParamValidationError, ClientError
import json
import sure # noqa
from moto import mock_cloudformation_deprecated, mock_ec2, mock_ec2_deprecated
@mock_ec2_deprecated
def test_subnets():
ec2 = boto.connect_ec2('the_key', 'the_secret')
conn = boto.connect_vpc('the_key', 'the_secret')
vpc = conn.create_vpc("10.0.0.0/16")
subnet = conn.create_subnet(vpc.id, "10.0.0.0/18")
all_subnets = conn.get_all_subnets()
all_subnets.should.have.length_of(1 + len(ec2.get_all_zones()))
conn.delete_subnet(subnet.id)
all_subnets = conn.get_all_subnets()
all_subnets.should.have.length_of(0 + len(ec2.get_all_zones()))
with assert_raises(EC2ResponseError) as cm:
conn.delete_subnet(subnet.id)
cm.exception.code.should.equal('InvalidSubnetID.NotFound')
cm.exception.status.should.equal(400)
cm.exception.request_id.should_not.be.none
@mock_ec2_deprecated
def test_subnet_create_vpc_validation():
conn = boto.connect_vpc('the_key', 'the_secret')
with assert_raises(EC2ResponseError) as cm:
conn.create_subnet("vpc-abcd1234", "10.0.0.0/18")
cm.exception.code.should.equal('InvalidVpcID.NotFound')
cm.exception.status.should.equal(400)
cm.exception.request_id.should_not.be.none
@mock_ec2_deprecated
def test_subnet_tagging():
conn = boto.connect_vpc('the_key', 'the_secret')
vpc = conn.create_vpc("10.0.0.0/16")
subnet = conn.create_subnet(vpc.id, "10.0.0.0/18")
subnet.add_tag("a key", "some value")
tag = conn.get_all_tags()[0]
tag.name.should.equal("a key")
tag.value.should.equal("some value")
# Refresh the subnet
subnet = conn.get_all_subnets(subnet_ids=[subnet.id])[0]
subnet.tags.should.have.length_of(1)
subnet.tags["a key"].should.equal("some value")
@mock_ec2_deprecated
def test_subnet_should_have_proper_availability_zone_set():
conn = boto.vpc.connect_to_region('us-west-1')
vpcA = conn.create_vpc("10.0.0.0/16")
subnetA = conn.create_subnet(
vpcA.id, "10.0.0.0/24", availability_zone='us-west-1b')
subnetA.availability_zone.should.equal('us-west-1b')
@mock_ec2
def test_default_subnet():
ec2 = boto3.resource('ec2', region_name='us-west-1')
default_vpc = list(ec2.vpcs.all())[0]
default_vpc.cidr_block.should.equal('172.31.0.0/16')
default_vpc.reload()
default_vpc.is_default.should.be.ok
subnet = ec2.create_subnet(
VpcId=default_vpc.id, CidrBlock='172.31.48.0/20', AvailabilityZone='us-west-1a')
subnet.reload()
subnet.map_public_ip_on_launch.shouldnt.be.ok
@mock_ec2_deprecated
def test_non_default_subnet():
vpc_cli = boto.vpc.connect_to_region('us-west-1')
# Create the non default VPC
vpc = vpc_cli.create_vpc("10.0.0.0/16")
vpc.is_default.shouldnt.be.ok
subnet = vpc_cli.create_subnet(vpc.id, "10.0.0.0/24")
subnet = vpc_cli.get_all_subnets(subnet_ids=[subnet.id])[0]
subnet.mapPublicIpOnLaunch.should.equal('false')
@mock_ec2
def test_boto3_non_default_subnet():
ec2 = boto3.resource('ec2', region_name='us-west-1')
# Create the non default VPC
vpc = ec2.create_vpc(CidrBlock='10.0.0.0/16')
vpc.reload()
vpc.is_default.shouldnt.be.ok
subnet = ec2.create_subnet(
VpcId=vpc.id, CidrBlock='10.0.0.0/24', AvailabilityZone='us-west-1a')
subnet.reload()
subnet.map_public_ip_on_launch.shouldnt.be.ok
@mock_ec2
def test_modify_subnet_attribute():
ec2 = boto3.resource('ec2', region_name='us-west-1')
client = boto3.client('ec2', region_name='us-west-1')
# Get the default VPC
vpc = list(ec2.vpcs.all())[0]
subnet = ec2.create_subnet(
VpcId=vpc.id, CidrBlock="172.31.48.0/20", AvailabilityZone='us-west-1a')
# 'map_public_ip_on_launch' is set when calling 'DescribeSubnets' action
subnet.reload()
# For non default subnet, attribute value should be 'False'
subnet.map_public_ip_on_launch.shouldnt.be.ok
client.modify_subnet_attribute(
SubnetId=subnet.id, MapPublicIpOnLaunch={'Value': False})
subnet.reload()
subnet.map_public_ip_on_launch.shouldnt.be.ok
client.modify_subnet_attribute(
SubnetId=subnet.id, MapPublicIpOnLaunch={'Value': True})
subnet.reload()
subnet.map_public_ip_on_launch.should.be.ok
@mock_ec2
def test_modify_subnet_attribute_validation():
ec2 = boto3.resource('ec2', region_name='us-west-1')
client = boto3.client('ec2', region_name='us-west-1')
vpc = ec2.create_vpc(CidrBlock='10.0.0.0/16')
subnet = ec2.create_subnet(
VpcId=vpc.id, CidrBlock='10.0.0.0/24', AvailabilityZone='us-west-1a')
with assert_raises(ParamValidationError):
client.modify_subnet_attribute(
SubnetId=subnet.id, MapPublicIpOnLaunch={'Value': 'invalid'})
@mock_ec2_deprecated
def test_subnet_get_by_id():
ec2 = boto.ec2.connect_to_region('us-west-1')
conn = boto.vpc.connect_to_region('us-west-1')
vpcA = conn.create_vpc("10.0.0.0/16")
subnetA = conn.create_subnet(
vpcA.id, "10.0.0.0/24", availability_zone='us-west-1a')
vpcB = conn.create_vpc("10.0.0.0/16")
subnetB1 = conn.create_subnet(
vpcB.id, "10.0.0.0/24", availability_zone='us-west-1a')
subnetB2 = conn.create_subnet(
vpcB.id, "10.0.1.0/24", availability_zone='us-west-1b')
subnets_by_id = conn.get_all_subnets(subnet_ids=[subnetA.id, subnetB1.id])
subnets_by_id.should.have.length_of(2)
subnets_by_id = tuple(map(lambda s: s.id, subnets_by_id))
subnetA.id.should.be.within(subnets_by_id)
subnetB1.id.should.be.within(subnets_by_id)
with assert_raises(EC2ResponseError) as cm:
conn.get_all_subnets(subnet_ids=['subnet-does_not_exist'])
cm.exception.code.should.equal('InvalidSubnetID.NotFound')
cm.exception.status.should.equal(400)
cm.exception.request_id.should_not.be.none
@mock_ec2_deprecated
def test_get_subnets_filtering():
ec2 = boto.ec2.connect_to_region('us-west-1')
conn = boto.vpc.connect_to_region('us-west-1')
vpcA = conn.create_vpc("10.0.0.0/16")
subnetA = conn.create_subnet(
vpcA.id, "10.0.0.0/24", availability_zone='us-west-1a')
vpcB = conn.create_vpc("10.0.0.0/16")
subnetB1 = conn.create_subnet(
vpcB.id, "10.0.0.0/24", availability_zone='us-west-1a')
subnetB2 = conn.create_subnet(
vpcB.id, "10.0.1.0/24", availability_zone='us-west-1b')
all_subnets = conn.get_all_subnets()
all_subnets.should.have.length_of(3 + len(ec2.get_all_zones()))
# Filter by VPC ID
subnets_by_vpc = conn.get_all_subnets(filters={'vpc-id': vpcB.id})
subnets_by_vpc.should.have.length_of(2)
set([subnet.id for subnet in subnets_by_vpc]).should.equal(
set([subnetB1.id, subnetB2.id]))
# Filter by CIDR variations
subnets_by_cidr1 = conn.get_all_subnets(filters={'cidr': "10.0.0.0/24"})
subnets_by_cidr1.should.have.length_of(2)
set([subnet.id for subnet in subnets_by_cidr1]
).should.equal(set([subnetA.id, subnetB1.id]))
subnets_by_cidr2 = conn.get_all_subnets(
filters={'cidr-block': "10.0.0.0/24"})
subnets_by_cidr2.should.have.length_of(2)
set([subnet.id for subnet in subnets_by_cidr2]
).should.equal(set([subnetA.id, subnetB1.id]))
subnets_by_cidr3 = conn.get_all_subnets(
filters={'cidrBlock': "10.0.0.0/24"})
subnets_by_cidr3.should.have.length_of(2)
set([subnet.id for subnet in subnets_by_cidr3]
).should.equal(set([subnetA.id, subnetB1.id]))
# Filter by VPC ID and CIDR
subnets_by_vpc_and_cidr = conn.get_all_subnets(
filters={'vpc-id': vpcB.id, 'cidr': "10.0.0.0/24"})
subnets_by_vpc_and_cidr.should.have.length_of(1)
set([subnet.id for subnet in subnets_by_vpc_and_cidr]
).should.equal(set([subnetB1.id]))
# Filter by subnet ID
subnets_by_id = conn.get_all_subnets(filters={'subnet-id': subnetA.id})
subnets_by_id.should.have.length_of(1)
set([subnet.id for subnet in subnets_by_id]).should.equal(set([subnetA.id]))
# Filter by availabilityZone
subnets_by_az = conn.get_all_subnets(
filters={'availabilityZone': 'us-west-1a', 'vpc-id': vpcB.id})
subnets_by_az.should.have.length_of(1)
set([subnet.id for subnet in subnets_by_az]
).should.equal(set([subnetB1.id]))
# Filter by defaultForAz
subnets_by_az = conn.get_all_subnets(filters={'defaultForAz': "true"})
subnets_by_az.should.have.length_of(len(conn.get_all_zones()))
# Unsupported filter
conn.get_all_subnets.when.called_with(
filters={'not-implemented-filter': 'foobar'}).should.throw(NotImplementedError)
@mock_ec2_deprecated
@mock_cloudformation_deprecated
def test_subnet_tags_through_cloudformation():
vpc_conn = boto.vpc.connect_to_region('us-west-1')
vpc = vpc_conn.create_vpc("10.0.0.0/16")
subnet_template = {
"AWSTemplateFormatVersion": "2010-09-09",
"Resources": {
"testSubnet": {
"Type": "AWS::EC2::Subnet",
"Properties": {
"VpcId": vpc.id,
"CidrBlock": "10.0.0.0/24",
"AvailabilityZone": "us-west-1b",
"Tags": [{
"Key": "foo",
"Value": "bar",
}, {
"Key": "blah",
"Value": "baz",
}]
}
}
}
}
cf_conn = boto.cloudformation.connect_to_region("us-west-1")
template_json = json.dumps(subnet_template)
cf_conn.create_stack(
"test_stack",
template_body=template_json,
)
subnet = vpc_conn.get_all_subnets(filters={'cidrBlock': '10.0.0.0/24'})[0]
subnet.tags["foo"].should.equal("bar")
subnet.tags["blah"].should.equal("baz")
@mock_ec2
def test_create_subnet_with_invalid_cidr_range():
ec2 = boto3.resource('ec2', region_name='us-west-1')
vpc = ec2.create_vpc(CidrBlock='10.0.0.0/16')
vpc.reload()
vpc.is_default.shouldnt.be.ok
subnet_cidr_block = '10.1.0.0/20'
with assert_raises(ClientError) as ex:
subnet = ec2.create_subnet(VpcId=vpc.id, CidrBlock=subnet_cidr_block)
str(ex.exception).should.equal(
"An error occurred (InvalidSubnet.Range) when calling the CreateSubnet "
"operation: The CIDR '{}' is invalid.".format(subnet_cidr_block))
@mock_ec2
def test_create_subnet_with_invalid_cidr_block_parameter():
ec2 = boto3.resource('ec2', region_name='us-west-1')
vpc = ec2.create_vpc(CidrBlock='10.0.0.0/16')
vpc.reload()
vpc.is_default.shouldnt.be.ok
subnet_cidr_block = '1000.1.0.0/20'
with assert_raises(ClientError) as ex:
subnet = ec2.create_subnet(VpcId=vpc.id, CidrBlock=subnet_cidr_block)
str(ex.exception).should.equal(
"An error occurred (InvalidParameterValue) when calling the CreateSubnet "
"operation: Value ({}) for parameter cidrBlock is invalid. This is not a valid CIDR block.".format(subnet_cidr_block))
@mock_ec2
def test_create_subnets_with_overlapping_cidr_blocks():
ec2 = boto3.resource('ec2', region_name='us-west-1')
vpc = ec2.create_vpc(CidrBlock='10.0.0.0/16')
vpc.reload()
vpc.is_default.shouldnt.be.ok
subnet_cidr_block = '10.0.0.0/24'
with assert_raises(ClientError) as ex:
subnet1 = ec2.create_subnet(VpcId=vpc.id, CidrBlock=subnet_cidr_block)
subnet2 = ec2.create_subnet(VpcId=vpc.id, CidrBlock=subnet_cidr_block)
str(ex.exception).should.equal(
"An error occurred (InvalidSubnet.Conflict) when calling the CreateSubnet "
"operation: The CIDR '{}' conflicts with another subnet".format(subnet_cidr_block))

View file

@ -1,8 +1,12 @@
from moto.ec2 import utils
def test_random_key_pair():
key_pair = utils.random_key_pair()
assert len(key_pair['fingerprint']) == 59
assert key_pair['material'].startswith('---- BEGIN RSA PRIVATE KEY ----')
assert key_pair['material'].endswith('-----END RSA PRIVATE KEY-----')
from moto.ec2 import utils
from .helpers import rsa_check_private_key
def test_random_key_pair():
key_pair = utils.random_key_pair()
rsa_check_private_key(key_pair['material'])
# AWS uses MD5 fingerprints, which are 47 characters long, *not* SHA1
# fingerprints with 59 characters.
assert len(key_pair['fingerprint']) == 47

View file

@ -107,14 +107,19 @@ def test_vpc_peering_connections_cross_region():
ec2_apn1 = boto3.resource('ec2', region_name='ap-northeast-1')
vpc_apn1 = ec2_apn1.create_vpc(CidrBlock='10.20.0.0/16')
# create peering
vpc_pcx = ec2_usw1.create_vpc_peering_connection(
vpc_pcx_usw1 = ec2_usw1.create_vpc_peering_connection(
VpcId=vpc_usw1.id,
PeerVpcId=vpc_apn1.id,
PeerRegion='ap-northeast-1',
)
vpc_pcx.status['Code'].should.equal('initiating-request')
vpc_pcx.requester_vpc.id.should.equal(vpc_usw1.id)
vpc_pcx.accepter_vpc.id.should.equal(vpc_apn1.id)
vpc_pcx_usw1.status['Code'].should.equal('initiating-request')
vpc_pcx_usw1.requester_vpc.id.should.equal(vpc_usw1.id)
vpc_pcx_usw1.accepter_vpc.id.should.equal(vpc_apn1.id)
# test cross region vpc peering connection exist
vpc_pcx_apn1 = ec2_apn1.VpcPeeringConnection(vpc_pcx_usw1.id)
vpc_pcx_apn1.id.should.equal(vpc_pcx_usw1.id)
vpc_pcx_apn1.requester_vpc.id.should.equal(vpc_usw1.id)
vpc_pcx_apn1.accepter_vpc.id.should.equal(vpc_apn1.id)
@mock_ec2
@ -131,3 +136,148 @@ def test_vpc_peering_connections_cross_region_fail():
PeerVpcId=vpc_apn1.id,
PeerRegion='ap-northeast-2')
cm.exception.response['Error']['Code'].should.equal('InvalidVpcID.NotFound')
@mock_ec2
def test_vpc_peering_connections_cross_region_accept():
# create vpc in us-west-1 and ap-northeast-1
ec2_usw1 = boto3.resource('ec2', region_name='us-west-1')
vpc_usw1 = ec2_usw1.create_vpc(CidrBlock='10.90.0.0/16')
ec2_apn1 = boto3.resource('ec2', region_name='ap-northeast-1')
vpc_apn1 = ec2_apn1.create_vpc(CidrBlock='10.20.0.0/16')
# create peering
vpc_pcx_usw1 = ec2_usw1.create_vpc_peering_connection(
VpcId=vpc_usw1.id,
PeerVpcId=vpc_apn1.id,
PeerRegion='ap-northeast-1',
)
# accept peering from ap-northeast-1
ec2_apn1 = boto3.client('ec2', region_name='ap-northeast-1')
ec2_usw1 = boto3.client('ec2', region_name='us-west-1')
acp_pcx_apn1 = ec2_apn1.accept_vpc_peering_connection(
VpcPeeringConnectionId=vpc_pcx_usw1.id
)
des_pcx_apn1 = ec2_usw1.describe_vpc_peering_connections(
VpcPeeringConnectionIds=[vpc_pcx_usw1.id]
)
des_pcx_usw1 = ec2_usw1.describe_vpc_peering_connections(
VpcPeeringConnectionIds=[vpc_pcx_usw1.id]
)
acp_pcx_apn1['VpcPeeringConnection']['Status']['Code'].should.equal('active')
des_pcx_apn1['VpcPeeringConnections'][0]['Status']['Code'].should.equal('active')
des_pcx_usw1['VpcPeeringConnections'][0]['Status']['Code'].should.equal('active')
@mock_ec2
def test_vpc_peering_connections_cross_region_reject():
# create vpc in us-west-1 and ap-northeast-1
ec2_usw1 = boto3.resource('ec2', region_name='us-west-1')
vpc_usw1 = ec2_usw1.create_vpc(CidrBlock='10.90.0.0/16')
ec2_apn1 = boto3.resource('ec2', region_name='ap-northeast-1')
vpc_apn1 = ec2_apn1.create_vpc(CidrBlock='10.20.0.0/16')
# create peering
vpc_pcx_usw1 = ec2_usw1.create_vpc_peering_connection(
VpcId=vpc_usw1.id,
PeerVpcId=vpc_apn1.id,
PeerRegion='ap-northeast-1',
)
# reject peering from ap-northeast-1
ec2_apn1 = boto3.client('ec2', region_name='ap-northeast-1')
ec2_usw1 = boto3.client('ec2', region_name='us-west-1')
rej_pcx_apn1 = ec2_apn1.reject_vpc_peering_connection(
VpcPeeringConnectionId=vpc_pcx_usw1.id
)
des_pcx_apn1 = ec2_usw1.describe_vpc_peering_connections(
VpcPeeringConnectionIds=[vpc_pcx_usw1.id]
)
des_pcx_usw1 = ec2_usw1.describe_vpc_peering_connections(
VpcPeeringConnectionIds=[vpc_pcx_usw1.id]
)
rej_pcx_apn1['Return'].should.equal(True)
des_pcx_apn1['VpcPeeringConnections'][0]['Status']['Code'].should.equal('rejected')
des_pcx_usw1['VpcPeeringConnections'][0]['Status']['Code'].should.equal('rejected')
@mock_ec2
def test_vpc_peering_connections_cross_region_delete():
# create vpc in us-west-1 and ap-northeast-1
ec2_usw1 = boto3.resource('ec2', region_name='us-west-1')
vpc_usw1 = ec2_usw1.create_vpc(CidrBlock='10.90.0.0/16')
ec2_apn1 = boto3.resource('ec2', region_name='ap-northeast-1')
vpc_apn1 = ec2_apn1.create_vpc(CidrBlock='10.20.0.0/16')
# create peering
vpc_pcx_usw1 = ec2_usw1.create_vpc_peering_connection(
VpcId=vpc_usw1.id,
PeerVpcId=vpc_apn1.id,
PeerRegion='ap-northeast-1',
)
# reject peering from ap-northeast-1
ec2_apn1 = boto3.client('ec2', region_name='ap-northeast-1')
ec2_usw1 = boto3.client('ec2', region_name='us-west-1')
del_pcx_apn1 = ec2_apn1.delete_vpc_peering_connection(
VpcPeeringConnectionId=vpc_pcx_usw1.id
)
des_pcx_apn1 = ec2_usw1.describe_vpc_peering_connections(
VpcPeeringConnectionIds=[vpc_pcx_usw1.id]
)
des_pcx_usw1 = ec2_usw1.describe_vpc_peering_connections(
VpcPeeringConnectionIds=[vpc_pcx_usw1.id]
)
del_pcx_apn1['Return'].should.equal(True)
des_pcx_apn1['VpcPeeringConnections'][0]['Status']['Code'].should.equal('deleted')
des_pcx_usw1['VpcPeeringConnections'][0]['Status']['Code'].should.equal('deleted')
@mock_ec2
def test_vpc_peering_connections_cross_region_accept_wrong_region():
# create vpc in us-west-1 and ap-northeast-1
ec2_usw1 = boto3.resource('ec2', region_name='us-west-1')
vpc_usw1 = ec2_usw1.create_vpc(CidrBlock='10.90.0.0/16')
ec2_apn1 = boto3.resource('ec2', region_name='ap-northeast-1')
vpc_apn1 = ec2_apn1.create_vpc(CidrBlock='10.20.0.0/16')
# create peering
vpc_pcx_usw1 = ec2_usw1.create_vpc_peering_connection(
VpcId=vpc_usw1.id,
PeerVpcId=vpc_apn1.id,
PeerRegion='ap-northeast-1',
)
# accept wrong peering from us-west-1 which will raise error
ec2_apn1 = boto3.client('ec2', region_name='ap-northeast-1')
ec2_usw1 = boto3.client('ec2', region_name='us-west-1')
with assert_raises(ClientError) as cm:
ec2_usw1.accept_vpc_peering_connection(
VpcPeeringConnectionId=vpc_pcx_usw1.id
)
cm.exception.response['Error']['Code'].should.equal('OperationNotPermitted')
exp_msg = 'Incorrect region ({0}) specified for this request.VPC ' \
'peering connection {1} must be ' \
'accepted in region {2}'.format('us-west-1', vpc_pcx_usw1.id, 'ap-northeast-1')
cm.exception.response['Error']['Message'].should.equal(exp_msg)
@mock_ec2
def test_vpc_peering_connections_cross_region_reject_wrong_region():
# create vpc in us-west-1 and ap-northeast-1
ec2_usw1 = boto3.resource('ec2', region_name='us-west-1')
vpc_usw1 = ec2_usw1.create_vpc(CidrBlock='10.90.0.0/16')
ec2_apn1 = boto3.resource('ec2', region_name='ap-northeast-1')
vpc_apn1 = ec2_apn1.create_vpc(CidrBlock='10.20.0.0/16')
# create peering
vpc_pcx_usw1 = ec2_usw1.create_vpc_peering_connection(
VpcId=vpc_usw1.id,
PeerVpcId=vpc_apn1.id,
PeerRegion='ap-northeast-1',
)
# reject wrong peering from us-west-1 which will raise error
ec2_apn1 = boto3.client('ec2', region_name='ap-northeast-1')
ec2_usw1 = boto3.client('ec2', region_name='us-west-1')
with assert_raises(ClientError) as cm:
ec2_usw1.reject_vpc_peering_connection(
VpcPeeringConnectionId=vpc_pcx_usw1.id
)
cm.exception.response['Error']['Code'].should.equal('OperationNotPermitted')
exp_msg = 'Incorrect region ({0}) specified for this request.VPC ' \
'peering connection {1} must be accepted or ' \
'rejected in region {2}'.format('us-west-1', vpc_pcx_usw1.id, 'ap-northeast-1')
cm.exception.response['Error']['Message'].should.equal(exp_msg)

File diff suppressed because it is too large Load diff

View file

@ -388,23 +388,32 @@ def test_list_services():
cluster='test_ecs_cluster',
serviceName='test_ecs_service1',
taskDefinition='test_ecs_task',
schedulingStrategy='REPLICA',
desiredCount=2
)
_ = client.create_service(
cluster='test_ecs_cluster',
serviceName='test_ecs_service2',
taskDefinition='test_ecs_task',
schedulingStrategy='DAEMON',
desiredCount=2
)
response = client.list_services(
unfiltered_response = client.list_services(
cluster='test_ecs_cluster'
)
len(response['serviceArns']).should.equal(2)
response['serviceArns'][0].should.equal(
len(unfiltered_response['serviceArns']).should.equal(2)
unfiltered_response['serviceArns'][0].should.equal(
'arn:aws:ecs:us-east-1:012345678910:service/test_ecs_service1')
response['serviceArns'][1].should.equal(
unfiltered_response['serviceArns'][1].should.equal(
'arn:aws:ecs:us-east-1:012345678910:service/test_ecs_service2')
filtered_response = client.list_services(
cluster='test_ecs_cluster',
schedulingStrategy='REPLICA'
)
len(filtered_response['serviceArns']).should.equal(1)
filtered_response['serviceArns'][0].should.equal(
'arn:aws:ecs:us-east-1:012345678910:service/test_ecs_service1')
@mock_ecs
def test_describe_services():

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,426 +1,447 @@
from __future__ import unicode_literals
import sure # noqa
import re
from nose.tools import assert_raises
import boto3
from botocore.client import ClientError
from datetime import datetime
import pytz
from moto import mock_glue
from . import helpers
@mock_glue
def test_create_database():
client = boto3.client('glue', region_name='us-east-1')
database_name = 'myspecialdatabase'
helpers.create_database(client, database_name)
response = helpers.get_database(client, database_name)
database = response['Database']
database.should.equal({'Name': database_name})
@mock_glue
def test_create_database_already_exists():
client = boto3.client('glue', region_name='us-east-1')
database_name = 'cantcreatethisdatabasetwice'
helpers.create_database(client, database_name)
with assert_raises(ClientError) as exc:
helpers.create_database(client, database_name)
exc.exception.response['Error']['Code'].should.equal('AlreadyExistsException')
@mock_glue
def test_get_database_not_exits():
client = boto3.client('glue', region_name='us-east-1')
database_name = 'nosuchdatabase'
with assert_raises(ClientError) as exc:
helpers.get_database(client, database_name)
exc.exception.response['Error']['Code'].should.equal('EntityNotFoundException')
exc.exception.response['Error']['Message'].should.match('Database nosuchdatabase not found')
@mock_glue
def test_create_table():
client = boto3.client('glue', region_name='us-east-1')
database_name = 'myspecialdatabase'
helpers.create_database(client, database_name)
table_name = 'myspecialtable'
table_input = helpers.create_table_input(database_name, table_name)
helpers.create_table(client, database_name, table_name, table_input)
response = helpers.get_table(client, database_name, table_name)
table = response['Table']
table['Name'].should.equal(table_input['Name'])
table['StorageDescriptor'].should.equal(table_input['StorageDescriptor'])
table['PartitionKeys'].should.equal(table_input['PartitionKeys'])
@mock_glue
def test_create_table_already_exists():
client = boto3.client('glue', region_name='us-east-1')
database_name = 'myspecialdatabase'
helpers.create_database(client, database_name)
table_name = 'cantcreatethistabletwice'
helpers.create_table(client, database_name, table_name)
with assert_raises(ClientError) as exc:
helpers.create_table(client, database_name, table_name)
exc.exception.response['Error']['Code'].should.equal('AlreadyExistsException')
@mock_glue
def test_get_tables():
client = boto3.client('glue', region_name='us-east-1')
database_name = 'myspecialdatabase'
helpers.create_database(client, database_name)
table_names = ['myfirsttable', 'mysecondtable', 'mythirdtable']
table_inputs = {}
for table_name in table_names:
table_input = helpers.create_table_input(database_name, table_name)
table_inputs[table_name] = table_input
helpers.create_table(client, database_name, table_name, table_input)
response = helpers.get_tables(client, database_name)
tables = response['TableList']
tables.should.have.length_of(3)
for table in tables:
table_name = table['Name']
table_name.should.equal(table_inputs[table_name]['Name'])
table['StorageDescriptor'].should.equal(table_inputs[table_name]['StorageDescriptor'])
table['PartitionKeys'].should.equal(table_inputs[table_name]['PartitionKeys'])
@mock_glue
def test_get_table_versions():
client = boto3.client('glue', region_name='us-east-1')
database_name = 'myspecialdatabase'
helpers.create_database(client, database_name)
table_name = 'myfirsttable'
version_inputs = {}
table_input = helpers.create_table_input(database_name, table_name)
helpers.create_table(client, database_name, table_name, table_input)
version_inputs["1"] = table_input
columns = [{'Name': 'country', 'Type': 'string'}]
table_input = helpers.create_table_input(database_name, table_name, columns=columns)
helpers.update_table(client, database_name, table_name, table_input)
version_inputs["2"] = table_input
# Updateing with an indentical input should still create a new version
helpers.update_table(client, database_name, table_name, table_input)
version_inputs["3"] = table_input
response = helpers.get_table_versions(client, database_name, table_name)
vers = response['TableVersions']
vers.should.have.length_of(3)
vers[0]['Table']['StorageDescriptor']['Columns'].should.equal([])
vers[-1]['Table']['StorageDescriptor']['Columns'].should.equal(columns)
for n, ver in enumerate(vers):
n = str(n + 1)
ver['VersionId'].should.equal(n)
ver['Table']['Name'].should.equal(table_name)
ver['Table']['StorageDescriptor'].should.equal(version_inputs[n]['StorageDescriptor'])
ver['Table']['PartitionKeys'].should.equal(version_inputs[n]['PartitionKeys'])
response = helpers.get_table_version(client, database_name, table_name, "3")
ver = response['TableVersion']
ver['VersionId'].should.equal("3")
ver['Table']['Name'].should.equal(table_name)
ver['Table']['StorageDescriptor']['Columns'].should.equal(columns)
@mock_glue
def test_get_table_version_not_found():
client = boto3.client('glue', region_name='us-east-1')
database_name = 'myspecialdatabase'
table_name = 'myfirsttable'
helpers.create_database(client, database_name)
helpers.create_table(client, database_name, table_name)
with assert_raises(ClientError) as exc:
helpers.get_table_version(client, database_name, 'myfirsttable', "20")
exc.exception.response['Error']['Code'].should.equal('EntityNotFoundException')
exc.exception.response['Error']['Message'].should.match('version', re.I)
@mock_glue
def test_get_table_version_invalid_input():
client = boto3.client('glue', region_name='us-east-1')
database_name = 'myspecialdatabase'
table_name = 'myfirsttable'
helpers.create_database(client, database_name)
helpers.create_table(client, database_name, table_name)
with assert_raises(ClientError) as exc:
helpers.get_table_version(client, database_name, 'myfirsttable', "10not-an-int")
exc.exception.response['Error']['Code'].should.equal('InvalidInputException')
@mock_glue
def test_get_table_not_exits():
client = boto3.client('glue', region_name='us-east-1')
database_name = 'myspecialdatabase'
helpers.create_database(client, database_name)
with assert_raises(ClientError) as exc:
helpers.get_table(client, database_name, 'myfirsttable')
exc.exception.response['Error']['Code'].should.equal('EntityNotFoundException')
exc.exception.response['Error']['Message'].should.match('Table myfirsttable not found')
@mock_glue
def test_get_table_when_database_not_exits():
client = boto3.client('glue', region_name='us-east-1')
database_name = 'nosuchdatabase'
with assert_raises(ClientError) as exc:
helpers.get_table(client, database_name, 'myfirsttable')
exc.exception.response['Error']['Code'].should.equal('EntityNotFoundException')
exc.exception.response['Error']['Message'].should.match('Database nosuchdatabase not found')
@mock_glue
def test_get_partitions_empty():
client = boto3.client('glue', region_name='us-east-1')
database_name = 'myspecialdatabase'
table_name = 'myfirsttable'
helpers.create_database(client, database_name)
helpers.create_table(client, database_name, table_name)
response = client.get_partitions(DatabaseName=database_name, TableName=table_name)
response['Partitions'].should.have.length_of(0)
@mock_glue
def test_create_partition():
client = boto3.client('glue', region_name='us-east-1')
database_name = 'myspecialdatabase'
table_name = 'myfirsttable'
values = ['2018-10-01']
helpers.create_database(client, database_name)
helpers.create_table(client, database_name, table_name)
before = datetime.now(pytz.utc)
part_input = helpers.create_partition_input(database_name, table_name, values=values)
helpers.create_partition(client, database_name, table_name, part_input)
after = datetime.now(pytz.utc)
response = client.get_partitions(DatabaseName=database_name, TableName=table_name)
partitions = response['Partitions']
partitions.should.have.length_of(1)
partition = partitions[0]
partition['TableName'].should.equal(table_name)
partition['StorageDescriptor'].should.equal(part_input['StorageDescriptor'])
partition['Values'].should.equal(values)
partition['CreationTime'].should.be.greater_than(before)
partition['CreationTime'].should.be.lower_than(after)
@mock_glue
def test_create_partition_already_exist():
client = boto3.client('glue', region_name='us-east-1')
database_name = 'myspecialdatabase'
table_name = 'myfirsttable'
values = ['2018-10-01']
helpers.create_database(client, database_name)
helpers.create_table(client, database_name, table_name)
helpers.create_partition(client, database_name, table_name, values=values)
with assert_raises(ClientError) as exc:
helpers.create_partition(client, database_name, table_name, values=values)
exc.exception.response['Error']['Code'].should.equal('AlreadyExistsException')
@mock_glue
def test_get_partition_not_found():
client = boto3.client('glue', region_name='us-east-1')
database_name = 'myspecialdatabase'
table_name = 'myfirsttable'
values = ['2018-10-01']
helpers.create_database(client, database_name)
helpers.create_table(client, database_name, table_name)
with assert_raises(ClientError) as exc:
helpers.get_partition(client, database_name, table_name, values)
exc.exception.response['Error']['Code'].should.equal('EntityNotFoundException')
exc.exception.response['Error']['Message'].should.match('partition')
@mock_glue
def test_get_partition():
client = boto3.client('glue', region_name='us-east-1')
database_name = 'myspecialdatabase'
table_name = 'myfirsttable'
helpers.create_database(client, database_name)
helpers.create_table(client, database_name, table_name)
values = [['2018-10-01'], ['2018-09-01']]
helpers.create_partition(client, database_name, table_name, values=values[0])
helpers.create_partition(client, database_name, table_name, values=values[1])
response = client.get_partition(DatabaseName=database_name, TableName=table_name, PartitionValues=values[1])
partition = response['Partition']
partition['TableName'].should.equal(table_name)
partition['Values'].should.equal(values[1])
@mock_glue
def test_update_partition_not_found_moving():
client = boto3.client('glue', region_name='us-east-1')
database_name = 'myspecialdatabase'
table_name = 'myfirsttable'
helpers.create_database(client, database_name)
helpers.create_table(client, database_name, table_name)
with assert_raises(ClientError) as exc:
helpers.update_partition(client, database_name, table_name, old_values=['0000-00-00'], values=['2018-10-02'])
exc.exception.response['Error']['Code'].should.equal('EntityNotFoundException')
exc.exception.response['Error']['Message'].should.match('partition')
@mock_glue
def test_update_partition_not_found_change_in_place():
client = boto3.client('glue', region_name='us-east-1')
database_name = 'myspecialdatabase'
table_name = 'myfirsttable'
values = ['2018-10-01']
helpers.create_database(client, database_name)
helpers.create_table(client, database_name, table_name)
with assert_raises(ClientError) as exc:
helpers.update_partition(client, database_name, table_name, old_values=values, values=values)
exc.exception.response['Error']['Code'].should.equal('EntityNotFoundException')
exc.exception.response['Error']['Message'].should.match('partition')
@mock_glue
def test_update_partition_cannot_overwrite():
client = boto3.client('glue', region_name='us-east-1')
database_name = 'myspecialdatabase'
table_name = 'myfirsttable'
helpers.create_database(client, database_name)
helpers.create_table(client, database_name, table_name)
values = [['2018-10-01'], ['2018-09-01']]
helpers.create_partition(client, database_name, table_name, values=values[0])
helpers.create_partition(client, database_name, table_name, values=values[1])
with assert_raises(ClientError) as exc:
helpers.update_partition(client, database_name, table_name, old_values=values[0], values=values[1])
exc.exception.response['Error']['Code'].should.equal('AlreadyExistsException')
@mock_glue
def test_update_partition():
client = boto3.client('glue', region_name='us-east-1')
database_name = 'myspecialdatabase'
table_name = 'myfirsttable'
values = ['2018-10-01']
helpers.create_database(client, database_name)
helpers.create_table(client, database_name, table_name)
helpers.create_partition(client, database_name, table_name, values=values)
response = helpers.update_partition(
client,
database_name,
table_name,
old_values=values,
values=values,
columns=[{'Name': 'country', 'Type': 'string'}],
)
response = client.get_partition(DatabaseName=database_name, TableName=table_name, PartitionValues=values)
partition = response['Partition']
partition['TableName'].should.equal(table_name)
partition['StorageDescriptor']['Columns'].should.equal([{'Name': 'country', 'Type': 'string'}])
@mock_glue
def test_update_partition_move():
client = boto3.client('glue', region_name='us-east-1')
database_name = 'myspecialdatabase'
table_name = 'myfirsttable'
values = ['2018-10-01']
new_values = ['2018-09-01']
helpers.create_database(client, database_name)
helpers.create_table(client, database_name, table_name)
helpers.create_partition(client, database_name, table_name, values=values)
response = helpers.update_partition(
client,
database_name,
table_name,
old_values=values,
values=new_values,
columns=[{'Name': 'country', 'Type': 'string'}],
)
with assert_raises(ClientError) as exc:
helpers.get_partition(client, database_name, table_name, values)
# Old partition shouldn't exist anymore
exc.exception.response['Error']['Code'].should.equal('EntityNotFoundException')
response = client.get_partition(DatabaseName=database_name, TableName=table_name, PartitionValues=new_values)
partition = response['Partition']
partition['TableName'].should.equal(table_name)
partition['StorageDescriptor']['Columns'].should.equal([{'Name': 'country', 'Type': 'string'}])
from __future__ import unicode_literals
import sure # noqa
import re
from nose.tools import assert_raises
import boto3
from botocore.client import ClientError
from datetime import datetime
import pytz
from moto import mock_glue
from . import helpers
@mock_glue
def test_create_database():
client = boto3.client('glue', region_name='us-east-1')
database_name = 'myspecialdatabase'
helpers.create_database(client, database_name)
response = helpers.get_database(client, database_name)
database = response['Database']
database.should.equal({'Name': database_name})
@mock_glue
def test_create_database_already_exists():
client = boto3.client('glue', region_name='us-east-1')
database_name = 'cantcreatethisdatabasetwice'
helpers.create_database(client, database_name)
with assert_raises(ClientError) as exc:
helpers.create_database(client, database_name)
exc.exception.response['Error']['Code'].should.equal('AlreadyExistsException')
@mock_glue
def test_get_database_not_exits():
client = boto3.client('glue', region_name='us-east-1')
database_name = 'nosuchdatabase'
with assert_raises(ClientError) as exc:
helpers.get_database(client, database_name)
exc.exception.response['Error']['Code'].should.equal('EntityNotFoundException')
exc.exception.response['Error']['Message'].should.match('Database nosuchdatabase not found')
@mock_glue
def test_create_table():
client = boto3.client('glue', region_name='us-east-1')
database_name = 'myspecialdatabase'
helpers.create_database(client, database_name)
table_name = 'myspecialtable'
table_input = helpers.create_table_input(database_name, table_name)
helpers.create_table(client, database_name, table_name, table_input)
response = helpers.get_table(client, database_name, table_name)
table = response['Table']
table['Name'].should.equal(table_input['Name'])
table['StorageDescriptor'].should.equal(table_input['StorageDescriptor'])
table['PartitionKeys'].should.equal(table_input['PartitionKeys'])
@mock_glue
def test_create_table_already_exists():
client = boto3.client('glue', region_name='us-east-1')
database_name = 'myspecialdatabase'
helpers.create_database(client, database_name)
table_name = 'cantcreatethistabletwice'
helpers.create_table(client, database_name, table_name)
with assert_raises(ClientError) as exc:
helpers.create_table(client, database_name, table_name)
exc.exception.response['Error']['Code'].should.equal('AlreadyExistsException')
@mock_glue
def test_get_tables():
client = boto3.client('glue', region_name='us-east-1')
database_name = 'myspecialdatabase'
helpers.create_database(client, database_name)
table_names = ['myfirsttable', 'mysecondtable', 'mythirdtable']
table_inputs = {}
for table_name in table_names:
table_input = helpers.create_table_input(database_name, table_name)
table_inputs[table_name] = table_input
helpers.create_table(client, database_name, table_name, table_input)
response = helpers.get_tables(client, database_name)
tables = response['TableList']
tables.should.have.length_of(3)
for table in tables:
table_name = table['Name']
table_name.should.equal(table_inputs[table_name]['Name'])
table['StorageDescriptor'].should.equal(table_inputs[table_name]['StorageDescriptor'])
table['PartitionKeys'].should.equal(table_inputs[table_name]['PartitionKeys'])
@mock_glue
def test_get_table_versions():
client = boto3.client('glue', region_name='us-east-1')
database_name = 'myspecialdatabase'
helpers.create_database(client, database_name)
table_name = 'myfirsttable'
version_inputs = {}
table_input = helpers.create_table_input(database_name, table_name)
helpers.create_table(client, database_name, table_name, table_input)
version_inputs["1"] = table_input
columns = [{'Name': 'country', 'Type': 'string'}]
table_input = helpers.create_table_input(database_name, table_name, columns=columns)
helpers.update_table(client, database_name, table_name, table_input)
version_inputs["2"] = table_input
# Updateing with an indentical input should still create a new version
helpers.update_table(client, database_name, table_name, table_input)
version_inputs["3"] = table_input
response = helpers.get_table_versions(client, database_name, table_name)
vers = response['TableVersions']
vers.should.have.length_of(3)
vers[0]['Table']['StorageDescriptor']['Columns'].should.equal([])
vers[-1]['Table']['StorageDescriptor']['Columns'].should.equal(columns)
for n, ver in enumerate(vers):
n = str(n + 1)
ver['VersionId'].should.equal(n)
ver['Table']['Name'].should.equal(table_name)
ver['Table']['StorageDescriptor'].should.equal(version_inputs[n]['StorageDescriptor'])
ver['Table']['PartitionKeys'].should.equal(version_inputs[n]['PartitionKeys'])
response = helpers.get_table_version(client, database_name, table_name, "3")
ver = response['TableVersion']
ver['VersionId'].should.equal("3")
ver['Table']['Name'].should.equal(table_name)
ver['Table']['StorageDescriptor']['Columns'].should.equal(columns)
@mock_glue
def test_get_table_version_not_found():
client = boto3.client('glue', region_name='us-east-1')
database_name = 'myspecialdatabase'
table_name = 'myfirsttable'
helpers.create_database(client, database_name)
helpers.create_table(client, database_name, table_name)
with assert_raises(ClientError) as exc:
helpers.get_table_version(client, database_name, 'myfirsttable', "20")
exc.exception.response['Error']['Code'].should.equal('EntityNotFoundException')
exc.exception.response['Error']['Message'].should.match('version', re.I)
@mock_glue
def test_get_table_version_invalid_input():
client = boto3.client('glue', region_name='us-east-1')
database_name = 'myspecialdatabase'
table_name = 'myfirsttable'
helpers.create_database(client, database_name)
helpers.create_table(client, database_name, table_name)
with assert_raises(ClientError) as exc:
helpers.get_table_version(client, database_name, 'myfirsttable', "10not-an-int")
exc.exception.response['Error']['Code'].should.equal('InvalidInputException')
@mock_glue
def test_get_table_not_exits():
client = boto3.client('glue', region_name='us-east-1')
database_name = 'myspecialdatabase'
helpers.create_database(client, database_name)
with assert_raises(ClientError) as exc:
helpers.get_table(client, database_name, 'myfirsttable')
exc.exception.response['Error']['Code'].should.equal('EntityNotFoundException')
exc.exception.response['Error']['Message'].should.match('Table myfirsttable not found')
@mock_glue
def test_get_table_when_database_not_exits():
client = boto3.client('glue', region_name='us-east-1')
database_name = 'nosuchdatabase'
with assert_raises(ClientError) as exc:
helpers.get_table(client, database_name, 'myfirsttable')
exc.exception.response['Error']['Code'].should.equal('EntityNotFoundException')
exc.exception.response['Error']['Message'].should.match('Database nosuchdatabase not found')
@mock_glue
def test_delete_table():
client = boto3.client('glue', region_name='us-east-1')
database_name = 'myspecialdatabase'
helpers.create_database(client, database_name)
table_name = 'myspecialtable'
table_input = helpers.create_table_input(database_name, table_name)
helpers.create_table(client, database_name, table_name, table_input)
result = client.delete_table(DatabaseName=database_name, Name=table_name)
result['ResponseMetadata']['HTTPStatusCode'].should.equal(200)
# confirm table is deleted
with assert_raises(ClientError) as exc:
helpers.get_table(client, database_name, table_name)
exc.exception.response['Error']['Code'].should.equal('EntityNotFoundException')
exc.exception.response['Error']['Message'].should.match('Table myspecialtable not found')
@mock_glue
def test_get_partitions_empty():
client = boto3.client('glue', region_name='us-east-1')
database_name = 'myspecialdatabase'
table_name = 'myfirsttable'
helpers.create_database(client, database_name)
helpers.create_table(client, database_name, table_name)
response = client.get_partitions(DatabaseName=database_name, TableName=table_name)
response['Partitions'].should.have.length_of(0)
@mock_glue
def test_create_partition():
client = boto3.client('glue', region_name='us-east-1')
database_name = 'myspecialdatabase'
table_name = 'myfirsttable'
values = ['2018-10-01']
helpers.create_database(client, database_name)
helpers.create_table(client, database_name, table_name)
before = datetime.now(pytz.utc)
part_input = helpers.create_partition_input(database_name, table_name, values=values)
helpers.create_partition(client, database_name, table_name, part_input)
after = datetime.now(pytz.utc)
response = client.get_partitions(DatabaseName=database_name, TableName=table_name)
partitions = response['Partitions']
partitions.should.have.length_of(1)
partition = partitions[0]
partition['TableName'].should.equal(table_name)
partition['StorageDescriptor'].should.equal(part_input['StorageDescriptor'])
partition['Values'].should.equal(values)
partition['CreationTime'].should.be.greater_than(before)
partition['CreationTime'].should.be.lower_than(after)
@mock_glue
def test_create_partition_already_exist():
client = boto3.client('glue', region_name='us-east-1')
database_name = 'myspecialdatabase'
table_name = 'myfirsttable'
values = ['2018-10-01']
helpers.create_database(client, database_name)
helpers.create_table(client, database_name, table_name)
helpers.create_partition(client, database_name, table_name, values=values)
with assert_raises(ClientError) as exc:
helpers.create_partition(client, database_name, table_name, values=values)
exc.exception.response['Error']['Code'].should.equal('AlreadyExistsException')
@mock_glue
def test_get_partition_not_found():
client = boto3.client('glue', region_name='us-east-1')
database_name = 'myspecialdatabase'
table_name = 'myfirsttable'
values = ['2018-10-01']
helpers.create_database(client, database_name)
helpers.create_table(client, database_name, table_name)
with assert_raises(ClientError) as exc:
helpers.get_partition(client, database_name, table_name, values)
exc.exception.response['Error']['Code'].should.equal('EntityNotFoundException')
exc.exception.response['Error']['Message'].should.match('partition')
@mock_glue
def test_get_partition():
client = boto3.client('glue', region_name='us-east-1')
database_name = 'myspecialdatabase'
table_name = 'myfirsttable'
helpers.create_database(client, database_name)
helpers.create_table(client, database_name, table_name)
values = [['2018-10-01'], ['2018-09-01']]
helpers.create_partition(client, database_name, table_name, values=values[0])
helpers.create_partition(client, database_name, table_name, values=values[1])
response = client.get_partition(DatabaseName=database_name, TableName=table_name, PartitionValues=values[1])
partition = response['Partition']
partition['TableName'].should.equal(table_name)
partition['Values'].should.equal(values[1])
@mock_glue
def test_update_partition_not_found_moving():
client = boto3.client('glue', region_name='us-east-1')
database_name = 'myspecialdatabase'
table_name = 'myfirsttable'
helpers.create_database(client, database_name)
helpers.create_table(client, database_name, table_name)
with assert_raises(ClientError) as exc:
helpers.update_partition(client, database_name, table_name, old_values=['0000-00-00'], values=['2018-10-02'])
exc.exception.response['Error']['Code'].should.equal('EntityNotFoundException')
exc.exception.response['Error']['Message'].should.match('partition')
@mock_glue
def test_update_partition_not_found_change_in_place():
client = boto3.client('glue', region_name='us-east-1')
database_name = 'myspecialdatabase'
table_name = 'myfirsttable'
values = ['2018-10-01']
helpers.create_database(client, database_name)
helpers.create_table(client, database_name, table_name)
with assert_raises(ClientError) as exc:
helpers.update_partition(client, database_name, table_name, old_values=values, values=values)
exc.exception.response['Error']['Code'].should.equal('EntityNotFoundException')
exc.exception.response['Error']['Message'].should.match('partition')
@mock_glue
def test_update_partition_cannot_overwrite():
client = boto3.client('glue', region_name='us-east-1')
database_name = 'myspecialdatabase'
table_name = 'myfirsttable'
helpers.create_database(client, database_name)
helpers.create_table(client, database_name, table_name)
values = [['2018-10-01'], ['2018-09-01']]
helpers.create_partition(client, database_name, table_name, values=values[0])
helpers.create_partition(client, database_name, table_name, values=values[1])
with assert_raises(ClientError) as exc:
helpers.update_partition(client, database_name, table_name, old_values=values[0], values=values[1])
exc.exception.response['Error']['Code'].should.equal('AlreadyExistsException')
@mock_glue
def test_update_partition():
client = boto3.client('glue', region_name='us-east-1')
database_name = 'myspecialdatabase'
table_name = 'myfirsttable'
values = ['2018-10-01']
helpers.create_database(client, database_name)
helpers.create_table(client, database_name, table_name)
helpers.create_partition(client, database_name, table_name, values=values)
response = helpers.update_partition(
client,
database_name,
table_name,
old_values=values,
values=values,
columns=[{'Name': 'country', 'Type': 'string'}],
)
response = client.get_partition(DatabaseName=database_name, TableName=table_name, PartitionValues=values)
partition = response['Partition']
partition['TableName'].should.equal(table_name)
partition['StorageDescriptor']['Columns'].should.equal([{'Name': 'country', 'Type': 'string'}])
@mock_glue
def test_update_partition_move():
client = boto3.client('glue', region_name='us-east-1')
database_name = 'myspecialdatabase'
table_name = 'myfirsttable'
values = ['2018-10-01']
new_values = ['2018-09-01']
helpers.create_database(client, database_name)
helpers.create_table(client, database_name, table_name)
helpers.create_partition(client, database_name, table_name, values=values)
response = helpers.update_partition(
client,
database_name,
table_name,
old_values=values,
values=new_values,
columns=[{'Name': 'country', 'Type': 'string'}],
)
with assert_raises(ClientError) as exc:
helpers.get_partition(client, database_name, table_name, values)
# Old partition shouldn't exist anymore
exc.exception.response['Error']['Code'].should.equal('EntityNotFoundException')
response = client.get_partition(DatabaseName=database_name, TableName=table_name, PartitionValues=new_values)
partition = response['Partition']
partition['TableName'].should.equal(table_name)
partition['StorageDescriptor']['Columns'].should.equal([{'Name': 'country', 'Type': 'string'}])

View file

@ -128,7 +128,6 @@ def test_create_role_and_instance_profile():
profile = conn.create_instance_profile('my-other-profile')
profile.path.should.equal('/')
@mock_iam_deprecated()
def test_remove_role_from_instance_profile():
conn = boto.connect_iam()
@ -358,7 +357,7 @@ def test_list_policy_versions():
versions = conn.list_policy_versions(
PolicyArn="arn:aws:iam::123456789012:policy/TestListPolicyVersions")
versions.get('Versions')[0].get('VersionId').should.equal('v1')
conn.create_policy_version(
PolicyArn="arn:aws:iam::123456789012:policy/TestListPolicyVersions",
PolicyDocument='{"second":"policy"}')
@ -1292,4 +1291,22 @@ def test_create_role_no_path():
conn = boto3.client('iam', region_name='us-east-1')
resp = conn.create_role(RoleName='my-role', AssumeRolePolicyDocument='some policy', Description='test')
resp.get('Role').get('Arn').should.equal('arn:aws:iam::123456789012:role/my-role')
resp.get('Role').should_not.have.key('PermissionsBoundary')
@mock_iam()
def test_create_role_with_permissions_boundary():
conn = boto3.client('iam', region_name='us-east-1')
boundary = 'arn:aws:iam::123456789012:policy/boundary'
resp = conn.create_role(RoleName='my-role', AssumeRolePolicyDocument='some policy', Description='test', PermissionsBoundary=boundary)
expected = {
'PermissionsBoundaryType': 'PermissionsBoundaryPolicy',
'PermissionsBoundaryArn': boundary
}
resp.get('Role').get('PermissionsBoundary').should.equal(expected)
invalid_boundary_arn = 'arn:aws:iam::123456789:not_a_boundary'
with assert_raises(ClientError):
conn.create_role(RoleName='bad-boundary', AssumeRolePolicyDocument='some policy', Description='test', PermissionsBoundary=invalid_boundary_arn)
# Ensure the PermissionsBoundary is included in role listing as well
conn.list_roles().get('Roles')[0].get('PermissionsBoundary').should.equal(expected)

View file

@ -350,7 +350,7 @@ def test_list_things_with_attribute_and_thing_type_filter_and_next_token():
@mock_iot
def test_certs():
client = boto3.client('iot', region_name='ap-northeast-1')
client = boto3.client('iot', region_name='us-east-1')
cert = client.create_keys_and_certificate(setAsActive=True)
cert.should.have.key('certificateArn').which.should_not.be.none
cert.should.have.key('certificateId').which.should_not.be.none
@ -367,6 +367,29 @@ def test_certs():
cert_desc.should.have.key('certificateId').which.should_not.be.none
cert_desc.should.have.key('certificatePem').which.should_not.be.none
cert_desc.should.have.key('status').which.should.equal('ACTIVE')
cert_pem = cert_desc['certificatePem']
res = client.list_certificates()
for cert in res['certificates']:
cert.should.have.key('certificateArn').which.should_not.be.none
cert.should.have.key('certificateId').which.should_not.be.none
cert.should.have.key('status').which.should_not.be.none
cert.should.have.key('creationDate').which.should_not.be.none
client.update_certificate(certificateId=cert_id, newStatus='REVOKED')
cert = client.describe_certificate(certificateId=cert_id)
cert_desc = cert['certificateDescription']
cert_desc.should.have.key('status').which.should.equal('REVOKED')
client.delete_certificate(certificateId=cert_id)
res = client.list_certificates()
res.should.have.key('certificates')
# Test register_certificate flow
cert = client.register_certificate(certificatePem=cert_pem, setAsActive=True)
cert.should.have.key('certificateId').which.should_not.be.none
cert.should.have.key('certificateArn').which.should_not.be.none
cert_id = cert['certificateId']
res = client.list_certificates()
res.should.have.key('certificates').which.should.have.length_of(1)
@ -378,11 +401,12 @@ def test_certs():
client.update_certificate(certificateId=cert_id, newStatus='REVOKED')
cert = client.describe_certificate(certificateId=cert_id)
cert_desc.should.have.key('status').which.should.equal('ACTIVE')
cert_desc = cert['certificateDescription']
cert_desc.should.have.key('status').which.should.equal('REVOKED')
client.delete_certificate(certificateId=cert_id)
res = client.list_certificates()
res.should.have.key('certificates').which.should.have.length_of(0)
res.should.have.key('certificates')
@mock_iot

File diff suppressed because it is too large Load diff

View file

@ -18,13 +18,14 @@ from dateutil.tz import tzutc
@mock_kms_deprecated
def test_create_key():
conn = boto.kms.connect_to_region("us-west-2")
with freeze_time("2015-01-01 00:00:00"):
key = conn.create_key(policy="my policy",
description="my key", key_usage='ENCRYPT_DECRYPT')
key = conn.create_key(policy="my policy",
description="my key", key_usage='ENCRYPT_DECRYPT')
key['KeyMetadata']['Description'].should.equal("my key")
key['KeyMetadata']['KeyUsage'].should.equal("ENCRYPT_DECRYPT")
key['KeyMetadata']['Enabled'].should.equal(True)
key['KeyMetadata']['Description'].should.equal("my key")
key['KeyMetadata']['KeyUsage'].should.equal("ENCRYPT_DECRYPT")
key['KeyMetadata']['Enabled'].should.equal(True)
key['KeyMetadata']['CreationDate'].should.equal("1420070400")
@mock_kms_deprecated
@ -980,5 +981,3 @@ def test_put_key_policy_key_not_found():
PolicyName='default',
Policy='new policy'
)

View file

@ -1,128 +1,164 @@
import boto3
import sure # noqa
import six
from botocore.exceptions import ClientError
from moto import mock_logs, settings
from nose.tools import assert_raises
_logs_region = 'us-east-1' if settings.TEST_SERVER_MODE else 'us-west-2'
@mock_logs
def test_log_group_create():
conn = boto3.client('logs', 'us-west-2')
log_group_name = 'dummy'
response = conn.create_log_group(logGroupName=log_group_name)
response = conn.describe_log_groups(logGroupNamePrefix=log_group_name)
assert len(response['logGroups']) == 1
response = conn.delete_log_group(logGroupName=log_group_name)
@mock_logs
def test_exceptions():
conn = boto3.client('logs', 'us-west-2')
log_group_name = 'dummy'
log_stream_name = 'dummp-stream'
conn.create_log_group(logGroupName=log_group_name)
with assert_raises(ClientError):
conn.create_log_group(logGroupName=log_group_name)
# descrine_log_groups is not implemented yet
conn.create_log_stream(
logGroupName=log_group_name,
logStreamName=log_stream_name
)
with assert_raises(ClientError):
conn.create_log_stream(
logGroupName=log_group_name,
logStreamName=log_stream_name
)
conn.put_log_events(
logGroupName=log_group_name,
logStreamName=log_stream_name,
logEvents=[
{
'timestamp': 0,
'message': 'line'
},
],
)
with assert_raises(ClientError):
conn.put_log_events(
logGroupName=log_group_name,
logStreamName="invalid-stream",
logEvents=[
{
'timestamp': 0,
'message': 'line'
},
],
)
@mock_logs
def test_put_logs():
conn = boto3.client('logs', 'us-west-2')
log_group_name = 'dummy'
log_stream_name = 'stream'
conn.create_log_group(logGroupName=log_group_name)
conn.create_log_stream(
logGroupName=log_group_name,
logStreamName=log_stream_name
)
messages = [
{'timestamp': 0, 'message': 'hello'},
{'timestamp': 0, 'message': 'world'}
]
putRes = conn.put_log_events(
logGroupName=log_group_name,
logStreamName=log_stream_name,
logEvents=messages
)
res = conn.get_log_events(
logGroupName=log_group_name,
logStreamName=log_stream_name
)
events = res['events']
nextSequenceToken = putRes['nextSequenceToken']
assert isinstance(nextSequenceToken, six.string_types) == True
assert len(nextSequenceToken) == 56
events.should.have.length_of(2)
@mock_logs
def test_filter_logs_interleaved():
conn = boto3.client('logs', 'us-west-2')
log_group_name = 'dummy'
log_stream_name = 'stream'
conn.create_log_group(logGroupName=log_group_name)
conn.create_log_stream(
logGroupName=log_group_name,
logStreamName=log_stream_name
)
messages = [
{'timestamp': 0, 'message': 'hello'},
{'timestamp': 0, 'message': 'world'}
]
conn.put_log_events(
logGroupName=log_group_name,
logStreamName=log_stream_name,
logEvents=messages
)
res = conn.filter_log_events(
logGroupName=log_group_name,
logStreamNames=[log_stream_name],
interleaved=True,
)
events = res['events']
for original_message, resulting_event in zip(messages, events):
resulting_event['eventId'].should.equal(str(resulting_event['eventId']))
resulting_event['timestamp'].should.equal(original_message['timestamp'])
resulting_event['message'].should.equal(original_message['message'])
import boto3
import sure # noqa
import six
from botocore.exceptions import ClientError
from moto import mock_logs, settings
from nose.tools import assert_raises
_logs_region = 'us-east-1' if settings.TEST_SERVER_MODE else 'us-west-2'
@mock_logs
def test_log_group_create():
conn = boto3.client('logs', 'us-west-2')
log_group_name = 'dummy'
response = conn.create_log_group(logGroupName=log_group_name)
response = conn.describe_log_groups(logGroupNamePrefix=log_group_name)
assert len(response['logGroups']) == 1
# AWS defaults to Never Expire for log group retention
assert response['logGroups'][0].get('retentionInDays') == None
response = conn.delete_log_group(logGroupName=log_group_name)
@mock_logs
def test_exceptions():
conn = boto3.client('logs', 'us-west-2')
log_group_name = 'dummy'
log_stream_name = 'dummp-stream'
conn.create_log_group(logGroupName=log_group_name)
with assert_raises(ClientError):
conn.create_log_group(logGroupName=log_group_name)
# descrine_log_groups is not implemented yet
conn.create_log_stream(
logGroupName=log_group_name,
logStreamName=log_stream_name
)
with assert_raises(ClientError):
conn.create_log_stream(
logGroupName=log_group_name,
logStreamName=log_stream_name
)
conn.put_log_events(
logGroupName=log_group_name,
logStreamName=log_stream_name,
logEvents=[
{
'timestamp': 0,
'message': 'line'
},
],
)
with assert_raises(ClientError):
conn.put_log_events(
logGroupName=log_group_name,
logStreamName="invalid-stream",
logEvents=[
{
'timestamp': 0,
'message': 'line'
},
],
)
@mock_logs
def test_put_logs():
conn = boto3.client('logs', 'us-west-2')
log_group_name = 'dummy'
log_stream_name = 'stream'
conn.create_log_group(logGroupName=log_group_name)
conn.create_log_stream(
logGroupName=log_group_name,
logStreamName=log_stream_name
)
messages = [
{'timestamp': 0, 'message': 'hello'},
{'timestamp': 0, 'message': 'world'}
]
putRes = conn.put_log_events(
logGroupName=log_group_name,
logStreamName=log_stream_name,
logEvents=messages
)
res = conn.get_log_events(
logGroupName=log_group_name,
logStreamName=log_stream_name
)
events = res['events']
nextSequenceToken = putRes['nextSequenceToken']
assert isinstance(nextSequenceToken, six.string_types) == True
assert len(nextSequenceToken) == 56
events.should.have.length_of(2)
@mock_logs
def test_filter_logs_interleaved():
conn = boto3.client('logs', 'us-west-2')
log_group_name = 'dummy'
log_stream_name = 'stream'
conn.create_log_group(logGroupName=log_group_name)
conn.create_log_stream(
logGroupName=log_group_name,
logStreamName=log_stream_name
)
messages = [
{'timestamp': 0, 'message': 'hello'},
{'timestamp': 0, 'message': 'world'}
]
conn.put_log_events(
logGroupName=log_group_name,
logStreamName=log_stream_name,
logEvents=messages
)
res = conn.filter_log_events(
logGroupName=log_group_name,
logStreamNames=[log_stream_name],
interleaved=True,
)
events = res['events']
for original_message, resulting_event in zip(messages, events):
resulting_event['eventId'].should.equal(str(resulting_event['eventId']))
resulting_event['timestamp'].should.equal(original_message['timestamp'])
resulting_event['message'].should.equal(original_message['message'])
@mock_logs
def test_put_retention_policy():
conn = boto3.client('logs', 'us-west-2')
log_group_name = 'dummy'
response = conn.create_log_group(logGroupName=log_group_name)
response = conn.put_retention_policy(logGroupName=log_group_name, retentionInDays=7)
response = conn.describe_log_groups(logGroupNamePrefix=log_group_name)
assert len(response['logGroups']) == 1
assert response['logGroups'][0].get('retentionInDays') == 7
response = conn.delete_log_group(logGroupName=log_group_name)
@mock_logs
def test_delete_retention_policy():
conn = boto3.client('logs', 'us-west-2')
log_group_name = 'dummy'
response = conn.create_log_group(logGroupName=log_group_name)
response = conn.put_retention_policy(logGroupName=log_group_name, retentionInDays=7)
response = conn.describe_log_groups(logGroupNamePrefix=log_group_name)
assert len(response['logGroups']) == 1
assert response['logGroups'][0].get('retentionInDays') == 7
response = conn.delete_retention_policy(logGroupName=log_group_name)
response = conn.describe_log_groups(logGroupNamePrefix=log_group_name)
assert len(response['logGroups']) == 1
assert response['logGroups'][0].get('retentionInDays') == None
response = conn.delete_log_group(logGroupName=log_group_name)

View file

@ -1,136 +1,152 @@
from __future__ import unicode_literals
import six
import sure # noqa
import datetime
from moto.organizations import utils
EMAIL_REGEX = "^.+@[a-zA-Z0-9-.]+.[a-zA-Z]{2,3}|[0-9]{1,3}$"
ORG_ID_REGEX = r'o-[a-z0-9]{%s}' % utils.ORG_ID_SIZE
ROOT_ID_REGEX = r'r-[a-z0-9]{%s}' % utils.ROOT_ID_SIZE
OU_ID_REGEX = r'ou-[a-z0-9]{%s}-[a-z0-9]{%s}' % (utils.ROOT_ID_SIZE, utils.OU_ID_SUFFIX_SIZE)
ACCOUNT_ID_REGEX = r'[0-9]{%s}' % utils.ACCOUNT_ID_SIZE
CREATE_ACCOUNT_STATUS_ID_REGEX = r'car-[a-z0-9]{%s}' % utils.CREATE_ACCOUNT_STATUS_ID_SIZE
def test_make_random_org_id():
org_id = utils.make_random_org_id()
org_id.should.match(ORG_ID_REGEX)
def test_make_random_root_id():
root_id = utils.make_random_root_id()
root_id.should.match(ROOT_ID_REGEX)
def test_make_random_ou_id():
root_id = utils.make_random_root_id()
ou_id = utils.make_random_ou_id(root_id)
ou_id.should.match(OU_ID_REGEX)
def test_make_random_account_id():
account_id = utils.make_random_account_id()
account_id.should.match(ACCOUNT_ID_REGEX)
def test_make_random_create_account_status_id():
create_account_status_id = utils.make_random_create_account_status_id()
create_account_status_id.should.match(CREATE_ACCOUNT_STATUS_ID_REGEX)
def validate_organization(response):
org = response['Organization']
sorted(org.keys()).should.equal([
'Arn',
'AvailablePolicyTypes',
'FeatureSet',
'Id',
'MasterAccountArn',
'MasterAccountEmail',
'MasterAccountId',
])
org['Id'].should.match(ORG_ID_REGEX)
org['MasterAccountId'].should.equal(utils.MASTER_ACCOUNT_ID)
org['MasterAccountArn'].should.equal(utils.MASTER_ACCOUNT_ARN_FORMAT.format(
org['MasterAccountId'],
org['Id'],
))
org['Arn'].should.equal(utils.ORGANIZATION_ARN_FORMAT.format(
org['MasterAccountId'],
org['Id'],
))
org['MasterAccountEmail'].should.equal(utils.MASTER_ACCOUNT_EMAIL)
org['FeatureSet'].should.be.within(['ALL', 'CONSOLIDATED_BILLING'])
org['AvailablePolicyTypes'].should.equal([{
'Type': 'SERVICE_CONTROL_POLICY',
'Status': 'ENABLED'
}])
def validate_roots(org, response):
response.should.have.key('Roots').should.be.a(list)
response['Roots'].should_not.be.empty
root = response['Roots'][0]
root.should.have.key('Id').should.match(ROOT_ID_REGEX)
root.should.have.key('Arn').should.equal(utils.ROOT_ARN_FORMAT.format(
org['MasterAccountId'],
org['Id'],
root['Id'],
))
root.should.have.key('Name').should.be.a(six.string_types)
root.should.have.key('PolicyTypes').should.be.a(list)
root['PolicyTypes'][0].should.have.key('Type').should.equal('SERVICE_CONTROL_POLICY')
root['PolicyTypes'][0].should.have.key('Status').should.equal('ENABLED')
def validate_organizational_unit(org, response):
response.should.have.key('OrganizationalUnit').should.be.a(dict)
ou = response['OrganizationalUnit']
ou.should.have.key('Id').should.match(OU_ID_REGEX)
ou.should.have.key('Arn').should.equal(utils.OU_ARN_FORMAT.format(
org['MasterAccountId'],
org['Id'],
ou['Id'],
))
ou.should.have.key('Name').should.be.a(six.string_types)
def validate_account(org, account):
sorted(account.keys()).should.equal([
'Arn',
'Email',
'Id',
'JoinedMethod',
'JoinedTimestamp',
'Name',
'Status',
])
account['Id'].should.match(ACCOUNT_ID_REGEX)
account['Arn'].should.equal(utils.ACCOUNT_ARN_FORMAT.format(
org['MasterAccountId'],
org['Id'],
account['Id'],
))
account['Email'].should.match(EMAIL_REGEX)
account['JoinedMethod'].should.be.within(['INVITED', 'CREATED'])
account['Status'].should.be.within(['ACTIVE', 'SUSPENDED'])
account['Name'].should.be.a(six.string_types)
account['JoinedTimestamp'].should.be.a(datetime.datetime)
def validate_create_account_status(create_status):
sorted(create_status.keys()).should.equal([
'AccountId',
'AccountName',
'CompletedTimestamp',
'Id',
'RequestedTimestamp',
'State',
])
create_status['Id'].should.match(CREATE_ACCOUNT_STATUS_ID_REGEX)
create_status['AccountId'].should.match(ACCOUNT_ID_REGEX)
create_status['AccountName'].should.be.a(six.string_types)
create_status['State'].should.equal('SUCCEEDED')
create_status['RequestedTimestamp'].should.be.a(datetime.datetime)
create_status['CompletedTimestamp'].should.be.a(datetime.datetime)
from __future__ import unicode_literals
import six
import sure # noqa
import datetime
from moto.organizations import utils
def test_make_random_org_id():
org_id = utils.make_random_org_id()
org_id.should.match(utils.ORG_ID_REGEX)
def test_make_random_root_id():
root_id = utils.make_random_root_id()
root_id.should.match(utils.ROOT_ID_REGEX)
def test_make_random_ou_id():
root_id = utils.make_random_root_id()
ou_id = utils.make_random_ou_id(root_id)
ou_id.should.match(utils.OU_ID_REGEX)
def test_make_random_account_id():
account_id = utils.make_random_account_id()
account_id.should.match(utils.ACCOUNT_ID_REGEX)
def test_make_random_create_account_status_id():
create_account_status_id = utils.make_random_create_account_status_id()
create_account_status_id.should.match(utils.CREATE_ACCOUNT_STATUS_ID_REGEX)
def test_make_random_service_control_policy_id():
service_control_policy_id = utils.make_random_service_control_policy_id()
service_control_policy_id.should.match(utils.SCP_ID_REGEX)
def validate_organization(response):
org = response['Organization']
sorted(org.keys()).should.equal([
'Arn',
'AvailablePolicyTypes',
'FeatureSet',
'Id',
'MasterAccountArn',
'MasterAccountEmail',
'MasterAccountId',
])
org['Id'].should.match(utils.ORG_ID_REGEX)
org['MasterAccountId'].should.equal(utils.MASTER_ACCOUNT_ID)
org['MasterAccountArn'].should.equal(utils.MASTER_ACCOUNT_ARN_FORMAT.format(
org['MasterAccountId'],
org['Id'],
))
org['Arn'].should.equal(utils.ORGANIZATION_ARN_FORMAT.format(
org['MasterAccountId'],
org['Id'],
))
org['MasterAccountEmail'].should.equal(utils.MASTER_ACCOUNT_EMAIL)
org['FeatureSet'].should.be.within(['ALL', 'CONSOLIDATED_BILLING'])
org['AvailablePolicyTypes'].should.equal([{
'Type': 'SERVICE_CONTROL_POLICY',
'Status': 'ENABLED'
}])
def validate_roots(org, response):
response.should.have.key('Roots').should.be.a(list)
response['Roots'].should_not.be.empty
root = response['Roots'][0]
root.should.have.key('Id').should.match(utils.ROOT_ID_REGEX)
root.should.have.key('Arn').should.equal(utils.ROOT_ARN_FORMAT.format(
org['MasterAccountId'],
org['Id'],
root['Id'],
))
root.should.have.key('Name').should.be.a(six.string_types)
root.should.have.key('PolicyTypes').should.be.a(list)
root['PolicyTypes'][0].should.have.key('Type').should.equal('SERVICE_CONTROL_POLICY')
root['PolicyTypes'][0].should.have.key('Status').should.equal('ENABLED')
def validate_organizational_unit(org, response):
response.should.have.key('OrganizationalUnit').should.be.a(dict)
ou = response['OrganizationalUnit']
ou.should.have.key('Id').should.match(utils.OU_ID_REGEX)
ou.should.have.key('Arn').should.equal(utils.OU_ARN_FORMAT.format(
org['MasterAccountId'],
org['Id'],
ou['Id'],
))
ou.should.have.key('Name').should.be.a(six.string_types)
def validate_account(org, account):
sorted(account.keys()).should.equal([
'Arn',
'Email',
'Id',
'JoinedMethod',
'JoinedTimestamp',
'Name',
'Status',
])
account['Id'].should.match(utils.ACCOUNT_ID_REGEX)
account['Arn'].should.equal(utils.ACCOUNT_ARN_FORMAT.format(
org['MasterAccountId'],
org['Id'],
account['Id'],
))
account['Email'].should.match(utils.EMAIL_REGEX)
account['JoinedMethod'].should.be.within(['INVITED', 'CREATED'])
account['Status'].should.be.within(['ACTIVE', 'SUSPENDED'])
account['Name'].should.be.a(six.string_types)
account['JoinedTimestamp'].should.be.a(datetime.datetime)
def validate_create_account_status(create_status):
sorted(create_status.keys()).should.equal([
'AccountId',
'AccountName',
'CompletedTimestamp',
'Id',
'RequestedTimestamp',
'State',
])
create_status['Id'].should.match(utils.CREATE_ACCOUNT_STATUS_ID_REGEX)
create_status['AccountId'].should.match(utils.ACCOUNT_ID_REGEX)
create_status['AccountName'].should.be.a(six.string_types)
create_status['State'].should.equal('SUCCEEDED')
create_status['RequestedTimestamp'].should.be.a(datetime.datetime)
create_status['CompletedTimestamp'].should.be.a(datetime.datetime)
def validate_policy_summary(org, summary):
summary.should.be.a(dict)
summary.should.have.key('Id').should.match(utils.SCP_ID_REGEX)
summary.should.have.key('Arn').should.equal(utils.SCP_ARN_FORMAT.format(
org['MasterAccountId'],
org['Id'],
summary['Id'],
))
summary.should.have.key('Name').should.be.a(six.string_types)
summary.should.have.key('Description').should.be.a(six.string_types)
summary.should.have.key('Type').should.equal('SERVICE_CONTROL_POLICY')
summary.should.have.key('AwsManaged').should.be.a(bool)
def validate_service_control_policy(org, response):
response.should.have.key('PolicySummary').should.be.a(dict)
response.should.have.key('Content').should.be.a(six.string_types)
validate_policy_summary(org, response['PolicySummary'])

View file

@ -1,322 +1,594 @@
from __future__ import unicode_literals
import boto3
import sure # noqa
from botocore.exceptions import ClientError
from nose.tools import assert_raises
from moto import mock_organizations
from moto.organizations import utils
from .organizations_test_utils import (
validate_organization,
validate_roots,
validate_organizational_unit,
validate_account,
validate_create_account_status,
)
@mock_organizations
def test_create_organization():
client = boto3.client('organizations', region_name='us-east-1')
response = client.create_organization(FeatureSet='ALL')
validate_organization(response)
response['Organization']['FeatureSet'].should.equal('ALL')
@mock_organizations
def test_describe_organization():
client = boto3.client('organizations', region_name='us-east-1')
client.create_organization(FeatureSet='ALL')
response = client.describe_organization()
validate_organization(response)
@mock_organizations
def test_describe_organization_exception():
client = boto3.client('organizations', region_name='us-east-1')
with assert_raises(ClientError) as e:
response = client.describe_organization()
ex = e.exception
ex.operation_name.should.equal('DescribeOrganization')
ex.response['Error']['Code'].should.equal('400')
ex.response['Error']['Message'].should.contain('AWSOrganizationsNotInUseException')
# Organizational Units
@mock_organizations
def test_list_roots():
client = boto3.client('organizations', region_name='us-east-1')
org = client.create_organization(FeatureSet='ALL')['Organization']
response = client.list_roots()
validate_roots(org, response)
@mock_organizations
def test_create_organizational_unit():
client = boto3.client('organizations', region_name='us-east-1')
org = client.create_organization(FeatureSet='ALL')['Organization']
root_id = client.list_roots()['Roots'][0]['Id']
ou_name = 'ou01'
response = client.create_organizational_unit(
ParentId=root_id,
Name=ou_name,
)
validate_organizational_unit(org, response)
response['OrganizationalUnit']['Name'].should.equal(ou_name)
@mock_organizations
def test_describe_organizational_unit():
client = boto3.client('organizations', region_name='us-east-1')
org = client.create_organization(FeatureSet='ALL')['Organization']
root_id = client.list_roots()['Roots'][0]['Id']
ou_id = client.create_organizational_unit(
ParentId=root_id,
Name='ou01',
)['OrganizationalUnit']['Id']
response = client.describe_organizational_unit(OrganizationalUnitId=ou_id)
validate_organizational_unit(org, response)
@mock_organizations
def test_describe_organizational_unit_exception():
client = boto3.client('organizations', region_name='us-east-1')
org = client.create_organization(FeatureSet='ALL')['Organization']
with assert_raises(ClientError) as e:
response = client.describe_organizational_unit(
OrganizationalUnitId=utils.make_random_root_id()
)
ex = e.exception
ex.operation_name.should.equal('DescribeOrganizationalUnit')
ex.response['Error']['Code'].should.equal('400')
ex.response['Error']['Message'].should.contain('OrganizationalUnitNotFoundException')
@mock_organizations
def test_list_organizational_units_for_parent():
client = boto3.client('organizations', region_name='us-east-1')
org = client.create_organization(FeatureSet='ALL')['Organization']
root_id = client.list_roots()['Roots'][0]['Id']
client.create_organizational_unit(ParentId=root_id, Name='ou01')
client.create_organizational_unit(ParentId=root_id, Name='ou02')
client.create_organizational_unit(ParentId=root_id, Name='ou03')
response = client.list_organizational_units_for_parent(ParentId=root_id)
response.should.have.key('OrganizationalUnits').should.be.a(list)
for ou in response['OrganizationalUnits']:
validate_organizational_unit(org, dict(OrganizationalUnit=ou))
@mock_organizations
def test_list_organizational_units_for_parent_exception():
client = boto3.client('organizations', region_name='us-east-1')
with assert_raises(ClientError) as e:
response = client.list_organizational_units_for_parent(
ParentId=utils.make_random_root_id()
)
ex = e.exception
ex.operation_name.should.equal('ListOrganizationalUnitsForParent')
ex.response['Error']['Code'].should.equal('400')
ex.response['Error']['Message'].should.contain('ParentNotFoundException')
# Accounts
mockname = 'mock-account'
mockdomain = 'moto-example.org'
mockemail = '@'.join([mockname, mockdomain])
@mock_organizations
def test_create_account():
client = boto3.client('organizations', region_name='us-east-1')
client.create_organization(FeatureSet='ALL')
create_status = client.create_account(
AccountName=mockname, Email=mockemail
)['CreateAccountStatus']
validate_create_account_status(create_status)
create_status['AccountName'].should.equal(mockname)
@mock_organizations
def test_describe_account():
client = boto3.client('organizations', region_name='us-east-1')
org = client.create_organization(FeatureSet='ALL')['Organization']
account_id = client.create_account(
AccountName=mockname, Email=mockemail
)['CreateAccountStatus']['AccountId']
response = client.describe_account(AccountId=account_id)
validate_account(org, response['Account'])
response['Account']['Name'].should.equal(mockname)
response['Account']['Email'].should.equal(mockemail)
@mock_organizations
def test_describe_account_exception():
client = boto3.client('organizations', region_name='us-east-1')
with assert_raises(ClientError) as e:
response = client.describe_account(AccountId=utils.make_random_account_id())
ex = e.exception
ex.operation_name.should.equal('DescribeAccount')
ex.response['Error']['Code'].should.equal('400')
ex.response['Error']['Message'].should.contain('AccountNotFoundException')
@mock_organizations
def test_list_accounts():
client = boto3.client('organizations', region_name='us-east-1')
org = client.create_organization(FeatureSet='ALL')['Organization']
for i in range(5):
name = mockname + str(i)
email = name + '@' + mockdomain
client.create_account(AccountName=name, Email=email)
response = client.list_accounts()
response.should.have.key('Accounts')
accounts = response['Accounts']
len(accounts).should.equal(5)
for account in accounts:
validate_account(org, account)
accounts[3]['Name'].should.equal(mockname + '3')
accounts[2]['Email'].should.equal(mockname + '2' + '@' + mockdomain)
@mock_organizations
def test_list_accounts_for_parent():
client = boto3.client('organizations', region_name='us-east-1')
org = client.create_organization(FeatureSet='ALL')['Organization']
root_id = client.list_roots()['Roots'][0]['Id']
account_id = client.create_account(
AccountName=mockname,
Email=mockemail,
)['CreateAccountStatus']['AccountId']
response = client.list_accounts_for_parent(ParentId=root_id)
account_id.should.be.within([account['Id'] for account in response['Accounts']])
@mock_organizations
def test_move_account():
client = boto3.client('organizations', region_name='us-east-1')
org = client.create_organization(FeatureSet='ALL')['Organization']
root_id = client.list_roots()['Roots'][0]['Id']
account_id = client.create_account(
AccountName=mockname, Email=mockemail
)['CreateAccountStatus']['AccountId']
ou01 = client.create_organizational_unit(ParentId=root_id, Name='ou01')
ou01_id = ou01['OrganizationalUnit']['Id']
client.move_account(
AccountId=account_id,
SourceParentId=root_id,
DestinationParentId=ou01_id,
)
response = client.list_accounts_for_parent(ParentId=ou01_id)
account_id.should.be.within([account['Id'] for account in response['Accounts']])
@mock_organizations
def test_list_parents_for_ou():
client = boto3.client('organizations', region_name='us-east-1')
org = client.create_organization(FeatureSet='ALL')['Organization']
root_id = client.list_roots()['Roots'][0]['Id']
ou01 = client.create_organizational_unit(ParentId=root_id, Name='ou01')
ou01_id = ou01['OrganizationalUnit']['Id']
response01 = client.list_parents(ChildId=ou01_id)
response01.should.have.key('Parents').should.be.a(list)
response01['Parents'][0].should.have.key('Id').should.equal(root_id)
response01['Parents'][0].should.have.key('Type').should.equal('ROOT')
ou02 = client.create_organizational_unit(ParentId=ou01_id, Name='ou02')
ou02_id = ou02['OrganizationalUnit']['Id']
response02 = client.list_parents(ChildId=ou02_id)
response02.should.have.key('Parents').should.be.a(list)
response02['Parents'][0].should.have.key('Id').should.equal(ou01_id)
response02['Parents'][0].should.have.key('Type').should.equal('ORGANIZATIONAL_UNIT')
@mock_organizations
def test_list_parents_for_accounts():
client = boto3.client('organizations', region_name='us-east-1')
org = client.create_organization(FeatureSet='ALL')['Organization']
root_id = client.list_roots()['Roots'][0]['Id']
ou01 = client.create_organizational_unit(ParentId=root_id, Name='ou01')
ou01_id = ou01['OrganizationalUnit']['Id']
account01_id = client.create_account(
AccountName='account01',
Email='account01@moto-example.org'
)['CreateAccountStatus']['AccountId']
account02_id = client.create_account(
AccountName='account02',
Email='account02@moto-example.org'
)['CreateAccountStatus']['AccountId']
client.move_account(
AccountId=account02_id,
SourceParentId=root_id,
DestinationParentId=ou01_id,
)
response01 = client.list_parents(ChildId=account01_id)
response01.should.have.key('Parents').should.be.a(list)
response01['Parents'][0].should.have.key('Id').should.equal(root_id)
response01['Parents'][0].should.have.key('Type').should.equal('ROOT')
response02 = client.list_parents(ChildId=account02_id)
response02.should.have.key('Parents').should.be.a(list)
response02['Parents'][0].should.have.key('Id').should.equal(ou01_id)
response02['Parents'][0].should.have.key('Type').should.equal('ORGANIZATIONAL_UNIT')
@mock_organizations
def test_list_children():
client = boto3.client('organizations', region_name='us-east-1')
org = client.create_organization(FeatureSet='ALL')['Organization']
root_id = client.list_roots()['Roots'][0]['Id']
ou01 = client.create_organizational_unit(ParentId=root_id, Name='ou01')
ou01_id = ou01['OrganizationalUnit']['Id']
ou02 = client.create_organizational_unit(ParentId=ou01_id, Name='ou02')
ou02_id = ou02['OrganizationalUnit']['Id']
account01_id = client.create_account(
AccountName='account01',
Email='account01@moto-example.org'
)['CreateAccountStatus']['AccountId']
account02_id = client.create_account(
AccountName='account02',
Email='account02@moto-example.org'
)['CreateAccountStatus']['AccountId']
client.move_account(
AccountId=account02_id,
SourceParentId=root_id,
DestinationParentId=ou01_id,
)
response01 = client.list_children(ParentId=root_id, ChildType='ACCOUNT')
response02 = client.list_children(ParentId=root_id, ChildType='ORGANIZATIONAL_UNIT')
response03 = client.list_children(ParentId=ou01_id, ChildType='ACCOUNT')
response04 = client.list_children(ParentId=ou01_id, ChildType='ORGANIZATIONAL_UNIT')
response01['Children'][0]['Id'].should.equal(account01_id)
response01['Children'][0]['Type'].should.equal('ACCOUNT')
response02['Children'][0]['Id'].should.equal(ou01_id)
response02['Children'][0]['Type'].should.equal('ORGANIZATIONAL_UNIT')
response03['Children'][0]['Id'].should.equal(account02_id)
response03['Children'][0]['Type'].should.equal('ACCOUNT')
response04['Children'][0]['Id'].should.equal(ou02_id)
response04['Children'][0]['Type'].should.equal('ORGANIZATIONAL_UNIT')
@mock_organizations
def test_list_children_exception():
client = boto3.client('organizations', region_name='us-east-1')
org = client.create_organization(FeatureSet='ALL')['Organization']
root_id = client.list_roots()['Roots'][0]['Id']
with assert_raises(ClientError) as e:
response = client.list_children(
ParentId=utils.make_random_root_id(),
ChildType='ACCOUNT'
)
ex = e.exception
ex.operation_name.should.equal('ListChildren')
ex.response['Error']['Code'].should.equal('400')
ex.response['Error']['Message'].should.contain('ParentNotFoundException')
with assert_raises(ClientError) as e:
response = client.list_children(
ParentId=root_id,
ChildType='BLEE'
)
ex = e.exception
ex.operation_name.should.equal('ListChildren')
ex.response['Error']['Code'].should.equal('400')
ex.response['Error']['Message'].should.contain('InvalidInputException')
from __future__ import unicode_literals
import boto3
import json
import six
import sure # noqa
from botocore.exceptions import ClientError
from nose.tools import assert_raises
from moto import mock_organizations
from moto.organizations import utils
from .organizations_test_utils import (
validate_organization,
validate_roots,
validate_organizational_unit,
validate_account,
validate_create_account_status,
validate_service_control_policy,
validate_policy_summary,
)
@mock_organizations
def test_create_organization():
client = boto3.client('organizations', region_name='us-east-1')
response = client.create_organization(FeatureSet='ALL')
validate_organization(response)
response['Organization']['FeatureSet'].should.equal('ALL')
@mock_organizations
def test_describe_organization():
client = boto3.client('organizations', region_name='us-east-1')
client.create_organization(FeatureSet='ALL')
response = client.describe_organization()
validate_organization(response)
@mock_organizations
def test_describe_organization_exception():
client = boto3.client('organizations', region_name='us-east-1')
with assert_raises(ClientError) as e:
response = client.describe_organization()
ex = e.exception
ex.operation_name.should.equal('DescribeOrganization')
ex.response['Error']['Code'].should.equal('400')
ex.response['Error']['Message'].should.contain('AWSOrganizationsNotInUseException')
# Organizational Units
@mock_organizations
def test_list_roots():
client = boto3.client('organizations', region_name='us-east-1')
org = client.create_organization(FeatureSet='ALL')['Organization']
response = client.list_roots()
validate_roots(org, response)
@mock_organizations
def test_create_organizational_unit():
client = boto3.client('organizations', region_name='us-east-1')
org = client.create_organization(FeatureSet='ALL')['Organization']
root_id = client.list_roots()['Roots'][0]['Id']
ou_name = 'ou01'
response = client.create_organizational_unit(
ParentId=root_id,
Name=ou_name,
)
validate_organizational_unit(org, response)
response['OrganizationalUnit']['Name'].should.equal(ou_name)
@mock_organizations
def test_describe_organizational_unit():
client = boto3.client('organizations', region_name='us-east-1')
org = client.create_organization(FeatureSet='ALL')['Organization']
root_id = client.list_roots()['Roots'][0]['Id']
ou_id = client.create_organizational_unit(
ParentId=root_id,
Name='ou01',
)['OrganizationalUnit']['Id']
response = client.describe_organizational_unit(OrganizationalUnitId=ou_id)
validate_organizational_unit(org, response)
@mock_organizations
def test_describe_organizational_unit_exception():
client = boto3.client('organizations', region_name='us-east-1')
org = client.create_organization(FeatureSet='ALL')['Organization']
with assert_raises(ClientError) as e:
response = client.describe_organizational_unit(
OrganizationalUnitId=utils.make_random_root_id()
)
ex = e.exception
ex.operation_name.should.equal('DescribeOrganizationalUnit')
ex.response['Error']['Code'].should.equal('400')
ex.response['Error']['Message'].should.contain('OrganizationalUnitNotFoundException')
@mock_organizations
def test_list_organizational_units_for_parent():
client = boto3.client('organizations', region_name='us-east-1')
org = client.create_organization(FeatureSet='ALL')['Organization']
root_id = client.list_roots()['Roots'][0]['Id']
client.create_organizational_unit(ParentId=root_id, Name='ou01')
client.create_organizational_unit(ParentId=root_id, Name='ou02')
client.create_organizational_unit(ParentId=root_id, Name='ou03')
response = client.list_organizational_units_for_parent(ParentId=root_id)
response.should.have.key('OrganizationalUnits').should.be.a(list)
for ou in response['OrganizationalUnits']:
validate_organizational_unit(org, dict(OrganizationalUnit=ou))
@mock_organizations
def test_list_organizational_units_for_parent_exception():
client = boto3.client('organizations', region_name='us-east-1')
with assert_raises(ClientError) as e:
response = client.list_organizational_units_for_parent(
ParentId=utils.make_random_root_id()
)
ex = e.exception
ex.operation_name.should.equal('ListOrganizationalUnitsForParent')
ex.response['Error']['Code'].should.equal('400')
ex.response['Error']['Message'].should.contain('ParentNotFoundException')
# Accounts
mockname = 'mock-account'
mockdomain = 'moto-example.org'
mockemail = '@'.join([mockname, mockdomain])
@mock_organizations
def test_create_account():
client = boto3.client('organizations', region_name='us-east-1')
client.create_organization(FeatureSet='ALL')
create_status = client.create_account(
AccountName=mockname, Email=mockemail
)['CreateAccountStatus']
validate_create_account_status(create_status)
create_status['AccountName'].should.equal(mockname)
@mock_organizations
def test_describe_account():
client = boto3.client('organizations', region_name='us-east-1')
org = client.create_organization(FeatureSet='ALL')['Organization']
account_id = client.create_account(
AccountName=mockname, Email=mockemail
)['CreateAccountStatus']['AccountId']
response = client.describe_account(AccountId=account_id)
validate_account(org, response['Account'])
response['Account']['Name'].should.equal(mockname)
response['Account']['Email'].should.equal(mockemail)
@mock_organizations
def test_describe_account_exception():
client = boto3.client('organizations', region_name='us-east-1')
with assert_raises(ClientError) as e:
response = client.describe_account(AccountId=utils.make_random_account_id())
ex = e.exception
ex.operation_name.should.equal('DescribeAccount')
ex.response['Error']['Code'].should.equal('400')
ex.response['Error']['Message'].should.contain('AccountNotFoundException')
@mock_organizations
def test_list_accounts():
client = boto3.client('organizations', region_name='us-east-1')
org = client.create_organization(FeatureSet='ALL')['Organization']
for i in range(5):
name = mockname + str(i)
email = name + '@' + mockdomain
client.create_account(AccountName=name, Email=email)
response = client.list_accounts()
response.should.have.key('Accounts')
accounts = response['Accounts']
len(accounts).should.equal(5)
for account in accounts:
validate_account(org, account)
accounts[3]['Name'].should.equal(mockname + '3')
accounts[2]['Email'].should.equal(mockname + '2' + '@' + mockdomain)
@mock_organizations
def test_list_accounts_for_parent():
client = boto3.client('organizations', region_name='us-east-1')
org = client.create_organization(FeatureSet='ALL')['Organization']
root_id = client.list_roots()['Roots'][0]['Id']
account_id = client.create_account(
AccountName=mockname,
Email=mockemail,
)['CreateAccountStatus']['AccountId']
response = client.list_accounts_for_parent(ParentId=root_id)
account_id.should.be.within([account['Id'] for account in response['Accounts']])
@mock_organizations
def test_move_account():
client = boto3.client('organizations', region_name='us-east-1')
org = client.create_organization(FeatureSet='ALL')['Organization']
root_id = client.list_roots()['Roots'][0]['Id']
account_id = client.create_account(
AccountName=mockname, Email=mockemail
)['CreateAccountStatus']['AccountId']
ou01 = client.create_organizational_unit(ParentId=root_id, Name='ou01')
ou01_id = ou01['OrganizationalUnit']['Id']
client.move_account(
AccountId=account_id,
SourceParentId=root_id,
DestinationParentId=ou01_id,
)
response = client.list_accounts_for_parent(ParentId=ou01_id)
account_id.should.be.within([account['Id'] for account in response['Accounts']])
@mock_organizations
def test_list_parents_for_ou():
client = boto3.client('organizations', region_name='us-east-1')
org = client.create_organization(FeatureSet='ALL')['Organization']
root_id = client.list_roots()['Roots'][0]['Id']
ou01 = client.create_organizational_unit(ParentId=root_id, Name='ou01')
ou01_id = ou01['OrganizationalUnit']['Id']
response01 = client.list_parents(ChildId=ou01_id)
response01.should.have.key('Parents').should.be.a(list)
response01['Parents'][0].should.have.key('Id').should.equal(root_id)
response01['Parents'][0].should.have.key('Type').should.equal('ROOT')
ou02 = client.create_organizational_unit(ParentId=ou01_id, Name='ou02')
ou02_id = ou02['OrganizationalUnit']['Id']
response02 = client.list_parents(ChildId=ou02_id)
response02.should.have.key('Parents').should.be.a(list)
response02['Parents'][0].should.have.key('Id').should.equal(ou01_id)
response02['Parents'][0].should.have.key('Type').should.equal('ORGANIZATIONAL_UNIT')
@mock_organizations
def test_list_parents_for_accounts():
client = boto3.client('organizations', region_name='us-east-1')
org = client.create_organization(FeatureSet='ALL')['Organization']
root_id = client.list_roots()['Roots'][0]['Id']
ou01 = client.create_organizational_unit(ParentId=root_id, Name='ou01')
ou01_id = ou01['OrganizationalUnit']['Id']
account01_id = client.create_account(
AccountName='account01',
Email='account01@moto-example.org'
)['CreateAccountStatus']['AccountId']
account02_id = client.create_account(
AccountName='account02',
Email='account02@moto-example.org'
)['CreateAccountStatus']['AccountId']
client.move_account(
AccountId=account02_id,
SourceParentId=root_id,
DestinationParentId=ou01_id,
)
response01 = client.list_parents(ChildId=account01_id)
response01.should.have.key('Parents').should.be.a(list)
response01['Parents'][0].should.have.key('Id').should.equal(root_id)
response01['Parents'][0].should.have.key('Type').should.equal('ROOT')
response02 = client.list_parents(ChildId=account02_id)
response02.should.have.key('Parents').should.be.a(list)
response02['Parents'][0].should.have.key('Id').should.equal(ou01_id)
response02['Parents'][0].should.have.key('Type').should.equal('ORGANIZATIONAL_UNIT')
@mock_organizations
def test_list_children():
client = boto3.client('organizations', region_name='us-east-1')
org = client.create_organization(FeatureSet='ALL')['Organization']
root_id = client.list_roots()['Roots'][0]['Id']
ou01 = client.create_organizational_unit(ParentId=root_id, Name='ou01')
ou01_id = ou01['OrganizationalUnit']['Id']
ou02 = client.create_organizational_unit(ParentId=ou01_id, Name='ou02')
ou02_id = ou02['OrganizationalUnit']['Id']
account01_id = client.create_account(
AccountName='account01',
Email='account01@moto-example.org'
)['CreateAccountStatus']['AccountId']
account02_id = client.create_account(
AccountName='account02',
Email='account02@moto-example.org'
)['CreateAccountStatus']['AccountId']
client.move_account(
AccountId=account02_id,
SourceParentId=root_id,
DestinationParentId=ou01_id,
)
response01 = client.list_children(ParentId=root_id, ChildType='ACCOUNT')
response02 = client.list_children(ParentId=root_id, ChildType='ORGANIZATIONAL_UNIT')
response03 = client.list_children(ParentId=ou01_id, ChildType='ACCOUNT')
response04 = client.list_children(ParentId=ou01_id, ChildType='ORGANIZATIONAL_UNIT')
response01['Children'][0]['Id'].should.equal(account01_id)
response01['Children'][0]['Type'].should.equal('ACCOUNT')
response02['Children'][0]['Id'].should.equal(ou01_id)
response02['Children'][0]['Type'].should.equal('ORGANIZATIONAL_UNIT')
response03['Children'][0]['Id'].should.equal(account02_id)
response03['Children'][0]['Type'].should.equal('ACCOUNT')
response04['Children'][0]['Id'].should.equal(ou02_id)
response04['Children'][0]['Type'].should.equal('ORGANIZATIONAL_UNIT')
@mock_organizations
def test_list_children_exception():
client = boto3.client('organizations', region_name='us-east-1')
org = client.create_organization(FeatureSet='ALL')['Organization']
root_id = client.list_roots()['Roots'][0]['Id']
with assert_raises(ClientError) as e:
response = client.list_children(
ParentId=utils.make_random_root_id(),
ChildType='ACCOUNT'
)
ex = e.exception
ex.operation_name.should.equal('ListChildren')
ex.response['Error']['Code'].should.equal('400')
ex.response['Error']['Message'].should.contain('ParentNotFoundException')
with assert_raises(ClientError) as e:
response = client.list_children(
ParentId=root_id,
ChildType='BLEE'
)
ex = e.exception
ex.operation_name.should.equal('ListChildren')
ex.response['Error']['Code'].should.equal('400')
ex.response['Error']['Message'].should.contain('InvalidInputException')
# Service Control Policies
policy_doc01 = dict(
Version='2012-10-17',
Statement=[dict(
Sid='MockPolicyStatement',
Effect='Allow',
Action='s3:*',
Resource='*',
)]
)
@mock_organizations
def test_create_policy():
client = boto3.client('organizations', region_name='us-east-1')
org = client.create_organization(FeatureSet='ALL')['Organization']
policy = client.create_policy(
Content=json.dumps(policy_doc01),
Description='A dummy service control policy',
Name='MockServiceControlPolicy',
Type='SERVICE_CONTROL_POLICY'
)['Policy']
validate_service_control_policy(org, policy)
policy['PolicySummary']['Name'].should.equal('MockServiceControlPolicy')
policy['PolicySummary']['Description'].should.equal('A dummy service control policy')
policy['Content'].should.equal(json.dumps(policy_doc01))
@mock_organizations
def test_describe_policy():
client = boto3.client('organizations', region_name='us-east-1')
org = client.create_organization(FeatureSet='ALL')['Organization']
policy_id = client.create_policy(
Content=json.dumps(policy_doc01),
Description='A dummy service control policy',
Name='MockServiceControlPolicy',
Type='SERVICE_CONTROL_POLICY'
)['Policy']['PolicySummary']['Id']
policy = client.describe_policy(PolicyId=policy_id)['Policy']
validate_service_control_policy(org, policy)
policy['PolicySummary']['Name'].should.equal('MockServiceControlPolicy')
policy['PolicySummary']['Description'].should.equal('A dummy service control policy')
policy['Content'].should.equal(json.dumps(policy_doc01))
@mock_organizations
def test_describe_policy_exception():
client = boto3.client('organizations', region_name='us-east-1')
client.create_organization(FeatureSet='ALL')['Organization']
policy_id = 'p-47fhe9s3'
with assert_raises(ClientError) as e:
response = client.describe_policy(PolicyId=policy_id)
ex = e.exception
ex.operation_name.should.equal('DescribePolicy')
ex.response['Error']['Code'].should.equal('400')
ex.response['Error']['Message'].should.contain('PolicyNotFoundException')
with assert_raises(ClientError) as e:
response = client.describe_policy(PolicyId='meaninglessstring')
ex = e.exception
ex.operation_name.should.equal('DescribePolicy')
ex.response['Error']['Code'].should.equal('400')
ex.response['Error']['Message'].should.contain('InvalidInputException')
@mock_organizations
def test_attach_policy():
client = boto3.client('organizations', region_name='us-east-1')
org = client.create_organization(FeatureSet='ALL')['Organization']
root_id = client.list_roots()['Roots'][0]['Id']
ou_id = client.create_organizational_unit(
ParentId=root_id,
Name='ou01',
)['OrganizationalUnit']['Id']
account_id = client.create_account(
AccountName=mockname,
Email=mockemail,
)['CreateAccountStatus']['AccountId']
policy_id = client.create_policy(
Content=json.dumps(policy_doc01),
Description='A dummy service control policy',
Name='MockServiceControlPolicy',
Type='SERVICE_CONTROL_POLICY'
)['Policy']['PolicySummary']['Id']
response = client.attach_policy(PolicyId=policy_id, TargetId=root_id)
response['ResponseMetadata']['HTTPStatusCode'].should.equal(200)
response = client.attach_policy(PolicyId=policy_id, TargetId=ou_id)
response['ResponseMetadata']['HTTPStatusCode'].should.equal(200)
response = client.attach_policy(PolicyId=policy_id, TargetId=account_id)
response['ResponseMetadata']['HTTPStatusCode'].should.equal(200)
@mock_organizations
def test_attach_policy_exception():
client = boto3.client('organizations', region_name='us-east-1')
client.create_organization(FeatureSet='ALL')['Organization']
root_id='r-dj873'
ou_id='ou-gi99-i7r8eh2i2'
account_id='126644886543'
policy_id = client.create_policy(
Content=json.dumps(policy_doc01),
Description='A dummy service control policy',
Name='MockServiceControlPolicy',
Type='SERVICE_CONTROL_POLICY'
)['Policy']['PolicySummary']['Id']
with assert_raises(ClientError) as e:
response = client.attach_policy(PolicyId=policy_id, TargetId=root_id)
ex = e.exception
ex.operation_name.should.equal('AttachPolicy')
ex.response['Error']['Code'].should.equal('400')
ex.response['Error']['Message'].should.contain('OrganizationalUnitNotFoundException')
with assert_raises(ClientError) as e:
response = client.attach_policy(PolicyId=policy_id, TargetId=ou_id)
ex = e.exception
ex.operation_name.should.equal('AttachPolicy')
ex.response['Error']['Code'].should.equal('400')
ex.response['Error']['Message'].should.contain('OrganizationalUnitNotFoundException')
with assert_raises(ClientError) as e:
response = client.attach_policy(PolicyId=policy_id, TargetId=account_id)
ex = e.exception
ex.operation_name.should.equal('AttachPolicy')
ex.response['Error']['Code'].should.equal('400')
ex.response['Error']['Message'].should.contain('AccountNotFoundException')
with assert_raises(ClientError) as e:
response = client.attach_policy(PolicyId=policy_id, TargetId='meaninglessstring')
ex = e.exception
ex.operation_name.should.equal('AttachPolicy')
ex.response['Error']['Code'].should.equal('400')
ex.response['Error']['Message'].should.contain('InvalidInputException')
@mock_organizations
def test_list_polices():
client = boto3.client('organizations', region_name='us-east-1')
org = client.create_organization(FeatureSet='ALL')['Organization']
for i in range(0,4):
client.create_policy(
Content=json.dumps(policy_doc01),
Description='A dummy service control policy',
Name='MockServiceControlPolicy' + str(i),
Type='SERVICE_CONTROL_POLICY'
)
response = client.list_policies(Filter='SERVICE_CONTROL_POLICY')
for policy in response['Policies']:
validate_policy_summary(org, policy)
@mock_organizations
def test_list_policies_for_target():
client = boto3.client('organizations', region_name='us-east-1')
org = client.create_organization(FeatureSet='ALL')['Organization']
root_id = client.list_roots()['Roots'][0]['Id']
ou_id = client.create_organizational_unit(
ParentId=root_id,
Name='ou01',
)['OrganizationalUnit']['Id']
account_id = client.create_account(
AccountName=mockname,
Email=mockemail,
)['CreateAccountStatus']['AccountId']
policy_id = client.create_policy(
Content=json.dumps(policy_doc01),
Description='A dummy service control policy',
Name='MockServiceControlPolicy',
Type='SERVICE_CONTROL_POLICY'
)['Policy']['PolicySummary']['Id']
client.attach_policy(PolicyId=policy_id, TargetId=ou_id)
response = client.list_policies_for_target(
TargetId=ou_id,
Filter='SERVICE_CONTROL_POLICY',
)
for policy in response['Policies']:
validate_policy_summary(org, policy)
client.attach_policy(PolicyId=policy_id, TargetId=account_id)
response = client.list_policies_for_target(
TargetId=account_id,
Filter='SERVICE_CONTROL_POLICY',
)
for policy in response['Policies']:
validate_policy_summary(org, policy)
@mock_organizations
def test_list_policies_for_target_exception():
client = boto3.client('organizations', region_name='us-east-1')
client.create_organization(FeatureSet='ALL')['Organization']
ou_id='ou-gi99-i7r8eh2i2'
account_id='126644886543'
with assert_raises(ClientError) as e:
response = client.list_policies_for_target(
TargetId=ou_id,
Filter='SERVICE_CONTROL_POLICY',
)
ex = e.exception
ex.operation_name.should.equal('ListPoliciesForTarget')
ex.response['Error']['Code'].should.equal('400')
ex.response['Error']['Message'].should.contain('OrganizationalUnitNotFoundException')
with assert_raises(ClientError) as e:
response = client.list_policies_for_target(
TargetId=account_id,
Filter='SERVICE_CONTROL_POLICY',
)
ex = e.exception
ex.operation_name.should.equal('ListPoliciesForTarget')
ex.response['Error']['Code'].should.equal('400')
ex.response['Error']['Message'].should.contain('AccountNotFoundException')
with assert_raises(ClientError) as e:
response = client.list_policies_for_target(
TargetId='meaninglessstring',
Filter='SERVICE_CONTROL_POLICY',
)
ex = e.exception
ex.operation_name.should.equal('ListPoliciesForTarget')
ex.response['Error']['Code'].should.equal('400')
ex.response['Error']['Message'].should.contain('InvalidInputException')
@mock_organizations
def test_list_targets_for_policy():
client = boto3.client('organizations', region_name='us-east-1')
org = client.create_organization(FeatureSet='ALL')['Organization']
root_id = client.list_roots()['Roots'][0]['Id']
ou_id = client.create_organizational_unit(
ParentId=root_id,
Name='ou01',
)['OrganizationalUnit']['Id']
account_id = client.create_account(
AccountName=mockname,
Email=mockemail,
)['CreateAccountStatus']['AccountId']
policy_id = client.create_policy(
Content=json.dumps(policy_doc01),
Description='A dummy service control policy',
Name='MockServiceControlPolicy',
Type='SERVICE_CONTROL_POLICY'
)['Policy']['PolicySummary']['Id']
client.attach_policy(PolicyId=policy_id, TargetId=root_id)
client.attach_policy(PolicyId=policy_id, TargetId=ou_id)
client.attach_policy(PolicyId=policy_id, TargetId=account_id)
response = client.list_targets_for_policy(PolicyId=policy_id)
for target in response['Targets']:
target.should.be.a(dict)
target.should.have.key('Name').should.be.a(six.string_types)
target.should.have.key('Arn').should.be.a(six.string_types)
target.should.have.key('TargetId').should.be.a(six.string_types)
target.should.have.key('Type').should.be.within(
['ROOT', 'ORGANIZATIONAL_UNIT', 'ACCOUNT']
)
@mock_organizations
def test_list_targets_for_policy_exception():
client = boto3.client('organizations', region_name='us-east-1')
client.create_organization(FeatureSet='ALL')['Organization']
policy_id = 'p-47fhe9s3'
with assert_raises(ClientError) as e:
response = client.list_targets_for_policy(PolicyId=policy_id)
ex = e.exception
ex.operation_name.should.equal('ListTargetsForPolicy')
ex.response['Error']['Code'].should.equal('400')
ex.response['Error']['Message'].should.contain('PolicyNotFoundException')
with assert_raises(ClientError) as e:
response = client.list_targets_for_policy(PolicyId='meaninglessstring')
ex = e.exception
ex.operation_name.should.equal('ListTargetsForPolicy')
ex.response['Error']['Code'].should.equal('400')
ex.response['Error']['Message'].should.contain('InvalidInputException')

View file

@ -1,324 +1,324 @@
from __future__ import unicode_literals
import boto3
import boto.rds
import boto.vpc
from boto.exception import BotoServerError
import sure # noqa
from moto import mock_ec2_deprecated, mock_rds_deprecated, mock_rds
from tests.helpers import disable_on_py3
@mock_rds_deprecated
def test_create_database():
conn = boto.rds.connect_to_region("us-west-2")
database = conn.create_dbinstance("db-master-1", 10, 'db.m1.small', 'root', 'hunter2',
security_groups=["my_sg"])
database.status.should.equal('available')
database.id.should.equal("db-master-1")
database.allocated_storage.should.equal(10)
database.instance_class.should.equal("db.m1.small")
database.master_username.should.equal("root")
database.endpoint.should.equal(
('db-master-1.aaaaaaaaaa.us-west-2.rds.amazonaws.com', 3306))
database.security_groups[0].name.should.equal('my_sg')
@mock_rds_deprecated
def test_get_databases():
conn = boto.rds.connect_to_region("us-west-2")
list(conn.get_all_dbinstances()).should.have.length_of(0)
conn.create_dbinstance("db-master-1", 10, 'db.m1.small', 'root', 'hunter2')
conn.create_dbinstance("db-master-2", 10, 'db.m1.small', 'root', 'hunter2')
list(conn.get_all_dbinstances()).should.have.length_of(2)
databases = conn.get_all_dbinstances("db-master-1")
list(databases).should.have.length_of(1)
databases[0].id.should.equal("db-master-1")
@mock_rds
def test_get_databases_paginated():
conn = boto3.client('rds', region_name="us-west-2")
for i in range(51):
conn.create_db_instance(AllocatedStorage=5,
Port=5432,
DBInstanceIdentifier='rds%d' % i,
DBInstanceClass='db.t1.micro',
Engine='postgres')
resp = conn.describe_db_instances()
resp["DBInstances"].should.have.length_of(50)
resp["Marker"].should.equal(resp["DBInstances"][-1]['DBInstanceIdentifier'])
resp2 = conn.describe_db_instances(Marker=resp["Marker"])
resp2["DBInstances"].should.have.length_of(1)
@mock_rds_deprecated
def test_describe_non_existant_database():
conn = boto.rds.connect_to_region("us-west-2")
conn.get_all_dbinstances.when.called_with(
"not-a-db").should.throw(BotoServerError)
@mock_rds_deprecated
def test_delete_database():
conn = boto.rds.connect_to_region("us-west-2")
list(conn.get_all_dbinstances()).should.have.length_of(0)
conn.create_dbinstance("db-master-1", 10, 'db.m1.small', 'root', 'hunter2')
list(conn.get_all_dbinstances()).should.have.length_of(1)
conn.delete_dbinstance("db-master-1")
list(conn.get_all_dbinstances()).should.have.length_of(0)
@mock_rds_deprecated
def test_delete_non_existant_database():
conn = boto.rds.connect_to_region("us-west-2")
conn.delete_dbinstance.when.called_with(
"not-a-db").should.throw(BotoServerError)
@mock_rds_deprecated
def test_create_database_security_group():
conn = boto.rds.connect_to_region("us-west-2")
security_group = conn.create_dbsecurity_group('db_sg', 'DB Security Group')
security_group.name.should.equal('db_sg')
security_group.description.should.equal("DB Security Group")
list(security_group.ip_ranges).should.equal([])
@mock_rds_deprecated
def test_get_security_groups():
conn = boto.rds.connect_to_region("us-west-2")
list(conn.get_all_dbsecurity_groups()).should.have.length_of(0)
conn.create_dbsecurity_group('db_sg1', 'DB Security Group')
conn.create_dbsecurity_group('db_sg2', 'DB Security Group')
list(conn.get_all_dbsecurity_groups()).should.have.length_of(2)
databases = conn.get_all_dbsecurity_groups("db_sg1")
list(databases).should.have.length_of(1)
databases[0].name.should.equal("db_sg1")
@mock_rds_deprecated
def test_get_non_existant_security_group():
conn = boto.rds.connect_to_region("us-west-2")
conn.get_all_dbsecurity_groups.when.called_with(
"not-a-sg").should.throw(BotoServerError)
@mock_rds_deprecated
def test_delete_database_security_group():
conn = boto.rds.connect_to_region("us-west-2")
conn.create_dbsecurity_group('db_sg', 'DB Security Group')
list(conn.get_all_dbsecurity_groups()).should.have.length_of(1)
conn.delete_dbsecurity_group("db_sg")
list(conn.get_all_dbsecurity_groups()).should.have.length_of(0)
@mock_rds_deprecated
def test_delete_non_existant_security_group():
conn = boto.rds.connect_to_region("us-west-2")
conn.delete_dbsecurity_group.when.called_with(
"not-a-db").should.throw(BotoServerError)
@disable_on_py3()
@mock_rds_deprecated
def test_security_group_authorize():
conn = boto.rds.connect_to_region("us-west-2")
security_group = conn.create_dbsecurity_group('db_sg', 'DB Security Group')
list(security_group.ip_ranges).should.equal([])
security_group.authorize(cidr_ip='10.3.2.45/32')
security_group = conn.get_all_dbsecurity_groups()[0]
list(security_group.ip_ranges).should.have.length_of(1)
security_group.ip_ranges[0].cidr_ip.should.equal('10.3.2.45/32')
@mock_rds_deprecated
def test_add_security_group_to_database():
conn = boto.rds.connect_to_region("us-west-2")
database = conn.create_dbinstance(
"db-master-1", 10, 'db.m1.small', 'root', 'hunter2')
security_group = conn.create_dbsecurity_group('db_sg', 'DB Security Group')
database.modify(security_groups=[security_group])
database = conn.get_all_dbinstances()[0]
list(database.security_groups).should.have.length_of(1)
database.security_groups[0].name.should.equal("db_sg")
@mock_ec2_deprecated
@mock_rds_deprecated
def test_add_database_subnet_group():
vpc_conn = boto.vpc.connect_to_region("us-west-2")
vpc = vpc_conn.create_vpc("10.0.0.0/16")
subnet1 = vpc_conn.create_subnet(vpc.id, "10.1.0.0/24")
subnet2 = vpc_conn.create_subnet(vpc.id, "10.2.0.0/24")
subnet_ids = [subnet1.id, subnet2.id]
conn = boto.rds.connect_to_region("us-west-2")
subnet_group = conn.create_db_subnet_group(
"db_subnet", "my db subnet", subnet_ids)
subnet_group.name.should.equal('db_subnet')
subnet_group.description.should.equal("my db subnet")
list(subnet_group.subnet_ids).should.equal(subnet_ids)
@mock_ec2_deprecated
@mock_rds_deprecated
def test_describe_database_subnet_group():
vpc_conn = boto.vpc.connect_to_region("us-west-2")
vpc = vpc_conn.create_vpc("10.0.0.0/16")
subnet = vpc_conn.create_subnet(vpc.id, "10.1.0.0/24")
conn = boto.rds.connect_to_region("us-west-2")
conn.create_db_subnet_group("db_subnet1", "my db subnet", [subnet.id])
conn.create_db_subnet_group("db_subnet2", "my db subnet", [subnet.id])
list(conn.get_all_db_subnet_groups()).should.have.length_of(2)
list(conn.get_all_db_subnet_groups("db_subnet1")).should.have.length_of(1)
conn.get_all_db_subnet_groups.when.called_with(
"not-a-subnet").should.throw(BotoServerError)
@mock_ec2_deprecated
@mock_rds_deprecated
def test_delete_database_subnet_group():
vpc_conn = boto.vpc.connect_to_region("us-west-2")
vpc = vpc_conn.create_vpc("10.0.0.0/16")
subnet = vpc_conn.create_subnet(vpc.id, "10.1.0.0/24")
conn = boto.rds.connect_to_region("us-west-2")
conn.create_db_subnet_group("db_subnet1", "my db subnet", [subnet.id])
list(conn.get_all_db_subnet_groups()).should.have.length_of(1)
conn.delete_db_subnet_group("db_subnet1")
list(conn.get_all_db_subnet_groups()).should.have.length_of(0)
conn.delete_db_subnet_group.when.called_with(
"db_subnet1").should.throw(BotoServerError)
@mock_ec2_deprecated
@mock_rds_deprecated
def test_create_database_in_subnet_group():
vpc_conn = boto.vpc.connect_to_region("us-west-2")
vpc = vpc_conn.create_vpc("10.0.0.0/16")
subnet = vpc_conn.create_subnet(vpc.id, "10.1.0.0/24")
conn = boto.rds.connect_to_region("us-west-2")
conn.create_db_subnet_group("db_subnet1", "my db subnet", [subnet.id])
database = conn.create_dbinstance("db-master-1", 10, 'db.m1.small',
'root', 'hunter2', db_subnet_group_name="db_subnet1")
database = conn.get_all_dbinstances("db-master-1")[0]
database.subnet_group.name.should.equal("db_subnet1")
@mock_rds_deprecated
def test_create_database_replica():
conn = boto.rds.connect_to_region("us-west-2")
primary = conn.create_dbinstance(
"db-master-1", 10, 'db.m1.small', 'root', 'hunter2')
replica = conn.create_dbinstance_read_replica(
"replica", "db-master-1", "db.m1.small")
replica.id.should.equal("replica")
replica.instance_class.should.equal("db.m1.small")
status_info = replica.status_infos[0]
status_info.normal.should.equal(True)
status_info.status_type.should.equal('read replication')
status_info.status.should.equal('replicating')
primary = conn.get_all_dbinstances("db-master-1")[0]
primary.read_replica_dbinstance_identifiers[0].should.equal("replica")
conn.delete_dbinstance("replica")
primary = conn.get_all_dbinstances("db-master-1")[0]
list(primary.read_replica_dbinstance_identifiers).should.have.length_of(0)
@mock_rds_deprecated
def test_create_cross_region_database_replica():
west_1_conn = boto.rds.connect_to_region("us-west-1")
west_2_conn = boto.rds.connect_to_region("us-west-2")
primary = west_1_conn.create_dbinstance(
"db-master-1", 10, 'db.m1.small', 'root', 'hunter2')
primary_arn = "arn:aws:rds:us-west-1:1234567890:db:db-master-1"
replica = west_2_conn.create_dbinstance_read_replica(
"replica",
primary_arn,
"db.m1.small",
)
primary = west_1_conn.get_all_dbinstances("db-master-1")[0]
primary.read_replica_dbinstance_identifiers[0].should.equal("replica")
replica = west_2_conn.get_all_dbinstances("replica")[0]
replica.instance_class.should.equal("db.m1.small")
west_2_conn.delete_dbinstance("replica")
primary = west_1_conn.get_all_dbinstances("db-master-1")[0]
list(primary.read_replica_dbinstance_identifiers).should.have.length_of(0)
@mock_rds_deprecated
def test_connecting_to_us_east_1():
# boto does not use us-east-1 in the URL for RDS,
# and that broke moto in the past:
# https://github.com/boto/boto/blob/e271ff09364ea18d9d8b6f4d63d6b0ac6cbc9b75/boto/endpoints.json#L285
conn = boto.rds.connect_to_region("us-east-1")
database = conn.create_dbinstance("db-master-1", 10, 'db.m1.small', 'root', 'hunter2',
security_groups=["my_sg"])
database.status.should.equal('available')
database.id.should.equal("db-master-1")
database.allocated_storage.should.equal(10)
database.instance_class.should.equal("db.m1.small")
database.master_username.should.equal("root")
database.endpoint.should.equal(
('db-master-1.aaaaaaaaaa.us-east-1.rds.amazonaws.com', 3306))
database.security_groups[0].name.should.equal('my_sg')
@mock_rds_deprecated
def test_create_database_with_iops():
conn = boto.rds.connect_to_region("us-west-2")
database = conn.create_dbinstance(
"db-master-1", 10, 'db.m1.small', 'root', 'hunter2', iops=6000)
database.status.should.equal('available')
database.iops.should.equal(6000)
# boto>2.36.0 may change the following property name to `storage_type`
database.StorageType.should.equal('io1')
from __future__ import unicode_literals
import boto3
import boto.rds
import boto.vpc
from boto.exception import BotoServerError
import sure # noqa
from moto import mock_ec2_deprecated, mock_rds_deprecated, mock_rds
from tests.helpers import disable_on_py3
@mock_rds_deprecated
def test_create_database():
conn = boto.rds.connect_to_region("us-west-2")
database = conn.create_dbinstance("db-master-1", 10, 'db.m1.small', 'root', 'hunter2',
security_groups=["my_sg"])
database.status.should.equal('available')
database.id.should.equal("db-master-1")
database.allocated_storage.should.equal(10)
database.instance_class.should.equal("db.m1.small")
database.master_username.should.equal("root")
database.endpoint.should.equal(
('db-master-1.aaaaaaaaaa.us-west-2.rds.amazonaws.com', 3306))
database.security_groups[0].name.should.equal('my_sg')
@mock_rds_deprecated
def test_get_databases():
conn = boto.rds.connect_to_region("us-west-2")
list(conn.get_all_dbinstances()).should.have.length_of(0)
conn.create_dbinstance("db-master-1", 10, 'db.m1.small', 'root', 'hunter2')
conn.create_dbinstance("db-master-2", 10, 'db.m1.small', 'root', 'hunter2')
list(conn.get_all_dbinstances()).should.have.length_of(2)
databases = conn.get_all_dbinstances("db-master-1")
list(databases).should.have.length_of(1)
databases[0].id.should.equal("db-master-1")
@mock_rds
def test_get_databases_paginated():
conn = boto3.client('rds', region_name="us-west-2")
for i in range(51):
conn.create_db_instance(AllocatedStorage=5,
Port=5432,
DBInstanceIdentifier='rds%d' % i,
DBInstanceClass='db.t1.micro',
Engine='postgres')
resp = conn.describe_db_instances()
resp["DBInstances"].should.have.length_of(50)
resp["Marker"].should.equal(resp["DBInstances"][-1]['DBInstanceIdentifier'])
resp2 = conn.describe_db_instances(Marker=resp["Marker"])
resp2["DBInstances"].should.have.length_of(1)
@mock_rds_deprecated
def test_describe_non_existant_database():
conn = boto.rds.connect_to_region("us-west-2")
conn.get_all_dbinstances.when.called_with(
"not-a-db").should.throw(BotoServerError)
@mock_rds_deprecated
def test_delete_database():
conn = boto.rds.connect_to_region("us-west-2")
list(conn.get_all_dbinstances()).should.have.length_of(0)
conn.create_dbinstance("db-master-1", 10, 'db.m1.small', 'root', 'hunter2')
list(conn.get_all_dbinstances()).should.have.length_of(1)
conn.delete_dbinstance("db-master-1")
list(conn.get_all_dbinstances()).should.have.length_of(0)
@mock_rds_deprecated
def test_delete_non_existant_database():
conn = boto.rds.connect_to_region("us-west-2")
conn.delete_dbinstance.when.called_with(
"not-a-db").should.throw(BotoServerError)
@mock_rds_deprecated
def test_create_database_security_group():
conn = boto.rds.connect_to_region("us-west-2")
security_group = conn.create_dbsecurity_group('db_sg', 'DB Security Group')
security_group.name.should.equal('db_sg')
security_group.description.should.equal("DB Security Group")
list(security_group.ip_ranges).should.equal([])
@mock_rds_deprecated
def test_get_security_groups():
conn = boto.rds.connect_to_region("us-west-2")
list(conn.get_all_dbsecurity_groups()).should.have.length_of(0)
conn.create_dbsecurity_group('db_sg1', 'DB Security Group')
conn.create_dbsecurity_group('db_sg2', 'DB Security Group')
list(conn.get_all_dbsecurity_groups()).should.have.length_of(2)
databases = conn.get_all_dbsecurity_groups("db_sg1")
list(databases).should.have.length_of(1)
databases[0].name.should.equal("db_sg1")
@mock_rds_deprecated
def test_get_non_existant_security_group():
conn = boto.rds.connect_to_region("us-west-2")
conn.get_all_dbsecurity_groups.when.called_with(
"not-a-sg").should.throw(BotoServerError)
@mock_rds_deprecated
def test_delete_database_security_group():
conn = boto.rds.connect_to_region("us-west-2")
conn.create_dbsecurity_group('db_sg', 'DB Security Group')
list(conn.get_all_dbsecurity_groups()).should.have.length_of(1)
conn.delete_dbsecurity_group("db_sg")
list(conn.get_all_dbsecurity_groups()).should.have.length_of(0)
@mock_rds_deprecated
def test_delete_non_existant_security_group():
conn = boto.rds.connect_to_region("us-west-2")
conn.delete_dbsecurity_group.when.called_with(
"not-a-db").should.throw(BotoServerError)
@disable_on_py3()
@mock_rds_deprecated
def test_security_group_authorize():
conn = boto.rds.connect_to_region("us-west-2")
security_group = conn.create_dbsecurity_group('db_sg', 'DB Security Group')
list(security_group.ip_ranges).should.equal([])
security_group.authorize(cidr_ip='10.3.2.45/32')
security_group = conn.get_all_dbsecurity_groups()[0]
list(security_group.ip_ranges).should.have.length_of(1)
security_group.ip_ranges[0].cidr_ip.should.equal('10.3.2.45/32')
@mock_rds_deprecated
def test_add_security_group_to_database():
conn = boto.rds.connect_to_region("us-west-2")
database = conn.create_dbinstance(
"db-master-1", 10, 'db.m1.small', 'root', 'hunter2')
security_group = conn.create_dbsecurity_group('db_sg', 'DB Security Group')
database.modify(security_groups=[security_group])
database = conn.get_all_dbinstances()[0]
list(database.security_groups).should.have.length_of(1)
database.security_groups[0].name.should.equal("db_sg")
@mock_ec2_deprecated
@mock_rds_deprecated
def test_add_database_subnet_group():
vpc_conn = boto.vpc.connect_to_region("us-west-2")
vpc = vpc_conn.create_vpc("10.0.0.0/16")
subnet1 = vpc_conn.create_subnet(vpc.id, "10.0.1.0/24")
subnet2 = vpc_conn.create_subnet(vpc.id, "10.0.2.0/24")
subnet_ids = [subnet1.id, subnet2.id]
conn = boto.rds.connect_to_region("us-west-2")
subnet_group = conn.create_db_subnet_group(
"db_subnet", "my db subnet", subnet_ids)
subnet_group.name.should.equal('db_subnet')
subnet_group.description.should.equal("my db subnet")
list(subnet_group.subnet_ids).should.equal(subnet_ids)
@mock_ec2_deprecated
@mock_rds_deprecated
def test_describe_database_subnet_group():
vpc_conn = boto.vpc.connect_to_region("us-west-2")
vpc = vpc_conn.create_vpc("10.0.0.0/16")
subnet = vpc_conn.create_subnet(vpc.id, "10.0.1.0/24")
conn = boto.rds.connect_to_region("us-west-2")
conn.create_db_subnet_group("db_subnet1", "my db subnet", [subnet.id])
conn.create_db_subnet_group("db_subnet2", "my db subnet", [subnet.id])
list(conn.get_all_db_subnet_groups()).should.have.length_of(2)
list(conn.get_all_db_subnet_groups("db_subnet1")).should.have.length_of(1)
conn.get_all_db_subnet_groups.when.called_with(
"not-a-subnet").should.throw(BotoServerError)
@mock_ec2_deprecated
@mock_rds_deprecated
def test_delete_database_subnet_group():
vpc_conn = boto.vpc.connect_to_region("us-west-2")
vpc = vpc_conn.create_vpc("10.0.0.0/16")
subnet = vpc_conn.create_subnet(vpc.id, "10.0.1.0/24")
conn = boto.rds.connect_to_region("us-west-2")
conn.create_db_subnet_group("db_subnet1", "my db subnet", [subnet.id])
list(conn.get_all_db_subnet_groups()).should.have.length_of(1)
conn.delete_db_subnet_group("db_subnet1")
list(conn.get_all_db_subnet_groups()).should.have.length_of(0)
conn.delete_db_subnet_group.when.called_with(
"db_subnet1").should.throw(BotoServerError)
@mock_ec2_deprecated
@mock_rds_deprecated
def test_create_database_in_subnet_group():
vpc_conn = boto.vpc.connect_to_region("us-west-2")
vpc = vpc_conn.create_vpc("10.0.0.0/16")
subnet = vpc_conn.create_subnet(vpc.id, "10.0.1.0/24")
conn = boto.rds.connect_to_region("us-west-2")
conn.create_db_subnet_group("db_subnet1", "my db subnet", [subnet.id])
database = conn.create_dbinstance("db-master-1", 10, 'db.m1.small',
'root', 'hunter2', db_subnet_group_name="db_subnet1")
database = conn.get_all_dbinstances("db-master-1")[0]
database.subnet_group.name.should.equal("db_subnet1")
@mock_rds_deprecated
def test_create_database_replica():
conn = boto.rds.connect_to_region("us-west-2")
primary = conn.create_dbinstance(
"db-master-1", 10, 'db.m1.small', 'root', 'hunter2')
replica = conn.create_dbinstance_read_replica(
"replica", "db-master-1", "db.m1.small")
replica.id.should.equal("replica")
replica.instance_class.should.equal("db.m1.small")
status_info = replica.status_infos[0]
status_info.normal.should.equal(True)
status_info.status_type.should.equal('read replication')
status_info.status.should.equal('replicating')
primary = conn.get_all_dbinstances("db-master-1")[0]
primary.read_replica_dbinstance_identifiers[0].should.equal("replica")
conn.delete_dbinstance("replica")
primary = conn.get_all_dbinstances("db-master-1")[0]
list(primary.read_replica_dbinstance_identifiers).should.have.length_of(0)
@mock_rds_deprecated
def test_create_cross_region_database_replica():
west_1_conn = boto.rds.connect_to_region("us-west-1")
west_2_conn = boto.rds.connect_to_region("us-west-2")
primary = west_1_conn.create_dbinstance(
"db-master-1", 10, 'db.m1.small', 'root', 'hunter2')
primary_arn = "arn:aws:rds:us-west-1:1234567890:db:db-master-1"
replica = west_2_conn.create_dbinstance_read_replica(
"replica",
primary_arn,
"db.m1.small",
)
primary = west_1_conn.get_all_dbinstances("db-master-1")[0]
primary.read_replica_dbinstance_identifiers[0].should.equal("replica")
replica = west_2_conn.get_all_dbinstances("replica")[0]
replica.instance_class.should.equal("db.m1.small")
west_2_conn.delete_dbinstance("replica")
primary = west_1_conn.get_all_dbinstances("db-master-1")[0]
list(primary.read_replica_dbinstance_identifiers).should.have.length_of(0)
@mock_rds_deprecated
def test_connecting_to_us_east_1():
# boto does not use us-east-1 in the URL for RDS,
# and that broke moto in the past:
# https://github.com/boto/boto/blob/e271ff09364ea18d9d8b6f4d63d6b0ac6cbc9b75/boto/endpoints.json#L285
conn = boto.rds.connect_to_region("us-east-1")
database = conn.create_dbinstance("db-master-1", 10, 'db.m1.small', 'root', 'hunter2',
security_groups=["my_sg"])
database.status.should.equal('available')
database.id.should.equal("db-master-1")
database.allocated_storage.should.equal(10)
database.instance_class.should.equal("db.m1.small")
database.master_username.should.equal("root")
database.endpoint.should.equal(
('db-master-1.aaaaaaaaaa.us-east-1.rds.amazonaws.com', 3306))
database.security_groups[0].name.should.equal('my_sg')
@mock_rds_deprecated
def test_create_database_with_iops():
conn = boto.rds.connect_to_region("us-west-2")
database = conn.create_dbinstance(
"db-master-1", 10, 'db.m1.small', 'root', 'hunter2', iops=6000)
database.status.should.equal('available')
database.iops.should.equal(6000)
# boto>2.36.0 may change the following property name to `storage_type`
database.StorageType.should.equal('io1')

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

View file

@ -0,0 +1,165 @@
from __future__ import unicode_literals
import boto3
import json
import sure # noqa
from moto import mock_resourcegroups
@mock_resourcegroups
def test_create_group():
resource_groups = boto3.client("resource-groups", region_name="us-east-1")
response = resource_groups.create_group(
Name="test_resource_group",
Description="description",
ResourceQuery={
"Type": "TAG_FILTERS_1_0",
"Query": json.dumps(
{
"ResourceTypeFilters": ["AWS::AllSupported"],
"TagFilters": [
{"Key": "resources_tag_key", "Values": ["resources_tag_value"]}
],
}
),
},
Tags={"resource_group_tag_key": "resource_group_tag_value"}
)
response["Group"]["Name"].should.contain("test_resource_group")
response["ResourceQuery"]["Type"].should.contain("TAG_FILTERS_1_0")
response["Tags"]["resource_group_tag_key"].should.contain("resource_group_tag_value")
@mock_resourcegroups
def test_delete_group():
resource_groups = boto3.client("resource-groups", region_name="us-east-1")
test_create_group()
response = resource_groups.delete_group(GroupName="test_resource_group")
response["Group"]["Name"].should.contain("test_resource_group")
response = resource_groups.list_groups()
response["GroupIdentifiers"].should.have.length_of(0)
response["Groups"].should.have.length_of(0)
@mock_resourcegroups
def test_get_group():
resource_groups = boto3.client("resource-groups", region_name="us-east-1")
test_create_group()
response = resource_groups.get_group(GroupName="test_resource_group")
response["Group"]["Description"].should.contain("description")
return response
@mock_resourcegroups
def test_get_group_query():
resource_groups = boto3.client("resource-groups", region_name="us-east-1")
test_create_group()
response = resource_groups.get_group_query(GroupName="test_resource_group")
response["GroupQuery"]["ResourceQuery"]["Type"].should.contain("TAG_FILTERS_1_0")
@mock_resourcegroups
def test_get_tags():
resource_groups = boto3.client("resource-groups", region_name="us-east-1")
response = test_get_group()
response = resource_groups.get_tags(Arn=response["Group"]["GroupArn"])
response["Tags"].should.have.length_of(1)
response["Tags"]["resource_group_tag_key"].should.contain("resource_group_tag_value")
return response
@mock_resourcegroups
def test_list_groups():
resource_groups = boto3.client("resource-groups", region_name="us-east-1")
test_create_group()
response = resource_groups.list_groups()
response["GroupIdentifiers"].should.have.length_of(1)
response["Groups"].should.have.length_of(1)
@mock_resourcegroups
def test_tag():
resource_groups = boto3.client("resource-groups", region_name="us-east-1")
response = test_get_tags()
response = resource_groups.tag(
Arn=response["Arn"],
Tags={"resource_group_tag_key_2": "resource_group_tag_value_2"}
)
response["Tags"]["resource_group_tag_key_2"].should.contain("resource_group_tag_value_2")
response = resource_groups.get_tags(Arn=response["Arn"])
response["Tags"].should.have.length_of(2)
response["Tags"]["resource_group_tag_key_2"].should.contain("resource_group_tag_value_2")
@mock_resourcegroups
def test_untag():
resource_groups = boto3.client("resource-groups", region_name="us-east-1")
response = test_get_tags()
response = resource_groups.untag(Arn=response["Arn"], Keys=["resource_group_tag_key"])
response["Keys"].should.contain("resource_group_tag_key")
response = resource_groups.get_tags(Arn=response["Arn"])
response["Tags"].should.have.length_of(0)
@mock_resourcegroups
def test_update_group():
resource_groups = boto3.client("resource-groups", region_name="us-east-1")
test_get_group()
response = resource_groups.update_group(
GroupName="test_resource_group",
Description="description_2",
)
response["Group"]["Description"].should.contain("description_2")
response = resource_groups.get_group(GroupName="test_resource_group")
response["Group"]["Description"].should.contain("description_2")
@mock_resourcegroups
def test_update_group_query():
resource_groups = boto3.client("resource-groups", region_name="us-east-1")
test_create_group()
response = resource_groups.update_group_query(
GroupName="test_resource_group",
ResourceQuery={
"Type": "CLOUDFORMATION_STACK_1_0",
"Query": json.dumps(
{
"ResourceTypeFilters": ["AWS::AllSupported"],
"StackIdentifier": (
"arn:aws:cloudformation:eu-west-1:012345678912:stack/"
"test_stack/c223eca0-e744-11e8-8910-500c41f59083"
)
}
),
},
)
response["GroupQuery"]["ResourceQuery"]["Type"].should.contain("CLOUDFORMATION_STACK_1_0")
response = resource_groups.get_group_query(GroupName="test_resource_group")
response["GroupQuery"]["ResourceQuery"]["Type"].should.contain("CLOUDFORMATION_STACK_1_0")

View file

@ -1,285 +1,285 @@
from __future__ import unicode_literals
import boto3
import sure # noqa
from moto import mock_resourcegroupstaggingapi, mock_s3, mock_ec2, mock_elbv2
@mock_s3
@mock_resourcegroupstaggingapi
def test_get_resources_s3():
# Tests pagination
s3_client = boto3.client('s3', region_name='eu-central-1')
# Will end up having key1,key2,key3,key4
response_keys = set()
# Create 4 buckets
for i in range(1, 5):
i_str = str(i)
s3_client.create_bucket(Bucket='test_bucket' + i_str)
s3_client.put_bucket_tagging(
Bucket='test_bucket' + i_str,
Tagging={'TagSet': [{'Key': 'key' + i_str, 'Value': 'value' + i_str}]}
)
response_keys.add('key' + i_str)
rtapi = boto3.client('resourcegroupstaggingapi', region_name='eu-central-1')
resp = rtapi.get_resources(ResourcesPerPage=2)
for resource in resp['ResourceTagMappingList']:
response_keys.remove(resource['Tags'][0]['Key'])
response_keys.should.have.length_of(2)
resp = rtapi.get_resources(
ResourcesPerPage=2,
PaginationToken=resp['PaginationToken']
)
for resource in resp['ResourceTagMappingList']:
response_keys.remove(resource['Tags'][0]['Key'])
response_keys.should.have.length_of(0)
@mock_ec2
@mock_resourcegroupstaggingapi
def test_get_resources_ec2():
client = boto3.client('ec2', region_name='eu-central-1')
instances = client.run_instances(
ImageId='ami-123',
MinCount=1,
MaxCount=1,
InstanceType='t2.micro',
TagSpecifications=[
{
'ResourceType': 'instance',
'Tags': [
{
'Key': 'MY_TAG1',
'Value': 'MY_VALUE1',
},
{
'Key': 'MY_TAG2',
'Value': 'MY_VALUE2',
},
],
},
{
'ResourceType': 'instance',
'Tags': [
{
'Key': 'MY_TAG3',
'Value': 'MY_VALUE3',
},
]
},
],
)
instance_id = instances['Instances'][0]['InstanceId']
image_id = client.create_image(Name='testami', InstanceId=instance_id)['ImageId']
client.create_tags(
Resources=[image_id],
Tags=[{'Key': 'ami', 'Value': 'test'}]
)
rtapi = boto3.client('resourcegroupstaggingapi', region_name='eu-central-1')
resp = rtapi.get_resources()
# Check we have 1 entry for Instance, 1 Entry for AMI
resp['ResourceTagMappingList'].should.have.length_of(2)
# 1 Entry for AMI
resp = rtapi.get_resources(ResourceTypeFilters=['ec2:image'])
resp['ResourceTagMappingList'].should.have.length_of(1)
resp['ResourceTagMappingList'][0]['ResourceARN'].should.contain('image/')
# As were iterating the same data, this rules out that the test above was a fluke
resp = rtapi.get_resources(ResourceTypeFilters=['ec2:instance'])
resp['ResourceTagMappingList'].should.have.length_of(1)
resp['ResourceTagMappingList'][0]['ResourceARN'].should.contain('instance/')
# Basic test of tag filters
resp = rtapi.get_resources(TagFilters=[{'Key': 'MY_TAG1', 'Values': ['MY_VALUE1', 'some_other_value']}])
resp['ResourceTagMappingList'].should.have.length_of(1)
resp['ResourceTagMappingList'][0]['ResourceARN'].should.contain('instance/')
@mock_ec2
@mock_resourcegroupstaggingapi
def test_get_tag_keys_ec2():
client = boto3.client('ec2', region_name='eu-central-1')
client.run_instances(
ImageId='ami-123',
MinCount=1,
MaxCount=1,
InstanceType='t2.micro',
TagSpecifications=[
{
'ResourceType': 'instance',
'Tags': [
{
'Key': 'MY_TAG1',
'Value': 'MY_VALUE1',
},
{
'Key': 'MY_TAG2',
'Value': 'MY_VALUE2',
},
],
},
{
'ResourceType': 'instance',
'Tags': [
{
'Key': 'MY_TAG3',
'Value': 'MY_VALUE3',
},
]
},
],
)
rtapi = boto3.client('resourcegroupstaggingapi', region_name='eu-central-1')
resp = rtapi.get_tag_keys()
resp['TagKeys'].should.contain('MY_TAG1')
resp['TagKeys'].should.contain('MY_TAG2')
resp['TagKeys'].should.contain('MY_TAG3')
# TODO test pagenation
@mock_ec2
@mock_resourcegroupstaggingapi
def test_get_tag_values_ec2():
client = boto3.client('ec2', region_name='eu-central-1')
client.run_instances(
ImageId='ami-123',
MinCount=1,
MaxCount=1,
InstanceType='t2.micro',
TagSpecifications=[
{
'ResourceType': 'instance',
'Tags': [
{
'Key': 'MY_TAG1',
'Value': 'MY_VALUE1',
},
{
'Key': 'MY_TAG2',
'Value': 'MY_VALUE2',
},
],
},
{
'ResourceType': 'instance',
'Tags': [
{
'Key': 'MY_TAG3',
'Value': 'MY_VALUE3',
},
]
},
],
)
client.run_instances(
ImageId='ami-123',
MinCount=1,
MaxCount=1,
InstanceType='t2.micro',
TagSpecifications=[
{
'ResourceType': 'instance',
'Tags': [
{
'Key': 'MY_TAG1',
'Value': 'MY_VALUE4',
},
{
'Key': 'MY_TAG2',
'Value': 'MY_VALUE5',
},
],
},
{
'ResourceType': 'instance',
'Tags': [
{
'Key': 'MY_TAG3',
'Value': 'MY_VALUE6',
},
]
},
],
)
rtapi = boto3.client('resourcegroupstaggingapi', region_name='eu-central-1')
resp = rtapi.get_tag_values(Key='MY_TAG1')
resp['TagValues'].should.contain('MY_VALUE1')
resp['TagValues'].should.contain('MY_VALUE4')
@mock_ec2
@mock_elbv2
@mock_resourcegroupstaggingapi
def test_get_resources_elbv2():
conn = boto3.client('elbv2', region_name='us-east-1')
ec2 = boto3.resource('ec2', region_name='us-east-1')
security_group = ec2.create_security_group(
GroupName='a-security-group', Description='First One')
vpc = ec2.create_vpc(CidrBlock='172.28.7.0/24', InstanceTenancy='default')
subnet1 = ec2.create_subnet(
VpcId=vpc.id,
CidrBlock='172.28.7.192/26',
AvailabilityZone='us-east-1a')
subnet2 = ec2.create_subnet(
VpcId=vpc.id,
CidrBlock='172.28.7.192/26',
AvailabilityZone='us-east-1b')
conn.create_load_balancer(
Name='my-lb',
Subnets=[subnet1.id, subnet2.id],
SecurityGroups=[security_group.id],
Scheme='internal',
Tags=[
{
'Key': 'key_name',
'Value': 'a_value'
},
{
'Key': 'key_2',
'Value': 'val2'
}
]
)
conn.create_load_balancer(
Name='my-other-lb',
Subnets=[subnet1.id, subnet2.id],
SecurityGroups=[security_group.id],
Scheme='internal',
)
rtapi = boto3.client('resourcegroupstaggingapi', region_name='us-east-1')
resp = rtapi.get_resources(ResourceTypeFilters=['elasticloadbalancer:loadbalancer'])
resp['ResourceTagMappingList'].should.have.length_of(2)
resp['ResourceTagMappingList'][0]['ResourceARN'].should.contain('loadbalancer/')
resp = rtapi.get_resources(
ResourceTypeFilters=['elasticloadbalancer:loadbalancer'],
TagFilters=[{
'Key': 'key_name'
}]
)
resp['ResourceTagMappingList'].should.have.length_of(1)
resp['ResourceTagMappingList'][0]['Tags'].should.contain({'Key': 'key_name', 'Value': 'a_value'})
# TODO test pagenation
from __future__ import unicode_literals
import boto3
import sure # noqa
from moto import mock_resourcegroupstaggingapi, mock_s3, mock_ec2, mock_elbv2
@mock_s3
@mock_resourcegroupstaggingapi
def test_get_resources_s3():
# Tests pagination
s3_client = boto3.client('s3', region_name='eu-central-1')
# Will end up having key1,key2,key3,key4
response_keys = set()
# Create 4 buckets
for i in range(1, 5):
i_str = str(i)
s3_client.create_bucket(Bucket='test_bucket' + i_str)
s3_client.put_bucket_tagging(
Bucket='test_bucket' + i_str,
Tagging={'TagSet': [{'Key': 'key' + i_str, 'Value': 'value' + i_str}]}
)
response_keys.add('key' + i_str)
rtapi = boto3.client('resourcegroupstaggingapi', region_name='eu-central-1')
resp = rtapi.get_resources(ResourcesPerPage=2)
for resource in resp['ResourceTagMappingList']:
response_keys.remove(resource['Tags'][0]['Key'])
response_keys.should.have.length_of(2)
resp = rtapi.get_resources(
ResourcesPerPage=2,
PaginationToken=resp['PaginationToken']
)
for resource in resp['ResourceTagMappingList']:
response_keys.remove(resource['Tags'][0]['Key'])
response_keys.should.have.length_of(0)
@mock_ec2
@mock_resourcegroupstaggingapi
def test_get_resources_ec2():
client = boto3.client('ec2', region_name='eu-central-1')
instances = client.run_instances(
ImageId='ami-123',
MinCount=1,
MaxCount=1,
InstanceType='t2.micro',
TagSpecifications=[
{
'ResourceType': 'instance',
'Tags': [
{
'Key': 'MY_TAG1',
'Value': 'MY_VALUE1',
},
{
'Key': 'MY_TAG2',
'Value': 'MY_VALUE2',
},
],
},
{
'ResourceType': 'instance',
'Tags': [
{
'Key': 'MY_TAG3',
'Value': 'MY_VALUE3',
},
]
},
],
)
instance_id = instances['Instances'][0]['InstanceId']
image_id = client.create_image(Name='testami', InstanceId=instance_id)['ImageId']
client.create_tags(
Resources=[image_id],
Tags=[{'Key': 'ami', 'Value': 'test'}]
)
rtapi = boto3.client('resourcegroupstaggingapi', region_name='eu-central-1')
resp = rtapi.get_resources()
# Check we have 1 entry for Instance, 1 Entry for AMI
resp['ResourceTagMappingList'].should.have.length_of(2)
# 1 Entry for AMI
resp = rtapi.get_resources(ResourceTypeFilters=['ec2:image'])
resp['ResourceTagMappingList'].should.have.length_of(1)
resp['ResourceTagMappingList'][0]['ResourceARN'].should.contain('image/')
# As were iterating the same data, this rules out that the test above was a fluke
resp = rtapi.get_resources(ResourceTypeFilters=['ec2:instance'])
resp['ResourceTagMappingList'].should.have.length_of(1)
resp['ResourceTagMappingList'][0]['ResourceARN'].should.contain('instance/')
# Basic test of tag filters
resp = rtapi.get_resources(TagFilters=[{'Key': 'MY_TAG1', 'Values': ['MY_VALUE1', 'some_other_value']}])
resp['ResourceTagMappingList'].should.have.length_of(1)
resp['ResourceTagMappingList'][0]['ResourceARN'].should.contain('instance/')
@mock_ec2
@mock_resourcegroupstaggingapi
def test_get_tag_keys_ec2():
client = boto3.client('ec2', region_name='eu-central-1')
client.run_instances(
ImageId='ami-123',
MinCount=1,
MaxCount=1,
InstanceType='t2.micro',
TagSpecifications=[
{
'ResourceType': 'instance',
'Tags': [
{
'Key': 'MY_TAG1',
'Value': 'MY_VALUE1',
},
{
'Key': 'MY_TAG2',
'Value': 'MY_VALUE2',
},
],
},
{
'ResourceType': 'instance',
'Tags': [
{
'Key': 'MY_TAG3',
'Value': 'MY_VALUE3',
},
]
},
],
)
rtapi = boto3.client('resourcegroupstaggingapi', region_name='eu-central-1')
resp = rtapi.get_tag_keys()
resp['TagKeys'].should.contain('MY_TAG1')
resp['TagKeys'].should.contain('MY_TAG2')
resp['TagKeys'].should.contain('MY_TAG3')
# TODO test pagenation
@mock_ec2
@mock_resourcegroupstaggingapi
def test_get_tag_values_ec2():
client = boto3.client('ec2', region_name='eu-central-1')
client.run_instances(
ImageId='ami-123',
MinCount=1,
MaxCount=1,
InstanceType='t2.micro',
TagSpecifications=[
{
'ResourceType': 'instance',
'Tags': [
{
'Key': 'MY_TAG1',
'Value': 'MY_VALUE1',
},
{
'Key': 'MY_TAG2',
'Value': 'MY_VALUE2',
},
],
},
{
'ResourceType': 'instance',
'Tags': [
{
'Key': 'MY_TAG3',
'Value': 'MY_VALUE3',
},
]
},
],
)
client.run_instances(
ImageId='ami-123',
MinCount=1,
MaxCount=1,
InstanceType='t2.micro',
TagSpecifications=[
{
'ResourceType': 'instance',
'Tags': [
{
'Key': 'MY_TAG1',
'Value': 'MY_VALUE4',
},
{
'Key': 'MY_TAG2',
'Value': 'MY_VALUE5',
},
],
},
{
'ResourceType': 'instance',
'Tags': [
{
'Key': 'MY_TAG3',
'Value': 'MY_VALUE6',
},
]
},
],
)
rtapi = boto3.client('resourcegroupstaggingapi', region_name='eu-central-1')
resp = rtapi.get_tag_values(Key='MY_TAG1')
resp['TagValues'].should.contain('MY_VALUE1')
resp['TagValues'].should.contain('MY_VALUE4')
@mock_ec2
@mock_elbv2
@mock_resourcegroupstaggingapi
def test_get_resources_elbv2():
conn = boto3.client('elbv2', region_name='us-east-1')
ec2 = boto3.resource('ec2', region_name='us-east-1')
security_group = ec2.create_security_group(
GroupName='a-security-group', Description='First One')
vpc = ec2.create_vpc(CidrBlock='172.28.7.0/24', InstanceTenancy='default')
subnet1 = ec2.create_subnet(
VpcId=vpc.id,
CidrBlock='172.28.7.192/26',
AvailabilityZone='us-east-1a')
subnet2 = ec2.create_subnet(
VpcId=vpc.id,
CidrBlock='172.28.7.0/26',
AvailabilityZone='us-east-1b')
conn.create_load_balancer(
Name='my-lb',
Subnets=[subnet1.id, subnet2.id],
SecurityGroups=[security_group.id],
Scheme='internal',
Tags=[
{
'Key': 'key_name',
'Value': 'a_value'
},
{
'Key': 'key_2',
'Value': 'val2'
}
]
)
conn.create_load_balancer(
Name='my-other-lb',
Subnets=[subnet1.id, subnet2.id],
SecurityGroups=[security_group.id],
Scheme='internal',
)
rtapi = boto3.client('resourcegroupstaggingapi', region_name='us-east-1')
resp = rtapi.get_resources(ResourceTypeFilters=['elasticloadbalancer:loadbalancer'])
resp['ResourceTagMappingList'].should.have.length_of(2)
resp['ResourceTagMappingList'][0]['ResourceARN'].should.contain('loadbalancer/')
resp = rtapi.get_resources(
ResourceTypeFilters=['elasticloadbalancer:loadbalancer'],
TagFilters=[{
'Key': 'key_name'
}]
)
resp['ResourceTagMappingList'].should.have.length_of(1)
resp['ResourceTagMappingList'][0]['Tags'].should.contain({'Key': 'key_name', 'Value': 'a_value'})
# TODO test pagenation

View file

@ -1529,6 +1529,28 @@ def test_boto3_copy_object_with_versioning():
# Version should be different to previous version
obj2_version_new.should_not.equal(obj2_version)
client.copy_object(CopySource={'Bucket': 'blah', 'Key': 'test2', 'VersionId': obj2_version}, Bucket='blah', Key='test3')
obj3_version_new = client.get_object(Bucket='blah', Key='test3')['VersionId']
obj3_version_new.should_not.equal(obj2_version_new)
# Copy file that doesn't exist
with assert_raises(ClientError) as e:
client.copy_object(CopySource={'Bucket': 'blah', 'Key': 'test4', 'VersionId': obj2_version}, Bucket='blah', Key='test5')
e.exception.response['Error']['Code'].should.equal('404')
response = client.create_multipart_upload(Bucket='blah', Key='test4')
upload_id = response['UploadId']
response = client.upload_part_copy(Bucket='blah', Key='test4', CopySource={'Bucket': 'blah', 'Key': 'test3', 'VersionId': obj3_version_new},
UploadId=upload_id, PartNumber=1)
etag = response["CopyPartResult"]["ETag"]
client.complete_multipart_upload(
Bucket='blah', Key='test4', UploadId=upload_id,
MultipartUpload={'Parts': [{'ETag': etag, 'PartNumber': 1}]})
response = client.get_object(Bucket='blah', Key='test4')
data = response["Body"].read()
data.should.equal(b'test2')
@mock_s3
def test_boto3_copy_object_from_unversioned_to_versioned_bucket():
@ -2762,6 +2784,7 @@ def test_boto3_multiple_delete_markers():
latest['Key'].should.equal('key-with-versions-and-unicode-ó')
oldest['Key'].should.equal('key-with-versions-and-unicode-ó')
@mock_s3
def test_get_stream_gzipped():
payload = b"this is some stuff here"
@ -2820,3 +2843,80 @@ def test_boto3_bucket_name_too_short():
with assert_raises(ClientError) as exc:
s3.create_bucket(Bucket='x'*2)
exc.exception.response['Error']['Code'].should.equal('InvalidBucketName')
@mock_s3
def test_accelerated_none_when_unspecified():
bucket_name = 'some_bucket'
s3 = boto3.client('s3')
s3.create_bucket(Bucket=bucket_name)
resp = s3.get_bucket_accelerate_configuration(Bucket=bucket_name)
resp.shouldnt.have.key('Status')
@mock_s3
def test_can_enable_bucket_acceleration():
bucket_name = 'some_bucket'
s3 = boto3.client('s3')
s3.create_bucket(Bucket=bucket_name)
resp = s3.put_bucket_accelerate_configuration(
Bucket=bucket_name,
AccelerateConfiguration={'Status': 'Enabled'},
)
resp.keys().should.have.length_of(1) # Response contains nothing (only HTTP headers)
resp = s3.get_bucket_accelerate_configuration(Bucket=bucket_name)
resp.should.have.key('Status')
resp['Status'].should.equal('Enabled')
@mock_s3
def test_can_suspend_bucket_acceleration():
bucket_name = 'some_bucket'
s3 = boto3.client('s3')
s3.create_bucket(Bucket=bucket_name)
resp = s3.put_bucket_accelerate_configuration(
Bucket=bucket_name,
AccelerateConfiguration={'Status': 'Enabled'},
)
resp = s3.put_bucket_accelerate_configuration(
Bucket=bucket_name,
AccelerateConfiguration={'Status': 'Suspended'},
)
resp.keys().should.have.length_of(1) # Response contains nothing (only HTTP headers)
resp = s3.get_bucket_accelerate_configuration(Bucket=bucket_name)
resp.should.have.key('Status')
resp['Status'].should.equal('Suspended')
@mock_s3
def test_suspending_acceleration_on_not_configured_bucket_does_nothing():
bucket_name = 'some_bucket'
s3 = boto3.client('s3')
s3.create_bucket(Bucket=bucket_name)
resp = s3.put_bucket_accelerate_configuration(
Bucket=bucket_name,
AccelerateConfiguration={'Status': 'Suspended'},
)
resp.keys().should.have.length_of(1) # Response contains nothing (only HTTP headers)
resp = s3.get_bucket_accelerate_configuration(Bucket=bucket_name)
resp.shouldnt.have.key('Status')
@mock_s3
def test_accelerate_configuration_status_validation():
bucket_name = 'some_bucket'
s3 = boto3.client('s3')
s3.create_bucket(Bucket=bucket_name)
with assert_raises(ClientError) as exc:
s3.put_bucket_accelerate_configuration(
Bucket=bucket_name,
AccelerateConfiguration={'Status': 'bad_status'},
)
exc.exception.response['Error']['Code'].should.equal('MalformedXML')
@mock_s3
def test_accelerate_configuration_is_not_supported_when_bucket_name_has_dots():
bucket_name = 'some.bucket.with.dots'
s3 = boto3.client('s3')
s3.create_bucket(Bucket=bucket_name)
with assert_raises(ClientError) as exc:
s3.put_bucket_accelerate_configuration(
Bucket=bucket_name,
AccelerateConfiguration={'Status': 'Enabled'},
)
exc.exception.response['Error']['Code'].should.equal('InvalidRequest')

View file

@ -4,13 +4,15 @@ import boto3
from moto import mock_secretsmanager
from botocore.exceptions import ClientError
import sure # noqa
import string
import unittest
import pytz
from datetime import datetime
import unittest
from nose.tools import assert_raises
DEFAULT_SECRET_NAME = 'test-secret'
@mock_secretsmanager
def test_get_secret_value():
conn = boto3.client('secretsmanager', region_name='us-west-2')
@ -389,34 +391,32 @@ def test_restore_secret_that_does_not_exist():
@mock_secretsmanager
def test_rotate_secret():
secret_name = 'test-secret'
conn = boto3.client('secretsmanager', region_name='us-west-2')
conn.create_secret(Name=secret_name,
conn.create_secret(Name=DEFAULT_SECRET_NAME,
SecretString='foosecret')
rotated_secret = conn.rotate_secret(SecretId=secret_name)
rotated_secret = conn.rotate_secret(SecretId=DEFAULT_SECRET_NAME)
assert rotated_secret
assert rotated_secret['ARN'] != '' # Test arn not empty
assert rotated_secret['Name'] == secret_name
assert rotated_secret['Name'] == DEFAULT_SECRET_NAME
assert rotated_secret['VersionId'] != ''
@mock_secretsmanager
def test_rotate_secret_enable_rotation():
secret_name = 'test-secret'
conn = boto3.client('secretsmanager', region_name='us-west-2')
conn.create_secret(Name=secret_name,
conn.create_secret(Name=DEFAULT_SECRET_NAME,
SecretString='foosecret')
initial_description = conn.describe_secret(SecretId=secret_name)
initial_description = conn.describe_secret(SecretId=DEFAULT_SECRET_NAME)
assert initial_description
assert initial_description['RotationEnabled'] is False
assert initial_description['RotationRules']['AutomaticallyAfterDays'] == 0
conn.rotate_secret(SecretId=secret_name,
conn.rotate_secret(SecretId=DEFAULT_SECRET_NAME,
RotationRules={'AutomaticallyAfterDays': 42})
rotated_description = conn.describe_secret(SecretId=secret_name)
rotated_description = conn.describe_secret(SecretId=DEFAULT_SECRET_NAME)
assert rotated_description
assert rotated_description['RotationEnabled'] is True
assert rotated_description['RotationRules']['AutomaticallyAfterDays'] == 42
@ -460,9 +460,8 @@ def test_rotate_secret_client_request_token_too_short():
@mock_secretsmanager
def test_rotate_secret_client_request_token_too_long():
secret_name = 'test-secret'
conn = boto3.client('secretsmanager', region_name='us-west-2')
conn.create_secret(Name=secret_name,
conn.create_secret(Name=DEFAULT_SECRET_NAME,
SecretString='foosecret')
client_request_token = (
@ -470,19 +469,18 @@ def test_rotate_secret_client_request_token_too_long():
'ED9F8B6C-85B7-446A-B7E4-38F2A3BEB13C'
)
with assert_raises(ClientError):
result = conn.rotate_secret(SecretId=secret_name,
result = conn.rotate_secret(SecretId=DEFAULT_SECRET_NAME,
ClientRequestToken=client_request_token)
@mock_secretsmanager
def test_rotate_secret_rotation_lambda_arn_too_long():
secret_name = 'test-secret'
conn = boto3.client('secretsmanager', region_name='us-west-2')
conn.create_secret(Name=secret_name,
conn.create_secret(Name=DEFAULT_SECRET_NAME,
SecretString='foosecret')
rotation_lambda_arn = '85B7-446A-B7E4' * 147 # == 2058 characters
with assert_raises(ClientError):
result = conn.rotate_secret(SecretId=secret_name,
result = conn.rotate_secret(SecretId=DEFAULT_SECRET_NAME,
RotationLambdaARN=rotation_lambda_arn)
@mock_secretsmanager
@ -494,12 +492,78 @@ def test_rotate_secret_rotation_period_zero():
@mock_secretsmanager
def test_rotate_secret_rotation_period_too_long():
secret_name = 'test-secret'
conn = boto3.client('secretsmanager', region_name='us-west-2')
conn.create_secret(Name=secret_name,
conn.create_secret(Name=DEFAULT_SECRET_NAME,
SecretString='foosecret')
rotation_rules = {'AutomaticallyAfterDays': 1001}
with assert_raises(ClientError):
result = conn.rotate_secret(SecretId=secret_name,
result = conn.rotate_secret(SecretId=DEFAULT_SECRET_NAME,
RotationRules=rotation_rules)
@mock_secretsmanager
def test_put_secret_value_puts_new_secret():
conn = boto3.client('secretsmanager', region_name='us-west-2')
put_secret_value_dict = conn.put_secret_value(SecretId=DEFAULT_SECRET_NAME,
SecretString='foosecret',
VersionStages=['AWSCURRENT'])
version_id = put_secret_value_dict['VersionId']
get_secret_value_dict = conn.get_secret_value(SecretId=DEFAULT_SECRET_NAME,
VersionId=version_id,
VersionStage='AWSCURRENT')
assert get_secret_value_dict
assert get_secret_value_dict['SecretString'] == 'foosecret'
@mock_secretsmanager
def test_put_secret_value_can_get_first_version_if_put_twice():
conn = boto3.client('secretsmanager', region_name='us-west-2')
put_secret_value_dict = conn.put_secret_value(SecretId=DEFAULT_SECRET_NAME,
SecretString='first_secret',
VersionStages=['AWSCURRENT'])
first_version_id = put_secret_value_dict['VersionId']
conn.put_secret_value(SecretId=DEFAULT_SECRET_NAME,
SecretString='second_secret',
VersionStages=['AWSCURRENT'])
first_secret_value_dict = conn.get_secret_value(SecretId=DEFAULT_SECRET_NAME,
VersionId=first_version_id)
first_secret_value = first_secret_value_dict['SecretString']
assert first_secret_value == 'first_secret'
@mock_secretsmanager
def test_put_secret_value_versions_differ_if_same_secret_put_twice():
conn = boto3.client('secretsmanager', region_name='us-west-2')
put_secret_value_dict = conn.put_secret_value(SecretId=DEFAULT_SECRET_NAME,
SecretString='dupe_secret',
VersionStages=['AWSCURRENT'])
first_version_id = put_secret_value_dict['VersionId']
put_secret_value_dict = conn.put_secret_value(SecretId=DEFAULT_SECRET_NAME,
SecretString='dupe_secret',
VersionStages=['AWSCURRENT'])
second_version_id = put_secret_value_dict['VersionId']
assert first_version_id != second_version_id
@mock_secretsmanager
def test_can_list_secret_version_ids():
conn = boto3.client('secretsmanager', region_name='us-west-2')
put_secret_value_dict = conn.put_secret_value(SecretId=DEFAULT_SECRET_NAME,
SecretString='dupe_secret',
VersionStages=['AWSCURRENT'])
first_version_id = put_secret_value_dict['VersionId']
put_secret_value_dict = conn.put_secret_value(SecretId=DEFAULT_SECRET_NAME,
SecretString='dupe_secret',
VersionStages=['AWSCURRENT'])
second_version_id = put_secret_value_dict['VersionId']
versions_list = conn.list_secret_version_ids(SecretId=DEFAULT_SECRET_NAME)
returned_version_ids = [v['VersionId'] for v in versions_list['Versions']]
assert [first_version_id, second_version_id].sort() == returned_version_ids.sort()

View file

@ -10,6 +10,8 @@ from moto import mock_secretsmanager
Test the different server responses for secretsmanager
'''
DEFAULT_SECRET_NAME = 'test-secret'
@mock_secretsmanager
def test_get_secret_value():
@ -18,19 +20,20 @@ def test_get_secret_value():
test_client = backend.test_client()
create_secret = test_client.post('/',
data={"Name": "test-secret",
data={"Name": DEFAULT_SECRET_NAME,
"SecretString": "foo-secret"},
headers={
"X-Amz-Target": "secretsmanager.CreateSecret"},
)
get_secret = test_client.post('/',
data={"SecretId": "test-secret",
"VersionStage": "AWSCURRENT"},
headers={
"X-Amz-Target": "secretsmanager.GetSecretValue"},
)
data={"SecretId": DEFAULT_SECRET_NAME,
"VersionStage": "AWSCURRENT"},
headers={
"X-Amz-Target": "secretsmanager.GetSecretValue"},
)
json_data = json.loads(get_secret.data.decode("utf-8"))
assert json_data['SecretString'] == 'foo-secret'
@mock_secretsmanager
@ -55,7 +58,7 @@ def test_get_secret_that_does_not_match():
test_client = backend.test_client()
create_secret = test_client.post('/',
data={"Name": "test-secret",
data={"Name": DEFAULT_SECRET_NAME,
"SecretString": "foo-secret"},
headers={
"X-Amz-Target": "secretsmanager.CreateSecret"},
@ -165,7 +168,7 @@ def test_describe_secret_that_does_not_match():
test_client = backend.test_client()
create_secret = test_client.post('/',
data={"Name": "test-secret",
data={"Name": DEFAULT_SECRET_NAME,
"SecretString": "foosecret"},
headers={
"X-Amz-Target": "secretsmanager.CreateSecret"
@ -188,7 +191,7 @@ def test_rotate_secret():
test_client = backend.test_client()
create_secret = test_client.post('/',
data={"Name": "test-secret",
data={"Name": DEFAULT_SECRET_NAME,
"SecretString": "foosecret"},
headers={
"X-Amz-Target": "secretsmanager.CreateSecret"
@ -197,7 +200,7 @@ def test_rotate_secret():
client_request_token = "EXAMPLE2-90ab-cdef-fedc-ba987SECRET2"
rotate_secret = test_client.post('/',
data={"SecretId": "test-secret",
data={"SecretId": DEFAULT_SECRET_NAME,
"ClientRequestToken": client_request_token},
headers={
"X-Amz-Target": "secretsmanager.RotateSecret"
@ -207,7 +210,7 @@ def test_rotate_secret():
json_data = json.loads(rotate_secret.data.decode("utf-8"))
assert json_data # Returned dict is not empty
assert json_data['ARN'] != ''
assert json_data['Name'] == 'test-secret'
assert json_data['Name'] == DEFAULT_SECRET_NAME
assert json_data['VersionId'] == client_request_token
# @mock_secretsmanager
@ -289,7 +292,7 @@ def test_rotate_secret_that_does_not_match():
test_client = backend.test_client()
create_secret = test_client.post('/',
data={"Name": "test-secret",
data={"Name": DEFAULT_SECRET_NAME,
"SecretString": "foosecret"},
headers={
"X-Amz-Target": "secretsmanager.CreateSecret"
@ -313,7 +316,7 @@ def test_rotate_secret_client_request_token_too_short():
test_client = backend.test_client()
create_secret = test_client.post('/',
data={"Name": "test-secret",
data={"Name": DEFAULT_SECRET_NAME,
"SecretString": "foosecret"},
headers={
"X-Amz-Target": "secretsmanager.CreateSecret"
@ -322,7 +325,7 @@ def test_rotate_secret_client_request_token_too_short():
client_request_token = "ED9F8B6C-85B7-B7E4-38F2A3BEB13C"
rotate_secret = test_client.post('/',
data={"SecretId": "test-secret",
data={"SecretId": DEFAULT_SECRET_NAME,
"ClientRequestToken": client_request_token},
headers={
"X-Amz-Target": "secretsmanager.RotateSecret"
@ -339,7 +342,7 @@ def test_rotate_secret_client_request_token_too_long():
test_client = backend.test_client()
create_secret = test_client.post('/',
data={"Name": "test-secret",
data={"Name": DEFAULT_SECRET_NAME,
"SecretString": "foosecret"},
headers={
"X-Amz-Target": "secretsmanager.CreateSecret"
@ -351,7 +354,7 @@ def test_rotate_secret_client_request_token_too_long():
'ED9F8B6C-85B7-446A-B7E4-38F2A3BEB13C'
)
rotate_secret = test_client.post('/',
data={"SecretId": "test-secret",
data={"SecretId": DEFAULT_SECRET_NAME,
"ClientRequestToken": client_request_token},
headers={
"X-Amz-Target": "secretsmanager.RotateSecret"
@ -368,7 +371,7 @@ def test_rotate_secret_rotation_lambda_arn_too_long():
test_client = backend.test_client()
create_secret = test_client.post('/',
data={"Name": "test-secret",
data={"Name": DEFAULT_SECRET_NAME,
"SecretString": "foosecret"},
headers={
"X-Amz-Target": "secretsmanager.CreateSecret"
@ -377,7 +380,7 @@ def test_rotate_secret_rotation_lambda_arn_too_long():
rotation_lambda_arn = '85B7-446A-B7E4' * 147 # == 2058 characters
rotate_secret = test_client.post('/',
data={"SecretId": "test-secret",
data={"SecretId": DEFAULT_SECRET_NAME,
"RotationLambdaARN": rotation_lambda_arn},
headers={
"X-Amz-Target": "secretsmanager.RotateSecret"
@ -389,7 +392,165 @@ def test_rotate_secret_rotation_lambda_arn_too_long():
assert json_data['__type'] == 'InvalidParameterException'
#
@mock_secretsmanager
def test_put_secret_value_puts_new_secret():
backend = server.create_backend_app('secretsmanager')
test_client = backend.test_client()
test_client.post('/',
data={
"SecretId": DEFAULT_SECRET_NAME,
"SecretString": "foosecret",
"VersionStages": ["AWSCURRENT"]},
headers={
"X-Amz-Target": "secretsmanager.PutSecretValue"},
)
put_second_secret_value_json = test_client.post('/',
data={
"SecretId": DEFAULT_SECRET_NAME,
"SecretString": "foosecret",
"VersionStages": ["AWSCURRENT"]},
headers={
"X-Amz-Target": "secretsmanager.PutSecretValue"},
)
second_secret_json_data = json.loads(put_second_secret_value_json.data.decode("utf-8"))
version_id = second_secret_json_data['VersionId']
secret_value_json = test_client.post('/',
data={
"SecretId": DEFAULT_SECRET_NAME,
"VersionId": version_id,
"VersionStage": 'AWSCURRENT'},
headers={
"X-Amz-Target": "secretsmanager.GetSecretValue"},
)
second_secret_json_data = json.loads(secret_value_json.data.decode("utf-8"))
assert second_secret_json_data
assert second_secret_json_data['SecretString'] == 'foosecret'
@mock_secretsmanager
def test_put_secret_value_can_get_first_version_if_put_twice():
backend = server.create_backend_app('secretsmanager')
test_client = backend.test_client()
first_secret_string = 'first_secret'
second_secret_string = 'second_secret'
put_first_secret_value_json = test_client.post('/',
data={
"SecretId": DEFAULT_SECRET_NAME,
"SecretString": first_secret_string,
"VersionStages": ["AWSCURRENT"]},
headers={
"X-Amz-Target": "secretsmanager.PutSecretValue"},
)
first_secret_json_data = json.loads(put_first_secret_value_json.data.decode("utf-8"))
first_secret_version_id = first_secret_json_data['VersionId']
test_client.post('/',
data={
"SecretId": DEFAULT_SECRET_NAME,
"SecretString": second_secret_string,
"VersionStages": ["AWSCURRENT"]},
headers={
"X-Amz-Target": "secretsmanager.PutSecretValue"},
)
get_first_secret_value_json = test_client.post('/',
data={
"SecretId": DEFAULT_SECRET_NAME,
"VersionId": first_secret_version_id,
"VersionStage": 'AWSCURRENT'},
headers={
"X-Amz-Target": "secretsmanager.GetSecretValue"},
)
get_first_secret_json_data = json.loads(get_first_secret_value_json.data.decode("utf-8"))
assert get_first_secret_json_data
assert get_first_secret_json_data['SecretString'] == first_secret_string
@mock_secretsmanager
def test_put_secret_value_versions_differ_if_same_secret_put_twice():
backend = server.create_backend_app('secretsmanager')
test_client = backend.test_client()
put_first_secret_value_json = test_client.post('/',
data={
"SecretId": DEFAULT_SECRET_NAME,
"SecretString": "secret",
"VersionStages": ["AWSCURRENT"]},
headers={
"X-Amz-Target": "secretsmanager.PutSecretValue"},
)
first_secret_json_data = json.loads(put_first_secret_value_json.data.decode("utf-8"))
first_secret_version_id = first_secret_json_data['VersionId']
put_second_secret_value_json = test_client.post('/',
data={
"SecretId": DEFAULT_SECRET_NAME,
"SecretString": "secret",
"VersionStages": ["AWSCURRENT"]},
headers={
"X-Amz-Target": "secretsmanager.PutSecretValue"},
)
second_secret_json_data = json.loads(put_second_secret_value_json.data.decode("utf-8"))
second_secret_version_id = second_secret_json_data['VersionId']
assert first_secret_version_id != second_secret_version_id
@mock_secretsmanager
def test_can_list_secret_version_ids():
backend = server.create_backend_app('secretsmanager')
test_client = backend.test_client()
put_first_secret_value_json = test_client.post('/',
data={
"SecretId": DEFAULT_SECRET_NAME,
"SecretString": "secret",
"VersionStages": ["AWSCURRENT"]},
headers={
"X-Amz-Target": "secretsmanager.PutSecretValue"},
)
first_secret_json_data = json.loads(put_first_secret_value_json.data.decode("utf-8"))
first_secret_version_id = first_secret_json_data['VersionId']
put_second_secret_value_json = test_client.post('/',
data={
"SecretId": DEFAULT_SECRET_NAME,
"SecretString": "secret",
"VersionStages": ["AWSCURRENT"]},
headers={
"X-Amz-Target": "secretsmanager.PutSecretValue"},
)
second_secret_json_data = json.loads(put_second_secret_value_json.data.decode("utf-8"))
second_secret_version_id = second_secret_json_data['VersionId']
list_secret_versions_json = test_client.post('/',
data={
"SecretId": DEFAULT_SECRET_NAME, },
headers={
"X-Amz-Target": "secretsmanager.ListSecretVersionIds"},
)
versions_list = json.loads(list_secret_versions_json.data.decode("utf-8"))
returned_version_ids = [v['VersionId'] for v in versions_list['Versions']]
assert [first_secret_version_id, second_secret_version_id].sort() == returned_version_ids.sort()
#
# The following tests should work, but fail on the embedded dict in
# RotationRules. The error message suggests a problem deeper in the code, which
# needs further investigation.

File diff suppressed because it is too large Load diff