346 lines
11 KiB
Python
346 lines
11 KiB
Python
|
from __future__ import unicode_literals
|
||
|
|
||
|
# Ensure 'pytest.raises' context manager support for Python 2.6
|
||
|
import pytest
|
||
|
|
||
|
import time
|
||
|
import json
|
||
|
import boto3
|
||
|
from botocore.exceptions import ClientError
|
||
|
import sure # noqa
|
||
|
|
||
|
from moto import mock_ec2, mock_iam, mock_cloudformation
|
||
|
|
||
|
|
||
|
def quick_instance_creation():
|
||
|
image_id = "ami-1234abcd"
|
||
|
conn_ec2 = boto3.resource("ec2", "us-east-1")
|
||
|
test_instance = conn_ec2.create_instances(ImageId=image_id, MinCount=1, MaxCount=1)
|
||
|
# We only need instance id for this tests
|
||
|
return test_instance[0].id
|
||
|
|
||
|
|
||
|
def quick_instance_profile_creation(name):
|
||
|
conn_iam = boto3.resource("iam", "us-east-1")
|
||
|
test_instance_profile = conn_iam.create_instance_profile(
|
||
|
InstanceProfileName=name, Path="/"
|
||
|
)
|
||
|
return test_instance_profile.arn, test_instance_profile.name
|
||
|
|
||
|
|
||
|
@mock_ec2
|
||
|
@mock_iam
|
||
|
def test_associate():
|
||
|
client = boto3.client("ec2", region_name="us-east-1")
|
||
|
instance_id = quick_instance_creation()
|
||
|
instance_profile_arn, instance_profile_name = quick_instance_profile_creation(
|
||
|
"test_profile"
|
||
|
)
|
||
|
|
||
|
association = client.associate_iam_instance_profile(
|
||
|
IamInstanceProfile={
|
||
|
"Arn": instance_profile_arn,
|
||
|
"Name": instance_profile_name,
|
||
|
},
|
||
|
InstanceId=instance_id,
|
||
|
)
|
||
|
association["IamInstanceProfileAssociation"]["InstanceId"].should.equal(instance_id)
|
||
|
association["IamInstanceProfileAssociation"]["IamInstanceProfile"][
|
||
|
"Arn"
|
||
|
].should.equal(instance_profile_arn)
|
||
|
association["IamInstanceProfileAssociation"]["State"].should.equal("associating")
|
||
|
|
||
|
|
||
|
@mock_ec2
|
||
|
@mock_iam
|
||
|
def test_invalid_associate():
|
||
|
client = boto3.client("ec2", region_name="us-east-1")
|
||
|
instance_id = quick_instance_creation()
|
||
|
instance_profile_arn, instance_profile_name = quick_instance_profile_creation(
|
||
|
"test_profile"
|
||
|
)
|
||
|
|
||
|
client.associate_iam_instance_profile(
|
||
|
IamInstanceProfile={
|
||
|
"Arn": instance_profile_arn,
|
||
|
"Name": instance_profile_name,
|
||
|
},
|
||
|
InstanceId=instance_id,
|
||
|
)
|
||
|
|
||
|
# Duplicate
|
||
|
with pytest.raises(ClientError) as ex:
|
||
|
client.associate_iam_instance_profile(
|
||
|
IamInstanceProfile={
|
||
|
"Arn": instance_profile_arn,
|
||
|
"Name": instance_profile_name,
|
||
|
},
|
||
|
InstanceId=instance_id,
|
||
|
)
|
||
|
ex.value.response["Error"]["Code"].should.equal("IncorrectState")
|
||
|
ex.value.response["Error"]["Message"].should.contain(
|
||
|
"There is an existing association for"
|
||
|
)
|
||
|
|
||
|
# Wrong instance profile
|
||
|
with pytest.raises(ClientError) as ex:
|
||
|
client.associate_iam_instance_profile(
|
||
|
IamInstanceProfile={"Arn": "fake", "Name": "fake"}, InstanceId=instance_id,
|
||
|
)
|
||
|
ex.value.response["Error"]["Code"].should.equal("NoSuchEntity")
|
||
|
ex.value.response["Error"]["Message"].should.contain("not found")
|
||
|
|
||
|
# Wrong instance id
|
||
|
with pytest.raises(ClientError) as ex:
|
||
|
client.associate_iam_instance_profile(
|
||
|
IamInstanceProfile={
|
||
|
"Arn": instance_profile_arn,
|
||
|
"Name": instance_profile_name,
|
||
|
},
|
||
|
InstanceId="fake",
|
||
|
)
|
||
|
ex.value.response["Error"]["Code"].should.equal("InvalidInstanceID.NotFound")
|
||
|
ex.value.response["Error"]["Message"].should.contain("does not exist")
|
||
|
|
||
|
|
||
|
@mock_ec2
|
||
|
@mock_iam
|
||
|
def test_describe():
|
||
|
client = boto3.client("ec2", region_name="us-east-1")
|
||
|
|
||
|
instance_id = quick_instance_creation()
|
||
|
instance_profile_arn, instance_profile_name = quick_instance_profile_creation(
|
||
|
"test_profile"
|
||
|
)
|
||
|
client.associate_iam_instance_profile(
|
||
|
IamInstanceProfile={
|
||
|
"Arn": instance_profile_arn,
|
||
|
"Name": instance_profile_name,
|
||
|
},
|
||
|
InstanceId=instance_id,
|
||
|
)
|
||
|
associations = client.describe_iam_instance_profile_associations()
|
||
|
associations["IamInstanceProfileAssociations"].should.have.length_of(1)
|
||
|
associations["IamInstanceProfileAssociations"][0]["InstanceId"].should.equal(
|
||
|
instance_id
|
||
|
)
|
||
|
associations["IamInstanceProfileAssociations"][0]["IamInstanceProfile"][
|
||
|
"Arn"
|
||
|
].should.equal(instance_profile_arn)
|
||
|
associations["IamInstanceProfileAssociations"][0]["State"].should.equal(
|
||
|
"associated"
|
||
|
)
|
||
|
|
||
|
instance_id = quick_instance_creation()
|
||
|
instance_profile_arn, instance_profile_name = quick_instance_profile_creation(
|
||
|
"test_profile1"
|
||
|
)
|
||
|
client.associate_iam_instance_profile(
|
||
|
IamInstanceProfile={
|
||
|
"Arn": instance_profile_arn,
|
||
|
"Name": instance_profile_name,
|
||
|
},
|
||
|
InstanceId=instance_id,
|
||
|
)
|
||
|
|
||
|
next_test_associations = client.describe_iam_instance_profile_associations()
|
||
|
next_test_associations["IamInstanceProfileAssociations"].should.have.length_of(2)
|
||
|
|
||
|
associations = client.describe_iam_instance_profile_associations(
|
||
|
AssociationIds=[
|
||
|
next_test_associations["IamInstanceProfileAssociations"][0][
|
||
|
"AssociationId"
|
||
|
],
|
||
|
]
|
||
|
)
|
||
|
associations["IamInstanceProfileAssociations"].should.have.length_of(1)
|
||
|
associations["IamInstanceProfileAssociations"][0]["IamInstanceProfile"][
|
||
|
"Arn"
|
||
|
].should.equal(
|
||
|
next_test_associations["IamInstanceProfileAssociations"][0][
|
||
|
"IamInstanceProfile"
|
||
|
]["Arn"]
|
||
|
)
|
||
|
|
||
|
associations = client.describe_iam_instance_profile_associations(
|
||
|
Filters=[
|
||
|
{
|
||
|
"Name": "instance-id",
|
||
|
"Values": [
|
||
|
next_test_associations["IamInstanceProfileAssociations"][0][
|
||
|
"InstanceId"
|
||
|
],
|
||
|
],
|
||
|
},
|
||
|
{"Name": "state", "Values": ["associated"]},
|
||
|
]
|
||
|
)
|
||
|
associations["IamInstanceProfileAssociations"].should.have.length_of(1)
|
||
|
associations["IamInstanceProfileAssociations"][0]["IamInstanceProfile"][
|
||
|
"Arn"
|
||
|
].should.equal(
|
||
|
next_test_associations["IamInstanceProfileAssociations"][0][
|
||
|
"IamInstanceProfile"
|
||
|
]["Arn"]
|
||
|
)
|
||
|
|
||
|
|
||
|
@mock_ec2
|
||
|
@mock_iam
|
||
|
def test_replace():
|
||
|
client = boto3.client("ec2", region_name="us-east-1")
|
||
|
instance_id1 = quick_instance_creation()
|
||
|
instance_profile_arn1, instance_profile_name1 = quick_instance_profile_creation(
|
||
|
"test_profile1"
|
||
|
)
|
||
|
instance_profile_arn2, instance_profile_name2 = quick_instance_profile_creation(
|
||
|
"test_profile2"
|
||
|
)
|
||
|
|
||
|
association = client.associate_iam_instance_profile(
|
||
|
IamInstanceProfile={
|
||
|
"Arn": instance_profile_arn1,
|
||
|
"Name": instance_profile_name1,
|
||
|
},
|
||
|
InstanceId=instance_id1,
|
||
|
)
|
||
|
|
||
|
association = client.replace_iam_instance_profile_association(
|
||
|
IamInstanceProfile={
|
||
|
"Arn": instance_profile_arn2,
|
||
|
"Name": instance_profile_name2,
|
||
|
},
|
||
|
AssociationId=association["IamInstanceProfileAssociation"]["AssociationId"],
|
||
|
)
|
||
|
|
||
|
association["IamInstanceProfileAssociation"]["IamInstanceProfile"][
|
||
|
"Arn"
|
||
|
].should.equal(instance_profile_arn2)
|
||
|
association["IamInstanceProfileAssociation"]["State"].should.equal("associating")
|
||
|
|
||
|
|
||
|
@mock_ec2
|
||
|
@mock_iam
|
||
|
def test_invalid_replace():
|
||
|
client = boto3.client("ec2", region_name="us-east-1")
|
||
|
instance_id = quick_instance_creation()
|
||
|
instance_profile_arn, instance_profile_name = quick_instance_profile_creation(
|
||
|
"test_profile"
|
||
|
)
|
||
|
instance_profile_arn2, instance_profile_name2 = quick_instance_profile_creation(
|
||
|
"test_profile2"
|
||
|
)
|
||
|
|
||
|
association = client.associate_iam_instance_profile(
|
||
|
IamInstanceProfile={
|
||
|
"Arn": instance_profile_arn,
|
||
|
"Name": instance_profile_name,
|
||
|
},
|
||
|
InstanceId=instance_id,
|
||
|
)
|
||
|
|
||
|
# Wrong id
|
||
|
with pytest.raises(ClientError) as ex:
|
||
|
client.replace_iam_instance_profile_association(
|
||
|
IamInstanceProfile={
|
||
|
"Arn": instance_profile_arn2,
|
||
|
"Name": instance_profile_name2,
|
||
|
},
|
||
|
AssociationId="fake",
|
||
|
)
|
||
|
ex.value.response["Error"]["Code"].should.equal("InvalidAssociationID.NotFound")
|
||
|
ex.value.response["Error"]["Message"].should.contain("An invalid association-id of")
|
||
|
|
||
|
# Wrong instance profile
|
||
|
with pytest.raises(ClientError) as ex:
|
||
|
client.replace_iam_instance_profile_association(
|
||
|
IamInstanceProfile={"Arn": "fake", "Name": "fake",},
|
||
|
AssociationId=association["IamInstanceProfileAssociation"]["AssociationId"],
|
||
|
)
|
||
|
ex.value.response["Error"]["Code"].should.equal("NoSuchEntity")
|
||
|
ex.value.response["Error"]["Message"].should.contain("not found")
|
||
|
|
||
|
|
||
|
@mock_ec2
|
||
|
@mock_iam
|
||
|
def test_disassociate():
|
||
|
client = boto3.client("ec2", region_name="us-east-1")
|
||
|
instance_id = quick_instance_creation()
|
||
|
instance_profile_arn, instance_profile_name = quick_instance_profile_creation(
|
||
|
"test_profile"
|
||
|
)
|
||
|
|
||
|
association = client.associate_iam_instance_profile(
|
||
|
IamInstanceProfile={
|
||
|
"Arn": instance_profile_arn,
|
||
|
"Name": instance_profile_name,
|
||
|
},
|
||
|
InstanceId=instance_id,
|
||
|
)
|
||
|
|
||
|
associations = client.describe_iam_instance_profile_associations()
|
||
|
associations["IamInstanceProfileAssociations"].should.have.length_of(1)
|
||
|
|
||
|
disassociation = client.disassociate_iam_instance_profile(
|
||
|
AssociationId=association["IamInstanceProfileAssociation"]["AssociationId"],
|
||
|
)
|
||
|
|
||
|
disassociation["IamInstanceProfileAssociation"]["IamInstanceProfile"][
|
||
|
"Arn"
|
||
|
].should.equal(instance_profile_arn)
|
||
|
disassociation["IamInstanceProfileAssociation"]["State"].should.equal(
|
||
|
"disassociating"
|
||
|
)
|
||
|
|
||
|
associations = client.describe_iam_instance_profile_associations()
|
||
|
associations["IamInstanceProfileAssociations"].should.have.length_of(0)
|
||
|
|
||
|
|
||
|
@mock_ec2
|
||
|
@mock_iam
|
||
|
def test_invalid_disassociate():
|
||
|
client = boto3.client("ec2", region_name="us-east-1")
|
||
|
|
||
|
# Wrong id
|
||
|
with pytest.raises(ClientError) as ex:
|
||
|
client.disassociate_iam_instance_profile(AssociationId="fake",)
|
||
|
ex.value.response["Error"]["Code"].should.equal("InvalidAssociationID.NotFound")
|
||
|
ex.value.response["Error"]["Message"].should.contain("An invalid association-id of")
|
||
|
|
||
|
|
||
|
@mock_ec2
|
||
|
@mock_cloudformation
|
||
|
def test_cloudformation():
|
||
|
dummy_template_json = {
|
||
|
"AWSTemplateFormatVersion": "2010-09-09",
|
||
|
"Resources": {
|
||
|
"InstanceProfile": {
|
||
|
"Type": "AWS::IAM::InstanceProfile",
|
||
|
"Properties": {"Path": "/", "Roles": []},
|
||
|
},
|
||
|
"Ec2Instance": {
|
||
|
"Type": "AWS::EC2::Instance",
|
||
|
"Properties": {
|
||
|
"IamInstanceProfile": {"Ref": "InstanceProfile"},
|
||
|
"KeyName": "mykey1",
|
||
|
"ImageId": "ami-7a11e213",
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
}
|
||
|
|
||
|
client = boto3.client("ec2", region_name="us-east-1")
|
||
|
cf_conn = boto3.client("cloudformation", region_name="us-east-1")
|
||
|
cf_conn.create_stack(
|
||
|
StackName="test_stack", TemplateBody=json.dumps(dummy_template_json)
|
||
|
)
|
||
|
associations = client.describe_iam_instance_profile_associations()
|
||
|
associations["IamInstanceProfileAssociations"].should.have.length_of(1)
|
||
|
associations["IamInstanceProfileAssociations"][0]["IamInstanceProfile"][
|
||
|
"Arn"
|
||
|
].should.contain("test_stack")
|
||
|
|
||
|
cf_conn.delete_stack(StackName="test_stack")
|
||
|
associations = client.describe_iam_instance_profile_associations()
|
||
|
associations["IamInstanceProfileAssociations"].should.have.length_of(0)
|