228 lines
7.7 KiB
Python
228 lines
7.7 KiB
Python
import boto3
|
|
import pytest
|
|
from botocore.exceptions import ClientError
|
|
|
|
from moto import mock_ec2, mock_opsworks
|
|
from tests import EXAMPLE_AMI_ID
|
|
|
|
|
|
@mock_opsworks
|
|
def test_create_instance():
|
|
client = boto3.client("opsworks", region_name="us-east-1")
|
|
stack_id = client.create_stack(
|
|
Name="test_stack_1",
|
|
Region="us-east-1",
|
|
ServiceRoleArn="service_arn",
|
|
DefaultInstanceProfileArn="profile_arn",
|
|
)["StackId"]
|
|
|
|
layer_id = client.create_layer(
|
|
StackId=stack_id,
|
|
Type="custom",
|
|
Name="TestLayer",
|
|
Shortname="TestLayerShortName",
|
|
)["LayerId"]
|
|
|
|
second_stack_id = client.create_stack(
|
|
Name="test_stack_2",
|
|
Region="us-east-1",
|
|
ServiceRoleArn="service_arn",
|
|
DefaultInstanceProfileArn="profile_arn",
|
|
)["StackId"]
|
|
|
|
second_layer_id = client.create_layer(
|
|
StackId=second_stack_id,
|
|
Type="custom",
|
|
Name="SecondTestLayer",
|
|
Shortname="SecondTestLayerShortName",
|
|
)["LayerId"]
|
|
|
|
response = client.create_instance(
|
|
StackId=stack_id, LayerIds=[layer_id], InstanceType="t2.micro"
|
|
)
|
|
|
|
assert "InstanceId" in response
|
|
|
|
with pytest.raises(ClientError) as exc:
|
|
client.create_instance(
|
|
StackId="nothere", LayerIds=[layer_id], InstanceType="t2.micro"
|
|
)
|
|
assert exc.value.response["Error"]["Message"] == (
|
|
"Unable to find stack with ID nothere"
|
|
)
|
|
|
|
with pytest.raises(ClientError) as exc:
|
|
client.create_instance(
|
|
StackId=stack_id, LayerIds=["nothere"], InstanceType="t2.micro"
|
|
)
|
|
assert exc.value.response["Error"]["Message"] == "nothere"
|
|
|
|
# ClientError
|
|
with pytest.raises(ClientError) as exc:
|
|
client.create_instance(
|
|
StackId=stack_id, LayerIds=[second_layer_id], InstanceType="t2.micro"
|
|
)
|
|
assert exc.value.response["Error"]["Message"] == (
|
|
"Please only provide layer IDs from the same stack"
|
|
)
|
|
|
|
# ClientError
|
|
with pytest.raises(ClientError) as exc:
|
|
client.start_instance(InstanceId="nothere")
|
|
assert exc.value.response["Error"]["Message"] == (
|
|
"Unable to find instance with ID nothere"
|
|
)
|
|
|
|
|
|
@mock_opsworks
|
|
def test_describe_instances():
|
|
"""
|
|
create two stacks, with 1 layer and 2 layers (S1L1, S2L1, S2L2)
|
|
|
|
populate S1L1 with 2 instances (S1L1_i1, S1L1_i2)
|
|
populate S2L1 with 1 instance (S2L1_i1)
|
|
populate S2L2 with 3 instances (S2L2_i1..2)
|
|
"""
|
|
|
|
client = boto3.client("opsworks", region_name="us-east-1")
|
|
S1 = client.create_stack(
|
|
Name="S1",
|
|
Region="us-east-1",
|
|
ServiceRoleArn="service_arn",
|
|
DefaultInstanceProfileArn="profile_arn",
|
|
)["StackId"]
|
|
S1L1 = client.create_layer(
|
|
StackId=S1, Type="custom", Name="S1L1", Shortname="S1L1"
|
|
)["LayerId"]
|
|
S2 = client.create_stack(
|
|
Name="S2",
|
|
Region="us-east-1",
|
|
ServiceRoleArn="service_arn",
|
|
DefaultInstanceProfileArn="profile_arn",
|
|
)["StackId"]
|
|
S2L1 = client.create_layer(
|
|
StackId=S2, Type="custom", Name="S2L1", Shortname="S2L1"
|
|
)["LayerId"]
|
|
S2L2 = client.create_layer(
|
|
StackId=S2, Type="custom", Name="S2L2", Shortname="S2L2"
|
|
)["LayerId"]
|
|
|
|
S1L1_i1 = client.create_instance(
|
|
StackId=S1, LayerIds=[S1L1], InstanceType="t2.micro"
|
|
)["InstanceId"]
|
|
S1L1_i2 = client.create_instance(
|
|
StackId=S1, LayerIds=[S1L1], InstanceType="t2.micro"
|
|
)["InstanceId"]
|
|
S2L1_i1 = client.create_instance(
|
|
StackId=S2, LayerIds=[S2L1], InstanceType="t2.micro"
|
|
)["InstanceId"]
|
|
S2L2_i1 = client.create_instance(
|
|
StackId=S2, LayerIds=[S2L2], InstanceType="t2.micro"
|
|
)["InstanceId"]
|
|
S2L2_i2 = client.create_instance(
|
|
StackId=S2, LayerIds=[S2L2], InstanceType="t2.micro"
|
|
)["InstanceId"]
|
|
|
|
# instances in Stack 1
|
|
response = client.describe_instances(StackId=S1)["Instances"]
|
|
assert len(response) == 2
|
|
assert S1L1_i1 in [i["InstanceId"] for i in response]
|
|
assert S1L1_i2 in [i["InstanceId"] for i in response]
|
|
|
|
response2 = client.describe_instances(InstanceIds=[S1L1_i1, S1L1_i2])["Instances"]
|
|
assert sorted(response2, key=lambda d: d["InstanceId"]) == (
|
|
sorted(response, key=lambda d: d["InstanceId"])
|
|
)
|
|
|
|
response3 = client.describe_instances(LayerId=S1L1)["Instances"]
|
|
assert sorted(response3, key=lambda d: d["InstanceId"]) == (
|
|
sorted(response, key=lambda d: d["InstanceId"])
|
|
)
|
|
|
|
response = client.describe_instances(StackId=S1)["Instances"]
|
|
assert len(response) == 2
|
|
assert S1L1_i1 in [i["InstanceId"] for i in response]
|
|
assert S1L1_i2 in [i["InstanceId"] for i in response]
|
|
|
|
# instances in Stack 2
|
|
response = client.describe_instances(StackId=S2)["Instances"]
|
|
assert len(response) == 3
|
|
assert S2L1_i1 in [i["InstanceId"] for i in response]
|
|
assert S2L2_i1 in [i["InstanceId"] for i in response]
|
|
assert S2L2_i2 in [i["InstanceId"] for i in response]
|
|
|
|
response = client.describe_instances(LayerId=S2L1)["Instances"]
|
|
assert len(response) == 1
|
|
assert S2L1_i1 in [i["InstanceId"] for i in response]
|
|
|
|
response = client.describe_instances(LayerId=S2L2)["Instances"]
|
|
assert len(response) == 2
|
|
assert S2L1_i1 not in [i["InstanceId"] for i in response]
|
|
|
|
# ClientError
|
|
with pytest.raises(ClientError) as exc:
|
|
client.describe_instances(StackId=S1, LayerId=S1L1)
|
|
assert "Please provide either one or more" in exc.value.response["Error"]["Message"]
|
|
|
|
# ClientError
|
|
with pytest.raises(ClientError) as exc:
|
|
client.describe_instances(StackId="nothere")
|
|
assert "nothere" in exc.value.response["Error"]["Message"]
|
|
|
|
# ClientError
|
|
with pytest.raises(ClientError) as exc:
|
|
client.describe_instances(LayerId="nothere")
|
|
assert "nothere" in exc.value.response["Error"]["Message"]
|
|
|
|
# ClientError
|
|
with pytest.raises(ClientError) as exc:
|
|
client.describe_instances(InstanceIds=["nothere"])
|
|
assert exc.value.response["Error"]["Message"] == "nothere"
|
|
|
|
|
|
@mock_opsworks
|
|
@mock_ec2
|
|
def test_ec2_integration():
|
|
"""Verify instances created via OpsWorks are discoverable via ec2."""
|
|
opsworks = boto3.client("opsworks", region_name="us-east-1")
|
|
stack_id = opsworks.create_stack(
|
|
Name="S1",
|
|
Region="us-east-1",
|
|
ServiceRoleArn="service_arn",
|
|
DefaultInstanceProfileArn="profile_arn",
|
|
)["StackId"]
|
|
|
|
layer_id = opsworks.create_layer(
|
|
StackId=stack_id, Type="custom", Name="S1L1", Shortname="S1L1"
|
|
)["LayerId"]
|
|
|
|
instance_id = opsworks.create_instance(
|
|
AmiId=EXAMPLE_AMI_ID,
|
|
StackId=stack_id,
|
|
LayerIds=[layer_id],
|
|
InstanceType="t2.micro",
|
|
SshKeyName="testSSH",
|
|
)["InstanceId"]
|
|
|
|
ec2 = boto3.client("ec2", region_name="us-east-1")
|
|
|
|
# Before starting the instance, it shouldn't be discoverable via ec2
|
|
reservations = ec2.describe_instances()["Reservations"]
|
|
assert not reservations
|
|
|
|
# Before starting the instance, its status should be "stopped"
|
|
opsworks_instance = opsworks.describe_instances(StackId=stack_id)["Instances"][0]
|
|
assert opsworks_instance["Status"] == "stopped"
|
|
|
|
# After starting the instance, it should be discoverable via ec2
|
|
opsworks.start_instance(InstanceId=instance_id)
|
|
reservations = ec2.describe_instances()["Reservations"]
|
|
assert len(reservations[0]["Instances"]) == 1
|
|
instance = reservations[0]["Instances"][0]
|
|
opsworks_instance = opsworks.describe_instances(StackId=stack_id)["Instances"][0]
|
|
|
|
assert instance["InstanceId"] == opsworks_instance["Ec2InstanceId"]
|
|
assert instance["PrivateIpAddress"] == opsworks_instance["PrivateIp"]
|
|
# After starting the instance, its status should be "online"
|
|
assert opsworks_instance["Status"] == "online"
|