1# Copyright (c) 2006-2012 Mitch Garnaat http://garnaat.org/ 2# Copyright (c) 2012 Amazon.com, Inc. or its affiliates. 3# All Rights Reserved 4# 5# Permission is hereby granted, free of charge, to any person obtaining a 6# copy of this software and associated documentation files (the 7# "Software"), to deal in the Software without restriction, including 8# without limitation the rights to use, copy, modify, merge, publish, dis- 9# tribute, sublicense, and/or sell copies of the Software, and to permit 10# persons to whom the Software is furnished to do so, subject to the fol- 11# lowing conditions: 12# 13# The above copyright notice and this permission notice shall be included 14# in all copies or substantial portions of the Software. 15# 16# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- 18# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 19# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22# IN THE SOFTWARE. 23# 24""" 25This module provides an interface to the Elastic Compute Cloud (EC2) 26load balancing service from AWS. 27""" 28from boto.connection import AWSQueryConnection 29from boto.ec2.instanceinfo import InstanceInfo 30from boto.ec2.elb.loadbalancer import LoadBalancer, LoadBalancerZones 31from boto.ec2.elb.instancestate import InstanceState 32from boto.ec2.elb.healthcheck import HealthCheck 33from boto.regioninfo import RegionInfo, get_regions, load_regions 34import boto 35from boto.compat import six 36 37RegionData = load_regions().get('elasticloadbalancing', {}) 38 39 40def regions(): 41 """ 42 Get all available regions for the ELB service. 43 44 :rtype: list 45 :return: A list of :class:`boto.RegionInfo` instances 46 """ 47 return get_regions('elasticloadbalancing', connection_cls=ELBConnection) 48 49 50def connect_to_region(region_name, **kw_params): 51 """ 52 Given a valid region name, return a 53 :class:`boto.ec2.elb.ELBConnection`. 54 55 :param str region_name: The name of the region to connect to. 56 57 :rtype: :class:`boto.ec2.ELBConnection` or ``None`` 58 :return: A connection to the given region, or None if an invalid region 59 name is given 60 """ 61 for region in regions(): 62 if region.name == region_name: 63 return region.connect(**kw_params) 64 return None 65 66 67class ELBConnection(AWSQueryConnection): 68 69 APIVersion = boto.config.get('Boto', 'elb_version', '2012-06-01') 70 DefaultRegionName = boto.config.get('Boto', 'elb_region_name', 'us-east-1') 71 DefaultRegionEndpoint = boto.config.get( 72 'Boto', 'elb_region_endpoint', 73 'elasticloadbalancing.us-east-1.amazonaws.com') 74 75 def __init__(self, aws_access_key_id=None, aws_secret_access_key=None, 76 is_secure=True, port=None, proxy=None, proxy_port=None, 77 proxy_user=None, proxy_pass=None, debug=0, 78 https_connection_factory=None, region=None, path='/', 79 security_token=None, validate_certs=True, profile_name=None): 80 """ 81 Init method to create a new connection to EC2 Load Balancing Service. 82 83 .. note:: The region argument is overridden by the region specified in 84 the boto configuration file. 85 """ 86 if not region: 87 region = RegionInfo(self, self.DefaultRegionName, 88 self.DefaultRegionEndpoint) 89 self.region = region 90 super(ELBConnection, self).__init__(aws_access_key_id, 91 aws_secret_access_key, 92 is_secure, port, proxy, proxy_port, 93 proxy_user, proxy_pass, 94 self.region.endpoint, debug, 95 https_connection_factory, path, 96 security_token, 97 validate_certs=validate_certs, 98 profile_name=profile_name) 99 100 def _required_auth_capability(self): 101 return ['hmac-v4'] 102 103 def build_list_params(self, params, items, label): 104 if isinstance(items, six.string_types): 105 items = [items] 106 for index, item in enumerate(items): 107 params[label % (index + 1)] = item 108 109 def get_all_load_balancers(self, load_balancer_names=None, marker=None): 110 """ 111 Retrieve all load balancers associated with your account. 112 113 :type load_balancer_names: list 114 :keyword load_balancer_names: An optional list of load balancer names. 115 116 :type marker: string 117 :param marker: Use this only when paginating results and only 118 in follow-up request after you've received a response 119 where the results are truncated. Set this to the value of 120 the Marker element in the response you just received. 121 122 :rtype: :py:class:`boto.resultset.ResultSet` 123 :return: A ResultSet containing instances of 124 :class:`boto.ec2.elb.loadbalancer.LoadBalancer` 125 """ 126 params = {} 127 if load_balancer_names: 128 self.build_list_params(params, load_balancer_names, 129 'LoadBalancerNames.member.%d') 130 131 if marker: 132 params['Marker'] = marker 133 134 return self.get_list('DescribeLoadBalancers', params, 135 [('member', LoadBalancer)]) 136 137 def create_load_balancer(self, name, zones, listeners=None, subnets=None, 138 security_groups=None, scheme='internet-facing', 139 complex_listeners=None): 140 """ 141 Create a new load balancer for your account. By default the load 142 balancer will be created in EC2. To create a load balancer inside a 143 VPC, parameter zones must be set to None and subnets must not be None. 144 The load balancer will be automatically created under the VPC that 145 contains the subnet(s) specified. 146 147 :type name: string 148 :param name: The mnemonic name associated with the new load balancer 149 150 :type zones: List of strings 151 :param zones: The names of the availability zone(s) to add. 152 153 :type listeners: List of tuples 154 :param listeners: Each tuple contains three or four values, 155 (LoadBalancerPortNumber, InstancePortNumber, Protocol, 156 [SSLCertificateId]) where LoadBalancerPortNumber and 157 InstancePortNumber are integer values between 1 and 65535, 158 Protocol is a string containing either 'TCP', 'SSL', HTTP', or 159 'HTTPS'; SSLCertificateID is the ARN of a AWS IAM 160 certificate, and must be specified when doing HTTPS. 161 162 :type subnets: list of strings 163 :param subnets: A list of subnet IDs in your VPC to attach to 164 your LoadBalancer. 165 166 :type security_groups: list of strings 167 :param security_groups: The security groups assigned to your 168 LoadBalancer within your VPC. 169 170 :type scheme: string 171 :param scheme: The type of a LoadBalancer. By default, Elastic 172 Load Balancing creates an internet-facing LoadBalancer with 173 a publicly resolvable DNS name, which resolves to public IP 174 addresses. 175 176 Specify the value internal for this option to create an 177 internal LoadBalancer with a DNS name that resolves to 178 private IP addresses. 179 180 This option is only available for LoadBalancers attached 181 to an Amazon VPC. 182 183 :type complex_listeners: List of tuples 184 :param complex_listeners: Each tuple contains four or five values, 185 (LoadBalancerPortNumber, InstancePortNumber, Protocol, 186 InstanceProtocol, SSLCertificateId). 187 188 Where: 189 - LoadBalancerPortNumber and InstancePortNumber are integer 190 values between 1 and 65535 191 - Protocol and InstanceProtocol is a string containing 192 either 'TCP', 193 'SSL', 'HTTP', or 'HTTPS' 194 - SSLCertificateId is the ARN of an SSL certificate loaded into 195 AWS IAM 196 197 :rtype: :class:`boto.ec2.elb.loadbalancer.LoadBalancer` 198 :return: The newly created 199 :class:`boto.ec2.elb.loadbalancer.LoadBalancer` 200 """ 201 if not listeners and not complex_listeners: 202 # Must specify one of the two options 203 return None 204 205 params = {'LoadBalancerName': name, 206 'Scheme': scheme} 207 208 # Handle legacy listeners 209 if listeners: 210 for index, listener in enumerate(listeners): 211 i = index + 1 212 protocol = listener[2].upper() 213 params['Listeners.member.%d.LoadBalancerPort' % i] = listener[0] 214 params['Listeners.member.%d.InstancePort' % i] = listener[1] 215 params['Listeners.member.%d.Protocol' % i] = listener[2] 216 if protocol == 'HTTPS' or protocol == 'SSL': 217 params['Listeners.member.%d.SSLCertificateId' % i] = listener[3] 218 219 # Handle the full listeners 220 if complex_listeners: 221 for index, listener in enumerate(complex_listeners): 222 i = index + 1 223 protocol = listener[2].upper() 224 InstanceProtocol = listener[3].upper() 225 params['Listeners.member.%d.LoadBalancerPort' % i] = listener[0] 226 params['Listeners.member.%d.InstancePort' % i] = listener[1] 227 params['Listeners.member.%d.Protocol' % i] = listener[2] 228 params['Listeners.member.%d.InstanceProtocol' % i] = listener[3] 229 if protocol == 'HTTPS' or protocol == 'SSL': 230 params['Listeners.member.%d.SSLCertificateId' % i] = listener[4] 231 232 if zones: 233 self.build_list_params(params, zones, 'AvailabilityZones.member.%d') 234 235 if subnets: 236 self.build_list_params(params, subnets, 'Subnets.member.%d') 237 238 if security_groups: 239 self.build_list_params(params, security_groups, 240 'SecurityGroups.member.%d') 241 242 load_balancer = self.get_object('CreateLoadBalancer', 243 params, LoadBalancer) 244 load_balancer.name = name 245 load_balancer.listeners = listeners 246 load_balancer.availability_zones = zones 247 load_balancer.subnets = subnets 248 load_balancer.security_groups = security_groups 249 return load_balancer 250 251 def create_load_balancer_listeners(self, name, listeners=None, 252 complex_listeners=None): 253 """ 254 Creates a Listener (or group of listeners) for an existing 255 Load Balancer 256 257 :type name: string 258 :param name: The name of the load balancer to create the listeners for 259 260 :type listeners: List of tuples 261 :param listeners: Each tuple contains three or four values, 262 (LoadBalancerPortNumber, InstancePortNumber, Protocol, 263 [SSLCertificateId]) where LoadBalancerPortNumber and 264 InstancePortNumber are integer values between 1 and 65535, 265 Protocol is a string containing either 'TCP', 'SSL', HTTP', or 266 'HTTPS'; SSLCertificateID is the ARN of a AWS IAM 267 certificate, and must be specified when doing HTTPS. 268 269 :type complex_listeners: List of tuples 270 :param complex_listeners: Each tuple contains four or five values, 271 (LoadBalancerPortNumber, InstancePortNumber, Protocol, 272 InstanceProtocol, SSLCertificateId). 273 274 Where: 275 - LoadBalancerPortNumber and InstancePortNumber are integer 276 values between 1 and 65535 277 - Protocol and InstanceProtocol is a string containing 278 either 'TCP', 279 'SSL', 'HTTP', or 'HTTPS' 280 - SSLCertificateId is the ARN of an SSL certificate loaded into 281 AWS IAM 282 283 :return: The status of the request 284 """ 285 if not listeners and not complex_listeners: 286 # Must specify one of the two options 287 return None 288 289 params = {'LoadBalancerName': name} 290 291 # Handle the simple listeners 292 if listeners: 293 for index, listener in enumerate(listeners): 294 i = index + 1 295 protocol = listener[2].upper() 296 params['Listeners.member.%d.LoadBalancerPort' % i] = listener[0] 297 params['Listeners.member.%d.InstancePort' % i] = listener[1] 298 params['Listeners.member.%d.Protocol' % i] = listener[2] 299 if protocol == 'HTTPS' or protocol == 'SSL': 300 params['Listeners.member.%d.SSLCertificateId' % i] = listener[3] 301 302 # Handle the full listeners 303 if complex_listeners: 304 for index, listener in enumerate(complex_listeners): 305 i = index + 1 306 protocol = listener[2].upper() 307 InstanceProtocol = listener[3].upper() 308 params['Listeners.member.%d.LoadBalancerPort' % i] = listener[0] 309 params['Listeners.member.%d.InstancePort' % i] = listener[1] 310 params['Listeners.member.%d.Protocol' % i] = listener[2] 311 params['Listeners.member.%d.InstanceProtocol' % i] = listener[3] 312 if protocol == 'HTTPS' or protocol == 'SSL': 313 params['Listeners.member.%d.SSLCertificateId' % i] = listener[4] 314 315 return self.get_status('CreateLoadBalancerListeners', params) 316 317 def delete_load_balancer(self, name): 318 """ 319 Delete a Load Balancer from your account. 320 321 :type name: string 322 :param name: The name of the Load Balancer to delete 323 """ 324 params = {'LoadBalancerName': name} 325 return self.get_status('DeleteLoadBalancer', params) 326 327 def delete_load_balancer_listeners(self, name, ports): 328 """ 329 Deletes a load balancer listener (or group of listeners) 330 331 :type name: string 332 :param name: The name of the load balancer to create the listeners for 333 334 :type ports: List int 335 :param ports: Each int represents the port on the ELB to be removed 336 337 :return: The status of the request 338 """ 339 params = {'LoadBalancerName': name} 340 for index, port in enumerate(ports): 341 params['LoadBalancerPorts.member.%d' % (index + 1)] = port 342 return self.get_status('DeleteLoadBalancerListeners', params) 343 344 def enable_availability_zones(self, load_balancer_name, zones_to_add): 345 """ 346 Add availability zones to an existing Load Balancer 347 All zones must be in the same region as the Load Balancer 348 Adding zones that are already registered with the Load Balancer 349 has no effect. 350 351 :type load_balancer_name: string 352 :param load_balancer_name: The name of the Load Balancer 353 354 :type zones: List of strings 355 :param zones: The name of the zone(s) to add. 356 357 :rtype: List of strings 358 :return: An updated list of zones for this Load Balancer. 359 360 """ 361 params = {'LoadBalancerName': load_balancer_name} 362 self.build_list_params(params, zones_to_add, 363 'AvailabilityZones.member.%d') 364 obj = self.get_object('EnableAvailabilityZonesForLoadBalancer', 365 params, LoadBalancerZones) 366 return obj.zones 367 368 def disable_availability_zones(self, load_balancer_name, zones_to_remove): 369 """ 370 Remove availability zones from an existing Load Balancer. 371 All zones must be in the same region as the Load Balancer. 372 Removing zones that are not registered with the Load Balancer 373 has no effect. 374 You cannot remove all zones from an Load Balancer. 375 376 :type load_balancer_name: string 377 :param load_balancer_name: The name of the Load Balancer 378 379 :type zones: List of strings 380 :param zones: The name of the zone(s) to remove. 381 382 :rtype: List of strings 383 :return: An updated list of zones for this Load Balancer. 384 385 """ 386 params = {'LoadBalancerName': load_balancer_name} 387 self.build_list_params(params, zones_to_remove, 388 'AvailabilityZones.member.%d') 389 obj = self.get_object('DisableAvailabilityZonesForLoadBalancer', 390 params, LoadBalancerZones) 391 return obj.zones 392 393 def modify_lb_attribute(self, load_balancer_name, attribute, value): 394 """Changes an attribute of a Load Balancer 395 396 :type load_balancer_name: string 397 :param load_balancer_name: The name of the Load Balancer 398 399 :type attribute: string 400 :param attribute: The attribute you wish to change. 401 402 * crossZoneLoadBalancing - Boolean (true) 403 * connectingSettings - :py:class:`ConnectionSettingAttribute` instance 404 * accessLog - :py:class:`AccessLogAttribute` instance 405 * connectionDraining - :py:class:`ConnectionDrainingAttribute` instance 406 407 :type value: string 408 :param value: The new value for the attribute 409 410 :rtype: bool 411 :return: Whether the operation succeeded or not 412 """ 413 414 bool_reqs = ('crosszoneloadbalancing',) 415 if attribute.lower() in bool_reqs: 416 if isinstance(value, bool): 417 if value: 418 value = 'true' 419 else: 420 value = 'false' 421 422 params = {'LoadBalancerName': load_balancer_name} 423 if attribute.lower() == 'crosszoneloadbalancing': 424 params['LoadBalancerAttributes.CrossZoneLoadBalancing.Enabled' 425 ] = value 426 elif attribute.lower() == 'accesslog': 427 params['LoadBalancerAttributes.AccessLog.Enabled'] = \ 428 value.enabled and 'true' or 'false' 429 params['LoadBalancerAttributes.AccessLog.S3BucketName'] = \ 430 value.s3_bucket_name 431 params['LoadBalancerAttributes.AccessLog.S3BucketPrefix'] = \ 432 value.s3_bucket_prefix 433 params['LoadBalancerAttributes.AccessLog.EmitInterval'] = \ 434 value.emit_interval 435 elif attribute.lower() == 'connectiondraining': 436 params['LoadBalancerAttributes.ConnectionDraining.Enabled'] = \ 437 value.enabled and 'true' or 'false' 438 params['LoadBalancerAttributes.ConnectionDraining.Timeout'] = \ 439 value.timeout 440 elif attribute.lower() == 'connectingsettings': 441 params['LoadBalancerAttributes.ConnectionSettings.IdleTimeout'] = \ 442 value.idle_timeout 443 else: 444 raise ValueError('InvalidAttribute', attribute) 445 return self.get_status('ModifyLoadBalancerAttributes', params, 446 verb='GET') 447 448 def get_all_lb_attributes(self, load_balancer_name): 449 """Gets all Attributes of a Load Balancer 450 451 :type load_balancer_name: string 452 :param load_balancer_name: The name of the Load Balancer 453 454 :rtype: boto.ec2.elb.attribute.LbAttributes 455 :return: The attribute object of the ELB. 456 """ 457 from boto.ec2.elb.attributes import LbAttributes 458 params = {'LoadBalancerName': load_balancer_name} 459 return self.get_object('DescribeLoadBalancerAttributes', 460 params, LbAttributes) 461 462 def get_lb_attribute(self, load_balancer_name, attribute): 463 """Gets an attribute of a Load Balancer 464 465 This will make an EC2 call for each method call. 466 467 :type load_balancer_name: string 468 :param load_balancer_name: The name of the Load Balancer 469 470 :type attribute: string 471 :param attribute: The attribute you wish to see. 472 473 * accessLog - :py:class:`AccessLogAttribute` instance 474 * crossZoneLoadBalancing - Boolean 475 * connectingSettings - :py:class:`ConnectionSettingAttribute` instance 476 * connectionDraining - :py:class:`ConnectionDrainingAttribute` 477 instance 478 479 :rtype: Attribute dependent 480 :return: The new value for the attribute 481 """ 482 attributes = self.get_all_lb_attributes(load_balancer_name) 483 if attribute.lower() == 'accesslog': 484 return attributes.access_log 485 if attribute.lower() == 'crosszoneloadbalancing': 486 return attributes.cross_zone_load_balancing.enabled 487 if attribute.lower() == 'connectiondraining': 488 return attributes.connection_draining 489 if attribute.lower() == 'connectingsettings': 490 return attributes.connecting_settings 491 return None 492 493 def register_instances(self, load_balancer_name, instances): 494 """ 495 Add new Instances to an existing Load Balancer. 496 497 :type load_balancer_name: string 498 :param load_balancer_name: The name of the Load Balancer 499 500 :type instances: List of strings 501 :param instances: The instance ID's of the EC2 instances to add. 502 503 :rtype: List of strings 504 :return: An updated list of instances for this Load Balancer. 505 506 """ 507 params = {'LoadBalancerName': load_balancer_name} 508 self.build_list_params(params, instances, 509 'Instances.member.%d.InstanceId') 510 return self.get_list('RegisterInstancesWithLoadBalancer', 511 params, [('member', InstanceInfo)]) 512 513 def deregister_instances(self, load_balancer_name, instances): 514 """ 515 Remove Instances from an existing Load Balancer. 516 517 :type load_balancer_name: string 518 :param load_balancer_name: The name of the Load Balancer 519 520 :type instances: List of strings 521 :param instances: The instance ID's of the EC2 instances to remove. 522 523 :rtype: List of strings 524 :return: An updated list of instances for this Load Balancer. 525 526 """ 527 params = {'LoadBalancerName': load_balancer_name} 528 self.build_list_params(params, instances, 529 'Instances.member.%d.InstanceId') 530 return self.get_list('DeregisterInstancesFromLoadBalancer', 531 params, [('member', InstanceInfo)]) 532 533 def describe_instance_health(self, load_balancer_name, instances=None): 534 """ 535 Get current state of all Instances registered to an Load Balancer. 536 537 :type load_balancer_name: string 538 :param load_balancer_name: The name of the Load Balancer 539 540 :type instances: List of strings 541 :param instances: The instance ID's of the EC2 instances 542 to return status for. If not provided, 543 the state of all instances will be returned. 544 545 :rtype: List of :class:`boto.ec2.elb.instancestate.InstanceState` 546 :return: list of state info for instances in this Load Balancer. 547 548 """ 549 params = {'LoadBalancerName': load_balancer_name} 550 if instances: 551 self.build_list_params(params, instances, 552 'Instances.member.%d.InstanceId') 553 return self.get_list('DescribeInstanceHealth', params, 554 [('member', InstanceState)]) 555 556 def configure_health_check(self, name, health_check): 557 """ 558 Define a health check for the EndPoints. 559 560 :type name: string 561 :param name: The mnemonic name associated with the load balancer 562 563 :type health_check: :class:`boto.ec2.elb.healthcheck.HealthCheck` 564 :param health_check: A HealthCheck object populated with the desired 565 values. 566 567 :rtype: :class:`boto.ec2.elb.healthcheck.HealthCheck` 568 :return: The updated :class:`boto.ec2.elb.healthcheck.HealthCheck` 569 """ 570 params = {'LoadBalancerName': name, 571 'HealthCheck.Timeout': health_check.timeout, 572 'HealthCheck.Target': health_check.target, 573 'HealthCheck.Interval': health_check.interval, 574 'HealthCheck.UnhealthyThreshold': health_check.unhealthy_threshold, 575 'HealthCheck.HealthyThreshold': health_check.healthy_threshold} 576 return self.get_object('ConfigureHealthCheck', params, HealthCheck) 577 578 def set_lb_listener_SSL_certificate(self, lb_name, lb_port, 579 ssl_certificate_id): 580 """ 581 Sets the certificate that terminates the specified listener's SSL 582 connections. The specified certificate replaces any prior certificate 583 that was used on the same LoadBalancer and port. 584 """ 585 params = {'LoadBalancerName': lb_name, 586 'LoadBalancerPort': lb_port, 587 'SSLCertificateId': ssl_certificate_id} 588 return self.get_status('SetLoadBalancerListenerSSLCertificate', params) 589 590 def create_app_cookie_stickiness_policy(self, name, lb_name, policy_name): 591 """ 592 Generates a stickiness policy with sticky session lifetimes that follow 593 that of an application-generated cookie. This policy can only be 594 associated with HTTP listeners. 595 596 This policy is similar to the policy created by 597 CreateLBCookieStickinessPolicy, except that the lifetime of the special 598 Elastic Load Balancing cookie follows the lifetime of the 599 application-generated cookie specified in the policy configuration. The 600 load balancer only inserts a new stickiness cookie when the application 601 response includes a new application cookie. 602 603 If the application cookie is explicitly removed or expires, the session 604 stops being sticky until a new application cookie is issued. 605 """ 606 params = {'CookieName': name, 607 'LoadBalancerName': lb_name, 608 'PolicyName': policy_name} 609 return self.get_status('CreateAppCookieStickinessPolicy', params) 610 611 def create_lb_cookie_stickiness_policy(self, cookie_expiration_period, 612 lb_name, policy_name): 613 """ 614 Generates a stickiness policy with sticky session lifetimes controlled 615 by the lifetime of the browser (user-agent) or a specified expiration 616 period. This policy can only be associated only with HTTP listeners. 617 618 When a load balancer implements this policy, the load balancer uses a 619 special cookie to track the backend server instance for each request. 620 When the load balancer receives a request, it first checks to see if 621 this cookie is present in the request. If so, the load balancer sends 622 the request to the application server specified in the cookie. If not, 623 the load balancer sends the request to a server that is chosen based on 624 the existing load balancing algorithm. 625 626 A cookie is inserted into the response for binding subsequent requests 627 from the same user to that server. The validity of the cookie is based 628 on the cookie expiration time, which is specified in the policy 629 configuration. 630 631 None may be passed for cookie_expiration_period. 632 """ 633 params = {'LoadBalancerName': lb_name, 634 'PolicyName': policy_name} 635 if cookie_expiration_period is not None: 636 params['CookieExpirationPeriod'] = cookie_expiration_period 637 return self.get_status('CreateLBCookieStickinessPolicy', params) 638 639 def create_lb_policy(self, lb_name, policy_name, policy_type, 640 policy_attributes): 641 """ 642 Creates a new policy that contains the necessary attributes 643 depending on the policy type. Policies are settings that are 644 saved for your load balancer and that can be applied to the 645 front-end listener, or the back-end application server. 646 647 """ 648 params = {'LoadBalancerName': lb_name, 649 'PolicyName': policy_name, 650 'PolicyTypeName': policy_type} 651 for index, (name, value) in enumerate(six.iteritems(policy_attributes), 1): 652 params['PolicyAttributes.member.%d.AttributeName' % index] = name 653 params['PolicyAttributes.member.%d.AttributeValue' % index] = value 654 else: 655 params['PolicyAttributes'] = '' 656 return self.get_status('CreateLoadBalancerPolicy', params) 657 658 def delete_lb_policy(self, lb_name, policy_name): 659 """ 660 Deletes a policy from the LoadBalancer. The specified policy must not 661 be enabled for any listeners. 662 """ 663 params = {'LoadBalancerName': lb_name, 664 'PolicyName': policy_name} 665 return self.get_status('DeleteLoadBalancerPolicy', params) 666 667 def set_lb_policies_of_listener(self, lb_name, lb_port, policies): 668 """ 669 Associates, updates, or disables a policy with a listener on the load 670 balancer. Currently only zero (0) or one (1) policy can be associated 671 with a listener. 672 """ 673 params = {'LoadBalancerName': lb_name, 674 'LoadBalancerPort': lb_port} 675 if len(policies): 676 self.build_list_params(params, policies, 'PolicyNames.member.%d') 677 else: 678 params['PolicyNames'] = '' 679 return self.get_status('SetLoadBalancerPoliciesOfListener', params) 680 681 def set_lb_policies_of_backend_server(self, lb_name, instance_port, 682 policies): 683 """ 684 Replaces the current set of policies associated with a port on which 685 the back-end server is listening with a new set of policies. 686 """ 687 params = {'LoadBalancerName': lb_name, 688 'InstancePort': instance_port} 689 if policies: 690 self.build_list_params(params, policies, 'PolicyNames.member.%d') 691 else: 692 params['PolicyNames'] = '' 693 return self.get_status('SetLoadBalancerPoliciesForBackendServer', 694 params) 695 696 def apply_security_groups_to_lb(self, name, security_groups): 697 """ 698 Associates one or more security groups with the load balancer. 699 The provided security groups will override any currently applied 700 security groups. 701 702 :type name: string 703 :param name: The name of the Load Balancer 704 705 :type security_groups: List of strings 706 :param security_groups: The name of the security group(s) to add. 707 708 :rtype: List of strings 709 :return: An updated list of security groups for this Load Balancer. 710 711 """ 712 params = {'LoadBalancerName': name} 713 self.build_list_params(params, security_groups, 714 'SecurityGroups.member.%d') 715 return self.get_list('ApplySecurityGroupsToLoadBalancer', 716 params, None) 717 718 def attach_lb_to_subnets(self, name, subnets): 719 """ 720 Attaches load balancer to one or more subnets. 721 Attaching subnets that are already registered with the 722 Load Balancer has no effect. 723 724 :type name: string 725 :param name: The name of the Load Balancer 726 727 :type subnets: List of strings 728 :param subnets: The name of the subnet(s) to add. 729 730 :rtype: List of strings 731 :return: An updated list of subnets for this Load Balancer. 732 733 """ 734 params = {'LoadBalancerName': name} 735 self.build_list_params(params, subnets, 736 'Subnets.member.%d') 737 return self.get_list('AttachLoadBalancerToSubnets', 738 params, None) 739 740 def detach_lb_from_subnets(self, name, subnets): 741 """ 742 Detaches load balancer from one or more subnets. 743 744 :type name: string 745 :param name: The name of the Load Balancer 746 747 :type subnets: List of strings 748 :param subnets: The name of the subnet(s) to detach. 749 750 :rtype: List of strings 751 :return: An updated list of subnets for this Load Balancer. 752 753 """ 754 params = {'LoadBalancerName': name} 755 self.build_list_params(params, subnets, 756 'Subnets.member.%d') 757 return self.get_list('DetachLoadBalancerFromSubnets', 758 params, None) 759