[WIP] refactor boto_vpc execution module

This commit is contained in:
Matthew Williams 2015-04-08 02:19:06 +00:00
parent 5376a13ca9
commit 6f9434cb10
2 changed files with 270 additions and 232 deletions

View File

@ -4,6 +4,11 @@ Connection module for Amazon VPC
.. versionadded:: 2014.7.0 .. versionadded:: 2014.7.0
.. versionchanged:: Beryllium
When boto raises a BotoServerError, this module now raises CommandExecutionError
instead of returning False.
:configuration: This module accepts explicit VPC credentials but can also :configuration: This module accepts explicit VPC credentials but can also
utilize IAM roles assigned to the instance trough Instance Profiles. utilize IAM roles assigned to the instance trough Instance Profiles.
Dynamic credentials are then automatically obtained from AWS API and no Dynamic credentials are then automatically obtained from AWS API and no
@ -110,8 +115,8 @@ def _get_profile(service, region, key, keyid, profile):
def _cache_id(name, sub_resource=None, resource_id=None, def _cache_id(name, sub_resource=None, resource_id=None,
invalidate=False, region=None, key=None, keyid=None, invalidate=False, region=None, key=None, keyid=None,
profile=None): profile=None):
# TODO: Move this to a common utils module # TODO: Move this to a common utils module
''' '''
Cache, invalidate, or retrieve an AWS resource id keyed by name. Cache, invalidate, or retrieve an AWS resource id keyed by name.
@ -146,8 +151,6 @@ def _check_vpc(vpc_id, vpc_name, region, key, keyid, profile):
''' '''
conn = _get_conn(region, key, keyid, profile) conn = _get_conn(region, key, keyid, profile)
if not conn:
return False
if vpc_name: if vpc_name:
vpc_id = get_id(name=vpc_name, region=region, key=key, keyid=keyid, vpc_id = get_id(name=vpc_name, region=region, key=key, keyid=keyid,
@ -166,8 +169,8 @@ def _check_vpc(vpc_id, vpc_name, region, key, keyid, profile):
return vpc_id return vpc_id
def _create_resource(resource, name, tags, region, key, keyid, def _create_resource(resource, name=None, tags=None, region=None, key=None,
profile, **kwargs): keyid=None, profile=None, **kwargs):
''' '''
Create a VPC resource. Returns the resource id if created, or False Create a VPC resource. Returns the resource id if created, or False
if not created. if not created.
@ -211,11 +214,11 @@ def _create_resource(resource, name, tags, region, key, keyid,
return False return False
except boto.exception.BotoServerError as exc: except boto.exception.BotoServerError as exc:
log.error(exc) log.error(exc)
return False raise CommandExecutionError(exc.reason)
def _delete_resource(resource, name, resource_id, region, def _delete_resource(resource, name=None, resource_id=None, region=None,
key, keyid, profile, **kwargs): key=None, keyid=None, profile=None, **kwargs):
''' '''
Delete a VPC resource. Returns True if succesful, otherwise False. Delete a VPC resource. Returns True if succesful, otherwise False.
''' '''
@ -252,26 +255,50 @@ def _delete_resource(resource, name, resource_id, region,
return False return False
except boto.exception.BotoServerError as exc: except boto.exception.BotoServerError as exc:
log.error(exc) log.error(exc)
raise CommandExecutionError(exc.reason)
def _get_resource(resource, name=None, resource_id=None, region=None,
key=None, keyid=None, profile=None):
'''
Get a VPC resource based on resource type and name or id.
Cache the id if name was provided.
'''
conn = _get_conn(region, key, keyid, profile)
if not conn:
return False return False
def _get_resource(resource, name, conn):
try: try:
get_resources = getattr(conn, 'get_all_{0}s'.format(resource)) get_resources = getattr(conn, 'get_all_{0}s'.format(resource))
r = get_resources(filters={'tag:Name': name}) filter_parameters = {}
if name:
filter_parameters['filters'] = {'tag:Name': name}
if resource_id:
filter_parameters['_ids'.format(resource)] = resource_id
if not filter_parameters:
return False
r = get_resources(**filter_parameters)
if r: if r:
if len(r) == 1: if len(r) == 1:
if name:
_cache_id(name, sub_resource=resource,
resource_id=r[0].id,
region=region,
key=key, keyid=keyid,
profile=profile)
return r[0] return r[0]
else: else:
raise CommandExecutionError('Found more than one ' log.warning('Found more than one {0} named '
'{0} named "{1}"'.format( '"{1}"'.format(resource, name))
resource, name)) return False
else: else:
return None return None
except boto.exception.BotoServerError as exc: except boto.exception.BotoServerError as exc:
log.error(exc) log.error(exc)
return False raise CommandExecutionError(exc.reason)
def resource_exists(resource, name, region=None, def resource_exists(resource, name, region=None,
@ -316,33 +343,13 @@ def get_resource_id(resource, name, region=None,
if _id: if _id:
return _id return _id
conn = _get_conn(region, key, keyid, profile) r = _get_resource(resource, name=name, region=region, key=key,
if not conn: keyid=keyid, profile=profile)
return None
try: if r:
f = getattr(conn, 'get_all_{0}s'.format(resource)) return r.id
r = f(filters={'tag:Name': name}) else:
return r
if r:
if len(r) == 1:
_id = r[0].id
_cache_id(name, sub_resource=resource,
resource_id=_id,
region=region,
key=key, keyid=keyid,
profile=profile)
return r[0].id
else:
raise CommandExecutionError('Found more than one '
'{0} named "{1}"'.format(
resource, name))
else:
log.warning('No {0} named "{1}"'.format(resource, name))
return None
except boto.exception.BotoServerError as exc:
log.error(exc)
return False
def get_subnet_association(subnets, region=None, key=None, keyid=None, def get_subnet_association(subnets, region=None, key=None, keyid=None,
@ -373,8 +380,8 @@ def get_subnet_association(subnets, region=None, key=None, keyid=None,
# subnet_ids=subnets can accept either a string or a list # subnet_ids=subnets can accept either a string or a list
subnets = conn.get_all_subnets(subnet_ids=subnets) subnets = conn.get_all_subnets(subnet_ids=subnets)
except boto.exception.BotoServerError as exc: except boto.exception.BotoServerError as exc:
log.debug(exc) log.error(exc)
return False raise CommandExecutionError(exc.reason)
# using a set to store vpc_ids - the use of set prevents duplicate # using a set to store vpc_ids - the use of set prevents duplicate
# vpc_id values # vpc_id values
vpc_ids = set() vpc_ids = set()
@ -399,8 +406,6 @@ def _find_vpc(vpc_id=None, name=None, cidr=None, tags=None, conn=None):
Given VPC properties, find and return matching VPC_IDs Given VPC properties, find and return matching VPC_IDs
''' '''
if not conn:
return False
if not vpc_id and not name and not tags and not cidr: if not vpc_id and not name and not tags and not cidr:
raise SaltInvocationError('At least one of the following must be specified: vpc id, name, cidr or tags.') raise SaltInvocationError('At least one of the following must be specified: vpc id, name, cidr or tags.')
@ -430,7 +435,7 @@ def _find_vpc(vpc_id=None, name=None, cidr=None, tags=None, conn=None):
return False return False
except boto.exception.BotoServerError as exc: except boto.exception.BotoServerError as exc:
log.error(exc) log.error(exc)
return False raise CommandExecutionError(exc.reason)
def get_id(name=None, cidr=None, tags=None, region=None, key=None, keyid=None, def get_id(name=None, cidr=None, tags=None, region=None, key=None, keyid=None,
@ -455,8 +460,6 @@ def get_id(name=None, cidr=None, tags=None, region=None, key=None, keyid=None,
return vpc_id return vpc_id
conn = _get_conn(region, key, keyid, profile) conn = _get_conn(region, key, keyid, profile)
if not conn:
return None
vpcs_id = _find_vpc(name=name, cidr=cidr, tags=tags, conn=conn) vpcs_id = _find_vpc(name=name, cidr=cidr, tags=tags, conn=conn)
if vpcs_id: if vpcs_id:
@ -543,7 +546,7 @@ def create(cidr_block, instance_tenancy=None, vpc_name=None,
log.warning('VPC was not created') log.warning('VPC was not created')
except boto.exception.BotoServerError as exc: except boto.exception.BotoServerError as exc:
log.error(exc) log.error(exc)
return False raise CommandExecutionError(exc.reason)
def delete(vpc_id=None, name=None, tags=None, region=None, key=None, keyid=None, profile=None): def delete(vpc_id=None, name=None, tags=None, region=None, key=None, keyid=None, profile=None):
@ -587,7 +590,7 @@ def delete(vpc_id=None, name=None, tags=None, region=None, key=None, keyid=None,
return False return False
except boto.exception.BotoServerError as exc: except boto.exception.BotoServerError as exc:
log.error(exc) log.error(exc)
return False raise CommandExecutionError(exc.reason)
def _find_subnets(subnet_name=None, vpc_id=None, cidr=None, tags=None, conn=None): def _find_subnets(subnet_name=None, vpc_id=None, cidr=None, tags=None, conn=None):
@ -627,7 +630,7 @@ def _find_subnets(subnet_name=None, vpc_id=None, cidr=None, tags=None, conn=None
return False return False
except boto.exception.BotoServerError as exc: except boto.exception.BotoServerError as exc:
log.error(exc) log.error(exc)
return False raise CommandExecutionError(exc.reason)
def create_subnet(vpc_id=None, cidr_block=None, vpc_name=None, def create_subnet(vpc_id=None, cidr_block=None, vpc_name=None,
@ -653,16 +656,12 @@ def create_subnet(vpc_id=None, cidr_block=None, vpc_name=None,
subnet_name='mysubnet', cidr_block='10.0.0.0/25' subnet_name='mysubnet', cidr_block='10.0.0.0/25'
''' '''
conn = _get_conn(region, key, keyid, profile)
if not conn:
return False
vpc_id = _check_vpc(vpc_id, vpc_name, region, key, keyid, profile) vpc_id = _check_vpc(vpc_id, vpc_name, region, key, keyid, profile)
if not vpc_id: if not vpc_id:
log.warning('Refusing to create subnet for non-existent VPC') log.warning('Refusing to create subnet for non-existent VPC')
return False return False
vpc_subnet = _create_resource('subnet', subnet_name, tags=tags, vpc_subnet = _create_resource('subnet', name=subnet_name, tags=tags,
vpc_id=vpc_id, cidr_block=cidr_block, vpc_id=vpc_id, cidr_block=cidr_block,
region=region, key=key, keyid=keyid, region=region, key=key, keyid=keyid,
profile=profile) profile=profile)
@ -692,31 +691,9 @@ def delete_subnet(subnet_id=None, subnet_name=None, region=None, key=None,
''' '''
conn = _get_conn(region, key, keyid, profile) return _delete_resource(resource='subnet', name=subnet_name,
if not conn: resource_id=subnet_id, region=region, key=key,
return False keyid=keyid, profile=profile)
if subnet_name:
ids = _find_subnets(subnet_name=subnet_name, conn=conn)
if ids and len(ids) > 1:
log.warning('multiple subnets found '
'named "{0}"'.format(subnet_name))
return False
elif ids:
subnet_id = ids[0]
try:
if conn.delete_subnet(subnet_id):
log.debug('Subnet {0} was deleted.'.format(subnet_id))
return True
else:
log.debug('Subnet {0} was not deleted.'.format(subnet_id))
return False
except boto.exception.BotoServerError as exc:
log.error(exc)
return False
def subnet_exists(subnet_id=None, name=None, subnet_name=None, cidr=None, def subnet_exists(subnet_id=None, name=None, subnet_name=None, cidr=None,
@ -781,7 +758,7 @@ def subnet_exists(subnet_id=None, name=None, subnet_name=None, cidr=None,
return False return False
except boto.exception.BotoServerError as exc: except boto.exception.BotoServerError as exc:
log.error(exc) log.error(exc)
return False raise CommandExecutionError(exc.reason)
def create_internet_gateway(internet_gateway_name=None, vpc_id=None, def create_internet_gateway(internet_gateway_name=None, vpc_id=None,
@ -791,7 +768,7 @@ def create_internet_gateway(internet_gateway_name=None, vpc_id=None,
Create an Internet Gateway, optionally attaching it to an existing VPC. Create an Internet Gateway, optionally attaching it to an existing VPC.
Returns the internet gateway id if the internet gateway was created and Returns the internet gateway id if the internet gateway was created and
returns False if the internet gateways as not created. returns False if the internet gateways was not created.
.. versionadded:: Beryllium .. versionadded:: Beryllium
CLI example:: CLI example::
@ -807,13 +784,11 @@ def create_internet_gateway(internet_gateway_name=None, vpc_id=None,
if not conn: if not conn:
return False return False
vpc_id = _check_vpc(vpc_id, vpc_name, region, key, keyid, profile) vpc_id = vpc_id or get_id(name=vpc_name, region=region, key=key,
if not vpc_id: keyid=keyid, profile=profile)
log.warning('Refusing to create internet for non-existent VPC') igw = _create_resource('internet_gateway', name=internet_gateway_name,
return False tags=tags, region=region, key=key, keyid=keyid,
profile=profile)
igw = _create_resource('internet_gateway', internet_gateway_name,
tags, region, key, keyid, profile)
if igw: if igw:
if vpc_id: if vpc_id:
try: try:
@ -822,7 +797,7 @@ def create_internet_gateway(internet_gateway_name=None, vpc_id=None,
'VPC {1}'.format(igw.id, (vpc_name or vpc_id))) 'VPC {1}'.format(igw.id, (vpc_name or vpc_id)))
except boto.exception.BotoServerError as exc: except boto.exception.BotoServerError as exc:
log.error(exc) log.error(exc)
return False raise CommandExecutionError(exc.reason)
return igw.id return igw.id
return False return False
@ -874,10 +849,12 @@ def delete_internet_gateway(internet_gateway_id=None,
return True return True
except boto.exception.BotoServerError as exc: except boto.exception.BotoServerError as exc:
log.error(exc) log.error(exc)
raise CommandExecutionError(exc.reason)
return False return False
def create_customer_gateway(vpn_connection_type, ip_address, bgp_asn, customer_gateway_name=None, tags=None, def create_customer_gateway(vpn_connection_type, ip_address, bgp_asn,
customer_gateway_name=None, tags=None,
region=None, key=None, keyid=None, profile=None): region=None, key=None, keyid=None, profile=None):
''' '''
Given a valid VPN connection type, a static IP address and a customer Given a valid VPN connection type, a static IP address and a customer
@ -895,25 +872,14 @@ def create_customer_gateway(vpn_connection_type, ip_address, bgp_asn, customer_g
''' '''
conn = _get_conn(region, key, keyid, profile) customer_gateway = _create_resource('customer_gateway', customer_gateway_name,
if not conn: vpn_connection_type=vpn_connection_type,
return False ip_address=ip_address, bgp_asn=bgp_asn,
tags=tags, region=region, key=key,
try: keyid=keyid, profile=profile)
customer_gateway = conn.create_customer_gateway(vpn_connection_type, ip_address, bgp_asn) if customer_gateway:
if customer_gateway: return customer_gateway.id
log.info('A customer gateway with id {0} was created'.format(customer_gateway.id)) return False
_maybe_set_name_tag(customer_gateway_name, customer_gateway)
_maybe_set_tags(tags, customer_gateway)
return customer_gateway.id
else:
log.warning('A customer gateway was not created')
return False
except boto.exception.BotoServerError as exc:
log.error(exc)
return False
def delete_customer_gateway(customer_gateway_id, region=None, key=None, keyid=None, profile=None): def delete_customer_gateway(customer_gateway_id, region=None, key=None, keyid=None, profile=None):
@ -945,7 +911,7 @@ def delete_customer_gateway(customer_gateway_id, region=None, key=None, keyid=No
return False return False
except boto.exception.BotoServerError as exc: except boto.exception.BotoServerError as exc:
log.error(exc) log.error(exc)
return False raise CommandExecutionError(exc.reason)
def customer_gateway_exists(customer_gateway_id, region=None, key=None, keyid=None, profile=None): def customer_gateway_exists(customer_gateway_id, region=None, key=None, keyid=None, profile=None):
@ -976,7 +942,7 @@ def customer_gateway_exists(customer_gateway_id, region=None, key=None, keyid=No
return False return False
except boto.exception.BotoServerError as exc: except boto.exception.BotoServerError as exc:
log.error(exc) log.error(exc)
return False raise CommandExecutionError(exc.reason)
def create_dhcp_options(domain_name=None, domain_name_servers=None, ntp_servers=None, def create_dhcp_options(domain_name=None, domain_name_servers=None, ntp_servers=None,
@ -1014,7 +980,7 @@ def create_dhcp_options(domain_name=None, domain_name_servers=None, ntp_servers=
return False return False
except boto.exception.BotoServerError as exc: except boto.exception.BotoServerError as exc:
log.error(exc) log.error(exc)
return False raise CommandExecutionError(exc.reason)
def associate_dhcp_options_to_vpc(dhcp_options_id, vpc_id, region=None, key=None, keyid=None, profile=None): def associate_dhcp_options_to_vpc(dhcp_options_id, vpc_id, region=None, key=None, keyid=None, profile=None):
@ -1043,7 +1009,7 @@ def associate_dhcp_options_to_vpc(dhcp_options_id, vpc_id, region=None, key=None
return False return False
except boto.exception.BotoServerError as exc: except boto.exception.BotoServerError as exc:
log.error(exc) log.error(exc)
return False raise CommandExecutionError(exc.reason)
def associate_new_dhcp_options_to_vpc(vpc_id, domain_name=None, domain_name_servers=None, ntp_servers=None, def associate_new_dhcp_options_to_vpc(vpc_id, domain_name=None, domain_name_servers=None, ntp_servers=None,
@ -1073,7 +1039,8 @@ def associate_new_dhcp_options_to_vpc(vpc_id, domain_name=None, domain_name_serv
return dhcp_options.id return dhcp_options.id
except boto.exception.BotoServerError as exc: except boto.exception.BotoServerError as exc:
log.error(exc) log.error(exc)
return False raise exc
raise CommandExecutionError(exc.reason)
def dhcp_options_exists(dhcp_options_id=None, name=None, tags=None, region=None, key=None, keyid=None, profile=None): def dhcp_options_exists(dhcp_options_id=None, name=None, tags=None, region=None, key=None, keyid=None, profile=None):
@ -1121,7 +1088,7 @@ def dhcp_options_exists(dhcp_options_id=None, name=None, tags=None, region=None,
return False return False
except boto.exception.BotoServerError as exc: except boto.exception.BotoServerError as exc:
log.error(exc) log.error(exc)
return False raise CommandExecutionError(exc.reason)
def create_network_acl(vpc_id, network_acl_name=None, tags=None, region=None, key=None, keyid=None, profile=None): def create_network_acl(vpc_id, network_acl_name=None, tags=None, region=None, key=None, keyid=None, profile=None):
@ -1153,7 +1120,7 @@ def create_network_acl(vpc_id, network_acl_name=None, tags=None, region=None, ke
return False return False
except boto.exception.BotoServerError as exc: except boto.exception.BotoServerError as exc:
log.error(exc) log.error(exc)
return False raise CommandExecutionError(exc.reason)
def delete_network_acl(network_acl_id, region=None, key=None, keyid=None, profile=None): def delete_network_acl(network_acl_id, region=None, key=None, keyid=None, profile=None):
@ -1182,7 +1149,7 @@ def delete_network_acl(network_acl_id, region=None, key=None, keyid=None, profil
return False return False
except boto.exception.BotoServerError as exc: except boto.exception.BotoServerError as exc:
log.error(exc) log.error(exc)
return False raise CommandExecutionError(exc.reason)
def network_acl_exists(network_acl_id=None, name=None, tags=None, region=None, key=None, keyid=None, profile=None): def network_acl_exists(network_acl_id=None, name=None, tags=None, region=None, key=None, keyid=None, profile=None):
@ -1227,7 +1194,7 @@ def network_acl_exists(network_acl_id=None, name=None, tags=None, region=None, k
return False return False
except boto.exception.BotoServerError as exc: except boto.exception.BotoServerError as exc:
log.error(exc) log.error(exc)
return False raise CommandExecutionError(exc.reason)
def associate_network_acl_to_subnet(network_acl_id, subnet_id, region=None, key=None, keyid=None, profile=None): def associate_network_acl_to_subnet(network_acl_id, subnet_id, region=None, key=None, keyid=None, profile=None):
@ -1257,7 +1224,7 @@ def associate_network_acl_to_subnet(network_acl_id, subnet_id, region=None, key=
return False return False
except boto.exception.BotoServerError as exc: except boto.exception.BotoServerError as exc:
log.error(exc) log.error(exc)
return False raise CommandExecutionError(exc.reason)
def associate_new_network_acl_to_subnet(vpc_id, subnet_id, network_acl_name=None, tags=None, def associate_new_network_acl_to_subnet(vpc_id, subnet_id, network_acl_name=None, tags=None,
@ -1297,7 +1264,7 @@ def associate_new_network_acl_to_subnet(vpc_id, subnet_id, network_acl_name=None
return False return False
except boto.exception.BotoServerError as exc: except boto.exception.BotoServerError as exc:
log.error(exc) log.error(exc)
return False raise CommandExecutionError(exc.reason)
def disassociate_network_acl(subnet_id, vpc_id=None, region=None, key=None, keyid=None, profile=None): def disassociate_network_acl(subnet_id, vpc_id=None, region=None, key=None, keyid=None, profile=None):
@ -1319,7 +1286,7 @@ def disassociate_network_acl(subnet_id, vpc_id=None, region=None, key=None, keyi
return conn.disassociate_network_acl(subnet_id, vpc_id=vpc_id) return conn.disassociate_network_acl(subnet_id, vpc_id=vpc_id)
except boto.exception.BotoServerError as exc: except boto.exception.BotoServerError as exc:
log.error(exc) log.error(exc)
return False raise CommandExecutionError(exc.reason)
def create_network_acl_entry(network_acl_id, rule_number, protocol, rule_action, cidr_block, egress=None, def create_network_acl_entry(network_acl_id, rule_number, protocol, rule_action, cidr_block, egress=None,
@ -1352,8 +1319,74 @@ def create_network_acl_entry(network_acl_id, rule_number, protocol, rule_action,
return False return False
except boto.exception.BotoServerError as exc: except boto.exception.BotoServerError as exc:
log.error(exc) log.error(exc)
raise CommandExecutionError(exc.reason)
def create_network_acl_entry(network_acl_id, rule_number, protocol, rule_action, cidr_block, egress=None,
icmp_code=None, icmp_type=None, port_range_from=None, port_range_to=None,
region=None, key=None, keyid=None, profile=None):
'''
Creates a network acl entry.
CLI Example::
.. code-block:: bash
salt myminion boto_vpc.create_network_acl_entry 'acl-5fb85d36' '32767' '-1' 'deny' '0.0.0.0/0'
'''
conn = _get_conn(region, key, keyid, profile)
if not conn:
return False return False
try:
network_acl_entry = conn.create_network_acl_entry(network_acl_id, rule_number, protocol, rule_action,
cidr_block,
egress=egress, icmp_code=icmp_code, icmp_type=icmp_type,
port_range_from=port_range_from, port_range_to=port_range_to)
if network_acl_entry:
log.info('Network ACL entry was created')
return True
else:
log.warning('Network ACL entry was not created')
return False
except boto.exception as exc:
log.error(exc)
raise CommandExecutionError(exc.reason)
def create_network_acl_entry(network_acl_id, rule_number, protocol, rule_action, cidr_block, egress=None,
icmp_code=None, icmp_type=None, port_range_from=None, port_range_to=None,
region=None, key=None, keyid=None, profile=None):
'''
Creates a network acl entry.
CLI Example::
.. code-block:: bash
salt myminion boto_vpc.create_network_acl_entry 'acl-5fb85d36' '32767' '-1' 'deny' '0.0.0.0/0'
'''
conn = _get_conn(region, key, keyid, profile)
if not conn:
return False
try:
network_acl_entry = conn.create_network_acl_entry(network_acl_id, rule_number, protocol, rule_action,
cidr_block,
egress=egress, icmp_code=icmp_code, icmp_type=icmp_type,
port_range_from=port_range_from, port_range_to=port_range_to)
if network_acl_entry:
log.info('Network ACL entry was created')
return True
else:
log.warning('Network ACL entry was not created')
return False
except boto.exception.BotoServerError as exc:
log.error(exc)
raise CommandExecutionError(exc.reason)
def replace_network_acl_entry(network_acl_id, rule_number, protocol, rule_action, cidr_block, egress=None, def replace_network_acl_entry(network_acl_id, rule_number, protocol, rule_action, cidr_block, egress=None,
icmp_code=None, icmp_type=None, port_range_from=None, port_range_to=None, icmp_code=None, icmp_type=None, port_range_from=None, port_range_to=None,
@ -1386,7 +1419,7 @@ def replace_network_acl_entry(network_acl_id, rule_number, protocol, rule_action
return False return False
except boto.exception.BotoServerError as exc: except boto.exception.BotoServerError as exc:
log.error(exc) log.error(exc)
return False raise CommandExecutionError(exc.reason)
def delete_network_acl_entry(network_acl_id, rule_number, egress=None, region=None, key=None, keyid=None, profile=None): def delete_network_acl_entry(network_acl_id, rule_number, egress=None, region=None, key=None, keyid=None, profile=None):
@ -1414,7 +1447,7 @@ def delete_network_acl_entry(network_acl_id, rule_number, egress=None, region=No
return False return False
except boto.exception.BotoServerError as exc: except boto.exception.BotoServerError as exc:
log.error(exc) log.error(exc)
return False raise CommandExecutionError(exc.reason)
def create_route_table(vpc_id=None, vpc_name=None, route_table_name=None, def create_route_table(vpc_id=None, vpc_name=None, route_table_name=None,
@ -1464,17 +1497,13 @@ def delete_route_table(route_table_id=None, route_table_name=None,
salt myminion boto_vpc.delete_route_table route_table_name='myroutetable' salt myminion boto_vpc.delete_route_table route_table_name='myroutetable'
''' '''
try: return _delete_resource(resource='route_table', name=route_table_name,
if _delete_resource(resource='route_table', name=route_table_name,
resource_id=route_table_id, region=region, key=key, resource_id=route_table_id, region=region, key=key,
keyid=keyid, profile=profile): keyid=keyid, profile=profile)
return True
except boto.exception.BotoServerError as exc:
log.error(exc)
return False
def route_table_exists(route_table_id=None, name=None, tags=None, region=None, key=None, keyid=None, profile=None): def route_table_exists(route_table_id=None, name=None, route_table_name=None,
tags=None, region=None, key=None, keyid=None, profile=None):
''' '''
Checks if a route table exists. Checks if a route table exists.
@ -1485,12 +1514,18 @@ def route_table_exists(route_table_id=None, name=None, tags=None, region=None, k
salt myminion boto_vpc.route_table_exists route_table_id='rtb-1f382e7d' salt myminion boto_vpc.route_table_exists route_table_id='rtb-1f382e7d'
''' '''
if name:
log.warning('boto_vpc.route_table_exists: name parameter is deprecated '
'use route_table_name instead.')
route_table_name = name
conn = _get_conn(region, key, keyid, profile) conn = _get_conn(region, key, keyid, profile)
if not conn: if not conn:
return False return False
if not route_table_id and not name and not tags: if not route_table_id and not route_table_name and not tags:
raise SaltInvocationError('At least one of the following must be specified: route table id, name or tags.') raise SaltInvocationError('At least one of the following must be specified: '
'router_table_id, route_table_name or tags.')
try: try:
filter_parameters = {'filters': {}} filter_parameters = {'filters': {}}
@ -1498,8 +1533,8 @@ def route_table_exists(route_table_id=None, name=None, tags=None, region=None, k
if route_table_id: if route_table_id:
filter_parameters['route_table_ids'] = [route_table_id] filter_parameters['route_table_ids'] = [route_table_id]
if name: if route_table_name:
filter_parameters['filters']['tag:Name'] = name filter_parameters['filters']['tag:Name'] = route_table_name
if tags: if tags:
for tag_name, tag_value in six.iteritems(tags): for tag_name, tag_value in six.iteritems(tags):
@ -1516,13 +1551,14 @@ def route_table_exists(route_table_id=None, name=None, tags=None, region=None, k
return False return False
except boto.exception.BotoServerError as exc: except boto.exception.BotoServerError as exc:
log.error(exc) log.error(exc)
return False raise CommandExecutionError(exc.reason)
def route_exists(destination_cidr_block, route_table_name=None, route_table_id=None, gateway_id=None, instance_id=None, def route_exists(destination_cidr_block, route_table_name=None, route_table_id=None, gateway_id=None, instance_id=None,
interface_id=None, tags=None, region=None, key=None, keyid=None, profile=None): interface_id=None, tags=None, region=None, key=None, keyid=None, profile=None):
''' '''
Checks if a route exists. Checks if a route exists.
.. versionadded:: Beryllium .. versionadded:: Beryllium
CLI Example:: CLI Example::
@ -1562,10 +1598,10 @@ def route_exists(destination_cidr_block, route_table_name=None, route_table_id=N
raise SaltInvocationError('Found more than one route table.') raise SaltInvocationError('Found more than one route table.')
route_check = {'destination_cidr_block': destination_cidr_block, route_check = {'destination_cidr_block': destination_cidr_block,
'gateway_id': gateway_id, 'gateway_id': gateway_id,
'instance_id': instance_id, 'instance_id': instance_id,
'interface_id': interface_id 'interface_id': interface_id
} }
for route_match in route_tables[0].routes: for route_match in route_tables[0].routes:
@ -1583,7 +1619,7 @@ def route_exists(destination_cidr_block, route_table_name=None, route_table_id=N
return False return False
except boto.exception.BotoServerError as exc: except boto.exception.BotoServerError as exc:
log.error(exc) log.error(exc)
return False raise CommandExecutionError(exc.reason)
def associate_route_table(route_table_id, subnet_id, region=None, key=None, keyid=None, profile=None): def associate_route_table(route_table_id, subnet_id, region=None, key=None, keyid=None, profile=None):
@ -1608,7 +1644,7 @@ def associate_route_table(route_table_id, subnet_id, region=None, key=None, keyi
return association_id return association_id
except boto.exception.BotoServerError as exc: except boto.exception.BotoServerError as exc:
log.error(exc) log.error(exc)
return False raise CommandExecutionError(exc.reason)
def disassociate_route_table(association_id, region=None, key=None, keyid=None, profile=None): def disassociate_route_table(association_id, region=None, key=None, keyid=None, profile=None):
@ -1640,7 +1676,7 @@ def disassociate_route_table(association_id, region=None, key=None, keyid=None,
return False return False
except boto.exception.BotoServerError as exc: except boto.exception.BotoServerError as exc:
log.error(exc) log.error(exc)
return False raise CommandExecutionError(exc.reason)
def replace_route_table_association(association_id, route_table_id, region=None, key=None, keyid=None, profile=None): def replace_route_table_association(association_id, route_table_id, region=None, key=None, keyid=None, profile=None):
@ -1665,7 +1701,7 @@ def replace_route_table_association(association_id, route_table_id, region=None,
return association_id return association_id
except boto.exception.BotoServerError as exc: except boto.exception.BotoServerError as exc:
log.error(exc) log.error(exc)
return False raise CommandExecutionError(exc.reason)
def create_route(route_table_id, destination_cidr_block, gateway_id=None, instance_id=None, interface_id=None, def create_route(route_table_id, destination_cidr_block, gateway_id=None, instance_id=None, interface_id=None,
@ -1697,7 +1733,7 @@ def create_route(route_table_id, destination_cidr_block, gateway_id=None, instan
return False return False
except boto.exception.BotoServerError as exc: except boto.exception.BotoServerError as exc:
log.error(exc) log.error(exc)
return False raise CommandExecutionError(exc.reason)
def delete_route(route_table_id, destination_cidr_block, region=None, key=None, keyid=None, profile=None): def delete_route(route_table_id, destination_cidr_block, region=None, key=None, keyid=None, profile=None):
@ -1727,7 +1763,7 @@ def delete_route(route_table_id, destination_cidr_block, region=None, key=None,
return False return False
except boto.exception.BotoServerError as exc: except boto.exception.BotoServerError as exc:
log.error(exc) log.error(exc)
return False raise CommandExecutionError(exc.reason)
def replace_route(route_table_id, destination_cidr_block, gateway_id=None, instance_id=None, interface_id=None, def replace_route(route_table_id, destination_cidr_block, gateway_id=None, instance_id=None, interface_id=None,
@ -1747,46 +1783,48 @@ def replace_route(route_table_id, destination_cidr_block, gateway_id=None, insta
return False return False
try: try:
if conn.replace_route(route_table_id, destination_cidr_block, gateway_id=gateway_id, instance_id=instance_id, if conn.replace_route(route_table_id, destination_cidr_block,
gateway_id=gateway_id, instance_id=instance_id,
interface_id=interface_id): interface_id=interface_id):
log.info('Route with cider block {0} on route table {1} was replaced'.format(route_table_id, log.info('Route with cider block {0} on route table {1} was '
destination_cidr_block)) 'replaced'.format(route_table_id, destination_cidr_block))
return True return True
else: else:
log.warning('Route with cider block {0} on route table {1} was not replaced'.format(route_table_id, log.warning('Route with cider block {0} on route table {1} was not replaced'.format(route_table_id,
destination_cidr_block)) destination_cidr_block))
return False return False
except boto.exception.BotoServerError as exc: except boto.exception.BotoServerError as exc:
log.error(exc) log.error(exc)
return False raise CommandExecutionError(exc.reason)
def describe(vpc_id=None, region=None, key=None, keyid=None, profile=None): def describe(vpc_id=None, vpc_name=None, region=None, key=None,
keyid=None, profile=None):
''' '''
Given a VPC ID describe it's properties. Given a VPC ID describe its properties.
Returns a dictionary of interesting properties. Returns a dictionary of interesting properties.
.. versionchanged Beryllium
Added vpc_name argument
CLI example:: CLI example::
.. code-block:: bash .. code-block:: bash
salt myminion boto_vpc.describe vpc_id=vpc-123456 salt myminion boto_vpc.describe vpc_id=vpc-123456
salt myminion boto_vpc.describe vpc_name=myvpc
''' '''
conn = _get_conn(region, key, keyid, profile) conn = _get_conn(region, key, keyid, profile)
_ret = dict(cidr_block=None,
is_default=None,
state=None,
tags=None,
dhcp_options_id=None,
instance_tenancy=None)
if not conn: if not any((vpc_id, vpc_name)):
return False raise SaltInvocationError('A valid vpc id or name needs to be specified.')
vpc_id = _check_vpc(vpc_id, vpc_name, region, key, keyid, profile)
if not vpc_id: if not vpc_id:
raise SaltInvocationError('VPC ID needs to be specified.') return None
try: try:
filter_parameters = {'vpc_ids': vpc_id} filter_parameters = {'vpc_ids': vpc_id}
@ -1796,13 +1834,14 @@ def describe(vpc_id=None, region=None, key=None, keyid=None, profile=None):
if vpcs: if vpcs:
vpc = vpcs[0] # Found! vpc = vpcs[0] # Found!
log.debug('Found VPC: {0}'.format(vpc.id)) log.debug('Found VPC: {0}'.format(vpc.id))
for k in six.iterkeys(_ret):
_ret[k] = getattr(vpc, k) keys = ('id', 'cidr_block', 'is_default', 'state', 'tags',
return _ret 'dhcp_options_id', 'instance_tenancy')
return dict([(k, getattr(vpc, k)) for k in keys])
except boto.exception.BotoServerError as exc: except boto.exception.BotoServerError as exc:
log.error(exc) log.error(exc)
return False raise CommandExecutionError(exc.reason)
def describe_vpcs(vpc_id=None, name=None, cidr=None, tags=None, def describe_vpcs(vpc_id=None, name=None, cidr=None, tags=None,
@ -1811,6 +1850,9 @@ def describe_vpcs(vpc_id=None, name=None, cidr=None, tags=None,
Describe all VPCs, matching the filter criteria if provided. Describe all VPCs, matching the filter criteria if provided.
Returns a a list of dictionaries with interesting properties. Returns a a list of dictionaries with interesting properties.
.. versionadded:: Beryllium
CLI example:: CLI example::
.. code-block:: bash .. code-block:: bash
@ -1819,13 +1861,13 @@ def describe_vpcs(vpc_id=None, name=None, cidr=None, tags=None,
''' '''
conn = _get_conn(region, key, keyid, profile) conn = _get_conn(region, key, keyid, profile)
items = ('id', keys = ('id',
'cidr_block', 'cidr_block',
'is_default', 'is_default',
'state', 'state',
'tags', 'tags',
'dhcp_options_id', 'dhcp_options_id',
'instance_tenancy') 'instance_tenancy')
if not conn: if not conn:
return False return False
@ -1851,55 +1893,43 @@ def describe_vpcs(vpc_id=None, name=None, cidr=None, tags=None,
if vpcs: if vpcs:
ret = [] ret = []
for vpc in vpcs: for vpc in vpcs:
ret.append(dict((k, getattr(vpc, k)) for k in items)) ret.append(dict((k, getattr(vpc, k)) for k in keys))
return ret return ret
except boto.exception.BotoServerError as exc: except boto.exception.BotoServerError as exc:
log.error(exc) log.error(exc)
return False raise CommandExecutionError(exc.reason)
def describe_subnet(subnet_id=None, region=None, key=None, keyid=None, profile=None): def describe_subnet(subnet_id=None, subnet_name=None, region=None,
key=None, keyid=None, profile=None):
''' '''
Given a subnet id, describe it's properties. Given a subnet id or name, describe its properties.
Returns a dictionary of interesting properties. Returns a dictionary of interesting properties.
CLI example::
.. versionadded:: Beryllium
CLI examples::
.. code-block:: bash .. code-block:: bash
salt myminion boto_vpc.describe_subnet subnet_id=subnet-123456 salt myminion boto_vpc.describe_subnet subnet_id=subnet-123456
salt myminion boto_vpc.describe_subnet subnet_name=mysubnet
''' '''
conn = _get_conn(region, key, keyid, profile) conn = _get_conn(region, key, keyid, profile)
_ret = dict(cidr_block=None,
availability_zone=None,
state=None,
vpc_id=None,
tags=None)
if not conn: if not conn:
return False return False
if not subnet_id: subnet = _get_resource('subnet', subnet_name=subnet_name, region=region,
raise SaltInvocationError('subnet id needs to be specified.') key=key, keyid=keyid, profile=profile)
if not subnet:
return subnet
log.debug('Found subnet: {0}'.format(subnet.id))
try: keys = ('id', 'cidr_block', 'availability_zone', 'tags')
filter_parameters = {'subnet_ids': subnet_id} return [getattr(subnet, k) for k in keys]
subnets = conn.get_all_subnets(**filter_parameters)
if subnets:
subnet = subnets[0] # Found!
log.debug('Found subnet: {0}'.format(subnet.id))
for k in six.iterkeys(_ret):
_ret[k] = getattr(subnet, k)
_ret['subnet_id'] = subnet.id
return _ret
except boto.exception.BotoServerError as exc:
log.error(exc)
return False
def describe_subnets(subnet_ids=None, vpc_id=None, cidr=None, region=None, key=None, def describe_subnets(subnet_ids=None, vpc_id=None, cidr=None, region=None, key=None,
@ -1907,9 +1937,11 @@ def describe_subnets(subnet_ids=None, vpc_id=None, cidr=None, region=None, key=N
''' '''
Given a VPC ID or subnet CIDR, returns a list of associated subnets and Given a VPC ID or subnet CIDR, returns a list of associated subnets and
their details. Return all subnets if VPC ID or CIDR are not provided. their details. Return all subnets if VPC ID or CIDR are not provided.
If a subnet CIDR is provided, only it's associated subnet details will be If a subnet id or CIDR is provided, only its associated subnet details will be
returned. returned.
.. versionadded:: Beryllium
CLI Examples:: CLI Examples::
.. code-block:: bash .. code-block:: bash
@ -1950,7 +1982,7 @@ def describe_subnets(subnet_ids=None, vpc_id=None, cidr=None, region=None, key=N
return False return False
subnets_list = [] subnets_list = []
keys = ['id', 'cidr_block', 'availability_zone', 'tags'] keys = ('id', 'cidr_block', 'availability_zone', 'tags')
for item in subnets: for item in subnets:
subnet = {} subnet = {}
for key in keys: for key in keys:
@ -1961,13 +1993,15 @@ def describe_subnets(subnet_ids=None, vpc_id=None, cidr=None, region=None, key=N
except boto.exception.BotoServerError as exc: except boto.exception.BotoServerError as exc:
log.debug(exc) log.debug(exc)
return False raise CommandExecutionError(exc.reason)
def describe_route_table(route_table_id=None, route_table_name=None, tags=None, region=None, key=None, keyid=None, def describe_route_tables(route_table_id=None, route_table_name=None, tags=None, region=None, key=None, keyid=None,
profile=None): profile=None):
''' '''
Given route table properties, return route table details if exists. Given route table properties, return route table details if matching table(s) exist.
.. versionadded:: Beryllium
CLI Example:: CLI Example::
@ -2002,7 +2036,7 @@ def describe_route_table(route_table_id=None, route_table_name=None, tags=None,
return False return False
route_table = {} route_table = {}
keys = ['id', 'vpc_id', 'tags', 'routes'] keys = ('id', 'vpc_id', 'tags', 'routes')
route_keys = ['destination_cidr_block', 'gateway_id', 'instance_id', 'interface_id'] route_keys = ['destination_cidr_block', 'gateway_id', 'instance_id', 'interface_id']
for item in route_tables: for item in route_tables:
routes_list = [] routes_list = []
@ -2021,7 +2055,7 @@ def describe_route_table(route_table_id=None, route_table_name=None, tags=None,
except boto.exception.BotoServerError as exc: except boto.exception.BotoServerError as exc:
log.error(exc) log.error(exc)
return False raise CommandExecutionError(exc.reason)
def _create_dhcp_options(conn, domain_name=None, domain_name_servers=None, ntp_servers=None, netbios_name_servers=None, def _create_dhcp_options(conn, domain_name=None, domain_name_servers=None, ntp_servers=None, netbios_name_servers=None,
@ -2073,9 +2107,10 @@ def _get_conn(region, key, keyid, profile):
conn = svc_mod.connect_to_region(region, aws_access_key_id=keyid, conn = svc_mod.connect_to_region(region, aws_access_key_id=keyid,
aws_secret_access_key=key) aws_secret_access_key=key)
except boto.exception.NoAuthHandlerFound: except boto.exception.NoAuthHandlerFound:
log.error('No authentication credentials found when ' message = ('No authentication credentials found when '
'attempting to make boto {0} connection to ' 'attempting to make boto {0} connection to '
'region "{1}".'.format(service, region)) 'region "{1}".'.format(service, region))
return None log.error(message)
raise CommandExecutionError(message)
__context__[cxkey] = conn __context__[cxkey] = conn
return conn return conn

View File

@ -62,7 +62,7 @@ dhcp_options_parameters = {'domain_name': 'example.com', 'domain_name_servers':
network_acl_entry_parameters = ('fake', 100, -1, 'allow', cidr_block) network_acl_entry_parameters = ('fake', 100, -1, 'allow', cidr_block)
dhcp_options_parameters.update(conn_parameters) dhcp_options_parameters.update(conn_parameters)
boto_vpc.__context__ = {} #boto_vpc.__context__ = {}
def _has_required_boto(): def _has_required_boto():
@ -96,6 +96,9 @@ def _has_required_moto():
class BotoVpcTestCaseBase(TestCase): class BotoVpcTestCaseBase(TestCase):
conn = None conn = None
def setUp(self):
boto_vpc.__context__ = {}
def _create_vpc(self, name=None, tags=None): def _create_vpc(self, name=None, tags=None):
''' '''
Helper function to create a test vpc Helper function to create a test vpc
@ -409,9 +412,8 @@ class BotoVpcTestCase(BotoVpcTestCaseBase):
tests False VPC not created. tests False VPC not created.
''' '''
with patch('moto.ec2.models.VPCBackend.create_vpc', side_effect=BotoServerError(400, 'Mocked error')): with patch('moto.ec2.models.VPCBackend.create_vpc', side_effect=BotoServerError(400, 'Mocked error')):
vpc_creation_result = boto_vpc.create(cidr_block, **conn_parameters) with self.assertRaisesRegexp(CommandExecutionError, 'Mocked error'):
vpc_creation_result = boto_vpc.create(cidr_block, **conn_parameters)
self.assertFalse(vpc_creation_result)
@mock_ec2 @mock_ec2
def test_that_when_deleting_an_existing_vpc_the_delete_vpc_method_returns_true(self): def test_that_when_deleting_an_existing_vpc_the_delete_vpc_method_returns_true(self):
@ -442,10 +444,11 @@ class BotoVpcTestCase(BotoVpcTestCaseBase):
describe_vpc = boto_vpc.describe(vpc_id=vpc.id, **conn_parameters) describe_vpc = boto_vpc.describe(vpc_id=vpc.id, **conn_parameters)
vpc_properties = dict(cidr_block=six.text_type(cidr_block), vpc_properties = dict(id=vpc.id,
cidr_block=six.text_type(cidr_block),
is_default=None, is_default=None,
state=u'available', state=u'available',
tags={'Name': 'test', 'test': 'testvalue'}, tags={u'Name': u'test', u'test': u'testvalue'},
dhcp_options_id=u'dopt-7a8b9c2d', dhcp_options_id=u'dopt-7a8b9c2d',
instance_tenancy=u'default') instance_tenancy=u'default')
@ -463,7 +466,7 @@ class BotoVpcTestCase(BotoVpcTestCaseBase):
self.assertFalse(describe_vpc) self.assertFalse(describe_vpc)
@mock_ec2 @mock_ec2
def test_that_when_describing_vpc_by_id_on_connection_error_it_returns_returns_false(self): def test_that_when_describing_vpc_by_id_on_connection_error_it_raises_execution_error(self):
''' '''
Tests describing parameters failure Tests describing parameters failure
''' '''
@ -471,9 +474,10 @@ class BotoVpcTestCase(BotoVpcTestCaseBase):
with patch('moto.ec2.models.VPCBackend.get_all_vpcs', with patch('moto.ec2.models.VPCBackend.get_all_vpcs',
side_effect=BotoServerError(400, 'Mocked error')): side_effect=BotoServerError(400, 'Mocked error')):
describe_vpc = boto_vpc.describe(vpc_id=vpc.id, **conn_parameters) with self.assertRaisesRegexp(CommandExecutionError,
'Mocked error'):
self.assertFalse(describe_vpc) describe_vpc = boto_vpc.describe(vpc_id=vpc.id, **conn_parameters)
self.assertEqual(describe_vpc, True)
@mock_ec2 @mock_ec2
def test_that_when_describing_vpc_but_providing_no_vpc_id_the_describe_method_raises_a_salt_invocation_error(self): def test_that_when_describing_vpc_but_providing_no_vpc_id_the_describe_method_raises_a_salt_invocation_error(self):
@ -481,7 +485,7 @@ class BotoVpcTestCase(BotoVpcTestCaseBase):
Tests describing vpc without vpc id Tests describing vpc without vpc id
''' '''
with self.assertRaisesRegexp(SaltInvocationError, with self.assertRaisesRegexp(SaltInvocationError,
'VPC ID needs to be specified.'): 'A valid vpc id or name needs to be specified.'):
boto_vpc.describe(vpc_id=None, **conn_parameters) boto_vpc.describe(vpc_id=None, **conn_parameters)
@ -574,9 +578,8 @@ class BotoVpcSubnetsTestCase(BotoVpcTestCaseBase):
vpc = self._create_vpc() vpc = self._create_vpc()
with patch('moto.ec2.models.SubnetBackend.create_subnet', side_effect=BotoServerError(400, 'Mocked error')): with patch('moto.ec2.models.SubnetBackend.create_subnet', side_effect=BotoServerError(400, 'Mocked error')):
subnet_creation_result = boto_vpc.create_subnet(vpc.id, '10.0.0.0/24', **conn_parameters) with self.assertRaisesRegexp(CommandExecutionError, 'Mocked error'):
subnet_creation_result = boto_vpc.create_subnet(vpc.id, '10.0.0.0/24', **conn_parameters)
self.assertFalse(subnet_creation_result)
@mock_ec2 @mock_ec2
def test_that_when_deleting_an_existing_subnet_the_delete_subnet_method_returns_true(self): def test_that_when_deleting_an_existing_subnet_the_delete_subnet_method_returns_true(self):