moto/tests/test_elb/test_elb.py

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

1124 lines
38 KiB
Python
Raw Normal View History

from uuid import uuid4
import boto3
import pytest
from botocore.exceptions import ClientError
2024-01-07 12:03:33 +00:00
from moto import mock_aws
2022-08-13 09:49:43 +00:00
from moto.core import DEFAULT_ACCOUNT_ID
from tests import EXAMPLE_AMI_ID
2013-07-23 02:50:58 +00:00
2017-02-24 02:37:43 +00:00
2021-09-24 20:00:10 +00:00
@pytest.mark.parametrize("region_name", ["us-east-1", "ap-south-1"])
2022-03-21 20:55:19 +00:00
@pytest.mark.parametrize("zones", [["a"], ["a", "b"]])
2024-01-07 12:03:33 +00:00
@mock_aws
2022-03-21 20:55:19 +00:00
def test_create_load_balancer(zones, region_name):
zones = [f"{region_name}{z}" for z in zones]
2021-09-24 20:00:10 +00:00
# Both regions and availability zones are parametrized
# This does not seem to have an effect on the DNS name
client = boto3.client("elb", region_name=region_name)
ec2 = boto3.resource("ec2", region_name=region_name)
security_group = ec2.create_security_group(
GroupName="sg01", Description="Test security group sg01"
)
lb = client.create_load_balancer(
LoadBalancerName="my-lb",
Listeners=[
{"Protocol": "tcp", "LoadBalancerPort": 80, "InstancePort": 8080},
{"Protocol": "http", "LoadBalancerPort": 81, "InstancePort": 9000},
],
AvailabilityZones=zones,
Scheme="internal",
SecurityGroups=[security_group.id],
)
assert lb["DNSName"] == "my-lb.us-east-1.elb.amazonaws.com"
2021-09-24 20:00:10 +00:00
describe = client.describe_load_balancers(LoadBalancerNames=["my-lb"])[
"LoadBalancerDescriptions"
][0]
assert describe["LoadBalancerName"] == "my-lb"
assert describe["DNSName"] == "my-lb.us-east-1.elb.amazonaws.com"
assert describe["CanonicalHostedZoneName"] == "my-lb.us-east-1.elb.amazonaws.com"
assert describe["AvailabilityZones"] == zones
assert "VPCId" in describe
assert len(describe["Subnets"]) == len(zones) # Default subnet for each zone
assert describe["SecurityGroups"] == [security_group.id]
assert describe["Scheme"] == "internal"
2021-09-24 20:00:10 +00:00
assert len(describe["ListenerDescriptions"]) == 2
2021-09-24 20:00:10 +00:00
tcp = [
2022-04-27 11:58:59 +00:00
desc["Listener"]
for desc in describe["ListenerDescriptions"]
if desc["Listener"]["Protocol"] == "TCP"
2021-09-24 20:00:10 +00:00
][0]
http = [
2022-04-27 11:58:59 +00:00
desc["Listener"]
for desc in describe["ListenerDescriptions"]
if desc["Listener"]["Protocol"] == "HTTP"
2021-09-24 20:00:10 +00:00
][0]
assert tcp == {
"Protocol": "TCP",
"LoadBalancerPort": 80,
"InstanceProtocol": "TCP",
"InstancePort": 8080,
"SSLCertificateId": "None",
}
assert http == {
"Protocol": "HTTP",
"LoadBalancerPort": 81,
"InstanceProtocol": "HTTP",
"InstancePort": 9000,
"SSLCertificateId": "None",
}
2021-09-24 20:00:10 +00:00
2024-01-07 12:03:33 +00:00
@mock_aws
2022-03-21 20:55:19 +00:00
def test_get_missing_elb():
2021-09-24 20:00:10 +00:00
client = boto3.client("elb", region_name="us-west-2")
with pytest.raises(ClientError) as ex:
client.describe_load_balancers(LoadBalancerNames=["unknown-lb"])
err = ex.value.response["Error"]
assert err["Code"] == "LoadBalancerNotFound"
assert err["Message"] == "The specified load balancer does not exist: unknown-lb"
2021-09-24 20:00:10 +00:00
2024-01-07 12:03:33 +00:00
@mock_aws
2022-03-21 20:55:19 +00:00
def test_create_elb_in_multiple_region():
2021-09-24 20:00:10 +00:00
client_east = boto3.client("elb", region_name="us-east-2")
client_west = boto3.client("elb", region_name="us-west-2")
name_east = str(uuid4())[0:6]
name_west = str(uuid4())[0:6]
client_east.create_load_balancer(
LoadBalancerName=name_east,
Listeners=[{"Protocol": "tcp", "LoadBalancerPort": 80, "InstancePort": 8080}],
2022-03-21 20:55:19 +00:00
AvailabilityZones=["us-east-2a"],
2021-09-24 20:00:10 +00:00
)
client_west.create_load_balancer(
LoadBalancerName=name_west,
Listeners=[{"Protocol": "tcp", "LoadBalancerPort": 80, "InstancePort": 8080}],
2022-03-21 20:55:19 +00:00
AvailabilityZones=["us-west-2a"],
2021-09-24 20:00:10 +00:00
)
east_names = [
lb["LoadBalancerName"]
for lb in client_east.describe_load_balancers()["LoadBalancerDescriptions"]
]
assert name_east in east_names
assert name_west not in east_names
2021-09-24 20:00:10 +00:00
west_names = [
lb["LoadBalancerName"]
for lb in client_west.describe_load_balancers()["LoadBalancerDescriptions"]
]
assert name_west in west_names
assert name_east not in west_names
2021-09-24 20:00:10 +00:00
2024-01-07 12:03:33 +00:00
@mock_aws
2022-03-21 20:55:19 +00:00
def test_create_load_balancer_with_certificate():
2021-10-14 21:43:10 +00:00
acm_client = boto3.client("acm", region_name="us-east-2")
acm_request_response = acm_client.request_certificate(
DomainName="fake.domain.com",
DomainValidationOptions=[
{"DomainName": "fake.domain.com", "ValidationDomain": "domain.com"},
],
)
certificate_arn = acm_request_response["CertificateArn"]
2021-09-24 20:00:10 +00:00
client = boto3.client("elb", region_name="us-east-2")
name = str(uuid4())[0:6]
client.create_load_balancer(
LoadBalancerName=name,
Listeners=[
{
"Protocol": "https",
"LoadBalancerPort": 8443,
"InstancePort": 443,
2021-10-14 21:43:10 +00:00
"SSLCertificateId": certificate_arn,
2021-09-24 20:00:10 +00:00
}
],
2022-03-21 20:55:19 +00:00
AvailabilityZones=["us-east-2a"],
2021-09-24 20:00:10 +00:00
)
describe = client.describe_load_balancers(LoadBalancerNames=[name])[
"LoadBalancerDescriptions"
][0]
assert describe["Scheme"] == "internet-facing"
2021-09-24 20:00:10 +00:00
listener = describe["ListenerDescriptions"][0]["Listener"]
assert listener["Protocol"] == "HTTPS"
assert listener["SSLCertificateId"] == certificate_arn
2021-10-14 21:43:10 +00:00
2024-01-07 12:03:33 +00:00
@mock_aws
2021-10-14 21:43:10 +00:00
def test_create_load_balancer_with_invalid_certificate():
client = boto3.client("elb", region_name="us-east-2")
name = str(uuid4())[0:6]
with pytest.raises(ClientError) as exc:
client.create_load_balancer(
LoadBalancerName=name,
Listeners=[
{
"Protocol": "https",
"LoadBalancerPort": 8443,
"InstancePort": 443,
"SSLCertificateId": "invalid_arn",
}
],
2022-03-21 20:55:19 +00:00
AvailabilityZones=["us-east-2a"],
2021-10-14 21:43:10 +00:00
)
err = exc.value.response["Error"]
assert err["Code"] == "CertificateNotFoundException"
2021-09-24 20:00:10 +00:00
2024-01-07 12:03:33 +00:00
@mock_aws
2022-03-21 20:55:19 +00:00
def test_create_and_delete_load_balancer():
client = boto3.client("elb", region_name="us-east-1")
client.create_load_balancer(
LoadBalancerName="my-lb",
2017-02-24 02:37:43 +00:00
Listeners=[{"Protocol": "tcp", "LoadBalancerPort": 80, "InstancePort": 8080}],
AvailabilityZones=["us-east-1a", "us-east-1b"],
)
assert len(client.describe_load_balancers()["LoadBalancerDescriptions"]) == 1
client.delete_load_balancer(LoadBalancerName="my-lb")
assert len(client.describe_load_balancers()["LoadBalancerDescriptions"]) == 0
2017-02-24 02:37:43 +00:00
2024-01-07 12:03:33 +00:00
@mock_aws
def test_create_load_balancer_with_no_listeners_defined():
client = boto3.client("elb", region_name="us-east-1")
with pytest.raises(ClientError):
client.create_load_balancer(
LoadBalancerName="my-lb",
Listeners=[],
AvailabilityZones=["us-east-1a", "us-east-1b"],
)
2024-01-07 12:03:33 +00:00
@mock_aws
2022-03-21 20:55:19 +00:00
def test_create_load_balancer_without_security_groups():
lb_name = str(uuid4())[0:6]
client = boto3.client("elb", region_name="us-east-1")
ec2 = boto3.client("ec2", region_name="us-east-1")
client.create_load_balancer(
LoadBalancerName=lb_name,
AvailabilityZones=["us-east-1a"],
Listeners=[{"Protocol": "tcp", "LoadBalancerPort": 80, "InstancePort": 8080}],
)
describe = client.describe_load_balancers(LoadBalancerNames=[lb_name])[
"LoadBalancerDescriptions"
][0]
assert len(describe["SecurityGroups"]) == 1
2022-03-21 20:55:19 +00:00
sec_group_id = describe["SecurityGroups"][0]
sg = ec2.describe_security_groups(GroupIds=[sec_group_id])["SecurityGroups"][0]
assert sg["GroupName"].startswith("default_elb_")
2024-01-07 12:03:33 +00:00
@mock_aws
2017-05-11 01:58:42 +00:00
def test_describe_paginated_balancers():
client = boto3.client("elb", region_name="us-east-1")
for i in range(51):
client.create_load_balancer(
LoadBalancerName=f"my-lb{i}",
2017-05-11 01:58:42 +00:00
Listeners=[
{"Protocol": "tcp", "LoadBalancerPort": 80, "InstancePort": 8080}
],
AvailabilityZones=["us-east-1a", "us-east-1b"],
)
resp = client.describe_load_balancers()
assert len(resp["LoadBalancerDescriptions"]) == 50
assert (
resp["NextMarker"] == resp["LoadBalancerDescriptions"][-1]["LoadBalancerName"]
2017-05-11 01:58:42 +00:00
)
resp2 = client.describe_load_balancers(Marker=resp["NextMarker"])
assert len(resp2["LoadBalancerDescriptions"]) == 1
2017-05-11 01:58:42 +00:00
assert "NextToken" not in resp2.keys()
2024-01-07 12:03:33 +00:00
@mock_aws
def test_apply_security_groups_to_load_balancer():
2017-07-19 19:20:01 +00:00
client = boto3.client("elb", region_name="us-east-1")
ec2 = boto3.resource("ec2", region_name="us-east-1")
2017-07-19 19:20:01 +00:00
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
security_group = ec2.create_security_group(
GroupName="sg01", Description="Test security group sg01", VpcId=vpc.id
)
client.create_load_balancer(
LoadBalancerName="my-lb",
Listeners=[{"Protocol": "tcp", "LoadBalancerPort": 80, "InstancePort": 8080}],
AvailabilityZones=["us-east-1a", "us-east-1b"],
)
response = client.apply_security_groups_to_load_balancer(
LoadBalancerName="my-lb", SecurityGroups=[security_group.id]
)
2017-07-19 19:20:01 +00:00
assert response["SecurityGroups"] == [security_group.id]
balancer = client.describe_load_balancers()["LoadBalancerDescriptions"][0]
assert balancer["SecurityGroups"] == [security_group.id]
2017-07-19 23:01:00 +00:00
# Using a not-real security group raises an error
with pytest.raises(ClientError) as error:
response = client.apply_security_groups_to_load_balancer(
LoadBalancerName="my-lb", SecurityGroups=["not-really-a-security-group"]
)
2020-10-06 06:46:05 +00:00
assert "One or more of the specified security groups do not exist." in str(
error.value
)
2017-07-19 19:20:01 +00:00
2017-05-11 01:58:42 +00:00
2024-01-07 12:03:33 +00:00
@mock_aws
2022-03-21 20:55:19 +00:00
def test_create_and_delete_listener():
client = boto3.client("elb", region_name="us-east-1")
client.create_load_balancer(
LoadBalancerName="my-lb",
2017-02-24 02:37:43 +00:00
Listeners=[{"Protocol": "http", "LoadBalancerPort": 80, "InstancePort": 8080}],
AvailabilityZones=["us-east-1a", "us-east-1b"],
)
assert len(client.describe_load_balancers()["LoadBalancerDescriptions"]) == 1
client.create_load_balancer_listeners(
LoadBalancerName="my-lb",
2017-02-24 02:37:43 +00:00
Listeners=[{"Protocol": "tcp", "LoadBalancerPort": 443, "InstancePort": 8443}],
)
balancer = client.describe_load_balancers()["LoadBalancerDescriptions"][0]
assert len(balancer["ListenerDescriptions"]) == 2
assert balancer["ListenerDescriptions"][0]["Listener"]["Protocol"] == "HTTP"
assert balancer["ListenerDescriptions"][0]["Listener"]["LoadBalancerPort"] == 80
assert balancer["ListenerDescriptions"][0]["Listener"]["InstancePort"] == 8080
assert balancer["ListenerDescriptions"][1]["Listener"]["Protocol"] == "TCP"
assert balancer["ListenerDescriptions"][1]["Listener"]["LoadBalancerPort"] == 443
assert balancer["ListenerDescriptions"][1]["Listener"]["InstancePort"] == 8443
2022-03-21 20:55:19 +00:00
client.delete_load_balancer_listeners(
LoadBalancerName="my-lb", LoadBalancerPorts=[443]
)
balancer = client.describe_load_balancers()["LoadBalancerDescriptions"][0]
assert len(balancer["ListenerDescriptions"]) == 1
2022-03-21 20:55:19 +00:00
2024-01-07 12:03:33 +00:00
@mock_aws
2022-03-21 20:55:19 +00:00
@pytest.mark.parametrize("first,second", [["tcp", "http"], ["http", "TCP"]])
def test_create_duplicate_listener_different_protocols(first, second):
client = boto3.client("elb", region_name="us-east-1")
client.create_load_balancer(
LoadBalancerName="my-lb",
Listeners=[{"Protocol": first, "LoadBalancerPort": 80, "InstancePort": 8080}],
AvailabilityZones=["us-east-1a", "us-east-1b"],
)
# Creating this listener with an conflicting definition throws error
2022-03-21 20:55:19 +00:00
with pytest.raises(ClientError) as exc:
client.create_load_balancer_listeners(
LoadBalancerName="my-lb",
Listeners=[
2022-03-21 20:55:19 +00:00
{"Protocol": second, "LoadBalancerPort": 80, "InstancePort": 8080}
2019-10-31 15:44:26 +00:00
],
)
2022-03-21 20:55:19 +00:00
err = exc.value.response["Error"]
assert err["Code"] == "DuplicateListener"
assert (
err["Message"]
== "A listener already exists for my-lb with LoadBalancerPort 80, but with a different InstancePort, Protocol, or SSLCertificateId"
2022-03-21 20:55:19 +00:00
)
2022-03-21 20:55:19 +00:00
2024-01-07 12:03:33 +00:00
@mock_aws
2022-03-21 20:55:19 +00:00
@pytest.mark.parametrize(
"first,second", [["tcp", "tcp"], ["tcp", "TcP"], ["http", "HTTP"]]
)
def test_create_duplicate_listener_same_details(first, second):
client = boto3.client("elb", region_name="us-east-1")
client.create_load_balancer(
LoadBalancerName="my-lb",
Listeners=[{"Protocol": first, "LoadBalancerPort": 80, "InstancePort": 8080}],
AvailabilityZones=["us-east-1a", "us-east-1b"],
)
# Creating this listener with the same definition succeeds
client.create_load_balancer_listeners(
LoadBalancerName="my-lb",
Listeners=[{"Protocol": second, "LoadBalancerPort": 80, "InstancePort": 8080}],
2017-07-07 04:29:18 +00:00
)
2022-03-21 20:55:19 +00:00
# We still only have one though
2017-07-07 04:29:18 +00:00
balancer = client.describe_load_balancers()["LoadBalancerDescriptions"][0]
assert len(balancer["ListenerDescriptions"]) == 1
2017-07-07 04:29:18 +00:00
2024-01-07 12:03:33 +00:00
@mock_aws
2022-03-21 20:55:19 +00:00
def test_create_lb_listener_with_ssl_certificate_from_acm():
2021-10-14 21:43:10 +00:00
acm_client = boto3.client("acm", region_name="eu-west-1")
acm_request_response = acm_client.request_certificate(
DomainName="fake.domain.com",
DomainValidationOptions=[
{"DomainName": "fake.domain.com", "ValidationDomain": "domain.com"},
],
)
certificate_arn = acm_request_response["CertificateArn"]
2014-07-19 00:31:57 +00:00
2021-10-14 21:43:10 +00:00
client = boto3.client("elb", region_name="eu-west-1")
2014-07-19 00:31:57 +00:00
2021-10-14 21:43:10 +00:00
client.create_load_balancer(
LoadBalancerName="my-lb",
Listeners=[{"Protocol": "http", "LoadBalancerPort": 80, "InstancePort": 8080}],
2022-03-21 20:55:19 +00:00
AvailabilityZones=["eu-west-1a", "eu-west-1b"],
)
client.create_load_balancer_listeners(
LoadBalancerName="my-lb",
Listeners=[
{
"Protocol": "tcp",
"LoadBalancerPort": 443,
"InstancePort": 8443,
"SSLCertificateId": certificate_arn,
}
],
)
balancer = client.describe_load_balancers()["LoadBalancerDescriptions"][0]
listeners = balancer["ListenerDescriptions"]
assert len(listeners) == 2
2022-03-21 20:55:19 +00:00
assert listeners[0]["Listener"]["Protocol"] == "HTTP"
assert listeners[0]["Listener"]["SSLCertificateId"] == "None"
2022-03-21 20:55:19 +00:00
assert listeners[1]["Listener"]["Protocol"] == "TCP"
assert listeners[1]["Listener"]["SSLCertificateId"] == certificate_arn
2022-03-21 20:55:19 +00:00
2024-01-07 12:03:33 +00:00
@mock_aws
2022-03-21 20:55:19 +00:00
def test_create_lb_listener_with_ssl_certificate_from_iam():
iam_client = boto3.client("iam", region_name="eu-west-2")
iam_cert_response = iam_client.upload_server_certificate(
ServerCertificateName="test-cert",
CertificateBody="cert-body",
PrivateKey="private-key",
)
certificate_arn = iam_cert_response["ServerCertificateMetadata"]["Arn"]
client = boto3.client("elb", region_name="eu-west-1")
client.create_load_balancer(
LoadBalancerName="my-lb",
Listeners=[{"Protocol": "http", "LoadBalancerPort": 80, "InstancePort": 8080}],
AvailabilityZones=["eu-west-1a", "eu-west-1b"],
2021-10-14 21:43:10 +00:00
)
2014-07-19 00:31:57 +00:00
2021-10-14 21:43:10 +00:00
client.create_load_balancer_listeners(
LoadBalancerName="my-lb",
Listeners=[
{
"Protocol": "tcp",
"LoadBalancerPort": 443,
"InstancePort": 8443,
"SSLCertificateId": certificate_arn,
}
],
)
balancer = client.describe_load_balancers()["LoadBalancerDescriptions"][0]
listeners = balancer["ListenerDescriptions"]
assert len(listeners) == 2
2021-10-14 21:43:10 +00:00
assert listeners[0]["Listener"]["Protocol"] == "HTTP"
assert listeners[0]["Listener"]["SSLCertificateId"] == "None"
2021-10-14 21:43:10 +00:00
assert listeners[1]["Listener"]["Protocol"] == "TCP"
assert listeners[1]["Listener"]["SSLCertificateId"] == certificate_arn
2021-10-14 21:43:10 +00:00
2024-01-07 12:03:33 +00:00
@mock_aws
2021-10-14 21:43:10 +00:00
def test_create_lb_listener_with_invalid_ssl_certificate():
client = boto3.client("elb", region_name="eu-west-1")
client.create_load_balancer(
LoadBalancerName="my-lb",
Listeners=[{"Protocol": "http", "LoadBalancerPort": 80, "InstancePort": 8080}],
2022-03-21 20:55:19 +00:00
AvailabilityZones=["eu-west-1a", "eu-west-1b"],
2021-10-14 21:43:10 +00:00
)
with pytest.raises(ClientError) as exc:
client.create_load_balancer_listeners(
LoadBalancerName="my-lb",
Listeners=[
{
"Protocol": "tcp",
"LoadBalancerPort": 443,
"InstancePort": 8443,
"SSLCertificateId": "unknownarn",
}
],
)
err = exc.value.response["Error"]
assert err["Code"] == "CertificateNotFoundException"
2021-10-14 21:43:10 +00:00
2024-01-07 12:03:33 +00:00
@mock_aws
2022-03-21 20:55:19 +00:00
def test_set_sslcertificate():
2021-10-14 21:43:10 +00:00
acm_client = boto3.client("acm", region_name="us-east-1")
acm_request_response = acm_client.request_certificate(
DomainName="fake.domain.com",
DomainValidationOptions=[
{"DomainName": "fake.domain.com", "ValidationDomain": "domain.com"},
],
)
certificate_arn = acm_request_response["CertificateArn"]
2021-09-24 20:00:10 +00:00
client = boto3.client("elb", region_name="us-east-1")
lb_name = str(uuid4())[0:6]
client.create_load_balancer(
LoadBalancerName=lb_name,
Listeners=[
{"Protocol": "http", "LoadBalancerPort": 80, "InstancePort": 8080},
{"Protocol": "https", "LoadBalancerPort": 81, "InstancePort": 8081},
],
AvailabilityZones=["us-east-1a"],
)
client.set_load_balancer_listener_ssl_certificate(
2021-10-14 21:43:10 +00:00
LoadBalancerName=lb_name, LoadBalancerPort=81, SSLCertificateId=certificate_arn
2021-09-24 20:00:10 +00:00
)
elb = client.describe_load_balancers()["LoadBalancerDescriptions"][0]
listener = elb["ListenerDescriptions"][0]["Listener"]
assert listener["LoadBalancerPort"] == 80
assert listener["SSLCertificateId"] == "None"
2021-09-24 20:00:10 +00:00
listener = elb["ListenerDescriptions"][1]["Listener"]
assert listener["LoadBalancerPort"] == 81
assert listener["SSLCertificateId"] == certificate_arn
2021-09-24 20:00:10 +00:00
2024-01-07 12:03:33 +00:00
@mock_aws
2022-03-21 20:55:19 +00:00
def test_get_load_balancers_by_name():
2021-09-24 20:00:10 +00:00
client = boto3.client("elb", region_name="us-east-1")
lb_name1 = str(uuid4())[0:6]
lb_name2 = str(uuid4())[0:6]
client.create_load_balancer(
LoadBalancerName=lb_name1,
Listeners=[{"Protocol": "http", "LoadBalancerPort": 80, "InstancePort": 8080}],
AvailabilityZones=["us-east-1a"],
)
client.create_load_balancer(
LoadBalancerName=lb_name2,
Listeners=[{"Protocol": "http", "LoadBalancerPort": 80, "InstancePort": 8080}],
AvailabilityZones=["us-east-1a"],
)
lbs = client.describe_load_balancers(LoadBalancerNames=[lb_name1])
assert len(lbs["LoadBalancerDescriptions"]) == 1
2021-09-24 20:00:10 +00:00
lbs = client.describe_load_balancers(LoadBalancerNames=[lb_name2])
assert len(lbs["LoadBalancerDescriptions"]) == 1
2021-09-24 20:00:10 +00:00
lbs = client.describe_load_balancers(LoadBalancerNames=[lb_name1, lb_name2])
assert len(lbs["LoadBalancerDescriptions"]) == 2
2021-09-24 20:00:10 +00:00
with pytest.raises(ClientError) as ex:
client.describe_load_balancers(LoadBalancerNames=["unknownlb"])
err = ex.value.response["Error"]
assert err["Code"] == "LoadBalancerNotFound"
assert err["Message"] == "The specified load balancer does not exist: unknownlb"
2021-09-24 20:00:10 +00:00
with pytest.raises(ClientError) as ex:
client.describe_load_balancers(LoadBalancerNames=[lb_name1, "unknownlb"])
err = ex.value.response["Error"]
assert err["Code"] == "LoadBalancerNotFound"
2021-09-24 20:00:10 +00:00
# Bug - message sometimes shows the lb that does exist
assert "The specified load balancer does not exist:" in err["Message"]
2021-09-24 20:00:10 +00:00
2024-01-07 12:03:33 +00:00
@mock_aws
2022-03-21 20:55:19 +00:00
def test_delete_load_balancer():
2021-09-24 20:00:10 +00:00
client = boto3.client("elb", region_name="us-east-1")
lb_name1 = str(uuid4())[0:6]
lb_name2 = str(uuid4())[0:6]
client.create_load_balancer(
LoadBalancerName=lb_name1,
Listeners=[{"Protocol": "http", "LoadBalancerPort": 80, "InstancePort": 8080}],
AvailabilityZones=["us-east-1a"],
)
client.create_load_balancer(
LoadBalancerName=lb_name2,
Listeners=[{"Protocol": "http", "LoadBalancerPort": 80, "InstancePort": 8080}],
AvailabilityZones=["us-east-1a"],
)
lbs = client.describe_load_balancers()["LoadBalancerDescriptions"]
lb_names = [lb["LoadBalancerName"] for lb in lbs]
assert lb_name1 in lb_names
assert lb_name2 in lb_names
2021-09-24 20:00:10 +00:00
client.delete_load_balancer(LoadBalancerName=lb_name1)
lbs = client.describe_load_balancers()["LoadBalancerDescriptions"]
lb_names = [lb["LoadBalancerName"] for lb in lbs]
assert lb_name1 not in lb_names
assert lb_name2 in lb_names
2021-09-24 20:00:10 +00:00
2024-01-07 12:03:33 +00:00
@mock_aws
2022-03-21 20:55:19 +00:00
def test_create_health_check():
client = boto3.client("elb", region_name="us-east-1")
client.create_load_balancer(
LoadBalancerName="my-lb",
2017-02-24 02:37:43 +00:00
Listeners=[{"Protocol": "http", "LoadBalancerPort": 80, "InstancePort": 8080}],
AvailabilityZones=["us-east-1a", "us-east-1b"],
)
client.configure_health_check(
LoadBalancerName="my-lb",
HealthCheck={
"Target": "HTTP:8080/health",
"Interval": 20,
"Timeout": 23,
"HealthyThreshold": 3,
"UnhealthyThreshold": 5,
},
)
balancer = client.describe_load_balancers()["LoadBalancerDescriptions"][0]
assert balancer["HealthCheck"]["Target"] == "HTTP:8080/health"
assert balancer["HealthCheck"]["Interval"] == 20
assert balancer["HealthCheck"]["Timeout"] == 23
assert balancer["HealthCheck"]["HealthyThreshold"] == 3
assert balancer["HealthCheck"]["UnhealthyThreshold"] == 5
2024-01-07 12:03:33 +00:00
@mock_aws
2022-03-21 20:55:19 +00:00
def test_register_instances():
ec2 = boto3.resource("ec2", region_name="us-east-1")
response = ec2.create_instances(ImageId=EXAMPLE_AMI_ID, MinCount=2, MaxCount=2)
instance_id1 = response[0].id
instance_id2 = response[1].id
client = boto3.client("elb", region_name="us-east-1")
client.create_load_balancer(
LoadBalancerName="my-lb",
2017-02-24 02:37:43 +00:00
Listeners=[{"Protocol": "http", "LoadBalancerPort": 80, "InstancePort": 8080}],
AvailabilityZones=["us-east-1a", "us-east-1b"],
)
client.register_instances_with_load_balancer(
LoadBalancerName="my-lb",
Instances=[{"InstanceId": instance_id1}, {"InstanceId": instance_id2}],
)
balancer = client.describe_load_balancers()["LoadBalancerDescriptions"][0]
2017-02-24 02:37:43 +00:00
instance_ids = [instance["InstanceId"] for instance in balancer["Instances"]]
assert set(instance_ids) == set([instance_id1, instance_id2])
2024-01-07 12:03:33 +00:00
@mock_aws
2022-03-21 20:55:19 +00:00
def test_deregister_instances():
ec2 = boto3.resource("ec2", region_name="us-east-1")
response = ec2.create_instances(ImageId=EXAMPLE_AMI_ID, MinCount=2, MaxCount=2)
instance_id1 = response[0].id
instance_id2 = response[1].id
client = boto3.client("elb", region_name="us-east-1")
client.create_load_balancer(
LoadBalancerName="my-lb",
2017-02-24 02:37:43 +00:00
Listeners=[{"Protocol": "http", "LoadBalancerPort": 80, "InstancePort": 8080}],
AvailabilityZones=["us-east-1a", "us-east-1b"],
)
client.register_instances_with_load_balancer(
LoadBalancerName="my-lb",
Instances=[{"InstanceId": instance_id1}, {"InstanceId": instance_id2}],
)
balancer = client.describe_load_balancers()["LoadBalancerDescriptions"][0]
assert len(balancer["Instances"]) == 2
client.deregister_instances_from_load_balancer(
LoadBalancerName="my-lb", Instances=[{"InstanceId": instance_id1}]
)
balancer = client.describe_load_balancers()["LoadBalancerDescriptions"][0]
assert len(balancer["Instances"]) == 1
assert balancer["Instances"][0]["InstanceId"] == instance_id2
2015-03-22 20:00:16 +00:00
2024-01-07 12:03:33 +00:00
@mock_aws
2022-03-21 20:55:19 +00:00
def test_default_attributes():
2021-09-24 20:00:10 +00:00
lb_name = str(uuid4())[0:6]
client = boto3.client("elb", region_name="us-east-1")
client.create_load_balancer(
LoadBalancerName=lb_name,
Listeners=[{"Protocol": "http", "LoadBalancerPort": 80, "InstancePort": 8080}],
AvailabilityZones=["us-east-1a"],
)
attributes = client.describe_load_balancer_attributes(LoadBalancerName=lb_name)[
"LoadBalancerAttributes"
]
assert attributes["CrossZoneLoadBalancing"] == {"Enabled": False}
assert attributes["AccessLog"] == {"Enabled": False}
assert attributes["ConnectionDraining"] == {"Enabled": False}
assert attributes["ConnectionSettings"] == {"IdleTimeout": 60}
2021-09-24 20:00:10 +00:00
2024-01-07 12:03:33 +00:00
@mock_aws
2022-03-21 20:55:19 +00:00
def test_cross_zone_load_balancing_attribute():
2021-09-24 20:00:10 +00:00
lb_name = str(uuid4())[0:6]
client = boto3.client("elb", region_name="us-east-1")
client.create_load_balancer(
LoadBalancerName=lb_name,
Listeners=[{"Protocol": "http", "LoadBalancerPort": 80, "InstancePort": 8080}],
AvailabilityZones=["us-east-1a"],
)
client.modify_load_balancer_attributes(
LoadBalancerName=lb_name,
LoadBalancerAttributes={"CrossZoneLoadBalancing": {"Enabled": True}},
)
attributes = client.describe_load_balancer_attributes(LoadBalancerName=lb_name)[
"LoadBalancerAttributes"
]
assert attributes["CrossZoneLoadBalancing"] == {"Enabled": True}
assert attributes["AccessLog"] == {"Enabled": False}
assert attributes["ConnectionDraining"] == {"Enabled": False}
assert attributes["ConnectionSettings"] == {"IdleTimeout": 60}
2021-09-24 20:00:10 +00:00
client.modify_load_balancer_attributes(
LoadBalancerName=lb_name,
LoadBalancerAttributes={"CrossZoneLoadBalancing": {"Enabled": False}},
)
attributes = client.describe_load_balancer_attributes(LoadBalancerName=lb_name)[
"LoadBalancerAttributes"
]
assert attributes["CrossZoneLoadBalancing"] == {"Enabled": False}
2021-09-24 20:00:10 +00:00
2024-01-07 12:03:33 +00:00
@mock_aws
2022-03-21 20:55:19 +00:00
def test_connection_draining_attribute():
2021-09-24 20:00:10 +00:00
lb_name = str(uuid4())[0:6]
client = boto3.client("elb", region_name="us-east-1")
client.create_load_balancer(
LoadBalancerName=lb_name,
Listeners=[{"Protocol": "http", "LoadBalancerPort": 80, "InstancePort": 8080}],
AvailabilityZones=["us-east-1a"],
)
client.modify_load_balancer_attributes(
LoadBalancerName=lb_name,
LoadBalancerAttributes={"ConnectionDraining": {"Enabled": True, "Timeout": 42}},
)
attributes = client.describe_load_balancer_attributes(LoadBalancerName=lb_name)[
"LoadBalancerAttributes"
]
assert attributes["ConnectionDraining"] == {"Enabled": True, "Timeout": 42}
2021-09-24 20:00:10 +00:00
client.modify_load_balancer_attributes(
LoadBalancerName=lb_name,
LoadBalancerAttributes={"ConnectionDraining": {"Enabled": False}},
)
attributes = client.describe_load_balancer_attributes(LoadBalancerName=lb_name)[
"LoadBalancerAttributes"
]
assert attributes["ConnectionDraining"] == {"Enabled": False, "Timeout": 300}
2021-09-24 20:00:10 +00:00
2024-01-07 12:03:33 +00:00
@mock_aws
2022-03-21 20:55:19 +00:00
def test_access_log_attribute():
lb_name = str(uuid4())[0:6]
client = boto3.client("elb", region_name="us-east-1")
client.create_load_balancer(
LoadBalancerName=lb_name,
Listeners=[{"Protocol": "http", "LoadBalancerPort": 80, "InstancePort": 8080}],
AvailabilityZones=["us-east-1a"],
)
lb_attrs = client.describe_load_balancer_attributes(LoadBalancerName=lb_name)[
"LoadBalancerAttributes"
]
access_log = lb_attrs["AccessLog"]
assert access_log == {"Enabled": False}
# Specify our AccessLog attributes
client.modify_load_balancer_attributes(
LoadBalancerName=lb_name,
LoadBalancerAttributes={
"AccessLog": {
"Enabled": True,
"S3BucketName": "mb",
"EmitInterval": 42,
"S3BucketPrefix": "s3bf",
}
},
)
lb_attrs = client.describe_load_balancer_attributes(LoadBalancerName=lb_name)[
"LoadBalancerAttributes"
]
access_log = lb_attrs["AccessLog"]
assert access_log == {
"Enabled": True,
"S3BucketName": "mb",
"EmitInterval": 42,
"S3BucketPrefix": "s3bf",
}
# Verify the attribute can be reset
client.modify_load_balancer_attributes(
LoadBalancerName=lb_name,
LoadBalancerAttributes={"AccessLog": {"Enabled": False}},
)
lb_attrs = client.describe_load_balancer_attributes(LoadBalancerName=lb_name)[
"LoadBalancerAttributes"
]
access_log = lb_attrs["AccessLog"]
assert access_log == {"Enabled": False}
2024-01-07 12:03:33 +00:00
@mock_aws
2022-03-21 20:55:19 +00:00
def test_connection_settings_attribute():
lb_name = str(uuid4())[0:6]
client = boto3.client("elb", region_name="us-east-1")
client.create_load_balancer(
LoadBalancerName=lb_name,
Listeners=[{"Protocol": "http", "LoadBalancerPort": 80, "InstancePort": 8080}],
AvailabilityZones=["us-east-1a"],
)
lb_attrs = client.describe_load_balancer_attributes(LoadBalancerName=lb_name)[
"LoadBalancerAttributes"
]
conn_settings = lb_attrs["ConnectionSettings"]
assert conn_settings == {"IdleTimeout": 60}
# Specify our AccessLog attributes
client.modify_load_balancer_attributes(
LoadBalancerName=lb_name,
LoadBalancerAttributes={"ConnectionSettings": {"IdleTimeout": 123}},
)
lb_attrs = client.describe_load_balancer_attributes(LoadBalancerName=lb_name)[
"LoadBalancerAttributes"
]
conn_settings = lb_attrs["ConnectionSettings"]
assert conn_settings == {"IdleTimeout": 123}
2017-02-24 02:37:43 +00:00
2015-07-14 23:54:58 +00:00
2024-01-07 12:03:33 +00:00
@mock_aws
2022-03-21 20:55:19 +00:00
def test_describe_instance_health():
2018-08-06 09:01:33 +00:00
elb = boto3.client("elb", region_name="us-east-1")
ec2 = boto3.client("ec2", region_name="us-east-1")
# Create three instances
resp = ec2.run_instances(ImageId=EXAMPLE_AMI_ID, MinCount=2, MaxCount=2)
instance_ids = [i["InstanceId"] for i in resp["Instances"]]
# Register two instances with an LB
lb_name = "my_load_balancer"
elb.create_load_balancer(
Listeners=[{"InstancePort": 80, "LoadBalancerPort": 8080, "Protocol": "HTTP"}],
LoadBalancerName=lb_name,
)
elb.register_instances_with_load_balancer(
LoadBalancerName=lb_name,
Instances=[{"InstanceId": instance_ids[0]}, {"InstanceId": instance_ids[1]}],
2019-10-31 15:44:26 +00:00
)
# Describe the Health of all instances
instances_health = elb.describe_instance_health(LoadBalancerName=lb_name)[
"InstanceStates"
]
assert len(instances_health) == 2
2024-01-07 12:03:33 +00:00
@mock_aws
def test_describe_instance_health__with_instance_ids():
elb = boto3.client("elb", region_name="us-east-1")
ec2 = boto3.client("ec2", region_name="us-east-1")
# Create three instances
resp = ec2.run_instances(ImageId=EXAMPLE_AMI_ID, MinCount=3, MaxCount=3)
instance_ids = [i["InstanceId"] for i in resp["Instances"]]
# Register two instances with an LB
lb_name = "my_load_balancer"
elb.create_load_balancer(
Listeners=[{"InstancePort": 80, "LoadBalancerPort": 8080, "Protocol": "HTTP"}],
LoadBalancerName=lb_name,
)
elb.register_instances_with_load_balancer(
LoadBalancerName=lb_name,
Instances=[{"InstanceId": instance_ids[0]}, {"InstanceId": instance_ids[2]}],
)
# Stop one instance
ec2.stop_instances(InstanceIds=[instance_ids[2]])
# Describe the Health of instances
instances_health = elb.describe_instance_health(
LoadBalancerName=lb_name,
Instances=[{"InstanceId": iid} for iid in instance_ids],
)["InstanceStates"]
assert len(instances_health) == 3
# The first instance is healthy
assert instances_health[0]["InstanceId"] == instance_ids[0]
assert instances_health[0]["State"] == "InService"
# The second instance was never known to ELB
assert instances_health[1]["InstanceId"] == instance_ids[1]
assert instances_health[1]["State"] == "Unknown"
# The third instance was stopped
assert instances_health[2]["InstanceId"] == instance_ids[2]
assert instances_health[2]["State"] == "OutOfService"
2024-01-07 12:03:33 +00:00
@mock_aws
def test_describe_instance_health_of_unknown_lb():
elb = boto3.client("elb", region_name="us-east-1")
with pytest.raises(ClientError) as exc:
elb.describe_instance_health(LoadBalancerName="what")
err = exc.value.response["Error"]
assert err["Code"] == "LoadBalancerNotFound"
assert err["Message"] == "There is no ACTIVE Load Balancer named 'what'"
2024-01-07 12:03:33 +00:00
@mock_aws
def test_add_remove_tags():
client = boto3.client("elb", region_name="us-east-1")
with pytest.raises(ClientError):
client.add_tags(LoadBalancerNames=["my-lb"], Tags=[{"Key": "a", "Value": "b"}])
client.create_load_balancer(
LoadBalancerName="my-lb",
2017-02-24 02:37:43 +00:00
Listeners=[{"Protocol": "tcp", "LoadBalancerPort": 80, "InstancePort": 8080}],
AvailabilityZones=["us-east-1a", "us-east-1b"],
)
2019-10-31 15:44:26 +00:00
assert len(client.describe_load_balancers()["LoadBalancerDescriptions"]) == 1
2019-10-31 15:44:26 +00:00
client.add_tags(LoadBalancerNames=["my-lb"], Tags=[{"Key": "a", "Value": "b"}])
2019-10-31 15:44:26 +00:00
2017-02-24 02:37:43 +00:00
tags = dict(
2019-10-31 15:44:26 +00:00
[
2017-02-24 02:37:43 +00:00
(d["Key"], d["Value"])
for d in client.describe_tags(LoadBalancerNames=["my-lb"])[
"TagDescriptions"
][0]["Tags"]
2019-10-31 15:44:26 +00:00
]
2017-02-24 02:37:43 +00:00
)
assert tags["a"] == "b"
2019-10-31 15:44:26 +00:00
client.add_tags(
LoadBalancerNames=["my-lb"],
Tags=[
2017-02-24 02:37:43 +00:00
{"Key": "a", "Value": "b"},
{"Key": "b", "Value": "b"},
{"Key": "c", "Value": "b"},
{"Key": "d", "Value": "b"},
{"Key": "e", "Value": "b"},
2017-02-24 02:37:43 +00:00
{"Key": "f", "Value": "b"},
{"Key": "g", "Value": "b"},
{"Key": "h", "Value": "b"},
{"Key": "i", "Value": "b"},
{"Key": "j", "Value": "b"},
],
)
2019-10-31 15:44:26 +00:00
with pytest.raises(ClientError):
client.add_tags(LoadBalancerNames=["my-lb"], Tags=[{"Key": "k", "Value": "b"}])
2019-10-31 15:44:26 +00:00
client.add_tags(LoadBalancerNames=["my-lb"], Tags=[{"Key": "j", "Value": "c"}])
2019-10-31 15:44:26 +00:00
2017-02-24 02:37:43 +00:00
tags = dict(
2019-10-31 15:44:26 +00:00
[
2017-02-24 02:37:43 +00:00
(d["Key"], d["Value"])
for d in client.describe_tags(LoadBalancerNames=["my-lb"])[
2017-02-24 02:37:43 +00:00
"TagDescriptions"
2019-10-31 15:44:26 +00:00
][0]["Tags"]
]
)
assert tags["a"] == "b"
assert tags["b"] == "b"
assert tags["c"] == "b"
assert tags["d"] == "b"
assert tags["e"] == "b"
assert tags["f"] == "b"
assert tags["g"] == "b"
assert tags["h"] == "b"
assert tags["i"] == "b"
assert tags["j"] == "c"
assert "k" not in tags
2019-10-31 15:44:26 +00:00
client.remove_tags(LoadBalancerNames=["my-lb"], Tags=[{"Key": "a"}])
2019-10-31 15:44:26 +00:00
2017-02-24 02:37:43 +00:00
tags = dict(
2019-10-31 15:44:26 +00:00
[
2017-02-24 02:37:43 +00:00
(d["Key"], d["Value"])
for d in client.describe_tags(LoadBalancerNames=["my-lb"])[
"TagDescriptions"
][0]["Tags"]
2019-10-31 15:44:26 +00:00
]
2017-02-24 02:37:43 +00:00
)
2019-10-31 15:44:26 +00:00
assert "a" not in tags
assert tags["b"] == "b"
assert tags["c"] == "b"
assert tags["d"] == "b"
assert tags["e"] == "b"
assert tags["f"] == "b"
assert tags["g"] == "b"
assert tags["h"] == "b"
assert tags["i"] == "b"
assert tags["j"] == "c"
client.create_load_balancer(
LoadBalancerName="other-lb",
2017-02-24 02:37:43 +00:00
Listeners=[{"Protocol": "tcp", "LoadBalancerPort": 433, "InstancePort": 8433}],
AvailabilityZones=["us-east-1a", "us-east-1b"],
)
client.add_tags(
LoadBalancerNames=["other-lb"], Tags=[{"Key": "other", "Value": "something"}]
)
lb_tags = dict(
2019-10-31 15:44:26 +00:00
[
2022-04-27 11:58:59 +00:00
(lb["LoadBalancerName"], dict([(d["Key"], d["Value"]) for d in lb["Tags"]]))
for lb in client.describe_tags(LoadBalancerNames=["my-lb", "other-lb"])[
"TagDescriptions"
2019-10-31 15:44:26 +00:00
]
]
)
assert "my-lb" in lb_tags
assert "other-lb" in lb_tags
assert "other" not in lb_tags["my-lb"]
assert lb_tags["other-lb"]["other"] == "something"
2024-01-07 12:03:33 +00:00
@mock_aws
def test_create_with_tags():
client = boto3.client("elb", region_name="us-east-1")
client.create_load_balancer(
LoadBalancerName="my-lb",
2017-02-24 02:37:43 +00:00
Listeners=[{"Protocol": "tcp", "LoadBalancerPort": 80, "InstancePort": 8080}],
AvailabilityZones=["us-east-1a", "us-east-1b"],
Tags=[{"Key": "k", "Value": "v"}],
)
2017-02-24 02:37:43 +00:00
tags = dict(
(d["Key"], d["Value"])
for d in client.describe_tags(LoadBalancerNames=["my-lb"])["TagDescriptions"][
2019-10-31 15:44:26 +00:00
0
2017-02-24 02:37:43 +00:00
]["Tags"]
)
assert tags["k"] == "v"
2024-01-07 12:03:33 +00:00
@mock_aws
def test_modify_attributes():
client = boto3.client("elb", region_name="us-east-1")
client.create_load_balancer(
LoadBalancerName="my-lb",
Listeners=[{"Protocol": "tcp", "LoadBalancerPort": 80, "InstancePort": 8080}],
AvailabilityZones=["us-east-1a", "us-east-1b"],
)
# Default ConnectionDraining timeout of 300 seconds
client.modify_load_balancer_attributes(
LoadBalancerName="my-lb",
LoadBalancerAttributes={"ConnectionDraining": {"Enabled": True}},
2019-10-31 15:44:26 +00:00
)
lb_attrs = client.describe_load_balancer_attributes(LoadBalancerName="my-lb")
assert lb_attrs["LoadBalancerAttributes"]["ConnectionDraining"]["Enabled"] is True
assert lb_attrs["LoadBalancerAttributes"]["ConnectionDraining"]["Timeout"] == 300
# specify a custom ConnectionDraining timeout
client.modify_load_balancer_attributes(
LoadBalancerName="my-lb",
LoadBalancerAttributes={"ConnectionDraining": {"Enabled": True, "Timeout": 45}},
2019-10-31 15:44:26 +00:00
)
lb_attrs = client.describe_load_balancer_attributes(LoadBalancerName="my-lb")
assert lb_attrs["LoadBalancerAttributes"]["ConnectionDraining"]["Enabled"] is True
assert lb_attrs["LoadBalancerAttributes"]["ConnectionDraining"]["Timeout"] == 45
2024-01-07 12:03:33 +00:00
@mock_aws
def test_subnets():
ec2 = boto3.resource("ec2", region_name="us-east-1")
vpc = ec2.create_vpc(CidrBlock="172.28.7.0/24", InstanceTenancy="default")
subnet = ec2.create_subnet(VpcId=vpc.id, CidrBlock="172.28.7.192/26")
client = boto3.client("elb", region_name="us-east-1")
client.create_load_balancer(
LoadBalancerName="my-lb",
2017-02-24 02:37:43 +00:00
Listeners=[{"Protocol": "tcp", "LoadBalancerPort": 80, "InstancePort": 8080}],
Subnets=[subnet.id],
)
lb = client.describe_load_balancers()["LoadBalancerDescriptions"][0]
2022-03-21 20:55:19 +00:00
assert len(lb["Subnets"]) == 1
assert lb["Subnets"][0] == subnet.id
assert lb["VPCId"] == vpc.id
assert lb["SourceSecurityGroup"] == {
"OwnerAlias": f"{DEFAULT_ACCOUNT_ID}",
"GroupName": "default",
}
2024-01-07 12:03:33 +00:00
@mock_aws
2022-03-21 20:55:19 +00:00
def test_create_load_balancer_duplicate():
2021-09-24 20:00:10 +00:00
lb_name = str(uuid4())[0:6]
client = boto3.client("elb", region_name="us-east-1")
client.create_load_balancer(
LoadBalancerName=lb_name,
Listeners=[{"Protocol": "tcp", "LoadBalancerPort": 80, "InstancePort": 8080}],
)
with pytest.raises(ClientError) as ex:
client.create_load_balancer(
LoadBalancerName=lb_name,
Listeners=[
{"Protocol": "tcp", "LoadBalancerPort": 80, "InstancePort": 8080}
],
)
err = ex.value.response["Error"]
assert err["Code"] == "DuplicateLoadBalancerName"
assert (
err["Message"]
== f"The specified load balancer name already exists for this account: {lb_name}"
2021-09-24 20:00:10 +00:00
)