salt/salt/modules/boto_elb.py

1115 lines
36 KiB
Python
Raw Normal View History

# -*- coding: utf-8 -*-
'''
Connection module for Amazon ELB
2014-07-15 18:43:24 -06:00
.. versionadded:: 2014.7.0
:configuration: This module accepts explicit elb credentials but can also utilize
2016-06-04 03:08:22 +00:00
IAM roles assigned to the instance through Instance Profiles. Dynamic
credentials are then automatically obtained from AWS API and no further
2015-05-18 12:53:49 -04:00
configuration is necessary. More Information available at:
2015-05-18 12:53:49 -04:00
.. code-block:: text
http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html
If IAM roles are not used you need to specify them either in a pillar or
2015-05-18 12:53:49 -04:00
in the minion's config file:
.. code-block:: yaml
elb.keyid: GKTADJGHEIQSXMKKRBJ08H
elb.key: askdjghsdfjkghWupUjasdflkdfklgjsdfjajkghs
2015-05-18 12:53:49 -04:00
A region may also be specified in the configuration:
.. code-block:: yaml
elb.region: us-east-1
If a region is not specified, the default is us-east-1.
It's also possible to specify key, keyid and region via a profile, either
as a passed in dict, or as a string to pull from pillars or minion config:
2015-05-18 12:53:49 -04:00
.. code-block:: yaml
myprofile:
keyid: GKTADJGHEIQSXMKKRBJ08H
key: askdjghsdfjkghWupUjasdflkdfklgjsdfjajkghs
region: us-east-1
:depends: boto >= 2.33.0
'''
2015-04-13 21:33:14 +00:00
# keep lint from choking on _get_conn and _cache_id
# pylint: disable=E0602
2015-04-13 21:33:14 +00:00
from __future__ import absolute_import
# Import Python libs
import logging
import time
log = logging.getLogger(__name__)
# Import Salt libs
import salt.utils.json
import salt.utils.odict as odict
from salt.utils.versions import LooseVersion as _LooseVersion
# Import third party libs
Use explicit unicode strings + break up salt.utils This PR is part of what will be an ongoing effort to use explicit unicode strings in Salt. Because Python 3 does not suport Python 2's raw unicode string syntax (i.e. `ur'\d+'`), we must use `salt.utils.locales.sdecode()` to ensure that the raw string is unicode. However, because of how `salt/utils/__init__.py` has evolved into the hulking monstrosity it is today, this means importing a large module in places where it is not needed, which could negatively impact performance. For this reason, this PR also breaks out some of the functions from `salt/utils/__init__.py` into new/existing modules under `salt/utils/`. The long term goal will be that the modules within this directory do not depend on importing `salt.utils`. A summary of the changes in this PR is as follows: * Moves the following functions from `salt.utils` to new locations (including a deprecation warning if invoked from `salt.utils`): `to_bytes`, `to_str`, `to_unicode`, `str_to_num`, `is_quoted`, `dequote`, `is_hex`, `is_bin_str`, `rand_string`, `contains_whitespace`, `clean_kwargs`, `invalid_kwargs`, `which`, `which_bin`, `path_join`, `shlex_split`, `rand_str`, `is_windows`, `is_proxy`, `is_linux`, `is_darwin`, `is_sunos`, `is_smartos`, `is_smartos_globalzone`, `is_smartos_zone`, `is_freebsd`, `is_netbsd`, `is_openbsd`, `is_aix` * Moves the functions already deprecated by @rallytime to the bottom of `salt/utils/__init__.py` for better organization, so we can keep the deprecated ones separate from the ones yet to be deprecated as we continue to break up `salt.utils` * Updates `salt/*.py` and all files under `salt/client/` to use explicit unicode string literals. * Gets rid of implicit imports of `salt.utils` (e.g. `from salt.utils import foo` becomes `import salt.utils.foo as foo`). * Renames the `test.rand_str` function to `test.random_hash` to more accurately reflect what it does * Modifies `salt.utils.stringutils.random()` (née `salt.utils.rand_string()`) such that it returns a string matching the passed size. Previously this function would get `size` bytes from `os.urandom()`, base64-encode it, and return the result, which would in most cases not be equal to the passed size.
2017-07-24 20:47:15 -05:00
from salt.ext import six
try:
import boto
import boto.ec2 # pylint: enable=unused-import
# connection settings were added in 2.33.0
required_boto_version = '2.33.0'
if (_LooseVersion(boto.__version__) <
_LooseVersion(required_boto_version)):
msg = 'boto_elb requires boto {0}.'.format(required_boto_version)
logging.debug(msg)
raise ImportError()
from boto.ec2.elb import HealthCheck
from boto.ec2.elb.attributes import AccessLogAttribute
from boto.ec2.elb.attributes import ConnectionDrainingAttribute
from boto.ec2.elb.attributes import ConnectionSettingAttribute
from boto.ec2.elb.attributes import CrossZoneLoadBalancingAttribute
logging.getLogger('boto').setLevel(logging.CRITICAL)
HAS_BOTO = True
except ImportError:
HAS_BOTO = False
def __virtual__():
'''
Only load if boto libraries exist.
'''
if not HAS_BOTO:
return (False, "The boto_elb module cannot be loaded: boto library not found")
__utils__['boto.assign_funcs'](__name__, 'elb', module='ec2.elb', pack=__salt__)
return True
def exists(name, region=None, key=None, keyid=None, profile=None):
'''
Check to see if an ELB exists.
CLI example:
.. code-block:: bash
salt myminion boto_elb.exists myelb region=us-east-1
'''
2015-04-13 21:33:14 +00:00
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
try:
elb = conn.get_all_load_balancers(load_balancer_names=[name])
if elb:
return True
2014-12-06 17:38:44 -05:00
else:
msg = 'The load balancer does not exist in region {0}'.format(region)
log.debug(msg)
return False
2015-04-24 11:07:44 -06:00
except boto.exception.BotoServerError as error:
log.warning(error)
return False
def get_all_elbs(region=None, key=None, keyid=None, profile=None):
'''
Return all load balancers associated with an account
CLI example:
.. code-block:: bash
salt myminion boto_elb.get_all_elbs region=us-east-1
'''
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
try:
return [e for e in conn.get_all_load_balancers()]
except boto.exception.BotoServerError as error:
log.warning(error)
return []
def list_elbs(region=None, key=None, keyid=None, profile=None):
'''
Return names of all load balancers associated with an account
CLI example:
.. code-block:: bash
salt myminion boto_elb.list_elbs region=us-east-1
'''
return [e.name for e in get_all_elbs(region=region, key=key, keyid=keyid,
profile=profile)]
def get_elb_config(name, region=None, key=None, keyid=None, profile=None):
'''
[develop] Merge forward from 2016.3 to develop (#32494) * fix sorting by latest version when called with an attribute * remove reference to master_alive_check * Fixes saltstack/salt#28262 * Resolve memory leak in authentication * outputter virt_list does not exist anymore * Update proxmox documentation * Fix documentation on boto_asg and boto_elb modules and states * modules.win_timezone: don't list all zones in debug log * Correcty index glusterfs bricks Fixes issue #32311 * Cleaner deprecation process with decorators * Add deprecation decorator scaffold * Capture type error and unhandled exceptions while function calls * Aware of the current and future version of deprecation * Implement initially is_deprecated decorator * Add an alias for the capitalization * Fix capitalization easier way * Remove an extra line * Add successor name to the deprecation decorator. * Granulate logging and error messages. * Implement function swapper * Raise later the caught exception * Clarify exception message * Save function original name * Remove an extra line * Hide an alternative hidden function name in the error message, preserving the error itself * Rename variable as private * Add a method to detect if a function is using its previous version * Message to the log and/or raise an exception accordingly to the status of used function * Log an error along with the exception * Add internal method documentation * Add documentation and usage process for decorator "is_deprecated" * Add documentation and process usage for the decorator "with_deprecated" * Hide private method name * Fix PEP8, re-word the error message * Deprecate basic uptime function * Add initial decorator unit test * Rename old/new functions, mock versions * Move frequent data to the test setup * Add logging on EOL exception * Rename and document high to low version test on is_deprecated * Implement a test on low to high version of is_deprecated decorator * Add a correction to the test description * Remove a dead code * Implement a test for high to low version on is_deprecated, using with_successor param * Correct typso adn mistaeks * Implement high to low version with successor param on is_deprecated * Setup a virtual name for the module * Implement test for with_deprecated should raise an exception if same deprecated function not found * Implement test for with_deprecated an old function is picked up if configured * Correct test description purpose * Implement test with_deprecated when no deprecation is requested * Add logging test to the configured deprecation request * Add logging testing when deprecated version wasn't requested * Implement test EOL for with_deprecated decorator * Correct test explanation * Rename the test * Implement with_deprecated no EOL, deprecated other function name * Implement with_deprecated, deprecated other function name, EOL reached * Add test description for the with_deprecated + with_name + EOL * Fix confusing test names * Add logging test to the is_deprecated decorator when function as not found. * Add more test point to each test, remove empty lines * Bugfix: at certain conditions a wrong alias name is reported to the log * Fix a typo in a comment * Add test for the logging * Disable a pylint: None will _never_ be raised * Fix test for the deprecated "status.uptime" version * Bugfix: Do not yank raised exceptions * Remove unnecessary decorator * Add test for the new uptime * Add test for the new uptime fails when /proc/uptime does not exists * Rename old test case * Skip test for the UTC time, unless freeze time is used. * Fix pylint * Fix documentation * Bugfix: proxy-pass the docstring of the decorated function * Lint fix * Fixes saltstack/salt#28262 for 2015.5 branch * Update master config docs * Improve git_pillar documentation/logging * Add note about different behavior of top file in git_pillar * Make log entry for a missing pillar SLS file more accurate for git_pillar * FreeBSD supports packages in format java/openjdk7 so the prior commit broke that functionality. Check freebsd/pkg#1409 for more info. * FreeBSD supports packages in format java/openjdk7 so the prior commit broke that functionality. Check freebsd/pkg#1409 for more info. * Update glusterfs_test to be inline with #32312 * Fix salt-cloud paralell provisioning Closes #31632 * Ignore Raspbian in service.py __virtual__ (#32421) * Ignore Raspbian in service.py __virtual__ This prevents more than one execution module from trying to load as the service virtual module. Refs: #32413 * pack __salt__ before loading provider overrides We can (and should) pack here since we're just packing a reference to the object. __salt__ needs to be available when we're loading our provider overrides * Fix broken __salt__ dict in provider override Using ret.items() here sets ``__salt__`` to its items (tuple containing function name and reference), breaking usage of ``__salt__`` inside overridden functions. * Merge #32293 with test fixes (#32418) * Fix issue #11497 * Remove check for working directory presence in tests * Fix Domainname introspection Default value needs to be extracted from the container itself, because dockerd set Domainname value when network_mode=host. * Add pgjsonb_queue to queue doc index * Pylint fixes * Pass parser options into batch mode Resolves #31738 * Changed the target file in file.symlink test (#32443) * Argument name in docs should match actual arg name (#32445) Fixes #31851 * tests.integration: bypass MacOS TMPDIR, gettempdir (#32447) Updates 0edd532, 8f558a5. When logging in as root over `ssh root@host`, `$TMPDIR` and `tempfile.gettempdir()` are both set to a variation of: ``` /private/var/folders/zz/zyxvpxvq6csfxvn_n0000000000000/T/ ``` When logging in as root over `sudo -i`, `$TMPDIR` is unset and `tempfile.gettempdir()` is set to `/tmp`. My guess is that the second case is an unintended or uncorrected omision by Apple as they have introduced the longer, randomized temp path in a recent version of MacOS. * Issue #28706: Fix state user.present behavior. (#32448) - As mentionned in issue #28706, state user.present no longer remove user from groups if the keyword 'groups' with empty value '[]' is not explicitly set, salt will assume current groups are still wanted. * tests.integration: fix 4230c8a * Move the tables of virtual modules to individual documentation pages * Add new doc pages to toctree * Add external ref to windows package manager docs * Improve docstrings * Add documentation on virtual module provider overrides to the module docs * Clarify the scope of the provider param in states. * Add link to provider override docs to all package providers * Add link to provider override docs to all service providers * Add link to provider override docs to all user providers * dd link to provider override docs to all shadow providers * Add link to provider override docs to all group providers * Backport 31164 and 31364 (#32474) * Don't send REQ while another one is waiting for response. The message has to be removed from the queue the only *after* it's already processed to don't confuse send() functionality that expects empty queue means: there's no active sendings. * Fixed zeromq ReqMessageClient destroy * Add link to provider override docs to opkg.py This is a companion to https://github.com/saltstack/salt/pull/32458, but this module was not added until the 2016.3 branch, so the documentation is being updated there for this module. * Add documentation for some master/minion configs (#32454) Refs #32400 Adds docs for: - cli_summary - event_return_queue - event_return_whitelist - event_return_blacklist - file_recv_max_size - fileserver_followsymlinks - fileserver_ignoresymlinks - fileserver_limit_traversal * Automatically detect correct MySQL password column for 5.7 and fix setting passwords (#32440) * Automatically detect MySQL password column * Fix changing password in MySQL 5.7 * Fix lint test * Fix unit tests (?) They will still fail if "authentication_string" is legitimately the right column name, but I don't know what to do about that. * Additional unit test fix * Only unsub if we have a jid Closes #32479
2016-04-11 17:07:15 -06:00
Get an ELB configuration.
CLI example:
.. code-block:: bash
salt myminion boto_elb.exists myelb region=us-east-1
'''
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
retries = 30
while retries:
try:
lb = conn.get_all_load_balancers(load_balancer_names=[name])
lb = lb[0]
ret = {}
ret['availability_zones'] = lb.availability_zones
listeners = []
for _listener in lb.listeners:
listener_dict = {}
listener_dict['elb_port'] = _listener.load_balancer_port
listener_dict['elb_protocol'] = _listener.protocol
listener_dict['instance_port'] = _listener.instance_port
listener_dict['instance_protocol'] = _listener.instance_protocol
listener_dict['policies'] = _listener.policy_names
if _listener.ssl_certificate_id:
listener_dict['certificate'] = _listener.ssl_certificate_id
listeners.append(listener_dict)
ret['listeners'] = listeners
backends = []
for _backend in lb.backends:
bs_dict = {}
bs_dict['instance_port'] = _backend.instance_port
bs_dict['policies'] = [p.policy_name for p in _backend.policies]
backends.append(bs_dict)
ret['backends'] = backends
ret['subnets'] = lb.subnets
ret['security_groups'] = lb.security_groups
ret['scheme'] = lb.scheme
ret['dns_name'] = lb.dns_name
ret['tags'] = _get_all_tags(conn, name)
lb_policy_lists = [
lb.policies.app_cookie_stickiness_policies,
lb.policies.lb_cookie_stickiness_policies,
lb.policies.other_policies
]
policies = []
for policy_list in lb_policy_lists:
policies += [p.policy_name for p in policy_list]
ret['policies'] = policies
return ret
except boto.exception.BotoServerError as error:
if error.error_code == 'Throttling':
log.debug('Throttled by AWS API, will retry in 5 seconds.')
time.sleep(5)
retries -= 1
continue
log.error('Error fetching config for ELB {0}: {1}'.format(name, error.message))
log.error(error)
return {}
return {}
def listener_dict_to_tuple(listener):
2015-10-06 01:24:38 -07:00
'''
Convert an ELB listener dict into a listener tuple used by certain parts of
the AWS ELB API.
2015-10-09 15:05:57 -07:00
CLI example:
.. code-block:: bash
salt myminion boto_elb.listener_dict_to_tuple '{"elb_port":80,"instance_port":80,"elb_protocol":"HTTP"}'
2015-10-06 01:24:38 -07:00
'''
# We define all listeners as complex listeners.
if 'instance_protocol' not in listener:
instance_protocol = listener['elb_protocol'].upper()
else:
instance_protocol = listener['instance_protocol'].upper()
listener_tuple = [listener['elb_port'], listener['instance_port'],
listener['elb_protocol'], instance_protocol]
if 'certificate' in listener:
listener_tuple.append(listener['certificate'])
return tuple(listener_tuple)
def create(name, availability_zones, listeners, subnets=None,
security_groups=None, scheme='internet-facing',
region=None, key=None, keyid=None,
profile=None):
'''
Create an ELB
CLI example to create an ELB:
.. code-block:: bash
salt myminion boto_elb.create myelb '["us-east-1a", "us-east-1e"]' '{"elb_port": 443, "elb_protocol": "HTTPS", ...}' region=us-east-1
'''
2015-04-13 21:33:14 +00:00
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
if exists(name, region, key, keyid, profile):
return True
if isinstance(availability_zones, six.string_types):
availability_zones = salt.utils.json.loads(availability_zones)
if isinstance(listeners, six.string_types):
listeners = salt.utils.json.loads(listeners)
_complex_listeners = []
for listener in listeners:
_complex_listeners.append(listener_dict_to_tuple(listener))
try:
lb = conn.create_load_balancer(name=name, zones=availability_zones, subnets=subnets,
security_groups=security_groups, scheme=scheme,
complex_listeners=_complex_listeners)
if lb:
log.info('Created ELB {0}'.format(name))
return True
else:
msg = 'Failed to create ELB {0}'.format(name)
log.error(msg)
return False
2015-04-24 11:07:44 -06:00
except boto.exception.BotoServerError as error:
log.debug(error)
msg = 'Failed to create ELB {0}: {1}: {2}'.format(name, error.error_code, error.message)
log.error(msg)
return False
def delete(name, region=None, key=None, keyid=None, profile=None):
'''
Delete an ELB.
CLI example to delete an ELB:
.. code-block:: bash
salt myminion boto_elb.delete myelb region=us-east-1
'''
2015-04-13 21:33:14 +00:00
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
if not exists(name, region, key, keyid, profile):
return True
try:
conn.delete_load_balancer(name)
msg = 'Deleted ELB {0}.'.format(name)
log.info(msg)
return True
2015-04-24 11:07:44 -06:00
except boto.exception.BotoServerError as error:
log.debug(error)
msg = 'Failed to delete ELB {0}'.format(name)
log.error(msg)
return False
def create_listeners(name, listeners, region=None, key=None, keyid=None,
profile=None):
'''
Create listeners on an ELB.
CLI example:
.. code-block:: bash
salt myminion boto_elb.create_listeners myelb '[["HTTPS", "HTTP", 443, 80, "arn:aws:iam::11 11111:server-certificate/mycert"]]'
'''
2015-04-13 21:33:14 +00:00
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
if isinstance(listeners, six.string_types):
listeners = salt.utils.json.loads(listeners)
_complex_listeners = []
for listener in listeners:
_complex_listeners.append(listener_dict_to_tuple(listener))
try:
conn.create_load_balancer_listeners(name, [], _complex_listeners)
msg = 'Created ELB listeners on {0}'.format(name)
log.info(msg)
return True
2015-04-24 11:07:44 -06:00
except boto.exception.BotoServerError as error:
log.debug(error)
msg = 'Failed to create ELB listeners on {0}: {1}'.format(name, error)
log.error(msg)
return False
def delete_listeners(name, ports, region=None, key=None, keyid=None,
profile=None):
'''
Delete listeners on an ELB.
CLI example:
.. code-block:: bash
salt myminion boto_elb.delete_listeners myelb '[80,443]'
'''
2015-04-13 21:33:14 +00:00
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
if isinstance(ports, six.string_types):
ports = salt.utils.json.loads(ports)
try:
conn.delete_load_balancer_listeners(name, ports)
msg = 'Deleted ELB listeners on {0}'.format(name)
log.info(msg)
return True
2015-04-24 11:07:44 -06:00
except boto.exception.BotoServerError as error:
log.debug(error)
msg = 'Failed to delete ELB listeners on {0}: {1}'.format(name, error)
log.error(msg)
return False
def apply_security_groups(name, security_groups, region=None, key=None,
keyid=None, profile=None):
'''
Apply security groups to ELB.
CLI example:
.. code-block:: bash
salt myminion boto_elb.apply_security_groups myelb '["mysecgroup1"]'
'''
2015-04-13 21:33:14 +00:00
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
if isinstance(security_groups, six.string_types):
security_groups = salt.utils.json.loads(security_groups)
try:
conn.apply_security_groups_to_lb(name, security_groups)
msg = 'Applied security_groups on ELB {0}'.format(name)
log.info(msg)
return True
except boto.exception.BotoServerError as e:
log.debug(e)
msg = 'Failed to appply security_groups on ELB {0}: {1}'
msg = msg.format(name, e.message)
log.error(msg)
return False
def enable_availability_zones(name, availability_zones, region=None, key=None,
keyid=None, profile=None):
'''
Enable availability zones for ELB.
CLI example:
.. code-block:: bash
salt myminion boto_elb.enable_availability_zones myelb '["us-east-1a"]'
'''
2015-04-13 21:33:14 +00:00
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
if isinstance(availability_zones, six.string_types):
availability_zones = salt.utils.json.loads(availability_zones)
try:
conn.enable_availability_zones(name, availability_zones)
msg = 'Enabled availability_zones on ELB {0}'.format(name)
log.info(msg)
return True
2015-04-24 11:07:44 -06:00
except boto.exception.BotoServerError as error:
log.debug(error)
msg = 'Failed to enable availability_zones on ELB {0}: {1}'.format(name, error)
log.error(msg)
return False
def disable_availability_zones(name, availability_zones, region=None, key=None,
keyid=None, profile=None):
'''
Disable availability zones for ELB.
CLI example:
.. code-block:: bash
salt myminion boto_elb.disable_availability_zones myelb '["us-east-1a"]'
'''
2015-04-13 21:33:14 +00:00
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
if isinstance(availability_zones, six.string_types):
availability_zones = salt.utils.json.loads(availability_zones)
try:
conn.disable_availability_zones(name, availability_zones)
msg = 'Disabled availability_zones on ELB {0}'.format(name)
log.info(msg)
return True
2015-04-24 11:07:44 -06:00
except boto.exception.BotoServerError as error:
log.debug(error)
msg = 'Failed to disable availability_zones on ELB {0}: {1}'.format(name, error)
log.error(msg)
return False
def attach_subnets(name, subnets, region=None, key=None, keyid=None,
profile=None):
'''
Attach ELB to subnets.
CLI example:
.. code-block:: bash
salt myminion boto_elb.attach_subnets myelb '["mysubnet"]'
'''
2015-04-13 21:33:14 +00:00
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
if isinstance(subnets, six.string_types):
subnets = salt.utils.json.loads(subnets)
try:
conn.attach_lb_to_subnets(name, subnets)
msg = 'Attached ELB {0} on subnets.'.format(name)
log.info(msg)
return True
2015-04-24 11:07:44 -06:00
except boto.exception.BotoServerError as error:
log.debug(error)
msg = 'Failed to attach ELB {0} on subnets: {1}'.format(name, error)
log.error(msg)
return False
def detach_subnets(name, subnets, region=None, key=None, keyid=None,
profile=None):
'''
Detach ELB from subnets.
CLI example:
.. code-block:: bash
salt myminion boto_elb.detach_subnets myelb '["mysubnet"]'
'''
2015-04-13 21:33:14 +00:00
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
if isinstance(subnets, six.string_types):
subnets = salt.utils.json.loads(subnets)
try:
conn.detach_lb_from_subnets(name, subnets)
2014-11-05 13:57:47 -08:00
msg = 'Detached ELB {0} from subnets.'.format(name)
log.info(msg)
return True
2015-04-24 11:07:44 -06:00
except boto.exception.BotoServerError as error:
log.debug(error)
msg = 'Failed to detach ELB {0} from subnets: {1}'.format(name, error)
log.error(msg)
return False
def get_attributes(name, region=None, key=None, keyid=None, profile=None):
'''
Check to see if attributes are set on an ELB.
CLI example:
.. code-block:: bash
salt myminion boto_elb.get_attributes myelb
'''
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
retries = 30
while retries:
try:
lbattrs = conn.get_all_lb_attributes(name)
ret = odict.OrderedDict()
ret['access_log'] = odict.OrderedDict()
ret['cross_zone_load_balancing'] = odict.OrderedDict()
ret['connection_draining'] = odict.OrderedDict()
ret['connecting_settings'] = odict.OrderedDict()
al = lbattrs.access_log
czlb = lbattrs.cross_zone_load_balancing
cd = lbattrs.connection_draining
cs = lbattrs.connecting_settings
ret['access_log']['enabled'] = al.enabled
ret['access_log']['s3_bucket_name'] = al.s3_bucket_name
ret['access_log']['s3_bucket_prefix'] = al.s3_bucket_prefix
ret['access_log']['emit_interval'] = al.emit_interval
ret['cross_zone_load_balancing']['enabled'] = czlb.enabled
ret['connection_draining']['enabled'] = cd.enabled
ret['connection_draining']['timeout'] = cd.timeout
ret['connecting_settings']['idle_timeout'] = cs.idle_timeout
return ret
except boto.exception.BotoServerError as e:
if e.error_code == 'Throttling':
log.debug("Throttled by AWS API, will retry in 5 seconds...")
time.sleep(5)
retries -= 1
continue
log.error('ELB {0} does not exist: {1}'.format(name, e.message))
return {}
2017-09-19 17:14:25 -04:00
return {}
def set_attributes(name, attributes, region=None, key=None, keyid=None,
profile=None):
'''
Set attributes on an ELB.
[develop] Merge forward from 2016.3 to develop (#33408) * Fix master hanging after a request from minion with removed key. (#33333) * ZMQ monitor for MWorker connections. * Reauth minion if the key was removed on the master side. * Allow concurrency mode in state runs if using sudo (#33325) Closes #30130 * Disambiguate non-exact matches when checking if sysv service is enabled (#33324) Fixes #33323 * remove redundant, incorrect sudo_runas config documentation (#33318) * remove sudo_runas documentation `sudo_runas` was renamed to `sudo_user` and the documentation was not updated accordingly. * conf/minion: update sudo_user description The description from sudo_runas was better. * import ps from psutil_compat in beacons (#33334) * beacons.network_info: import gate psutil * beacons.ps: import gate psutil * Add docs for mine_functions config var (#33326) * Add docs for mine_functions config var * Note that mine_enabled essentially just doesn't add the mine update function to the scheduler. * Bp 28467 calm mine (#33327) * make minion mine update behavior more configurable * Add docs for mine_functions config var * Remove config dup from mine config options Refs #28467 * 2015.8 does not have _DFLT_MULTIPROCESSING_MODE * This won't be in until 2015.8.10. * Fix network.managed for windows (#33312) * Fix some link errors in the test writing tutorial (#33347) * Describes parameters in register_instances function (#33339) * Fix UnboundLocalError in git.latest (#33340) Resolves #32260. * Expanded documentation for boto_elb state and module (#33341) * Describes what happens when the CNAME parameter is given. * Describes what the recognized attributes are for for ELBs. * Properly detect newer Linux Mint distros (#33359) * Properly detect newer Linux Mint distros LMDE 2 and Linux Mint 17.3 changed the DISTRIB_ID in /etc/lsb-release to ``LinuxMint``, breaking OS detection for these distros. This commit fixes that by adding an entry to the OS_NAME_MAP in the core grains. * Remove LinuxMint os_family from aptpkg.py It is no longer necessary as the distro is now detected properly, which will lead to an os_family of Debian. * Update job_cache and keep_jobs docs to be more specific to their behavior (#33328) * Update job_cache and keep_jobs docs to be more specific to their behavior Also fixed a bug discovered when investigating job_cache/keep_jobs functionality where the jid directory and files were removed by the cache cleaner, but not the original jid clash detection directory created in /var/cache/salt/master/jobs/. Fixes #29286 * Add testcase for the changes in the local_cache.clean_old_jobs func * Mark tests as destructive * Put destructive test decorator in correct location * Remove mentions of windows not supporting pkgs param (#33361) Fixes #33313 * Updates docs version to 2015.8.9 Adds note regarding the os grain on Mint Linux Adds an FAQ regarding grains that change due to upstream changes * revved 2015.8 branch to .9 in version selector * Add initscripts, SystemD service units and environment files for Debian (#32857) * Add note to docs about api settings for Hipchat API v2 (#33365) Fixes #27779 * Add win_pkg to list of modules that support "version" in pkg.installed (#33362) Fixes #32913 * Add note about name parameter in git_pillar docs (#33369) Fixes #27737 * Better YAML syntax error handling (#33375) Closes #26574 * Improve doc clarity for disable_modules documentation (#33379) * Improve doc clarity for disable_modules documentation * Additional clarification on blacklisted name * maintain the fallabck because I am totally sick of this crap * blast, put the try/except int he right place * restore whitespace * Fix traceback in logging for config validation (#33386) * 2015.8.10 release notes * Sync pillarstack to latest upstream version (#33391) * Don't lay down all available opts (#33385) * Don't lay down all available opts * We need at least one opt in there * Condense defaults * Put the default hash type back
2016-05-20 14:48:40 -06:00
name (string)
Name of the ELB instance to set attributes for
attributes
A dict of attributes to set.
Valid attributes are:
access_log (dict)
enabled (bool)
Enable storage of access logs.
s3_bucket_name (string)
The name of the S3 bucket to place logs.
s3_bucket_prefix (string)
Prefix for the log file name.
emit_interval (int)
Interval for storing logs in S3 in minutes. Valid values are
5 and 60.
connection_draining (dict)
enabled (bool)
Enable connection draining.
timeout (int)
Maximum allowed time in seconds for sending existing
connections to an instance that is deregistering or unhealthy.
Default is 300.
cross_zone_load_balancing (dict)
enabled (bool)
Enable cross-zone load balancing.
CLI example to set attributes on an ELB:
.. code-block:: bash
salt myminion boto_elb.set_attributes myelb '{"access_log": {"enabled": "true", "s3_bucket_name": "mybucket", "s3_bucket_prefix": "mylogs/", "emit_interval": "5"}}' region=us-east-1
'''
2015-04-13 21:33:14 +00:00
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
al = attributes.get('access_log', {})
czlb = attributes.get('cross_zone_load_balancing', {})
cd = attributes.get('connection_draining', {})
cs = attributes.get('connecting_settings', {})
if not al and not czlb and not cd and not cs:
log.error('No supported attributes for ELB.')
return False
if al:
_al = AccessLogAttribute()
_al.enabled = al.get('enabled', False)
if not _al.enabled:
msg = 'Access log attribute configured, but enabled config missing'
log.error(msg)
return False
_al.s3_bucket_name = al.get('s3_bucket_name', None)
_al.s3_bucket_prefix = al.get('s3_bucket_prefix', None)
_al.emit_interval = al.get('emit_interval', None)
added_attr = conn.modify_lb_attribute(name, 'accessLog', _al)
if added_attr:
log.info('Added access_log attribute to {0} elb.'.format(name))
else:
msg = 'Failed to add access_log attribute to {0} elb.'
log.error(msg.format(name))
return False
if czlb:
_czlb = CrossZoneLoadBalancingAttribute()
_czlb.enabled = czlb['enabled']
added_attr = conn.modify_lb_attribute(name, 'crossZoneLoadBalancing',
_czlb.enabled)
if added_attr:
msg = 'Added cross_zone_load_balancing attribute to {0} elb.'
log.info(msg.format(name))
else:
log.error('Failed to add cross_zone_load_balancing attribute.')
return False
if cd:
_cd = ConnectionDrainingAttribute()
_cd.enabled = cd['enabled']
_cd.timeout = cd.get('timeout', 300)
added_attr = conn.modify_lb_attribute(name, 'connectionDraining', _cd)
if added_attr:
msg = 'Added connection_draining attribute to {0} elb.'
log.info(msg.format(name))
else:
log.error('Failed to add connection_draining attribute.')
return False
if cs:
_cs = ConnectionSettingAttribute()
_cs.idle_timeout = cs.get('idle_timeout', 60)
added_attr = conn.modify_lb_attribute(name, 'connectingSettings', _cs)
if added_attr:
msg = 'Added connecting_settings attribute to {0} elb.'
log.info(msg.format(name))
else:
log.error('Failed to add connecting_settings attribute.')
return False
return True
def get_health_check(name, region=None, key=None, keyid=None, profile=None):
'''
Get the health check configured for this ELB.
CLI example:
.. code-block:: bash
salt myminion boto_elb.get_health_check myelb
'''
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
retries = 30
while True:
try:
lb = conn.get_all_load_balancers(load_balancer_names=[name])
lb = lb[0]
ret = odict.OrderedDict()
hc = lb.health_check
ret['interval'] = hc.interval
ret['target'] = hc.target
ret['healthy_threshold'] = hc.healthy_threshold
ret['timeout'] = hc.timeout
ret['unhealthy_threshold'] = hc.unhealthy_threshold
return ret
except boto.exception.BotoServerError as e:
if retries and e.code == 'Throttling':
log.debug('Throttled by AWS API, will retry in 5 seconds.')
time.sleep(5)
retries -= 1
continue
log.error(error)
log.error('ELB {0} not found.'.format(name))
return {}
def set_health_check(name, health_check, region=None, key=None, keyid=None,
profile=None):
'''
Set attributes on an ELB.
CLI example to set attributes on an ELB:
.. code-block:: bash
salt myminion boto_elb.set_health_check myelb '{"target": "HTTP:80/"}'
'''
2015-04-13 21:33:14 +00:00
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
retries = 30
2015-04-13 21:33:14 +00:00
hc = HealthCheck(**health_check)
while True:
try:
conn.configure_health_check(name, hc)
log.info('Configured health check on ELB {0}'.format(name))
return True
except boto.exception.BotoServerError as error:
if retries and e.code == 'Throttling':
log.debug('Throttled by AWS API, will retry in 5 seconds.')
time.sleep(5)
retries -= 1
continue
log.error(error)
log.error('Failed to configure health check on ELB {0}'.format(name))
return False
def register_instances(name, instances, region=None, key=None, keyid=None,
profile=None):
'''
Register instances with an ELB. Instances is either a string
instance id or a list of string instance id's.
Returns:
- ``True``: instance(s) registered successfully
- ``False``: instance(s) failed to be registered
CLI example:
.. code-block:: bash
salt myminion boto_elb.register_instances myelb instance_id
salt myminion boto_elb.register_instances myelb "[instance_id,instance_id]"
'''
# convert instances to list type, enabling consistent use of instances
# variable throughout the register_instances method
Use explicit unicode strings + break up salt.utils This PR is part of what will be an ongoing effort to use explicit unicode strings in Salt. Because Python 3 does not suport Python 2's raw unicode string syntax (i.e. `ur'\d+'`), we must use `salt.utils.locales.sdecode()` to ensure that the raw string is unicode. However, because of how `salt/utils/__init__.py` has evolved into the hulking monstrosity it is today, this means importing a large module in places where it is not needed, which could negatively impact performance. For this reason, this PR also breaks out some of the functions from `salt/utils/__init__.py` into new/existing modules under `salt/utils/`. The long term goal will be that the modules within this directory do not depend on importing `salt.utils`. A summary of the changes in this PR is as follows: * Moves the following functions from `salt.utils` to new locations (including a deprecation warning if invoked from `salt.utils`): `to_bytes`, `to_str`, `to_unicode`, `str_to_num`, `is_quoted`, `dequote`, `is_hex`, `is_bin_str`, `rand_string`, `contains_whitespace`, `clean_kwargs`, `invalid_kwargs`, `which`, `which_bin`, `path_join`, `shlex_split`, `rand_str`, `is_windows`, `is_proxy`, `is_linux`, `is_darwin`, `is_sunos`, `is_smartos`, `is_smartos_globalzone`, `is_smartos_zone`, `is_freebsd`, `is_netbsd`, `is_openbsd`, `is_aix` * Moves the functions already deprecated by @rallytime to the bottom of `salt/utils/__init__.py` for better organization, so we can keep the deprecated ones separate from the ones yet to be deprecated as we continue to break up `salt.utils` * Updates `salt/*.py` and all files under `salt/client/` to use explicit unicode string literals. * Gets rid of implicit imports of `salt.utils` (e.g. `from salt.utils import foo` becomes `import salt.utils.foo as foo`). * Renames the `test.rand_str` function to `test.random_hash` to more accurately reflect what it does * Modifies `salt.utils.stringutils.random()` (née `salt.utils.rand_string()`) such that it returns a string matching the passed size. Previously this function would get `size` bytes from `os.urandom()`, base64-encode it, and return the result, which would in most cases not be equal to the passed size.
2017-07-24 20:47:15 -05:00
if isinstance(instances, six.string_types) or isinstance(instances, six.text_type):
instances = [instances]
2015-04-13 21:33:14 +00:00
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
try:
registered_instances = conn.register_instances(name, instances)
2015-04-24 11:07:44 -06:00
except boto.exception.BotoServerError as error:
log.warning(error)
return False
registered_instance_ids = [instance.id for instance in
registered_instances]
# register_failues is a set that will contain any instances that were not
# able to be registered with the given ELB
register_failures = set(instances).difference(set(registered_instance_ids))
if register_failures:
log.warning('Instance(s): {0} not registered with ELB {1}.'
.format(list(register_failures), name))
register_result = False
else:
register_result = True
return register_result
def deregister_instances(name, instances, region=None, key=None, keyid=None,
profile=None):
'''
Deregister instances with an ELB. Instances is either a string
instance id or a list of string instance id's.
Returns:
- ``True``: instance(s) deregistered successfully
- ``False``: instance(s) failed to be deregistered
- ``None``: instance(s) not valid or not registered, no action taken
CLI example:
.. code-block:: bash
salt myminion boto_elb.deregister_instances myelb instance_id
salt myminion boto_elb.deregister_instances myelb "[instance_id, instance_id]"
'''
# convert instances to list type, enabling consistent use of instances
# variable throughout the deregister_instances method
Use explicit unicode strings + break up salt.utils This PR is part of what will be an ongoing effort to use explicit unicode strings in Salt. Because Python 3 does not suport Python 2's raw unicode string syntax (i.e. `ur'\d+'`), we must use `salt.utils.locales.sdecode()` to ensure that the raw string is unicode. However, because of how `salt/utils/__init__.py` has evolved into the hulking monstrosity it is today, this means importing a large module in places where it is not needed, which could negatively impact performance. For this reason, this PR also breaks out some of the functions from `salt/utils/__init__.py` into new/existing modules under `salt/utils/`. The long term goal will be that the modules within this directory do not depend on importing `salt.utils`. A summary of the changes in this PR is as follows: * Moves the following functions from `salt.utils` to new locations (including a deprecation warning if invoked from `salt.utils`): `to_bytes`, `to_str`, `to_unicode`, `str_to_num`, `is_quoted`, `dequote`, `is_hex`, `is_bin_str`, `rand_string`, `contains_whitespace`, `clean_kwargs`, `invalid_kwargs`, `which`, `which_bin`, `path_join`, `shlex_split`, `rand_str`, `is_windows`, `is_proxy`, `is_linux`, `is_darwin`, `is_sunos`, `is_smartos`, `is_smartos_globalzone`, `is_smartos_zone`, `is_freebsd`, `is_netbsd`, `is_openbsd`, `is_aix` * Moves the functions already deprecated by @rallytime to the bottom of `salt/utils/__init__.py` for better organization, so we can keep the deprecated ones separate from the ones yet to be deprecated as we continue to break up `salt.utils` * Updates `salt/*.py` and all files under `salt/client/` to use explicit unicode string literals. * Gets rid of implicit imports of `salt.utils` (e.g. `from salt.utils import foo` becomes `import salt.utils.foo as foo`). * Renames the `test.rand_str` function to `test.random_hash` to more accurately reflect what it does * Modifies `salt.utils.stringutils.random()` (née `salt.utils.rand_string()`) such that it returns a string matching the passed size. Previously this function would get `size` bytes from `os.urandom()`, base64-encode it, and return the result, which would in most cases not be equal to the passed size.
2017-07-24 20:47:15 -05:00
if isinstance(instances, six.string_types) or isinstance(instances, six.text_type):
instances = [instances]
2015-04-13 21:33:14 +00:00
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
try:
registered_instances = conn.deregister_instances(name, instances)
2015-04-24 11:07:44 -06:00
except boto.exception.BotoServerError as error:
# if the instance(s) given as an argument are not members of the ELB
2015-04-24 11:07:44 -06:00
# boto returns error.error_code == 'InvalidInstance'
# deregister_instances returns "None" because the instances are
# effectively deregistered from ELB
2015-04-24 11:07:44 -06:00
if error.error_code == 'InvalidInstance':
log.warning('One or more of instance(s) {0} are not part of ELB {1}.'
' deregister_instances not performed.'
.format(instances, name))
return None
else:
log.warning(error)
return False
registered_instance_ids = [instance.id for instance in
registered_instances]
# deregister_failures is a set that will contain any instances that were
# unable to be deregistered from the given ELB
deregister_failures = set(instances).intersection(set(registered_instance_ids))
if deregister_failures:
log.warning('Instance(s): {0} not deregistered from ELB {1}.'
.format(list(deregister_failures), name))
deregister_result = False
else:
deregister_result = True
return deregister_result
def set_instances(name, instances, test=False, region=None, key=None, keyid=None,
profile=None):
'''
Set the instances assigned to an ELB to exactly the list given
CLI example:
.. code-block:: bash
salt myminion boto_elb.set_instances myelb region=us-east-1 instances="[instance_id,instance_id]"
'''
ret = True
current = set([i['instance_id'] for i in get_instance_health(name, region, key, keyid, profile)])
desired = set(instances)
add = desired - current
remove = current - desired
if test:
return bool(add or remove)
if len(remove):
if deregister_instances(name, list(remove), region, key, keyid, profile) is False:
ret = False
if len(add):
if register_instances(name, list(add), region, key, keyid, profile) is False:
ret = False
return ret
def get_instance_health(name, region=None, key=None, keyid=None, profile=None, instances=None):
'''
Get a list of instances and their health state
CLI example:
.. code-block:: bash
salt myminion boto_elb.get_instance_health myelb
salt myminion boto_elb.get_instance_health myelb region=us-east-1 instances="[instance_id,instance_id]"
'''
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
2015-04-13 21:33:14 +00:00
try:
instance_states = conn.describe_instance_health(name, instances)
ret = []
for _instance in instance_states:
2014-08-22 15:13:53 -06:00
ret.append({'instance_id': _instance.instance_id,
'description': _instance.description,
'state': _instance.state,
'reason_code': _instance.reason_code
})
return ret
2015-04-24 11:07:44 -06:00
except boto.exception.BotoServerError as error:
log.debug(error)
return []
def create_policy(name, policy_name, policy_type, policy, region=None,
key=None, keyid=None, profile=None):
2015-10-05 23:41:16 -07:00
'''
Create an ELB policy.
.. versionadded:: 2016.3.0
CLI example:
.. code-block:: bash
2015-10-05 23:41:16 -07:00
salt myminion boto_elb.create_policy myelb mypolicy LBCookieStickinessPolicyType '{"CookieExpirationPeriod": 3600}'
'''
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
if not exists(name, region, key, keyid, profile):
return False
try:
success = conn.create_lb_policy(name, policy_name, policy_type, policy)
if success:
log.info('Created policy {0} on ELB {1}'.format(policy_name, name))
return True
else:
msg = 'Failed to create policy {0} on ELB {1}'.format(policy_name, name)
log.error(msg)
return False
except boto.exception.BotoServerError as e:
log.debug(e)
msg = 'Failed to create policy {0} on ELB {1}: {2}'.format(policy_name, name, e.message)
log.error(msg)
return False
def delete_policy(name, policy_name, region=None, key=None, keyid=None,
profile=None):
2015-10-05 23:41:16 -07:00
'''
Delete an ELB policy.
.. versionadded:: 2016.3.0
CLI example:
.. code-block:: bash
2015-10-05 23:41:16 -07:00
salt myminion boto_elb.delete_policy myelb mypolicy
'''
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
if not exists(name, region, key, keyid, profile):
return True
try:
conn.delete_lb_policy(name, policy_name)
log.info('Deleted policy {0} on ELB {1}'.format(policy_name, name))
return True
except boto.exception.BotoServerError as e:
log.debug(e)
msg = 'Failed to delete policy {0} on ELB {1}: {2}'.format(policy_name, name, e.message)
log.error(msg)
return False
def set_listener_policy(name, port, policies=None, region=None, key=None,
keyid=None, profile=None):
2015-10-05 23:41:16 -07:00
'''
Set the policies of an ELB listener.
.. versionadded:: 2016.3.0
CLI example:
.. code-block:: Bash
2015-10-05 23:41:16 -07:00
salt myminion boto_elb.set_listener_policy myelb 443 "[policy1,policy2]"
'''
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
if not exists(name, region, key, keyid, profile):
return True
if policies is None:
policies = []
try:
conn.set_lb_policies_of_listener(name, port, policies)
log.info('Set policies {0} on ELB {1} listener {2}'.format(policies, name, port))
except boto.exception.BotoServerError as e:
log.debug(e)
log.info('Failed to set policy {0} on ELB {1} listener {2}: {3}'.format(policies, name, port, e.message))
return False
return True
2015-10-06 17:01:33 +00:00
def set_backend_policy(name, port, policies=None, region=None, key=None,
keyid=None, profile=None):
'''
Set the policies of an ELB backend server.
CLI example:
salt myminion boto_elb.set_backend_policy myelb 443 "[policy1,policy2]"
'''
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
if not exists(name, region, key, keyid, profile):
return True
if policies is None:
policies = []
try:
conn.set_lb_policies_of_backend_server(name, port, policies)
log.info('Set policies {0} on ELB {1} backend server {2}'.format(policies, name, port))
except boto.exception.BotoServerError as e:
log.debug(e)
log.info('Failed to set policy {0} on ELB {1} backend server {2}: {3}'.format(policies, name, port, e.message))
return False
return True
2015-10-06 17:01:33 +00:00
def set_tags(name, tags, region=None, key=None, keyid=None, profile=None):
'''
Add the tags on an ELB
.. versionadded:: 2016.3.0
2015-10-06 17:01:33 +00:00
name
name of the ELB
tags
dict of name/value pair tags
CLI Example:
.. code-block:: bash
salt myminion boto_elb.set_tags my-elb-name "{'Tag1': 'Value', 'Tag2': 'Another Value'}"
'''
if exists(name, region, key, keyid, profile):
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
ret = _add_tags(conn, name, tags)
return ret
else:
return False
def delete_tags(name, tags, region=None, key=None, keyid=None, profile=None):
'''
Add the tags on an ELB
name
name of the ELB
tags
list of tags to remove
CLI Example:
.. code-block:: bash
salt myminion boto_elb.delete_tags my-elb-name ['TagToRemove1', 'TagToRemove2']
'''
if exists(name, region, key, keyid, profile):
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
ret = _remove_tags(conn, name, tags)
return ret
else:
return False
def _build_tag_param_list(params, tags):
'''
helper function to build a tag parameter list to send
'''
keys = sorted(tags.keys())
i = 1
for key in keys:
value = tags[key]
params['Tags.member.{0}.Key'.format(i)] = key
if value is not None:
params['Tags.member.{0}.Value'.format(i)] = value
i += 1
def _get_all_tags(conn, load_balancer_names=None):
'''
Retrieve all the metadata tags associated with your ELB(s).
:type load_balancer_names: list
:param load_balancer_names: An optional list of load balancer names.
:rtype: list
:return: A list of :class:`boto.ec2.elb.tag.Tag` objects
'''
params = {}
if load_balancer_names:
conn.build_list_params(params, load_balancer_names,
'LoadBalancerNames.member.%d')
tags = conn.get_object(
'DescribeTags',
params,
__utils__['boto_elb_tag.get_tag_descriptions'](),
verb='POST'
)
2015-10-06 17:01:33 +00:00
if tags[load_balancer_names]:
return tags[load_balancer_names]
else:
return None
def _add_tags(conn, load_balancer_names, tags):
'''
Create new metadata tags for the specified resource ids.
:type load_balancer_names: list
:param load_balancer_names: A list of load balancer names.
:type tags: dict
:param tags: A dictionary containing the name/value pairs.
If you want to create only a tag name, the
value for that tag should be the empty string
(e.g. '').
'''
params = {}
conn.build_list_params(params, load_balancer_names,
'LoadBalancerNames.member.%d')
_build_tag_param_list(params, tags)
return conn.get_status('AddTags', params, verb='POST')
def _remove_tags(conn, load_balancer_names, tags):
'''
Delete metadata tags for the specified resource ids.
:type load_balancer_names: list
:param load_balancer_names: A list of load balancer names.
:type tags: list
:param tags: A list containing just tag names for the tags to be
deleted.
'''
params = {}
conn.build_list_params(params, load_balancer_names,
'LoadBalancerNames.member.%d')
conn.build_list_params(params, tags,
'Tags.member.%d.Key')
return conn.get_status('RemoveTags', params, verb='POST')