664 lines
22 KiB
Python
664 lines
22 KiB
Python
|
import boto3
|
||
|
import sure # noqa # pylint: disable=unused-import
|
||
|
import pytest
|
||
|
|
||
|
from moto import mock_ec2
|
||
|
from tests import EXAMPLE_AMI_ID
|
||
|
from uuid import uuid4
|
||
|
|
||
|
|
||
|
def get_subnet_id(conn):
|
||
|
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"]
|
||
|
return subnet_id
|
||
|
|
||
|
|
||
|
def get_launch_template(conn, instance_type="t2.micro"):
|
||
|
launch_template = conn.create_launch_template(
|
||
|
LaunchTemplateName="test" + str(uuid4()),
|
||
|
LaunchTemplateData={
|
||
|
"ImageId": EXAMPLE_AMI_ID,
|
||
|
"InstanceType": instance_type,
|
||
|
"KeyName": "test",
|
||
|
"SecurityGroups": ["sg-123456"],
|
||
|
"DisableApiTermination": False,
|
||
|
"TagSpecifications": [
|
||
|
{
|
||
|
"ResourceType": "instance",
|
||
|
"Tags": [
|
||
|
{"Key": "test", "Value": "value"},
|
||
|
{"Key": "Name", "Value": "test"},
|
||
|
],
|
||
|
}
|
||
|
],
|
||
|
},
|
||
|
)["LaunchTemplate"]
|
||
|
launch_template_id = launch_template["LaunchTemplateId"]
|
||
|
launch_template_name = launch_template["LaunchTemplateName"]
|
||
|
return launch_template_id, launch_template_name
|
||
|
|
||
|
|
||
|
@mock_ec2
|
||
|
def test_create_spot_fleet_with_lowest_price():
|
||
|
conn = boto3.client("ec2", region_name="us-west-2")
|
||
|
launch_template_id, _ = get_launch_template(conn)
|
||
|
|
||
|
fleet_res = conn.create_fleet(
|
||
|
ExcessCapacityTerminationPolicy="terminate",
|
||
|
LaunchTemplateConfigs=[
|
||
|
{
|
||
|
"LaunchTemplateSpecification": {
|
||
|
"LaunchTemplateId": launch_template_id,
|
||
|
"Version": "1",
|
||
|
},
|
||
|
},
|
||
|
],
|
||
|
TargetCapacitySpecification={
|
||
|
"DefaultTargetCapacityType": "spot",
|
||
|
"OnDemandTargetCapacity": 0,
|
||
|
"SpotTargetCapacity": 1,
|
||
|
"TotalTargetCapacity": 1,
|
||
|
},
|
||
|
SpotOptions={
|
||
|
"AllocationStrategy": "lowest-price",
|
||
|
},
|
||
|
Type="maintain",
|
||
|
ValidFrom="2020-01-01T00:00:00Z",
|
||
|
ValidUntil="2020-12-31T00:00:00Z",
|
||
|
)
|
||
|
|
||
|
fleet_id = fleet_res["FleetId"]
|
||
|
fleet_id.should.be.a(str)
|
||
|
fleet_id.should.have.length_of(42)
|
||
|
|
||
|
fleets_res = conn.describe_fleets(FleetIds=[fleet_id])
|
||
|
fleets_res.should.have.key("Fleets")
|
||
|
fleets = fleets_res["Fleets"]
|
||
|
|
||
|
fleet = fleets[0]
|
||
|
fleet["FleetState"].should.equal("active")
|
||
|
fleet_config = fleet["LaunchTemplateConfigs"][0]
|
||
|
|
||
|
launch_template_spec = fleet_config["LaunchTemplateSpecification"]
|
||
|
|
||
|
launch_template_spec["LaunchTemplateId"].should.equal(launch_template_id)
|
||
|
launch_template_spec["Version"].should.equal("1")
|
||
|
|
||
|
instance_res = conn.describe_fleet_instances(FleetId=fleet_id)
|
||
|
instances = instance_res["ActiveInstances"]
|
||
|
len(instances).should.equal(1)
|
||
|
|
||
|
|
||
|
@mock_ec2
|
||
|
def test_create_on_demand_fleet():
|
||
|
conn = boto3.client("ec2", region_name="us-west-2")
|
||
|
launch_template_id, _ = get_launch_template(conn)
|
||
|
|
||
|
fleet_res = conn.create_fleet(
|
||
|
ExcessCapacityTerminationPolicy="terminate",
|
||
|
LaunchTemplateConfigs=[
|
||
|
{
|
||
|
"LaunchTemplateSpecification": {
|
||
|
"LaunchTemplateId": launch_template_id,
|
||
|
"Version": "1",
|
||
|
},
|
||
|
},
|
||
|
],
|
||
|
TargetCapacitySpecification={
|
||
|
"DefaultTargetCapacityType": "on-demand",
|
||
|
"OnDemandTargetCapacity": 1,
|
||
|
"SpotTargetCapacity": 0,
|
||
|
"TotalTargetCapacity": 1,
|
||
|
},
|
||
|
OnDemandOptions={
|
||
|
"AllocationStrategy": "lowestPrice",
|
||
|
},
|
||
|
Type="maintain",
|
||
|
ValidFrom="2020-01-01T00:00:00Z",
|
||
|
ValidUntil="2020-12-31T00:00:00Z",
|
||
|
)
|
||
|
|
||
|
fleet_id = fleet_res["FleetId"]
|
||
|
fleet_id.should.be.a(str)
|
||
|
fleet_id.should.have.length_of(42)
|
||
|
|
||
|
fleets_res = conn.describe_fleets(FleetIds=[fleet_id])
|
||
|
fleets_res.should.have.key("Fleets")
|
||
|
fleets = fleets_res["Fleets"]
|
||
|
|
||
|
fleet = fleets[0]
|
||
|
fleet["FleetState"].should.equal("active")
|
||
|
fleet_config = fleet["LaunchTemplateConfigs"][0]
|
||
|
|
||
|
launch_template_spec = fleet_config["LaunchTemplateSpecification"]
|
||
|
|
||
|
launch_template_spec["LaunchTemplateId"].should.equal(launch_template_id)
|
||
|
launch_template_spec["Version"].should.equal("1")
|
||
|
|
||
|
instance_res = conn.describe_fleet_instances(FleetId=fleet_id)
|
||
|
instances = instance_res["ActiveInstances"]
|
||
|
len(instances).should.equal(1)
|
||
|
|
||
|
|
||
|
@mock_ec2
|
||
|
def test_create_diversified_spot_fleet():
|
||
|
conn = boto3.client("ec2", region_name="us-west-2")
|
||
|
launch_template_id_1, _ = get_launch_template(conn, instance_type="t2.small")
|
||
|
launch_template_id_2, _ = get_launch_template(conn, instance_type="t2.large")
|
||
|
|
||
|
fleet_res = conn.create_fleet(
|
||
|
ExcessCapacityTerminationPolicy="terminate",
|
||
|
LaunchTemplateConfigs=[
|
||
|
{
|
||
|
"LaunchTemplateSpecification": {
|
||
|
"LaunchTemplateId": launch_template_id_1,
|
||
|
"Version": "1",
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
"LaunchTemplateSpecification": {
|
||
|
"LaunchTemplateId": launch_template_id_2,
|
||
|
"Version": "1",
|
||
|
},
|
||
|
},
|
||
|
],
|
||
|
TargetCapacitySpecification={
|
||
|
"DefaultTargetCapacityType": "spot",
|
||
|
"OnDemandTargetCapacity": 0,
|
||
|
"SpotTargetCapacity": 2,
|
||
|
"TotalTargetCapacity": 2,
|
||
|
},
|
||
|
SpotOptions={
|
||
|
"AllocationStrategy": "diversified",
|
||
|
},
|
||
|
Type="maintain",
|
||
|
ValidFrom="2020-01-01T00:00:00Z",
|
||
|
ValidUntil="2020-12-31T00:00:00Z",
|
||
|
)
|
||
|
fleet_id = fleet_res["FleetId"]
|
||
|
|
||
|
instance_res = conn.describe_fleet_instances(FleetId=fleet_id)
|
||
|
instances = instance_res["ActiveInstances"]
|
||
|
len(instances).should.equal(2)
|
||
|
instance_types = set([instance["InstanceType"] for instance in instances])
|
||
|
instance_types.should.equal(set(["t2.small", "t2.large"]))
|
||
|
instances[0]["InstanceId"].should.contain("i-")
|
||
|
|
||
|
|
||
|
@mock_ec2
|
||
|
@pytest.mark.parametrize(
|
||
|
"spot_allocation_strategy",
|
||
|
[
|
||
|
"diversified",
|
||
|
"lowest-price",
|
||
|
"capacity-optimized",
|
||
|
"capacity-optimized-prioritized",
|
||
|
],
|
||
|
)
|
||
|
@pytest.mark.parametrize(
|
||
|
"on_demand_allocation_strategy",
|
||
|
["lowestPrice", "prioritized"],
|
||
|
)
|
||
|
def test_request_fleet_using_launch_template_config__name(
|
||
|
spot_allocation_strategy, on_demand_allocation_strategy
|
||
|
):
|
||
|
|
||
|
conn = boto3.client("ec2", region_name="us-east-2")
|
||
|
|
||
|
_, launch_template_name = get_launch_template(conn, instance_type="t2.medium")
|
||
|
|
||
|
fleet_res = conn.create_fleet(
|
||
|
LaunchTemplateConfigs=[
|
||
|
{
|
||
|
"LaunchTemplateSpecification": {
|
||
|
"LaunchTemplateName": launch_template_name,
|
||
|
"Version": "1",
|
||
|
},
|
||
|
},
|
||
|
],
|
||
|
TargetCapacitySpecification={
|
||
|
"DefaultTargetCapacityType": "spot",
|
||
|
"OnDemandTargetCapacity": 1,
|
||
|
"SpotTargetCapacity": 2,
|
||
|
"TotalTargetCapacity": 3,
|
||
|
},
|
||
|
SpotOptions={
|
||
|
"AllocationStrategy": spot_allocation_strategy,
|
||
|
},
|
||
|
OnDemandOptions={
|
||
|
"AllocationStrategy": on_demand_allocation_strategy,
|
||
|
},
|
||
|
Type="maintain",
|
||
|
ValidFrom="2020-01-01T00:00:00Z",
|
||
|
ValidUntil="2020-12-31T00:00:00Z",
|
||
|
)
|
||
|
|
||
|
fleet_id = fleet_res["FleetId"]
|
||
|
|
||
|
instance_res = conn.describe_fleet_instances(FleetId=fleet_id)
|
||
|
instances = instance_res["ActiveInstances"]
|
||
|
len(instances).should.equal(3)
|
||
|
instance_types = set([instance["InstanceType"] for instance in instances])
|
||
|
instance_types.should.equal(set(["t2.medium"]))
|
||
|
instances[0]["InstanceId"].should.contain("i-")
|
||
|
|
||
|
|
||
|
@mock_ec2
|
||
|
def test_create_fleet_request_with_tags():
|
||
|
conn = boto3.client("ec2", region_name="us-west-2")
|
||
|
|
||
|
launch_template_id, _ = get_launch_template(conn)
|
||
|
tags = [
|
||
|
{"Key": "Name", "Value": "test-fleet"},
|
||
|
{"Key": "Another", "Value": "tag"},
|
||
|
]
|
||
|
tags_instance = [
|
||
|
{"Key": "test", "Value": "value"},
|
||
|
{"Key": "Name", "Value": "test"},
|
||
|
]
|
||
|
fleet_res = conn.create_fleet(
|
||
|
DryRun=False,
|
||
|
SpotOptions={
|
||
|
"AllocationStrategy": "lowestPrice",
|
||
|
"InstanceInterruptionBehavior": "terminate",
|
||
|
},
|
||
|
LaunchTemplateConfigs=[
|
||
|
{
|
||
|
"LaunchTemplateSpecification": {
|
||
|
"LaunchTemplateId": launch_template_id,
|
||
|
"Version": "1",
|
||
|
},
|
||
|
},
|
||
|
],
|
||
|
TargetCapacitySpecification={
|
||
|
"DefaultTargetCapacityType": "spot",
|
||
|
"OnDemandTargetCapacity": 1,
|
||
|
"SpotTargetCapacity": 2,
|
||
|
"TotalTargetCapacity": 3,
|
||
|
},
|
||
|
Type="request",
|
||
|
ValidFrom="2020-01-01T00:00:00Z",
|
||
|
ValidUntil="2020-12-31T00:00:00Z",
|
||
|
TagSpecifications=[
|
||
|
{
|
||
|
"ResourceType": "fleet",
|
||
|
"Tags": tags,
|
||
|
},
|
||
|
],
|
||
|
)
|
||
|
fleet_id = fleet_res["FleetId"]
|
||
|
fleets = conn.describe_fleets(FleetIds=[fleet_id])["Fleets"]
|
||
|
|
||
|
fleets[0]["Tags"].should.equal(tags)
|
||
|
|
||
|
instance_res = conn.describe_fleet_instances(FleetId=fleet_id)
|
||
|
instances = conn.describe_instances(
|
||
|
InstanceIds=[i["InstanceId"] for i in instance_res["ActiveInstances"]]
|
||
|
)
|
||
|
for instance in instances["Reservations"][0]["Instances"]:
|
||
|
for tag in tags_instance:
|
||
|
instance["Tags"].should.contain(tag)
|
||
|
|
||
|
|
||
|
@mock_ec2
|
||
|
def test_create_fleet_using_launch_template_config__overrides():
|
||
|
|
||
|
conn = boto3.client("ec2", region_name="us-east-2")
|
||
|
subnet_id = get_subnet_id(conn)
|
||
|
|
||
|
template_id, _ = get_launch_template(conn, instance_type="t2.medium")
|
||
|
|
||
|
template_config_overrides = [
|
||
|
{
|
||
|
"InstanceType": "t2.nano",
|
||
|
"SubnetId": subnet_id,
|
||
|
"AvailabilityZone": "us-west-1",
|
||
|
"WeightedCapacity": 2,
|
||
|
}
|
||
|
]
|
||
|
|
||
|
fleet_res = conn.create_fleet(
|
||
|
LaunchTemplateConfigs=[
|
||
|
{
|
||
|
"LaunchTemplateSpecification": {
|
||
|
"LaunchTemplateId": template_id,
|
||
|
"Version": "1",
|
||
|
},
|
||
|
"Overrides": template_config_overrides,
|
||
|
},
|
||
|
],
|
||
|
TargetCapacitySpecification={
|
||
|
"DefaultTargetCapacityType": "spot",
|
||
|
"OnDemandTargetCapacity": 1,
|
||
|
"SpotTargetCapacity": 0,
|
||
|
"TotalTargetCapacity": 1,
|
||
|
},
|
||
|
SpotOptions={
|
||
|
"AllocationStrategy": "lowest-price",
|
||
|
"InstanceInterruptionBehavior": "terminate",
|
||
|
},
|
||
|
Type="maintain",
|
||
|
ValidFrom="2020-01-01T00:00:00Z",
|
||
|
ValidUntil="2020-12-31T00:00:00Z",
|
||
|
)
|
||
|
fleet_id = fleet_res["FleetId"]
|
||
|
|
||
|
instance_res = conn.describe_fleet_instances(FleetId=fleet_id)
|
||
|
instances = instance_res["ActiveInstances"]
|
||
|
instances.should.have.length_of(1)
|
||
|
instances[0].should.have.key("InstanceType").equals("t2.nano")
|
||
|
|
||
|
instance = conn.describe_instances(
|
||
|
InstanceIds=[i["InstanceId"] for i in instances]
|
||
|
)["Reservations"][0]["Instances"][0]
|
||
|
instance.should.have.key("SubnetId").equals(subnet_id)
|
||
|
|
||
|
|
||
|
@mock_ec2
|
||
|
def test_delete_fleet():
|
||
|
conn = boto3.client("ec2", region_name="us-west-2")
|
||
|
|
||
|
launch_template_id, _ = get_launch_template(conn)
|
||
|
|
||
|
fleet_res = conn.create_fleet(
|
||
|
LaunchTemplateConfigs=[
|
||
|
{
|
||
|
"LaunchTemplateSpecification": {
|
||
|
"LaunchTemplateId": launch_template_id,
|
||
|
"Version": "1",
|
||
|
},
|
||
|
},
|
||
|
],
|
||
|
TargetCapacitySpecification={
|
||
|
"DefaultTargetCapacityType": "spot",
|
||
|
"OnDemandTargetCapacity": 1,
|
||
|
"SpotTargetCapacity": 2,
|
||
|
"TotalTargetCapacity": 3,
|
||
|
},
|
||
|
SpotOptions={
|
||
|
"AllocationStrategy": "lowestPrice",
|
||
|
"InstanceInterruptionBehavior": "terminate",
|
||
|
},
|
||
|
Type="maintain",
|
||
|
ValidFrom="2020-01-01T00:00:00Z",
|
||
|
ValidUntil="2020-12-31T00:00:00Z",
|
||
|
)
|
||
|
fleet_id = fleet_res["FleetId"]
|
||
|
|
||
|
delete_fleet_out = conn.delete_fleets(FleetIds=[fleet_id], TerminateInstances=True)
|
||
|
|
||
|
delete_fleet_out["SuccessfulFleetDeletions"].should.have.length_of(1)
|
||
|
delete_fleet_out["SuccessfulFleetDeletions"][0]["FleetId"].should.equal(fleet_id)
|
||
|
delete_fleet_out["SuccessfulFleetDeletions"][0]["CurrentFleetState"].should.equal(
|
||
|
"deleted"
|
||
|
)
|
||
|
|
||
|
fleets = conn.describe_fleets(FleetIds=[fleet_id])["Fleets"]
|
||
|
len(fleets).should.equal(1)
|
||
|
|
||
|
target_capacity_specification = fleets[0]["TargetCapacitySpecification"]
|
||
|
target_capacity_specification.should.have.key("TotalTargetCapacity").equals(0)
|
||
|
fleets[0]["FleetState"].should.equal("deleted")
|
||
|
|
||
|
# Instances should be terminated
|
||
|
instance_res = conn.describe_fleet_instances(FleetId=fleet_id)
|
||
|
instances = instance_res["ActiveInstances"]
|
||
|
len(instances).should.equal(0)
|
||
|
|
||
|
|
||
|
@mock_ec2
|
||
|
def test_describe_fleet_instences_api():
|
||
|
conn = boto3.client("ec2", region_name="us-west-1")
|
||
|
|
||
|
launch_template_id, _ = get_launch_template(conn)
|
||
|
|
||
|
fleet_res = conn.create_fleet(
|
||
|
LaunchTemplateConfigs=[
|
||
|
{
|
||
|
"LaunchTemplateSpecification": {
|
||
|
"LaunchTemplateId": launch_template_id,
|
||
|
"Version": "1",
|
||
|
},
|
||
|
},
|
||
|
],
|
||
|
TargetCapacitySpecification={
|
||
|
"DefaultTargetCapacityType": "spot",
|
||
|
"OnDemandTargetCapacity": 1,
|
||
|
"SpotTargetCapacity": 2,
|
||
|
"TotalTargetCapacity": 3,
|
||
|
},
|
||
|
SpotOptions={
|
||
|
"AllocationStrategy": "lowestPrice",
|
||
|
"InstanceInterruptionBehavior": "terminate",
|
||
|
},
|
||
|
Type="maintain",
|
||
|
ValidFrom="2020-01-01T00:00:00Z",
|
||
|
ValidUntil="2020-12-31T00:00:00Z",
|
||
|
)
|
||
|
|
||
|
fleet_id = fleet_res["FleetId"]
|
||
|
fleet_res = conn.describe_fleet_instances(FleetId=fleet_id)
|
||
|
|
||
|
fleet_res["FleetId"].should.equal(fleet_id)
|
||
|
fleet_res["ActiveInstances"].should.have.length_of(3)
|
||
|
|
||
|
instance_ids = [i["InstanceId"] for i in fleet_res["ActiveInstances"]]
|
||
|
for instance_id in instance_ids:
|
||
|
instance_id.startswith("i-").should.be.true
|
||
|
|
||
|
instance_types = [i["InstanceType"] for i in fleet_res["ActiveInstances"]]
|
||
|
instance_types.should.equal(["t2.micro", "t2.micro", "t2.micro"])
|
||
|
|
||
|
instance_healths = [i["InstanceHealth"] for i in fleet_res["ActiveInstances"]]
|
||
|
instance_healths.should.equal(["healthy", "healthy", "healthy"])
|
||
|
|
||
|
|
||
|
@mock_ec2
|
||
|
def test_create_fleet_api():
|
||
|
conn = boto3.client("ec2", region_name="us-west-1")
|
||
|
|
||
|
launch_template_id, _ = get_launch_template(conn)
|
||
|
|
||
|
fleet_res = conn.create_fleet(
|
||
|
LaunchTemplateConfigs=[
|
||
|
{
|
||
|
"LaunchTemplateSpecification": {
|
||
|
"LaunchTemplateId": launch_template_id,
|
||
|
"Version": "1",
|
||
|
},
|
||
|
},
|
||
|
],
|
||
|
TargetCapacitySpecification={
|
||
|
"DefaultTargetCapacityType": "spot",
|
||
|
"OnDemandTargetCapacity": 1,
|
||
|
"SpotTargetCapacity": 2,
|
||
|
"TotalTargetCapacity": 3,
|
||
|
},
|
||
|
SpotOptions={
|
||
|
"AllocationStrategy": "lowestPrice",
|
||
|
"InstanceInterruptionBehavior": "terminate",
|
||
|
},
|
||
|
Type="instant",
|
||
|
ValidFrom="2020-01-01T00:00:00Z",
|
||
|
ValidUntil="2020-12-31T00:00:00Z",
|
||
|
)
|
||
|
|
||
|
fleet_res.should.have.key("FleetId")
|
||
|
fleet_res["FleetId"].startswith("fleet-").should.be.true
|
||
|
|
||
|
fleet_res.should.have.key("Instances")
|
||
|
fleet_res["Instances"].should.have.length_of(3)
|
||
|
|
||
|
instance_ids = [i["InstanceIds"] for i in fleet_res["Instances"]]
|
||
|
for instance_id in instance_ids:
|
||
|
instance_id[0].startswith("i-").should.be.true
|
||
|
|
||
|
instance_types = [i["InstanceType"] for i in fleet_res["Instances"]]
|
||
|
instance_types.should.equal(["t2.micro", "t2.micro", "t2.micro"])
|
||
|
|
||
|
lifecycle = [i["Lifecycle"] for i in fleet_res["Instances"]]
|
||
|
lifecycle.should.contain("spot")
|
||
|
lifecycle.should.contain("on-demand")
|
||
|
|
||
|
|
||
|
@mock_ec2
|
||
|
def test_create_fleet_api_response():
|
||
|
conn = boto3.client("ec2", region_name="us-west-2")
|
||
|
subnet_id = get_subnet_id(conn)
|
||
|
|
||
|
launch_template_id, _ = get_launch_template(conn)
|
||
|
|
||
|
lt_config = {
|
||
|
"LaunchTemplateSpecification": {
|
||
|
"LaunchTemplateId": launch_template_id,
|
||
|
"Version": "1",
|
||
|
},
|
||
|
"Overrides": [
|
||
|
{
|
||
|
"AvailabilityZone": "us-west-1a",
|
||
|
"InstanceRequirements": {
|
||
|
"AcceleratorCount": {
|
||
|
"Max": 10,
|
||
|
"Min": 1,
|
||
|
},
|
||
|
"AcceleratorManufacturers": ["nvidia"],
|
||
|
"AcceleratorNames": ["t4"],
|
||
|
"AcceleratorTotalMemoryMiB": {
|
||
|
"Max": 20972,
|
||
|
"Min": 1,
|
||
|
},
|
||
|
"AcceleratorTypes": ["gpu"],
|
||
|
"BareMetal": "included",
|
||
|
"BaselineEbsBandwidthMbps": {
|
||
|
"Max": 10000,
|
||
|
"Min": 125,
|
||
|
},
|
||
|
"BurstablePerformance": "included",
|
||
|
"CpuManufacturers": ["amd", "intel"],
|
||
|
"ExcludedInstanceTypes": ["m5.8xlarge"],
|
||
|
"InstanceGenerations": ["current"],
|
||
|
"LocalStorage": "included",
|
||
|
"LocalStorageTypes": ["ssd"],
|
||
|
"MemoryGiBPerVCpu": {
|
||
|
"Min": 1,
|
||
|
"Max": 160,
|
||
|
},
|
||
|
"MemoryMiB": {
|
||
|
"Min": 2048,
|
||
|
"Max": 40960,
|
||
|
},
|
||
|
"NetworkInterfaceCount": {
|
||
|
"Max": 1,
|
||
|
"Min": 1,
|
||
|
},
|
||
|
"OnDemandMaxPricePercentageOverLowestPrice": 99999,
|
||
|
"RequireHibernateSupport": True,
|
||
|
"SpotMaxPricePercentageOverLowestPrice": 99999,
|
||
|
"TotalLocalStorageGB": {
|
||
|
"Min": 100,
|
||
|
"Max": 10000,
|
||
|
},
|
||
|
"VCpuCount": {
|
||
|
"Min": 2,
|
||
|
"Max": 160,
|
||
|
},
|
||
|
},
|
||
|
"MaxPrice": "0.5",
|
||
|
"Priority": 2,
|
||
|
"SubnetId": subnet_id,
|
||
|
"WeightedCapacity": 1,
|
||
|
},
|
||
|
],
|
||
|
}
|
||
|
|
||
|
fleet_res = conn.create_fleet(
|
||
|
ExcessCapacityTerminationPolicy="no-termination",
|
||
|
LaunchTemplateConfigs=[lt_config],
|
||
|
TargetCapacitySpecification={
|
||
|
"DefaultTargetCapacityType": "on-demand",
|
||
|
"OnDemandTargetCapacity": 10,
|
||
|
"SpotTargetCapacity": 10,
|
||
|
"TotalTargetCapacity": 30,
|
||
|
},
|
||
|
SpotOptions={
|
||
|
"AllocationStrategy": "lowest-price",
|
||
|
"InstanceInterruptionBehavior": "terminate",
|
||
|
"InstancePoolsToUseCount": 1,
|
||
|
"MaintenanceStrategies": {
|
||
|
"CapacityRebalance": {
|
||
|
"ReplacementStrategy": "launch-before-terminate",
|
||
|
"TerminationDelay": 120,
|
||
|
},
|
||
|
},
|
||
|
"MaxTotalPrice": "50",
|
||
|
"MinTargetCapacity": 1,
|
||
|
"SingleAvailabilityZone": True,
|
||
|
"SingleInstanceType": True,
|
||
|
},
|
||
|
OnDemandOptions={
|
||
|
"AllocationStrategy": "lowest-price",
|
||
|
"MaxTotalPrice": "50",
|
||
|
"MinTargetCapacity": 1,
|
||
|
"SingleAvailabilityZone": True,
|
||
|
"SingleInstanceType": True,
|
||
|
},
|
||
|
ReplaceUnhealthyInstances=True,
|
||
|
TerminateInstancesWithExpiration=True,
|
||
|
Type="maintain",
|
||
|
ValidFrom="2020-01-01T00:00:00Z",
|
||
|
ValidUntil="2020-12-31T00:00:00Z",
|
||
|
)
|
||
|
fleet_id = fleet_res["FleetId"]
|
||
|
|
||
|
fleet_res = conn.describe_fleets(FleetIds=[fleet_id])["Fleets"]
|
||
|
fleet_res.should.have.length_of(1)
|
||
|
fleet_res[0].should.have.key("FleetId").equals(fleet_id)
|
||
|
fleet_res[0].should.have.key("ExcessCapacityTerminationPolicy").equals(
|
||
|
"no-termination"
|
||
|
)
|
||
|
fleet_res[0].should.have.key("LaunchTemplateConfigs").equals([lt_config])
|
||
|
fleet_res[0].should.have.key("TargetCapacitySpecification").equals(
|
||
|
{
|
||
|
"DefaultTargetCapacityType": "on-demand",
|
||
|
"OnDemandTargetCapacity": 10,
|
||
|
"SpotTargetCapacity": 10,
|
||
|
"TotalTargetCapacity": 30,
|
||
|
}
|
||
|
)
|
||
|
fleet_res[0].should.have.key("SpotOptions").equals(
|
||
|
{
|
||
|
"AllocationStrategy": "lowest-price",
|
||
|
"InstanceInterruptionBehavior": "terminate",
|
||
|
"InstancePoolsToUseCount": 1,
|
||
|
"MaintenanceStrategies": {
|
||
|
"CapacityRebalance": {
|
||
|
"ReplacementStrategy": "launch-before-terminate",
|
||
|
"TerminationDelay": 120,
|
||
|
},
|
||
|
},
|
||
|
"MaxTotalPrice": "50",
|
||
|
"MinTargetCapacity": 1,
|
||
|
"SingleAvailabilityZone": True,
|
||
|
"SingleInstanceType": True,
|
||
|
}
|
||
|
)
|
||
|
fleet_res[0].should.have.key("OnDemandOptions").equals(
|
||
|
{
|
||
|
"AllocationStrategy": "lowest-price",
|
||
|
"MaxTotalPrice": "50",
|
||
|
"MinTargetCapacity": 1,
|
||
|
"SingleAvailabilityZone": True,
|
||
|
"SingleInstanceType": True,
|
||
|
}
|
||
|
)
|
||
|
fleet_res[0].should.have.key("ReplaceUnhealthyInstances").equals(True)
|
||
|
fleet_res[0].should.have.key("TerminateInstancesWithExpiration").equals(True)
|
||
|
fleet_res[0].should.have.key("Type").equals("maintain")
|
||
|
fleet_res[0].should.have.key("ValidFrom")
|
||
|
fleet_res[0]["ValidFrom"].isoformat().should.equal("2020-01-01T00:00:00+00:00")
|
||
|
fleet_res[0].should.have.key("ValidUntil")
|
||
|
fleet_res[0]["ValidUntil"].isoformat().should.equal("2020-12-31T00:00:00+00:00")
|