2017-04-12 22:25:07 -04:00
import datetime
2021-08-04 17:24:26 +01:00
from collections import OrderedDict
2023-02-27 22:08:24 -01:00
from typing import Any , Dict , List , Iterable , Optional
2022-10-19 20:56:24 +00:00
2022-11-10 08:43:20 -01:00
from moto . core import BaseBackend , BackendDict , BaseModel , CloudFormationModel
2016-04-14 14:43:03 +02:00
from moto . ec2 . models import ec2_backends
2022-05-21 22:55:36 +00:00
from moto . ec2 . exceptions import InvalidInstanceIdError
2022-09-28 09:35:12 +00:00
from moto . moto_api . _internal import mock_random
2016-05-15 20:04:00 +02:00
from . exceptions import (
BadHealthCheckDefinition ,
DuplicateLoadBalancerName ,
2017-07-06 21:52:01 -07:00
DuplicateListenerError ,
2017-06-12 16:42:42 -07:00
EmptyListenersError ,
2017-07-19 15:58:49 -07:00
InvalidSecurityGroupError ,
2017-06-12 16:42:42 -07:00
LoadBalancerNotFoundError ,
2022-11-23 18:10:18 -01:00
NoActiveLoadBalancerFoundError ,
2022-03-21 19:55:19 -01:00
PolicyNotFoundError ,
2017-06-12 16:42:42 -07:00
TooManyTagsError ,
2021-10-14 21:43:10 +00:00
CertificateNotFoundException ,
2016-05-15 20:04:00 +02:00
)
2023-02-27 22:08:24 -01:00
from . policies import (
AppCookieStickinessPolicy ,
LbCookieStickinessPolicy ,
OtherPolicy ,
Policy ,
)
2013-07-22 22:50:58 -04:00
2017-03-11 23:41:12 -05:00
class FakeHealthCheck ( BaseModel ) :
2013-07-22 22:50:58 -04:00
def __init__ (
2023-02-27 22:08:24 -01:00
self ,
timeout : str ,
healthy_threshold : str ,
unhealthy_threshold : str ,
interval : str ,
target : str ,
2013-07-22 22:50:58 -04:00
) :
self . timeout = timeout
self . healthy_threshold = healthy_threshold
self . unhealthy_threshold = unhealthy_threshold
self . interval = interval
self . target = target
2015-12-14 15:38:40 +02:00
if not target . startswith ( ( " HTTP " , " TCP " , " HTTPS " , " SSL " ) ) :
raise BadHealthCheckDefinition
2013-07-22 22:50:58 -04:00
2017-03-11 23:41:12 -05:00
class FakeListener ( BaseModel ) :
2023-02-27 22:08:24 -01:00
def __init__ (
self ,
load_balancer_port : str ,
instance_port : str ,
protocol : str ,
ssl_certificate_id : Optional [ str ] ,
) :
2013-07-22 22:50:58 -04:00
self . load_balancer_port = load_balancer_port
self . instance_port = instance_port
self . protocol = protocol . upper ( )
2014-07-14 17:54:45 -07:00
self . ssl_certificate_id = ssl_certificate_id
2023-02-27 22:08:24 -01:00
self . policy_names : List [ str ] = [ ]
2015-07-14 23:54:58 +00:00
2023-02-27 22:08:24 -01:00
def __repr__ ( self ) - > str :
2022-11-14 21:34:02 -01:00
return f " FakeListener(lbp: { self . load_balancer_port } , inp: { self . instance_port } , pro: { self . protocol } , cid: { self . ssl_certificate_id } , policies: { self . policy_names } ) "
2015-07-14 23:54:58 +00:00
2017-03-11 23:41:12 -05:00
class FakeBackend ( BaseModel ) :
2023-02-27 22:08:24 -01:00
def __init__ ( self , instance_port : str ) :
2015-07-14 23:54:58 +00:00
self . instance_port = instance_port
2023-02-27 22:08:24 -01:00
self . policy_names : List [ str ] = [ ]
2015-07-18 09:08:27 -04:00
2023-02-27 22:08:24 -01:00
def __repr__ ( self ) - > str :
2022-11-14 21:34:02 -01:00
return f " FakeBackend(inp: { self . instance_port } , policies: { self . policy_names } ) "
2013-07-22 22:50:58 -04:00
2020-08-01 07:23:36 -07:00
class FakeLoadBalancer ( CloudFormationModel ) :
2017-07-19 15:58:49 -07:00
def __init__ (
self ,
2023-02-27 22:08:24 -01:00
name : str ,
zones : List [ str ] ,
ports : List [ Dict [ str , Any ] ] ,
scheme : Optional [ str ] ,
vpc_id : Optional [ str ] ,
subnets : Optional [ List [ str ] ] ,
security_groups : Optional [ List [ str ] ] ,
elb_backend : " ELBBackend " ,
2017-07-19 15:58:49 -07:00
) :
2013-07-22 22:50:58 -04:00
self . name = name
2023-02-27 22:08:24 -01:00
self . health_check : Optional [ FakeHealthCheck ] = None
self . instance_sparse_ids : List [ str ] = [ ]
self . instance_autoscaling_ids : List [ str ] = [ ]
2013-07-22 22:50:58 -04:00
self . zones = zones
self . listeners = [ ]
2015-07-14 23:54:58 +00:00
self . backends = [ ]
2022-12-10 00:56:08 +01:00
self . created_time = datetime . datetime . now ( datetime . timezone . utc )
2021-09-24 20:00:10 +00:00
self . scheme = scheme or " internet-facing "
2015-03-22 15:35:27 +01:00
self . attributes = FakeLoadBalancer . get_default_attributes ( )
2023-02-27 22:08:24 -01:00
self . policies : List [ Policy ] = [ ]
2017-07-19 15:58:49 -07:00
self . security_groups = security_groups or [ ]
2016-04-14 14:43:03 +02:00
self . subnets = subnets or [ ]
2022-03-21 19:55:19 -01:00
self . vpc_id = vpc_id
2023-02-27 22:08:24 -01:00
self . tags : Dict [ str , str ] = { }
2022-11-14 21:34:02 -01:00
self . dns_name = f " { name } .us-east-1.elb.amazonaws.com "
2014-07-14 17:54:45 -07:00
2015-07-18 09:08:27 -04:00
for port in ports :
2013-07-22 22:50:58 -04:00
listener = FakeListener (
2016-04-28 09:21:54 -04:00
protocol = ( port . get ( " protocol " ) or port [ " Protocol " ] ) ,
2017-02-23 21:37:43 -05:00
load_balancer_port = (
port . get ( " load_balancer_port " ) or port [ " LoadBalancerPort " ]
) ,
instance_port = ( port . get ( " instance_port " ) or port [ " InstancePort " ] ) ,
ssl_certificate_id = port . get (
2017-03-15 23:39:36 -04:00
" ssl_certificate_id " , port . get ( " SSLCertificateId " )
) ,
2013-07-22 22:50:58 -04:00
)
2022-03-21 19:55:19 -01:00
if (
listener . ssl_certificate_id
and not listener . ssl_certificate_id . startswith ( " arn:aws:iam: " )
) :
2021-10-14 21:43:10 +00:00
elb_backend . _register_certificate (
listener . ssl_certificate_id , self . dns_name
)
2013-07-22 22:50:58 -04:00
self . listeners . append ( listener )
2015-07-18 09:08:27 -04:00
2015-07-14 23:54:58 +00:00
# it is unclear per the AWS documentation as to when or how backend
# information gets set, so let's guess and set it here *shrug*
backend = FakeBackend (
2017-02-23 21:37:43 -05:00
instance_port = ( port . get ( " instance_port " ) or port [ " InstancePort " ] )
2015-07-14 23:54:58 +00:00
)
self . backends . append ( backend )
2013-07-22 22:50:58 -04:00
2021-04-30 10:29:20 +02:00
@property
2023-02-27 22:08:24 -01:00
def instance_ids ( self ) - > List [ str ] :
2021-04-30 10:29:20 +02:00
""" Return all the instances attached to the ELB """
return self . instance_sparse_ids + self . instance_autoscaling_ids
2020-08-01 07:23:36 -07:00
@staticmethod
2023-02-27 22:08:24 -01:00
def cloudformation_name_type ( ) - > str :
2020-08-01 07:23:36 -07:00
return " LoadBalancerName "
@staticmethod
2023-02-27 22:08:24 -01:00
def cloudformation_type ( ) - > str :
2020-08-01 07:23:36 -07:00
# https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-elasticloadbalancing-loadbalancer.html
return " AWS::ElasticLoadBalancing::LoadBalancer "
2014-03-27 19:12:53 -04:00
@classmethod
2023-02-27 22:08:24 -01:00
def create_from_cloudformation_json ( # type: ignore[misc]
cls ,
resource_name : str ,
cloudformation_json : Any ,
account_id : str ,
region_name : str ,
* * kwargs : Any ,
) - > " FakeLoadBalancer " :
2014-03-27 19:12:53 -04:00
properties = cloudformation_json [ " Properties " ]
2022-08-13 09:49:43 +00:00
elb_backend = elb_backends [ account_id ] [ region_name ]
2014-03-27 19:12:53 -04:00
new_elb = elb_backend . create_load_balancer (
name = properties . get ( " LoadBalancerName " , resource_name ) ,
2016-04-28 09:21:54 -04:00
zones = properties . get ( " AvailabilityZones " , [ ] ) ,
ports = properties [ " Listeners " ] ,
scheme = properties . get ( " Scheme " , " internet-facing " ) ,
2014-03-27 19:12:53 -04:00
)
2016-04-28 09:21:54 -04:00
instance_ids = properties . get ( " Instances " , [ ] )
2014-03-27 19:12:53 -04:00
for instance_id in instance_ids :
elb_backend . register_instances ( new_elb . name , [ instance_id ] )
2016-04-28 09:21:54 -04:00
2017-01-18 20:02:04 -08:00
policies = properties . get ( " Policies " , [ ] )
2023-02-27 22:08:24 -01:00
port_policies : Dict [ str , Any ] = { }
2017-01-18 20:02:04 -08:00
for policy in policies :
policy_name = policy [ " PolicyName " ]
2023-02-27 22:08:24 -01:00
other_policy = OtherPolicy ( policy_name , " " , [ ] )
2017-01-18 20:02:04 -08:00
elb_backend . create_lb_other_policy ( new_elb . name , other_policy )
for port in policy . get ( " InstancePorts " , [ ] ) :
2023-02-27 22:08:24 -01:00
policies_for_port : Any = port_policies . get ( port , set ( ) )
2017-01-18 20:02:04 -08:00
policies_for_port . add ( policy_name )
port_policies [ port ] = policies_for_port
for port , policies in port_policies . items ( ) :
2017-02-23 21:37:43 -05:00
elb_backend . set_load_balancer_policies_of_backend_server (
new_elb . name , port , list ( policies )
2019-10-31 08:44:26 -07:00
)
2017-01-18 20:02:04 -08:00
2016-04-28 09:21:54 -04:00
health_check = properties . get ( " HealthCheck " )
if health_check :
elb_backend . configure_health_check (
load_balancer_name = new_elb . name ,
timeout = health_check [ " Timeout " ] ,
healthy_threshold = health_check [ " HealthyThreshold " ] ,
unhealthy_threshold = health_check [ " UnhealthyThreshold " ] ,
interval = health_check [ " Interval " ] ,
target = health_check [ " Target " ] ,
)
2014-03-27 19:12:53 -04:00
return new_elb
2016-04-28 09:21:54 -04:00
@classmethod
2023-02-27 22:08:24 -01:00
def update_from_cloudformation_json ( # type: ignore[misc]
2022-08-13 09:49:43 +00:00
cls ,
2023-02-27 22:08:24 -01:00
original_resource : Any ,
new_resource_name : str ,
cloudformation_json : Any ,
account_id : str ,
region_name : str ,
) - > " FakeLoadBalancer " :
2017-02-23 21:37:43 -05:00
cls . delete_from_cloudformation_json (
2022-08-13 09:49:43 +00:00
original_resource . name , cloudformation_json , account_id , region_name
2017-02-23 21:37:43 -05:00
)
2016-04-28 09:21:54 -04:00
return cls . create_from_cloudformation_json (
2022-08-13 09:49:43 +00:00
new_resource_name , cloudformation_json , account_id , region_name
2016-04-28 09:21:54 -04:00
)
@classmethod
2023-02-27 22:08:24 -01:00
def delete_from_cloudformation_json ( # type: ignore[misc]
cls ,
resource_name : str ,
cloudformation_json : Any ,
account_id : str ,
region_name : str ,
) - > None :
2022-08-13 09:49:43 +00:00
elb_backend = elb_backends [ account_id ] [ region_name ]
2016-04-28 09:21:54 -04:00
try :
elb_backend . delete_load_balancer ( resource_name )
except KeyError :
pass
2014-03-27 19:12:53 -04:00
@property
2023-02-27 22:08:24 -01:00
def physical_resource_id ( self ) - > str :
2014-03-27 19:12:53 -04:00
return self . name
2021-11-03 20:00:42 -01:00
@classmethod
2023-02-27 22:08:24 -01:00
def has_cfn_attr ( cls , attr : str ) - > bool :
2022-03-11 20:28:45 -01:00
return attr in [
2021-11-03 20:00:42 -01:00
" CanonicalHostedZoneName " ,
" CanonicalHostedZoneNameID " ,
" DNSName " ,
" SourceSecurityGroup.GroupName " ,
" SourceSecurityGroup.OwnerAlias " ,
]
2023-02-27 22:08:24 -01:00
def get_cfn_attribute ( self , attribute_name : str ) - > Any :
2014-10-21 14:51:26 -04:00
from moto . cloudformation . exceptions import UnformattedGetAttTemplateException
2019-10-31 08:44:26 -07:00
2014-10-21 12:45:03 -04:00
if attribute_name == " CanonicalHostedZoneName " :
2017-02-23 21:37:43 -05:00
raise NotImplementedError (
' " Fn::GetAtt " : [ " {0} " , " CanonicalHostedZoneName " ] " '
)
2014-10-21 12:45:03 -04:00
elif attribute_name == " CanonicalHostedZoneNameID " :
2017-02-23 21:37:43 -05:00
raise NotImplementedError (
' " Fn::GetAtt " : [ " {0} " , " CanonicalHostedZoneNameID " ] " '
)
2014-10-21 12:45:03 -04:00
elif attribute_name == " DNSName " :
2016-04-28 09:21:54 -04:00
return self . dns_name
2014-10-21 12:45:03 -04:00
elif attribute_name == " SourceSecurityGroup.GroupName " :
2017-02-23 21:37:43 -05:00
raise NotImplementedError (
' " Fn::GetAtt " : [ " {0} " , " SourceSecurityGroup.GroupName " ] " '
)
2014-10-21 12:45:03 -04:00
elif attribute_name == " SourceSecurityGroup.OwnerAlias " :
2017-02-23 21:37:43 -05:00
raise NotImplementedError (
' " Fn::GetAtt " : [ " {0} " , " SourceSecurityGroup.OwnerAlias " ] " '
)
2014-10-21 14:51:26 -04:00
raise UnformattedGetAttTemplateException ( )
2014-10-21 12:45:03 -04:00
2015-03-22 15:35:27 +01:00
@classmethod
2023-02-27 22:08:24 -01:00
def get_default_attributes ( cls ) - > Dict [ str , Any ] : # type: ignore[misc]
attributes : Dict [ str , Any ] = dict ( )
2022-01-18 14:18:57 -01:00
attributes [ " cross_zone_load_balancing " ] = { " enabled " : False }
attributes [ " connection_draining " ] = { " enabled " : False }
attributes [ " access_log " ] = { " enabled " : False }
attributes [ " connection_settings " ] = { " idle_timeout " : 60 }
2015-03-22 15:35:27 +01:00
return attributes
2023-02-27 22:08:24 -01:00
def add_tag ( self , key : str , value : str ) - > None :
2015-12-09 21:30:40 +01:00
if len ( self . tags ) > = 10 and key not in self . tags :
raise TooManyTagsError ( )
self . tags [ key ] = value
2023-02-27 22:08:24 -01:00
def list_tags ( self ) - > Dict [ str , str ] :
2015-12-09 21:30:40 +01:00
return self . tags
2015-12-13 22:41:17 -05:00
2023-02-27 22:08:24 -01:00
def remove_tag ( self , key : str ) - > None :
2015-12-09 21:30:40 +01:00
if key in self . tags :
del self . tags [ key ]
2023-02-27 22:08:24 -01:00
def delete ( self , account_id : str , region : str ) - > None :
2021-06-23 11:57:09 -04:00
""" Not exposed as part of the ELB API - used for CloudFormation. """
2022-08-13 09:49:43 +00:00
elb_backends [ account_id ] [ region ] . delete_load_balancer ( self . name )
2016-04-28 09:21:54 -04:00
2015-07-18 09:08:27 -04:00
2013-07-22 22:50:58 -04:00
class ELBBackend ( BaseBackend ) :
2023-02-27 22:08:24 -01:00
def __init__ ( self , region_name : str , account_id : str ) :
2022-06-04 11:30:16 +00:00
super ( ) . __init__ ( region_name , account_id )
2023-02-27 22:08:24 -01:00
self . load_balancers : Dict [ str , FakeLoadBalancer ] = OrderedDict ( )
2013-07-22 22:50:58 -04:00
2017-07-19 15:58:49 -07:00
def create_load_balancer (
self ,
2023-02-27 22:08:24 -01:00
name : str ,
zones : List [ str ] ,
ports : List [ Dict [ str , Any ] ] ,
scheme : str = " internet-facing " ,
subnets : Optional [ List [ str ] ] = None ,
security_groups : Optional [ List [ str ] ] = None ,
) - > FakeLoadBalancer :
2016-04-14 14:43:03 +02:00
vpc_id = None
2022-08-13 09:49:43 +00:00
ec2_backend = ec2_backends [ self . account_id ] [ self . region_name ]
2016-04-14 14:43:03 +02:00
if subnets :
subnet = ec2_backend . get_subnet ( subnets [ 0 ] )
vpc_id = subnet . vpc_id
2022-03-21 19:55:19 -01:00
elif zones :
subnets = [
ec2_backend . get_default_subnet ( availability_zone = zone ) . id
for zone in zones
]
subnet = ec2_backend . get_subnet ( subnets [ 0 ] )
vpc_id = subnet . vpc_id
2016-05-15 20:04:00 +02:00
if name in self . load_balancers :
raise DuplicateLoadBalancerName ( name )
2017-06-12 16:42:42 -07:00
if not ports :
raise EmptyListenersError ( )
2017-07-19 15:58:49 -07:00
if not security_groups :
2022-03-21 19:55:19 -01:00
sg = ec2_backend . create_security_group (
2022-09-28 09:35:12 +00:00
name = f " default_elb_ { mock_random . uuid4 ( ) } " ,
2022-03-21 19:55:19 -01:00
description = " ELB created security group used when no security group is specified during ELB creation - modifications could impact traffic to future ELBs " ,
vpc_id = vpc_id ,
)
security_groups = [ sg . id ]
2017-07-19 15:58:49 -07:00
for security_group in security_groups :
if ec2_backend . get_security_group_from_id ( security_group ) is None :
raise InvalidSecurityGroupError ( )
2017-02-23 21:37:43 -05:00
new_load_balancer = FakeLoadBalancer (
2017-07-19 15:58:49 -07:00
name = name ,
zones = zones ,
ports = ports ,
scheme = scheme ,
subnets = subnets ,
security_groups = security_groups ,
vpc_id = vpc_id ,
2021-10-14 21:43:10 +00:00
elb_backend = self ,
2017-07-19 15:58:49 -07:00
)
2013-07-22 22:50:58 -04:00
self . load_balancers [ name ] = new_load_balancer
return new_load_balancer
2023-02-27 22:08:24 -01:00
def create_load_balancer_listeners (
self , name : str , ports : List [ Dict [ str , Any ] ]
) - > Optional [ FakeLoadBalancer ] :
2014-07-14 17:54:45 -07:00
balancer = self . load_balancers . get ( name , None )
if balancer :
2015-07-18 09:08:27 -04:00
for port in ports :
protocol = port [ " protocol " ]
instance_port = port [ " instance_port " ]
lb_port = port [ " load_balancer_port " ]
2018-04-13 07:33:53 -04:00
ssl_certificate_id = port . get ( " ssl_certificate_id " )
2014-07-14 17:54:45 -07:00
for listener in balancer . listeners :
if lb_port == listener . load_balancer_port :
2022-03-21 19:55:19 -01:00
if protocol . lower ( ) != listener . protocol . lower ( ) :
2017-07-06 21:52:01 -07:00
raise DuplicateListenerError ( name , lb_port )
if instance_port != listener . instance_port :
raise DuplicateListenerError ( name , lb_port )
if ssl_certificate_id != listener . ssl_certificate_id :
raise DuplicateListenerError ( name , lb_port )
2014-07-14 17:54:45 -07:00
break
else :
2022-03-21 19:55:19 -01:00
if ssl_certificate_id and not ssl_certificate_id . startswith (
" arn:aws:iam:: "
) :
2021-10-14 21:43:10 +00:00
self . _register_certificate (
ssl_certificate_id , balancer . dns_name
)
2017-02-23 21:37:43 -05:00
balancer . listeners . append (
FakeListener (
lb_port , instance_port , protocol , ssl_certificate_id
)
2019-10-31 08:44:26 -07:00
)
2014-07-14 17:54:45 -07:00
return balancer
2022-10-19 20:56:24 +00:00
def describe_load_balancers ( self , names : List [ str ] ) - > List [ FakeLoadBalancer ] :
2023-02-27 22:08:24 -01:00
balancers = list ( self . load_balancers . values ( ) )
2013-07-22 22:50:58 -04:00
if names :
2017-02-23 21:37:43 -05:00
matched_balancers = [
balancer for balancer in balancers if balancer . name in names
]
2015-12-13 22:41:17 -05:00
if len ( names ) != len ( matched_balancers ) :
2023-02-27 22:08:24 -01:00
missing_elb = list ( set ( names ) - set ( matched_balancers ) ) [ 0 ] # type: ignore[arg-type]
2015-12-13 22:41:17 -05:00
raise LoadBalancerNotFoundError ( missing_elb )
return matched_balancers
2013-07-22 22:50:58 -04:00
else :
return balancers
2023-02-27 22:08:24 -01:00
def describe_load_balancer_policies (
self , lb_name : str , policy_names : List [ str ]
) - > List [ Policy ] :
2022-03-21 19:55:19 -01:00
lb = self . describe_load_balancers ( [ lb_name ] ) [ 0 ]
policies = lb . policies
if policy_names :
policies = [ p for p in policies if p . policy_name in policy_names ]
if len ( policy_names ) != len ( policies ) :
raise PolicyNotFoundError ( )
return policies
2023-02-27 22:08:24 -01:00
def describe_instance_health (
self , lb_name : str , instances : List [ Dict [ str , str ] ]
) - > List [ Dict [ str , Any ] ] :
2022-11-23 18:10:18 -01:00
elb = self . get_load_balancer ( lb_name )
if elb is None :
raise NoActiveLoadBalancerFoundError ( name = lb_name )
2022-05-21 22:55:36 +00:00
provided_ids = [ i [ " InstanceId " ] for i in instances ]
2022-11-23 18:10:18 -01:00
registered_ids = elb . instance_ids
2022-08-13 09:49:43 +00:00
ec2_backend = ec2_backends [ self . account_id ] [ self . region_name ]
2022-05-21 22:55:36 +00:00
if len ( provided_ids ) == 0 :
provided_ids = registered_ids
instances = [ ]
for instance_id in provided_ids :
if instance_id not in registered_ids :
instances . append ( { " InstanceId " : instance_id , " State " : " Unknown " } )
else :
try :
instance = ec2_backend . get_instance ( instance_id )
state = " InService " if instance . is_running ( ) else " OutOfService "
instances . append ( { " InstanceId " : instance_id , " State " : state } )
except InvalidInstanceIdError :
pass
return instances
2023-02-27 22:08:24 -01:00
def delete_load_balancer_listeners (
self , name : str , ports : List [ str ]
) - > Optional [ FakeLoadBalancer ] :
balancer = self . get_load_balancer ( name )
2014-07-14 17:54:45 -07:00
listeners = [ ]
if balancer :
for lb_port in ports :
for listener in balancer . listeners :
2014-07-18 17:31:57 -07:00
if int ( lb_port ) == int ( listener . load_balancer_port ) :
2014-07-14 17:54:45 -07:00
continue
else :
listeners . append ( listener )
balancer . listeners = listeners
return balancer
2023-02-27 22:08:24 -01:00
def delete_load_balancer ( self , load_balancer_name : str ) - > None :
2013-07-22 22:50:58 -04:00
self . load_balancers . pop ( load_balancer_name , None )
2023-02-27 22:08:24 -01:00
def delete_load_balancer_policy ( self , lb_name : str , policy_name : str ) - > None :
2022-03-21 19:55:19 -01:00
lb = self . get_load_balancer ( lb_name )
lb . policies = [ p for p in lb . policies if p . policy_name != policy_name ]
2023-02-27 22:08:24 -01:00
def get_load_balancer ( self , load_balancer_name : str ) - > FakeLoadBalancer :
return self . load_balancers . get ( load_balancer_name ) # type: ignore[return-value]
2013-07-22 22:50:58 -04:00
2017-07-19 15:58:49 -07:00
def apply_security_groups_to_load_balancer (
2023-02-27 22:08:24 -01:00
self , load_balancer_name : str , security_group_ids : List [ str ]
) - > None :
load_balancer = self . get_load_balancer ( load_balancer_name )
2022-08-13 09:49:43 +00:00
ec2_backend = ec2_backends [ self . account_id ] [ self . region_name ]
2017-07-19 15:58:49 -07:00
for security_group_id in security_group_ids :
if ec2_backend . get_security_group_from_id ( security_group_id ) is None :
raise InvalidSecurityGroupError ( )
load_balancer . security_groups = security_group_ids
2013-07-22 22:50:58 -04:00
def configure_health_check (
self ,
2023-02-27 22:08:24 -01:00
load_balancer_name : str ,
timeout : str ,
healthy_threshold : str ,
unhealthy_threshold : str ,
interval : str ,
target : str ,
) - > FakeHealthCheck :
2013-07-22 22:50:58 -04:00
check = FakeHealthCheck (
timeout , healthy_threshold , unhealthy_threshold , interval , target
)
load_balancer = self . get_load_balancer ( load_balancer_name )
load_balancer . health_check = check
return check
2021-09-24 20:00:10 +00:00
def set_load_balancer_listener_ssl_certificate (
2023-02-27 22:08:24 -01:00
self , name : str , lb_port : str , ssl_certificate_id : str
) - > Optional [ FakeLoadBalancer ] :
2014-07-14 17:54:45 -07:00
balancer = self . load_balancers . get ( name , None )
if balancer :
for idx , listener in enumerate ( balancer . listeners ) :
if lb_port == listener . load_balancer_port :
2017-02-23 21:37:43 -05:00
balancer . listeners [ idx ] . ssl_certificate_id = ssl_certificate_id
2021-10-14 21:43:10 +00:00
if ssl_certificate_id :
self . _register_certificate (
ssl_certificate_id , balancer . dns_name
)
2014-07-14 17:54:45 -07:00
return balancer
2021-04-30 10:29:20 +02:00
def register_instances (
2022-10-19 20:56:24 +00:00
self ,
load_balancer_name : str ,
instance_ids : Iterable [ str ] ,
from_autoscaling : bool = False ,
) - > FakeLoadBalancer :
2013-07-22 22:50:58 -04:00
load_balancer = self . get_load_balancer ( load_balancer_name )
2021-04-30 10:29:20 +02:00
attr_name = (
" instance_sparse_ids "
if not from_autoscaling
else " instance_autoscaling_ids "
)
actual_instance_ids = getattr ( load_balancer , attr_name )
actual_instance_ids . extend ( instance_ids )
2013-07-22 22:50:58 -04:00
return load_balancer
2021-04-30 10:29:20 +02:00
def deregister_instances (
2022-10-19 20:56:24 +00:00
self ,
load_balancer_name : str ,
instance_ids : Iterable [ str ] ,
from_autoscaling : bool = False ,
) - > FakeLoadBalancer :
2013-07-22 22:50:58 -04:00
load_balancer = self . get_load_balancer ( load_balancer_name )
2021-04-30 10:29:20 +02:00
attr_name = (
" instance_sparse_ids "
if not from_autoscaling
else " instance_autoscaling_ids "
)
actual_instance_ids = getattr ( load_balancer , attr_name )
2017-02-23 21:37:43 -05:00
new_instance_ids = [
instance_id
2021-04-30 10:29:20 +02:00
for instance_id in actual_instance_ids
2017-02-23 21:37:43 -05:00
if instance_id not in instance_ids
]
2021-04-30 10:29:20 +02:00
setattr ( load_balancer , attr_name , new_instance_ids )
2013-07-22 22:50:58 -04:00
return load_balancer
2022-01-18 14:18:57 -01:00
def modify_load_balancer_attributes (
self ,
2023-02-27 22:08:24 -01:00
load_balancer_name : str ,
cross_zone : Optional [ Dict [ str , Any ] ] = None ,
connection_settings : Optional [ Dict [ str , Any ] ] = None ,
connection_draining : Optional [ Dict [ str , Any ] ] = None ,
access_log : Optional [ Dict [ str , Any ] ] = None ,
) - > None :
2015-03-22 15:35:27 +01:00
load_balancer = self . get_load_balancer ( load_balancer_name )
2022-01-18 14:18:57 -01:00
if cross_zone :
load_balancer . attributes [ " cross_zone_load_balancing " ] = cross_zone
if connection_settings :
load_balancer . attributes [ " connection_settings " ] = connection_settings
if connection_draining :
load_balancer . attributes [ " connection_draining " ] = connection_draining
if " timeout " not in connection_draining :
load_balancer . attributes [ " connection_draining " ] [
" timeout "
] = 300 # default
if access_log :
load_balancer . attributes [ " access_log " ] = access_log
2015-03-22 15:35:27 +01:00
2022-03-21 19:55:19 -01:00
def create_lb_other_policy (
2023-02-27 22:08:24 -01:00
self ,
load_balancer_name : str ,
policy_name : str ,
policy_type_name : str ,
policy_attrs : List [ Dict [ str , str ] ] ,
) - > FakeLoadBalancer :
2015-07-14 23:54:58 +00:00
load_balancer = self . get_load_balancer ( load_balancer_name )
2022-03-21 19:55:19 -01:00
if policy_name not in [ p . policy_name for p in load_balancer . policies ] :
load_balancer . policies . append (
OtherPolicy ( policy_name , policy_type_name , policy_attrs )
)
2017-01-18 20:02:04 -08:00
2015-07-14 23:54:58 +00:00
return load_balancer
2022-03-21 19:55:19 -01:00
def create_app_cookie_stickiness_policy (
2023-02-27 22:08:24 -01:00
self , load_balancer_name : str , policy_name : str , cookie_name : str
) - > FakeLoadBalancer :
2015-07-14 23:54:58 +00:00
load_balancer = self . get_load_balancer ( load_balancer_name )
2022-03-21 19:55:19 -01:00
policy = AppCookieStickinessPolicy ( policy_name , cookie_name )
load_balancer . policies . append ( policy )
2015-07-14 23:54:58 +00:00
return load_balancer
2022-03-21 19:55:19 -01:00
def create_lb_cookie_stickiness_policy (
2023-02-27 22:08:24 -01:00
self ,
load_balancer_name : str ,
policy_name : str ,
cookie_expiration_period : Optional [ int ] ,
) - > FakeLoadBalancer :
2015-07-14 23:54:58 +00:00
load_balancer = self . get_load_balancer ( load_balancer_name )
2022-03-21 19:55:19 -01:00
policy = LbCookieStickinessPolicy ( policy_name , cookie_expiration_period )
load_balancer . policies . append ( policy )
2015-07-14 23:54:58 +00:00
return load_balancer
def set_load_balancer_policies_of_backend_server (
2023-02-27 22:08:24 -01:00
self , load_balancer_name : str , instance_port : int , policies : List [ str ]
) - > FakeLoadBalancer :
2015-07-14 23:54:58 +00:00
load_balancer = self . get_load_balancer ( load_balancer_name )
2017-02-23 21:37:43 -05:00
backend = [
b for b in load_balancer . backends if int ( b . instance_port ) == instance_port
] [ 0 ]
2015-07-14 23:54:58 +00:00
backend_idx = load_balancer . backends . index ( backend )
backend . policy_names = policies
load_balancer . backends [ backend_idx ] = backend
return load_balancer
def set_load_balancer_policies_of_listener (
2023-02-27 22:08:24 -01:00
self , load_balancer_name : str , load_balancer_port : int , policies : List [ str ]
) - > FakeLoadBalancer :
2015-07-14 23:54:58 +00:00
load_balancer = self . get_load_balancer ( load_balancer_name )
2017-02-23 21:37:43 -05:00
listener = [
2021-02-24 23:46:11 -08:00
l_listener
for l_listener in load_balancer . listeners
if int ( l_listener . load_balancer_port ) == load_balancer_port
2017-02-23 21:37:43 -05:00
] [ 0 ]
2015-07-14 23:54:58 +00:00
listener_idx = load_balancer . listeners . index ( listener )
listener . policy_names = policies
load_balancer . listeners [ listener_idx ] = listener
return load_balancer
2023-02-27 22:08:24 -01:00
def _register_certificate ( self , ssl_certificate_id : str , dns_name : str ) - > None :
2022-10-07 14:41:31 +00:00
from moto . acm . models import acm_backends , CertificateNotFound
2021-10-14 21:43:10 +00:00
2022-08-13 09:49:43 +00:00
acm_backend = acm_backends [ self . account_id ] [ self . region_name ]
2021-10-14 21:43:10 +00:00
try :
acm_backend . set_certificate_in_use_by ( ssl_certificate_id , dns_name )
2022-10-07 14:41:31 +00:00
except CertificateNotFound :
2021-10-14 21:43:10 +00:00
raise CertificateNotFoundException ( )
2022-03-21 19:55:19 -01:00
def enable_availability_zones_for_load_balancer (
2023-02-27 22:08:24 -01:00
self , load_balancer_name : str , availability_zones : List [ str ]
) - > List [ str ] :
2022-03-21 19:55:19 -01:00
load_balancer = self . get_load_balancer ( load_balancer_name )
load_balancer . zones = sorted (
list ( set ( load_balancer . zones + availability_zones ) )
)
return load_balancer . zones
def disable_availability_zones_for_load_balancer (
2023-02-27 22:08:24 -01:00
self , load_balancer_name : str , availability_zones : List [ str ]
) - > List [ str ] :
2022-03-21 19:55:19 -01:00
load_balancer = self . get_load_balancer ( load_balancer_name )
load_balancer . zones = sorted (
list (
set ( [ az for az in load_balancer . zones if az not in availability_zones ] )
)
)
return load_balancer . zones
2023-02-27 22:08:24 -01:00
def attach_load_balancer_to_subnets (
self , load_balancer_name : str , subnets : List [ str ]
) - > List [ str ] :
2022-03-21 19:55:19 -01:00
load_balancer = self . get_load_balancer ( load_balancer_name )
load_balancer . subnets = list ( set ( load_balancer . subnets + subnets ) )
return load_balancer . subnets
2023-02-27 22:08:24 -01:00
def detach_load_balancer_from_subnets (
self , load_balancer_name : str , subnets : List [ str ]
) - > List [ str ] :
2022-03-21 19:55:19 -01:00
load_balancer = self . get_load_balancer ( load_balancer_name )
load_balancer . subnets = [ s for s in load_balancer . subnets if s not in subnets ]
return load_balancer . subnets
2014-11-15 13:34:52 -05:00
2021-12-24 20:02:45 -01:00
# Use the same regions as EC2
elb_backends = BackendDict ( ELBBackend , " ec2 " )