mirror of
https://github.com/valitydev/salt.git
synced 2024-11-07 17:09:03 +00:00
Merge pull request #31838 from lomeroe/boto_vpc-subnet_present-route_table
allow boto_vpc.subnet_present state to manage a subnet's explicitly associated route table
This commit is contained in:
commit
86a3fc24ef
@ -128,14 +128,14 @@ def __virtual__():
|
||||
if not HAS_BOTO:
|
||||
return (False, 'The boto_vpc module could not be loaded: boto libraries not found')
|
||||
elif _LooseVersion(boto.__version__) < _LooseVersion(required_boto_version):
|
||||
return (False, 'The boto_vpc module could not be loaded: boto library is not required version 2.8.0')
|
||||
return (False, 'The boto_vpc module could not be loaded: boto library version 2.8.0 is required')
|
||||
required_boto3_version = '1.2.6'
|
||||
# the boto_vpc execution module relies on the create_nat_gateway() method
|
||||
# which was added in boto3 1.2.6
|
||||
if not HAS_BOTO3:
|
||||
return (False, 'The boto_vpc module could not be loaded: boto3 libraries not found')
|
||||
elif _LooseVersion(boto3.__version__) < _LooseVersion(required_boto3_version):
|
||||
return (False, 'The boto_vpc module could not be loaded: boto3 library is not required version 1.2.6')
|
||||
return (False, 'The boto_vpc module could not be loaded: boto3 library version 1.2.6 is required')
|
||||
return True
|
||||
|
||||
|
||||
@ -966,8 +966,15 @@ def describe_subnet(subnet_id=None, subnet_name=None, region=None,
|
||||
return {'subnet': None}
|
||||
log.debug('Found subnet: {0}'.format(subnet.id))
|
||||
|
||||
keys = ('id', 'cidr_block', 'availability_zone', 'tags')
|
||||
return {'subnet': dict((k, getattr(subnet, k)) for k in keys)}
|
||||
keys = ('id', 'cidr_block', 'availability_zone', 'tags', 'vpc_id')
|
||||
ret = {'subnet': dict((k, getattr(subnet, k)) for k in keys)}
|
||||
explicit_route_table_assoc = _get_subnet_explicit_route_table(ret['subnet']['id'],
|
||||
ret['subnet']['vpc_id'],
|
||||
conn=None, region=region,
|
||||
key=key, keyid=keyid, profile=profile)
|
||||
if explicit_route_table_assoc:
|
||||
ret['subnet']['explicit_route_table_association_id'] = explicit_route_table_assoc
|
||||
return ret
|
||||
|
||||
|
||||
def describe_subnets(subnet_ids=None, subnet_names=None, vpc_id=None, cidr=None,
|
||||
@ -1021,12 +1028,15 @@ def describe_subnets(subnet_ids=None, subnet_names=None, vpc_id=None, cidr=None,
|
||||
return {'subnets': None}
|
||||
|
||||
subnets_list = []
|
||||
keys = ('id', 'cidr_block', 'availability_zone', 'tags')
|
||||
keys = ('id', 'cidr_block', 'availability_zone', 'tags', 'vpc_id')
|
||||
for item in subnets:
|
||||
subnet = {}
|
||||
for key in keys:
|
||||
if hasattr(item, key):
|
||||
subnet[key] = getattr(item, key)
|
||||
explicit_route_table_assoc = _get_subnet_explicit_route_table(subnet['id'], subnet['vpc_id'], conn=conn)
|
||||
if explicit_route_table_assoc:
|
||||
subnet['explicit_route_table_association_id'] = explicit_route_table_assoc
|
||||
subnets_list.append(subnet)
|
||||
return {'subnets': subnets_list}
|
||||
|
||||
@ -2541,3 +2551,20 @@ def _key_remap(key, keys, item):
|
||||
element[r_outkey] = r_item.get(r_inkey)
|
||||
elements_list.append(element)
|
||||
return elements_list
|
||||
|
||||
|
||||
def _get_subnet_explicit_route_table(subnet_id, vpc_id, conn=None, region=None, key=None, keyid=None, profile=None):
|
||||
'''
|
||||
helper function to find subnet explicit route table associations
|
||||
|
||||
.. versionadded:: Carbon
|
||||
'''
|
||||
if not conn:
|
||||
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
|
||||
if conn:
|
||||
vpc_route_tables = conn.get_all_route_tables(filters={'vpc_id': vpc_id})
|
||||
for vpc_route_table in vpc_route_tables:
|
||||
for rt_association in vpc_route_table.associations:
|
||||
if rt_association.subnet_id == subnet_id and not rt_association.main:
|
||||
return rt_association.id
|
||||
return None
|
||||
|
@ -433,8 +433,11 @@ def dhcp_options_absent(name=None, dhcp_options_id=None, region=None, key=None,
|
||||
|
||||
|
||||
def subnet_present(name, cidr_block, vpc_name=None, vpc_id=None,
|
||||
availability_zone=None, tags=None, region=None,
|
||||
key=None, keyid=None, profile=None):
|
||||
availability_zone=None, tags=None,
|
||||
region=None, key=None,
|
||||
keyid=None, profile=None,
|
||||
route_table_id=None, route_table_name=None):
|
||||
|
||||
'''
|
||||
Ensure a subnet exists.
|
||||
|
||||
@ -459,6 +462,18 @@ def subnet_present(name, cidr_block, vpc_name=None, vpc_id=None,
|
||||
tags
|
||||
A list of tags.
|
||||
|
||||
route_table_id
|
||||
A route table ID to explicitly associate the subnet with. If both route_table_id
|
||||
and route_table_name are specified, route_table_id will take precedence.
|
||||
|
||||
.. versionadded:: Carbon
|
||||
|
||||
route_table_name
|
||||
A route table name to explicitly associate the subnet with. If both route_table_id
|
||||
and route_table_name are specified, route_table_id will take precedence.
|
||||
|
||||
.. versionadded:: Carbon
|
||||
|
||||
region
|
||||
Region to connect to.
|
||||
|
||||
@ -488,6 +503,40 @@ def subnet_present(name, cidr_block, vpc_name=None, vpc_id=None,
|
||||
ret['comment'] = 'Failed to create subnet: {0}.'.format(r['error']['message'])
|
||||
return ret
|
||||
|
||||
route_table_desc = None
|
||||
_describe = None
|
||||
rtid = None
|
||||
if route_table_id or route_table_name:
|
||||
rt = None
|
||||
route_table_found = False
|
||||
if route_table_id:
|
||||
rtid = route_table_id
|
||||
rt = __salt__['boto_vpc.route_table_exists'](route_table_id=route_table_id,
|
||||
region=region, key=key, keyid=keyid,
|
||||
profile=profile)
|
||||
elif route_table_name:
|
||||
rtid = route_table_name
|
||||
rt = __salt__['boto_vpc.route_table_exists'](route_table_name=route_table_name,
|
||||
region=region, key=key, keyid=keyid,
|
||||
profile=profile)
|
||||
if rt:
|
||||
if 'exists' in rt:
|
||||
if rt['exists']:
|
||||
if route_table_id:
|
||||
route_table_found = True
|
||||
route_table_desc = __salt__['boto_vpc.describe_route_table'](route_table_id=route_table_id,
|
||||
region=region, key=key, keyid=keyid,
|
||||
profile=profile)
|
||||
elif route_table_name:
|
||||
route_table_found = True
|
||||
route_table_desc = __salt__['boto_vpc.describe_route_table'](route_table_name=route_table_name,
|
||||
region=region, key=key, keyid=keyid,
|
||||
profile=profile)
|
||||
if not route_table_found:
|
||||
ret['result'] = False
|
||||
ret['comment'] = 'The specified route table {0} could not be found.'.format(rtid)
|
||||
return ret
|
||||
|
||||
if not r.get('exists'):
|
||||
if __opts__['test']:
|
||||
ret['comment'] = 'Subnet {0} is set to be created.'.format(name)
|
||||
@ -509,11 +558,73 @@ def subnet_present(name, cidr_block, vpc_name=None, vpc_id=None,
|
||||
ret['changes']['old'] = {'subnet': None}
|
||||
ret['changes']['new'] = _describe
|
||||
ret['comment'] = 'Subnet {0} created.'.format(name)
|
||||
return ret
|
||||
ret['comment'] = 'Subnet present.'
|
||||
else:
|
||||
ret['comment'] = 'Subnet present.'
|
||||
|
||||
if route_table_desc:
|
||||
if not _describe:
|
||||
_describe = __salt__['boto_vpc.describe_subnet'](subnet_name=name, region=region,
|
||||
key=key, keyid=keyid, profile=profile)
|
||||
if not _verify_subnet_association(route_table_desc, _describe['subnet']['id']):
|
||||
if __opts__['test']:
|
||||
msg = 'Subnet is set to be associated with route table {0}'.format(rtid)
|
||||
ret['comment'] = ' '.join([ret['comment'], msg])
|
||||
ret['result'] = None
|
||||
return ret
|
||||
if 'explicit_route_table_association_id' in _describe['subnet']:
|
||||
log.debug('Need to disassociate from existing route table')
|
||||
drt_ret = __salt__['boto_vpc.disassociate_route_table'](_describe['subnet']['explicit_route_table_association_id'],
|
||||
region=region, key=key, keyid=keyid, profile=profile)
|
||||
if not drt_ret['disassociated']:
|
||||
msg = 'Unable to disassociate subnet {0} with its current route table.'.format(name)
|
||||
ret['comment'] = ' '.join([ret['comment'], msg])
|
||||
ret['result'] = False
|
||||
return ret
|
||||
if 'old' not in ret['changes']:
|
||||
ret['changes']['old'] = _describe
|
||||
art_ret = __salt__['boto_vpc.associate_route_table'](route_table_id=route_table_desc['id'],
|
||||
subnet_name=name, region=region,
|
||||
key=key, keyid=keyid, profile=profile)
|
||||
if 'error' in art_ret:
|
||||
msg = 'Failed to associate subnet {0} with route table {1}: {2}.'.format(name, rtid,
|
||||
art_ret['error']['message'])
|
||||
ret['comment'] = ' '.join([ret['comment'], msg])
|
||||
ret['result'] = False
|
||||
return ret
|
||||
else:
|
||||
msg = 'Subnet successfully associated with route table {0}.'.format(rtid)
|
||||
ret['comment'] = ' '.join([ret['comment'], msg])
|
||||
if 'new' not in ret['changes']:
|
||||
ret['changes']['new'] = __salt__['boto_vpc.describe_subnet'](subnet_name=name, region=region,
|
||||
key=key, keyid=keyid, profile=profile)
|
||||
else:
|
||||
ret['changes']['new']['subnet']['explicit_route_table_association_id'] = art_ret['association_id']
|
||||
else:
|
||||
ret['comment'] = ' '.join([ret['comment'],
|
||||
'Subnet is already associated with route table {0}'.format(rtid)])
|
||||
return ret
|
||||
|
||||
|
||||
def _verify_subnet_association(route_table_desc, subnet_id):
|
||||
'''
|
||||
Helper function verify a subnet's route table association
|
||||
|
||||
route_table_desc
|
||||
the description of a route table, as returned from boto_vpc.describe_route_table
|
||||
|
||||
subnet_id
|
||||
the subnet id to verify
|
||||
|
||||
.. versionadded:: Carbon
|
||||
'''
|
||||
if route_table_desc:
|
||||
if 'associations' in route_table_desc:
|
||||
for association in route_table_desc['associations']:
|
||||
if association['subnet_id'] == subnet_id:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def subnet_absent(name=None, subnet_id=None, region=None, key=None, keyid=None, profile=None):
|
||||
'''
|
||||
Ensure subnet with passed properties is absent.
|
||||
|
Loading…
Reference in New Issue
Block a user