| OLD | NEW |
| (Empty) |
| 1 # Copyright (c) 2006-2011 Mitch Garnaat http://garnaat.org/ | |
| 2 # | |
| 3 # Permission is hereby granted, free of charge, to any person obtaining a | |
| 4 # copy of this software and associated documentation files (the | |
| 5 # "Software"), to deal in the Software without restriction, including | |
| 6 # without limitation the rights to use, copy, modify, merge, publish, dis- | |
| 7 # tribute, sublicense, and/or sell copies of the Software, and to permit | |
| 8 # persons to whom the Software is furnished to do so, subject to the fol- | |
| 9 # lowing conditions: | |
| 10 # | |
| 11 # The above copyright notice and this permission notice shall be included | |
| 12 # in all copies or substantial portions of the Software. | |
| 13 # | |
| 14 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |
| 15 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- | |
| 16 # ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT | |
| 17 # SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | |
| 18 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
| 19 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | |
| 20 # IN THE SOFTWARE. | |
| 21 # | |
| 22 """ | |
| 23 This module provides an interface to the Elastic Compute Cloud (EC2) | |
| 24 load balancing service from AWS. | |
| 25 """ | |
| 26 from boto.connection import AWSQueryConnection | |
| 27 from boto.ec2.instanceinfo import InstanceInfo | |
| 28 from boto.ec2.elb.loadbalancer import LoadBalancer | |
| 29 from boto.ec2.elb.instancestate import InstanceState | |
| 30 from boto.ec2.elb.healthcheck import HealthCheck | |
| 31 from boto.regioninfo import RegionInfo | |
| 32 import boto | |
| 33 | |
| 34 RegionData = { | |
| 35 'us-east-1' : 'elasticloadbalancing.us-east-1.amazonaws.com', | |
| 36 'us-west-1' : 'elasticloadbalancing.us-west-1.amazonaws.com', | |
| 37 'eu-west-1' : 'elasticloadbalancing.eu-west-1.amazonaws.com', | |
| 38 'ap-northeast-1' : 'elasticloadbalancing.ap-northeast-1.amazonaws.com', | |
| 39 'ap-southeast-1' : 'elasticloadbalancing.ap-southeast-1.amazonaws.com'} | |
| 40 | |
| 41 def regions(): | |
| 42 """ | |
| 43 Get all available regions for the SDB service. | |
| 44 | |
| 45 :rtype: list | |
| 46 :return: A list of :class:`boto.RegionInfo` instances | |
| 47 """ | |
| 48 regions = [] | |
| 49 for region_name in RegionData: | |
| 50 region = RegionInfo(name=region_name, | |
| 51 endpoint=RegionData[region_name], | |
| 52 connection_cls=ELBConnection) | |
| 53 regions.append(region) | |
| 54 return regions | |
| 55 | |
| 56 def connect_to_region(region_name, **kw_params): | |
| 57 """ | |
| 58 Given a valid region name, return a | |
| 59 :class:`boto.ec2.elb.ELBConnection`. | |
| 60 | |
| 61 :param str region_name: The name of the region to connect to. | |
| 62 | |
| 63 :rtype: :class:`boto.ec2.ELBConnection` or ``None`` | |
| 64 :return: A connection to the given region, or None if an invalid region | |
| 65 name is given | |
| 66 """ | |
| 67 for region in regions(): | |
| 68 if region.name == region_name: | |
| 69 return region.connect(**kw_params) | |
| 70 return None | |
| 71 | |
| 72 class ELBConnection(AWSQueryConnection): | |
| 73 | |
| 74 APIVersion = boto.config.get('Boto', 'elb_version', '2011-04-05') | |
| 75 DefaultRegionName = boto.config.get('Boto', 'elb_region_name', 'us-east-1') | |
| 76 DefaultRegionEndpoint = boto.config.get('Boto', 'elb_region_endpoint', | |
| 77 'elasticloadbalancing.amazonaws.com'
) | |
| 78 | |
| 79 def __init__(self, aws_access_key_id=None, aws_secret_access_key=None, | |
| 80 is_secure=False, port=None, proxy=None, proxy_port=None, | |
| 81 proxy_user=None, proxy_pass=None, debug=0, | |
| 82 https_connection_factory=None, region=None, path='/'): | |
| 83 """ | |
| 84 Init method to create a new connection to EC2 Load Balancing Service. | |
| 85 | |
| 86 B{Note:} The region argument is overridden by the region specified in | |
| 87 the boto configuration file. | |
| 88 """ | |
| 89 if not region: | |
| 90 region = RegionInfo(self, self.DefaultRegionName, | |
| 91 self.DefaultRegionEndpoint) | |
| 92 self.region = region | |
| 93 AWSQueryConnection.__init__(self, aws_access_key_id, | |
| 94 aws_secret_access_key, | |
| 95 is_secure, port, proxy, proxy_port, | |
| 96 proxy_user, proxy_pass, | |
| 97 self.region.endpoint, debug, | |
| 98 https_connection_factory, path) | |
| 99 | |
| 100 def _required_auth_capability(self): | |
| 101 return ['ec2'] | |
| 102 | |
| 103 def build_list_params(self, params, items, label): | |
| 104 if isinstance(items, str): | |
| 105 items = [items] | |
| 106 for i, item in enumerate(items, 1): | |
| 107 params[label % i] = item | |
| 108 | |
| 109 def get_all_load_balancers(self, load_balancer_names=None): | |
| 110 """ | |
| 111 Retrieve all load balancers associated with your account. | |
| 112 | |
| 113 :type load_balancer_names: list | |
| 114 :param load_balancer_names: An optional list of load balancer names | |
| 115 | |
| 116 :rtype: list | |
| 117 :return: A list of :class:`boto.ec2.elb.loadbalancer.LoadBalancer` | |
| 118 """ | |
| 119 params = {} | |
| 120 if load_balancer_names: | |
| 121 self.build_list_params(params, load_balancer_names, | |
| 122 'LoadBalancerNames.member.%d') | |
| 123 return self.get_list('DescribeLoadBalancers', params, | |
| 124 [('member', LoadBalancer)]) | |
| 125 | |
| 126 def create_load_balancer(self, name, zones, listeners): | |
| 127 """ | |
| 128 Create a new load balancer for your account. | |
| 129 | |
| 130 :type name: string | |
| 131 :param name: The mnemonic name associated with the new load balancer | |
| 132 | |
| 133 :type zones: List of strings | |
| 134 :param zones: The names of the availability zone(s) to add. | |
| 135 | |
| 136 :type listeners: List of tuples | |
| 137 :param listeners: Each tuple contains three or four values, | |
| 138 (LoadBalancerPortNumber, InstancePortNumber, | |
| 139 Protocol, [SSLCertificateId]) | |
| 140 where LoadBalancerPortNumber and InstancePortNumber | |
| 141 are integer values between 1 and 65535, Protocol is a | |
| 142 string containing either 'TCP', 'HTTP' or 'HTTPS'; | |
| 143 SSLCertificateID is the ARN of a AWS AIM certificate, | |
| 144 and must be specified when doing HTTPS. | |
| 145 | |
| 146 :rtype: :class:`boto.ec2.elb.loadbalancer.LoadBalancer` | |
| 147 :return: The newly created :class:`boto.ec2.elb.loadbalancer.LoadBalance
r` | |
| 148 """ | |
| 149 params = {'LoadBalancerName' : name} | |
| 150 for i, listener in enumerate(listeners, 1): | |
| 151 params['Listeners.member.%d.LoadBalancerPort' % i] = listener[0] | |
| 152 params['Listeners.member.%d.InstancePort' % i] = listener[1] | |
| 153 params['Listeners.member.%d.Protocol' % i] = listener[2] | |
| 154 if listener[2]=='HTTPS': | |
| 155 params['Listeners.member.%d.SSLCertificateId' % i] = listener[3] | |
| 156 self.build_list_params(params, zones, 'AvailabilityZones.member.%d') | |
| 157 load_balancer = self.get_object('CreateLoadBalancer', | |
| 158 params, LoadBalancer) | |
| 159 load_balancer.name = name | |
| 160 load_balancer.listeners = listeners | |
| 161 load_balancer.availability_zones = zones | |
| 162 return load_balancer | |
| 163 | |
| 164 def create_load_balancer_listeners(self, name, listeners): | |
| 165 """ | |
| 166 Creates a Listener (or group of listeners) for an existing Load Balancer | |
| 167 | |
| 168 :type name: string | |
| 169 :param name: The name of the load balancer to create the listeners for | |
| 170 | |
| 171 :type listeners: List of tuples | |
| 172 :param listeners: Each tuple contains three values, | |
| 173 (LoadBalancerPortNumber, InstancePortNumber, Protocol, | |
| 174 [SSLCertificateId]) | |
| 175 where LoadBalancerPortNumber and InstancePortNumber ar
e | |
| 176 integer values between 1 and 65535, Protocol is a | |
| 177 string containing either 'TCP', 'HTTP' or 'HTTPS'; | |
| 178 SSLCertificateID is the ARN of a AWS AIM certificate, | |
| 179 and must be specified when doing HTTPS. | |
| 180 | |
| 181 :return: The status of the request | |
| 182 """ | |
| 183 params = {'LoadBalancerName' : name} | |
| 184 for i, listener in enumerate(listeners, 1): | |
| 185 params['Listeners.member.%d.LoadBalancerPort' % i] = listener[0] | |
| 186 params['Listeners.member.%d.InstancePort' % i] = listener[1] | |
| 187 params['Listeners.member.%d.Protocol' % i] = listener[2] | |
| 188 if listener[2]=='HTTPS': | |
| 189 params['Listeners.member.%d.SSLCertificateId' % i] = listener[3] | |
| 190 return self.get_status('CreateLoadBalancerListeners', params) | |
| 191 | |
| 192 | |
| 193 def delete_load_balancer(self, name): | |
| 194 """ | |
| 195 Delete a Load Balancer from your account. | |
| 196 | |
| 197 :type name: string | |
| 198 :param name: The name of the Load Balancer to delete | |
| 199 """ | |
| 200 params = {'LoadBalancerName': name} | |
| 201 return self.get_status('DeleteLoadBalancer', params) | |
| 202 | |
| 203 def delete_load_balancer_listeners(self, name, ports): | |
| 204 """ | |
| 205 Deletes a load balancer listener (or group of listeners) | |
| 206 | |
| 207 :type name: string | |
| 208 :param name: The name of the load balancer to create the listeners for | |
| 209 | |
| 210 :type ports: List int | |
| 211 :param ports: Each int represents the port on the ELB to be removed | |
| 212 | |
| 213 :return: The status of the request | |
| 214 """ | |
| 215 params = {'LoadBalancerName' : name} | |
| 216 for i, port in enumerate(ports, 1): | |
| 217 params['LoadBalancerPorts.member.%d' % i] = port | |
| 218 return self.get_status('DeleteLoadBalancerListeners', params) | |
| 219 | |
| 220 def enable_availability_zones(self, load_balancer_name, zones_to_add): | |
| 221 """ | |
| 222 Add availability zones to an existing Load Balancer | |
| 223 All zones must be in the same region as the Load Balancer | |
| 224 Adding zones that are already registered with the Load Balancer | |
| 225 has no effect. | |
| 226 | |
| 227 :type load_balancer_name: string | |
| 228 :param load_balancer_name: The name of the Load Balancer | |
| 229 | |
| 230 :type zones: List of strings | |
| 231 :param zones: The name of the zone(s) to add. | |
| 232 | |
| 233 :rtype: List of strings | |
| 234 :return: An updated list of zones for this Load Balancer. | |
| 235 | |
| 236 """ | |
| 237 params = {'LoadBalancerName' : load_balancer_name} | |
| 238 self.build_list_params(params, zones_to_add, | |
| 239 'AvailabilityZones.member.%d') | |
| 240 return self.get_list('EnableAvailabilityZonesForLoadBalancer', | |
| 241 params, None) | |
| 242 | |
| 243 def disable_availability_zones(self, load_balancer_name, zones_to_remove): | |
| 244 """ | |
| 245 Remove availability zones from an existing Load Balancer. | |
| 246 All zones must be in the same region as the Load Balancer. | |
| 247 Removing zones that are not registered with the Load Balancer | |
| 248 has no effect. | |
| 249 You cannot remove all zones from an Load Balancer. | |
| 250 | |
| 251 :type load_balancer_name: string | |
| 252 :param load_balancer_name: The name of the Load Balancer | |
| 253 | |
| 254 :type zones: List of strings | |
| 255 :param zones: The name of the zone(s) to remove. | |
| 256 | |
| 257 :rtype: List of strings | |
| 258 :return: An updated list of zones for this Load Balancer. | |
| 259 | |
| 260 """ | |
| 261 params = {'LoadBalancerName' : load_balancer_name} | |
| 262 self.build_list_params(params, zones_to_remove, | |
| 263 'AvailabilityZones.member.%d') | |
| 264 return self.get_list('DisableAvailabilityZonesForLoadBalancer', | |
| 265 params, None) | |
| 266 | |
| 267 def register_instances(self, load_balancer_name, instances): | |
| 268 """ | |
| 269 Add new Instances to an existing Load Balancer. | |
| 270 | |
| 271 :type load_balancer_name: string | |
| 272 :param load_balancer_name: The name of the Load Balancer | |
| 273 | |
| 274 :type instances: List of strings | |
| 275 :param instances: The instance ID's of the EC2 instances to add. | |
| 276 | |
| 277 :rtype: List of strings | |
| 278 :return: An updated list of instances for this Load Balancer. | |
| 279 | |
| 280 """ | |
| 281 params = {'LoadBalancerName' : load_balancer_name} | |
| 282 self.build_list_params(params, instances, | |
| 283 'Instances.member.%d.InstanceId') | |
| 284 return self.get_list('RegisterInstancesWithLoadBalancer', | |
| 285 params, [('member', InstanceInfo)]) | |
| 286 | |
| 287 def deregister_instances(self, load_balancer_name, instances): | |
| 288 """ | |
| 289 Remove Instances from an existing Load Balancer. | |
| 290 | |
| 291 :type load_balancer_name: string | |
| 292 :param load_balancer_name: The name of the Load Balancer | |
| 293 | |
| 294 :type instances: List of strings | |
| 295 :param instances: The instance ID's of the EC2 instances to remove. | |
| 296 | |
| 297 :rtype: List of strings | |
| 298 :return: An updated list of instances for this Load Balancer. | |
| 299 | |
| 300 """ | |
| 301 params = {'LoadBalancerName' : load_balancer_name} | |
| 302 self.build_list_params(params, instances, | |
| 303 'Instances.member.%d.InstanceId') | |
| 304 return self.get_list('DeregisterInstancesFromLoadBalancer', | |
| 305 params, [('member', InstanceInfo)]) | |
| 306 | |
| 307 def describe_instance_health(self, load_balancer_name, instances=None): | |
| 308 """ | |
| 309 Get current state of all Instances registered to an Load Balancer. | |
| 310 | |
| 311 :type load_balancer_name: string | |
| 312 :param load_balancer_name: The name of the Load Balancer | |
| 313 | |
| 314 :type instances: List of strings | |
| 315 :param instances: The instance ID's of the EC2 instances | |
| 316 to return status for. If not provided, | |
| 317 the state of all instances will be returned. | |
| 318 | |
| 319 :rtype: List of :class:`boto.ec2.elb.instancestate.InstanceState` | |
| 320 :return: list of state info for instances in this Load Balancer. | |
| 321 | |
| 322 """ | |
| 323 params = {'LoadBalancerName' : load_balancer_name} | |
| 324 if instances: | |
| 325 self.build_list_params(params, instances, | |
| 326 'Instances.member.%d.InstanceId') | |
| 327 return self.get_list('DescribeInstanceHealth', params, | |
| 328 [('member', InstanceState)]) | |
| 329 | |
| 330 def configure_health_check(self, name, health_check): | |
| 331 """ | |
| 332 Define a health check for the EndPoints. | |
| 333 | |
| 334 :type name: string | |
| 335 :param name: The mnemonic name associated with the load balancer | |
| 336 | |
| 337 :type health_check: :class:`boto.ec2.elb.healthcheck.HealthCheck` | |
| 338 :param health_check: A HealthCheck object populated with the desired | |
| 339 values. | |
| 340 | |
| 341 :rtype: :class:`boto.ec2.elb.healthcheck.HealthCheck` | |
| 342 :return: The updated :class:`boto.ec2.elb.healthcheck.HealthCheck` | |
| 343 """ | |
| 344 params = {'LoadBalancerName' : name, | |
| 345 'HealthCheck.Timeout' : health_check.timeout, | |
| 346 'HealthCheck.Target' : health_check.target, | |
| 347 'HealthCheck.Interval' : health_check.interval, | |
| 348 'HealthCheck.UnhealthyThreshold' : health_check.unhealthy_thre
shold, | |
| 349 'HealthCheck.HealthyThreshold' : health_check.healthy_threshol
d} | |
| 350 return self.get_object('ConfigureHealthCheck', params, HealthCheck) | |
| 351 | |
| 352 def set_lb_listener_SSL_certificate(self, lb_name, lb_port, | |
| 353 ssl_certificate_id): | |
| 354 """ | |
| 355 Sets the certificate that terminates the specified listener's SSL | |
| 356 connections. The specified certificate replaces any prior certificate | |
| 357 that was used on the same LoadBalancer and port. | |
| 358 """ | |
| 359 params = { | |
| 360 'LoadBalancerName' : lb_name, | |
| 361 'LoadBalancerPort' : lb_port, | |
| 362 'SSLCertificateId' : ssl_certificate_id, | |
| 363 } | |
| 364 return self.get_status('SetLoadBalancerListenerSSLCertificate', params) | |
| 365 | |
| 366 def create_app_cookie_stickiness_policy(self, name, lb_name, policy_name): | |
| 367 """ | |
| 368 Generates a stickiness policy with sticky session lifetimes that follow | |
| 369 that of an application-generated cookie. This policy can only be | |
| 370 associated with HTTP listeners. | |
| 371 | |
| 372 This policy is similar to the policy created by | |
| 373 CreateLBCookieStickinessPolicy, except that the lifetime of the special | |
| 374 Elastic Load Balancing cookie follows the lifetime of the | |
| 375 application-generated cookie specified in the policy configuration. The | |
| 376 load balancer only inserts a new stickiness cookie when the application | |
| 377 response includes a new application cookie. | |
| 378 | |
| 379 If the application cookie is explicitly removed or expires, the session | |
| 380 stops being sticky until a new application cookie is issued. | |
| 381 """ | |
| 382 params = { | |
| 383 'CookieName' : name, | |
| 384 'LoadBalancerName' : lb_name, | |
| 385 'PolicyName' : policy_name, | |
| 386 } | |
| 387 return self.get_status('CreateAppCookieStickinessPolicy', params) | |
| 388 | |
| 389 def create_lb_cookie_stickiness_policy(self, cookie_expiration_period, | |
| 390 lb_name, policy_name): | |
| 391 """ | |
| 392 Generates a stickiness policy with sticky session lifetimes controlled | |
| 393 by the lifetime of the browser (user-agent) or a specified expiration | |
| 394 period. This policy can only be associated only with HTTP listeners. | |
| 395 | |
| 396 When a load balancer implements this policy, the load balancer uses a | |
| 397 special cookie to track the backend server instance for each request. | |
| 398 When the load balancer receives a request, it first checks to see if | |
| 399 this cookie is present in the request. If so, the load balancer sends | |
| 400 the request to the application server specified in the cookie. If not, | |
| 401 the load balancer sends the request to a server that is chosen based on | |
| 402 the existing load balancing algorithm. | |
| 403 | |
| 404 A cookie is inserted into the response for binding subsequent requests | |
| 405 from the same user to that server. The validity of the cookie is based | |
| 406 on the cookie expiration time, which is specified in the policy | |
| 407 configuration. | |
| 408 """ | |
| 409 params = { | |
| 410 'CookieExpirationPeriod' : cookie_expiration_period, | |
| 411 'LoadBalancerName' : lb_name, | |
| 412 'PolicyName' : policy_name, | |
| 413 } | |
| 414 return self.get_status('CreateLBCookieStickinessPolicy', params) | |
| 415 | |
| 416 def delete_lb_policy(self, lb_name, policy_name): | |
| 417 """ | |
| 418 Deletes a policy from the LoadBalancer. The specified policy must not | |
| 419 be enabled for any listeners. | |
| 420 """ | |
| 421 params = { | |
| 422 'LoadBalancerName' : lb_name, | |
| 423 'PolicyName' : policy_name, | |
| 424 } | |
| 425 return self.get_status('DeleteLoadBalancerPolicy', params) | |
| 426 | |
| 427 def set_lb_policies_of_listener(self, lb_name, lb_port, policies): | |
| 428 """ | |
| 429 Associates, updates, or disables a policy with a listener on the load | |
| 430 balancer. Currently only zero (0) or one (1) policy can be associated | |
| 431 with a listener. | |
| 432 """ | |
| 433 params = { | |
| 434 'LoadBalancerName' : lb_name, | |
| 435 'LoadBalancerPort' : lb_port, | |
| 436 } | |
| 437 self.build_list_params(params, policies, 'PolicyNames.member.%d') | |
| 438 return self.get_status('SetLoadBalancerPoliciesOfListener', params) | |
| 439 | |
| 440 | |
| OLD | NEW |