mirror of
https://github.com/valitydev/salt.git
synced 2024-11-07 17:09:03 +00:00
Merge pull request #27728 from tkwilliams/d.boto_vpc.dhcp_options_stuff
Enablement for using states to manage AWS EC2 instances
This commit is contained in:
commit
fafc6ce09f
@ -362,7 +362,8 @@ def get_zones(region=None, key=None, keyid=None, profile=None):
|
||||
|
||||
|
||||
def find_instances(instance_id=None, name=None, tags=None, region=None,
|
||||
key=None, keyid=None, profile=None, return_objs=False):
|
||||
key=None, keyid=None, profile=None, return_objs=False,
|
||||
in_states=None):
|
||||
|
||||
'''
|
||||
Given instance properties, find and return matching instance ids
|
||||
@ -378,6 +379,8 @@ def find_instances(instance_id=None, name=None, tags=None, region=None,
|
||||
'''
|
||||
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
|
||||
|
||||
if not any((instance_id, name, tags)):
|
||||
return []
|
||||
try:
|
||||
filter_parameters = {'filters': {}}
|
||||
|
||||
@ -396,15 +399,19 @@ def find_instances(instance_id=None, name=None, tags=None, region=None,
|
||||
log.debug('The filters criteria {0} matched the following '
|
||||
'instances:{1}'.format(filter_parameters, instances))
|
||||
|
||||
if in_states:
|
||||
instances = [i for i in instances if i.state in in_states]
|
||||
log.debug('Limiting instance matches to those in the requested '
|
||||
'states: {0}'.format(instances))
|
||||
if instances:
|
||||
if return_objs:
|
||||
return instances
|
||||
return [instance.id for instance in instances]
|
||||
else:
|
||||
return False
|
||||
return []
|
||||
except boto.exception.BotoServerError as exc:
|
||||
log.error(exc)
|
||||
return False
|
||||
return []
|
||||
|
||||
|
||||
def create_image(ami_name, instance_id=None, instance_name=None, tags=None, region=None,
|
||||
@ -506,19 +513,19 @@ def terminate(instance_id=None, name=None, region=None,
|
||||
instances = find_instances(instance_id=instance_id, name=name,
|
||||
region=region, key=key, keyid=keyid,
|
||||
profile=profile, return_objs=True)
|
||||
if instances in (False, None):
|
||||
if instances in (False, None, []):
|
||||
return instances
|
||||
|
||||
if len(instances) == 1:
|
||||
instances[0].terminate()
|
||||
return True
|
||||
else:
|
||||
log.warning('refusing to terminate multiple instances at once')
|
||||
log.warning('Refusing to terminate multiple instances at once')
|
||||
return False
|
||||
|
||||
|
||||
def get_id(name=None, tags=None, region=None, key=None,
|
||||
keyid=None, profile=None):
|
||||
keyid=None, profile=None, in_states=None):
|
||||
|
||||
'''
|
||||
Given instace properties, return the instance id if it exist.
|
||||
@ -531,7 +538,7 @@ def get_id(name=None, tags=None, region=None, key=None,
|
||||
|
||||
'''
|
||||
instance_ids = find_instances(name=name, tags=tags, region=region, key=key,
|
||||
keyid=keyid, profile=profile)
|
||||
keyid=keyid, profile=profile, in_states=in_states)
|
||||
if instance_ids:
|
||||
log.info("Instance ids: {0}".format(" ".join(instance_ids)))
|
||||
if len(instance_ids) == 1:
|
||||
@ -545,7 +552,7 @@ def get_id(name=None, tags=None, region=None, key=None,
|
||||
|
||||
|
||||
def exists(instance_id=None, name=None, tags=None, region=None, key=None,
|
||||
keyid=None, profile=None):
|
||||
keyid=None, profile=None, in_states=None):
|
||||
'''
|
||||
Given a instance id, check to see if the given instance id exists.
|
||||
|
||||
@ -558,18 +565,27 @@ def exists(instance_id=None, name=None, tags=None, region=None, key=None,
|
||||
|
||||
salt myminion boto_ec2.exists myinstance
|
||||
'''
|
||||
instances = find_instances(instance_id=instance_id, name=name, tags=tags)
|
||||
instances = find_instances(instance_id=instance_id, name=name, tags=tags,
|
||||
in_states=in_states)
|
||||
if instances:
|
||||
log.info('instance exists.')
|
||||
log.info('Instance exists.')
|
||||
return True
|
||||
else:
|
||||
log.warning('instance does not exist.')
|
||||
log.warning('Instance does not exist.')
|
||||
return False
|
||||
|
||||
|
||||
def run(image_id, name=None, tags=None, instance_type='m1.small',
|
||||
key_name=None, security_groups=None, user_data=None, placement=None,
|
||||
def run(image_id, name=None, tags=None, key_name=None, security_groups=None,
|
||||
user_data=None, instance_type='m1.small', placement=None,
|
||||
kernel_id=None, ramdisk_id=None, monitoring_enabled=None, vpc_id=None,
|
||||
vpc_name=None, subnet_id=None, subnet_name=None, private_ip_address=None,
|
||||
block_device_map=None, disable_api_termination=None,
|
||||
instance_initiated_shutdown_behavior=None, placement_group=None,
|
||||
client_token=None, security_group_ids=None, security_group_names=None,
|
||||
additional_info=None, tenancy=None, instance_profile_arn=None,
|
||||
instance_profile_name=None, ebs_optimized=None, network_interfaces=None,
|
||||
region=None, key=None, keyid=None, profile=None):
|
||||
#TODO: support multi-instance reservations
|
||||
'''
|
||||
Create and start an EC2 instance.
|
||||
|
||||
@ -581,18 +597,131 @@ def run(image_id, name=None, tags=None, instance_type='m1.small',
|
||||
|
||||
salt myminion boto_ec2.run ami-b80c2b87 name=myinstance
|
||||
|
||||
image_id
|
||||
(string) – The ID of the image to run.
|
||||
name
|
||||
(string) - The name of the instance.
|
||||
tags
|
||||
(dict of key: value pairs) - tags to apply to the instance.
|
||||
key_name
|
||||
(string) – The name of the key pair with which to launch instances.
|
||||
security_groups
|
||||
(list of strings) – The names of the EC2 classic security groups with
|
||||
which to associate instances
|
||||
user_data
|
||||
(string) – The Base64-encoded MIME user data to be made available to the
|
||||
instance(s) in this reservation.
|
||||
instance_type
|
||||
(string) – The type of instance to run. Note that some image types
|
||||
(e.g. hvm) only run on some instance types.
|
||||
placement
|
||||
(string) – The Availability Zone to launch the instance into.
|
||||
kernel_id
|
||||
(string) – The ID of the kernel with which to launch the instances.
|
||||
ramdisk_id
|
||||
(string) – The ID of the RAM disk with which to launch the instances.
|
||||
monitoring_enabled
|
||||
(bool) – Enable detailed CloudWatch monitoring on the instance.
|
||||
vpc_id
|
||||
(string) - ID of a VPC to bind the instance to. Exclusive with vpc_name.
|
||||
vpc_name
|
||||
(string) - Name of a VPC to bind the instance to. Exclusive with vpc_id.
|
||||
subnet_id
|
||||
(string) – The subnet ID within which to launch the instances for VPC.
|
||||
subnet_name
|
||||
(string) – The name of a subnet within which to launch the instances for VPC.
|
||||
private_ip_address
|
||||
(string) – If you’re using VPC, you can optionally use this parameter to
|
||||
assign the instance a specific available IP address from the subnet
|
||||
(e.g. 10.0.0.25).
|
||||
block_device_map
|
||||
(boto.ec2.blockdevicemapping.BlockDeviceMapping) – A BlockDeviceMapping
|
||||
data structure describing the EBS volumes associated with the Image.
|
||||
disable_api_termination
|
||||
(bool) – If True, the instances will be locked and will not be able to
|
||||
be terminated via the API.
|
||||
instance_initiated_shutdown_behavior
|
||||
(string) – Specifies whether the instance stops or terminates on
|
||||
instance-initiated shutdown. Valid values are: stop, terminate
|
||||
placement_group
|
||||
(string) – If specified, this is the name of the placement group in
|
||||
which the instance(s) will be launched.
|
||||
client_token
|
||||
(string) – Unique, case-sensitive identifier you provide to ensure
|
||||
idempotency of the request. Maximum 64 ASCII characters.
|
||||
security_group_ids
|
||||
(list of strings) – The ID(s) of the VPC security groups with which to
|
||||
associate instances.
|
||||
security_group_names
|
||||
(list of strings) – The name(s) of the VPC security groups with which to
|
||||
associate instances.
|
||||
additional_info
|
||||
(string) – Specifies additional information to make available to the
|
||||
instance(s).
|
||||
tenancy
|
||||
(string) – The tenancy of the instance you want to launch. An instance
|
||||
with a tenancy of ‘dedicated’ runs on single-tenant hardware and can
|
||||
only be launched into a VPC. Valid values are:”default” or “dedicated”.
|
||||
NOTE: To use dedicated tenancy you MUST specify a VPC subnet-ID as well.
|
||||
instance_profile_arn
|
||||
(string) – The Amazon resource name (ARN) of the IAM Instance Profile
|
||||
(IIP) to associate with the instances.
|
||||
instance_profile_name
|
||||
(string) – The name of the IAM Instance Profile (IIP) to associate with
|
||||
the instances.
|
||||
ebs_optimized
|
||||
(bool) – Whether the instance is optimized for EBS I/O. This
|
||||
optimization provides dedicated throughput to Amazon EBS and an
|
||||
optimized configuration stack to provide optimal EBS I/O performance.
|
||||
This optimization isn’t available with all instance types.
|
||||
network_interfaces
|
||||
(boto.ec2.networkinterface.NetworkInterfaceCollection) – A
|
||||
NetworkInterfaceCollection data structure containing the ENI
|
||||
specifications for the instance.
|
||||
|
||||
'''
|
||||
#TODO: support multi-instance reservations
|
||||
if all((subnet_id, subnet_name)):
|
||||
raise SaltInvocationError('Only one of subnet_name or subnet_id may be '
|
||||
'provided.')
|
||||
if subnet_name:
|
||||
r = __salt__['boto_vpc.get_resource_id']('subnet', subnet_name,
|
||||
region=region, key=key,
|
||||
keyid=keyid, profile=profile)
|
||||
if 'id' not in r:
|
||||
log.warning('Couldn\'t resolve subnet name {0}.').format(subnet_name)
|
||||
return False
|
||||
subnet_id = r['id']
|
||||
|
||||
if all((security_group_ids, security_group_names)):
|
||||
raise SaltInvocationError('Only one of security_group_ids or '
|
||||
'security_group_names may be provided.')
|
||||
if security_group_names:
|
||||
security_group_ids = []
|
||||
for sgn in security_group_names:
|
||||
r = __salt__['boto_secgroup.get_group_id'](sgn, vpc_name=vpc_name,
|
||||
region=region, key=key,
|
||||
keyid=keyid, profile=profile)
|
||||
if not r:
|
||||
log.warning('Couldn\'t resolve security group name ' + str(sgn))
|
||||
return False
|
||||
security_group_ids += [r]
|
||||
|
||||
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
|
||||
|
||||
reservation = conn.run_instances(image_id, instance_type=instance_type,
|
||||
key_name=key_name,
|
||||
security_groups=security_groups,
|
||||
user_data=user_data,
|
||||
placement=placement)
|
||||
reservation = conn.run_instances(image_id, key_name=key_name, security_groups=security_groups,
|
||||
user_data=user_data, instance_type=instance_type,
|
||||
placement=placement, kernel_id=kernel_id, ramdisk_id=ramdisk_id,
|
||||
monitoring_enabled=monitoring_enabled, subnet_id=subnet_id,
|
||||
private_ip_address=private_ip_address, block_device_map=block_device_map,
|
||||
disable_api_termination=disable_api_termination,
|
||||
instance_initiated_shutdown_behavior=instance_initiated_shutdown_behavior,
|
||||
placement_group=placement_group, client_token=client_token,
|
||||
security_group_ids=security_group_ids, additional_info=additional_info,
|
||||
tenancy=tenancy, instance_profile_arn=instance_profile_arn,
|
||||
instance_profile_name=instance_profile_name, ebs_optimized=ebs_optimized,
|
||||
network_interfaces=network_interfaces)
|
||||
if not reservation:
|
||||
log.warning('instances could not be reserved')
|
||||
log.warning('Instance could not be reserved')
|
||||
return False
|
||||
|
||||
instance = reservation.instances[0]
|
||||
@ -606,9 +735,9 @@ def run(image_id, name=None, tags=None, instance_type='m1.small',
|
||||
instance.add_tag('Name', name)
|
||||
if tags:
|
||||
instance.add_tags(tags)
|
||||
return True
|
||||
return {'instance_id': instance.id}
|
||||
else:
|
||||
log.warning('instance could not be started -- '
|
||||
log.warning('Instance could not be started -- '
|
||||
'status is "{0}"'.format(status))
|
||||
|
||||
|
||||
@ -741,7 +870,8 @@ def get_keys(keynames=None, filters=None, region=None, key=None,
|
||||
return False
|
||||
|
||||
|
||||
def get_attribute(attribute, instance_name=None, instance_id=None, region=None, key=None, keyid=None, profile=None):
|
||||
def get_attribute(attribute, instance_name=None, instance_id=None, region=None, key=None,
|
||||
keyid=None, profile=None):
|
||||
'''
|
||||
Get an EC2 instance attribute.
|
||||
|
||||
@ -772,7 +902,8 @@ def get_attribute(attribute, instance_name=None, instance_id=None, region=None,
|
||||
'instanceInitiatedShutdownBehavior', 'rootDeviceName', 'blockDeviceMapping', 'productCodes',
|
||||
'sourceDestCheck', 'groupSet', 'ebsOptimized', 'sriovNetSupport']
|
||||
if not any((instance_name, instance_id)):
|
||||
raise SaltInvocationError('At least one of the following must be specified: instance_name or instance_id.')
|
||||
raise SaltInvocationError('At least one of the following must be specified: '
|
||||
'instance_name or instance_id.')
|
||||
if instance_name and instance_id:
|
||||
raise SaltInvocationError('Both instance_name and instance_id can not be specified in the same command.')
|
||||
if attribute not in attribute_list:
|
||||
@ -780,8 +911,12 @@ def get_attribute(attribute, instance_name=None, instance_id=None, region=None,
|
||||
try:
|
||||
if instance_name:
|
||||
instances = find_instances(name=instance_name, region=region, key=key, keyid=keyid, profile=profile)
|
||||
if len(instances) != 1:
|
||||
raise CommandExecutionError('Found more than one EC2 instance matching the criteria.')
|
||||
if len(instances) > 1:
|
||||
log.error('Found more than one EC2 instance matching the criteria.')
|
||||
return False
|
||||
elif len(instances) < 1:
|
||||
log.error('Found no EC2 instance matching the criteria.')
|
||||
return False
|
||||
instance_id = instances[0]
|
||||
instance_attribute = conn.get_instance_attribute(instance_id, attribute)
|
||||
if not instance_attribute:
|
||||
|
@ -101,14 +101,17 @@ def exists(name=None, region=None, key=None, keyid=None, profile=None,
|
||||
'''
|
||||
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
|
||||
|
||||
group = _get_group(conn, name, vpc_id, vpc_name, group_id, region, key, keyid, profile)
|
||||
group = _get_group(conn, name=name, vpc_id=vpc_id, vpc_name=vpc_name,
|
||||
group_id=group_id, region=region, key=key, keyid=keyid,
|
||||
profile=profile)
|
||||
if group:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def _check_vpc(vpc_id, vpc_name, region, key, keyid, profile):
|
||||
def _check_vpc(vpc_id=None, vpc_name=None, region=None, key=None, keyid=None,
|
||||
profile=None):
|
||||
data = __salt__['boto_vpc.get_id'](name=vpc_name, region=region,
|
||||
key=key, keyid=keyid, profile=profile)
|
||||
try:
|
||||
@ -154,17 +157,14 @@ def _get_group(conn=None, name=None, vpc_id=None, vpc_name=None, group_id=None,
|
||||
if vpc_name and vpc_id:
|
||||
raise SaltInvocationError('The params \'vpc_id\' and \'vpc_name\' '
|
||||
'are mutually exclusive.')
|
||||
|
||||
if not vpc_id and vpc_name:
|
||||
if vpc_name:
|
||||
try:
|
||||
vpc_id = _check_vpc(vpc_id, vpc_name, region, key, keyid, profile)
|
||||
vpc_id = _check_vpc(vpc_id=vpc_id, vpc_name=vpc_name, region=region,
|
||||
key=key, keyid=keyid, profile=profile)
|
||||
except boto.exception.BotoServerError as e:
|
||||
log.debug(e)
|
||||
return None
|
||||
|
||||
if name:
|
||||
if vpc_name:
|
||||
vpc_id = __salt__['boto_vpc.check_vpc'](vpc_id, vpc_name, region, key, keyid, profile)
|
||||
if vpc_id is None:
|
||||
log.debug('getting group for {0}'.format(name))
|
||||
group_filter = {'group-name': name}
|
||||
@ -249,15 +249,15 @@ def get_group_id(name, vpc_id=None, vpc_name=None, region=None, key=None,
|
||||
'''
|
||||
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
|
||||
|
||||
group = _get_group(conn, name, vpc_id, vpc_name, region, key, keyid, profile)
|
||||
|
||||
group = _get_group(conn, name, vpc_id=vpc_id, vpc_name=vpc_name,
|
||||
region=region, key=key, keyid=keyid, profile=profile)
|
||||
if group:
|
||||
return group.id
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def convert_to_group_ids(groups, vpc_id=None, vpc_name=None, region=None, key=None,
|
||||
def convert_to_group_ids(groups, vpc_id, vpc_name=None, region=None, key=None,
|
||||
keyid=None, profile=None):
|
||||
'''
|
||||
Given a list of security groups and a vpc_id, convert_to_group_ids will
|
||||
@ -277,7 +277,9 @@ def convert_to_group_ids(groups, vpc_id=None, vpc_name=None, region=None, key=No
|
||||
else:
|
||||
log.debug('calling boto_secgroup.get_group_id for'
|
||||
' group name {0}'.format(group))
|
||||
group_id = get_group_id(group, vpc_id, vpc_name, region, key, keyid, profile)
|
||||
group_id = get_group_id(name=group, vpc_id=vpc_id,
|
||||
vpc_name=vpc_name, region=region,
|
||||
key=key, keyid=keyid, profile=profile)
|
||||
log.debug('group name {0} has group id {1}'.format(
|
||||
group, group_id)
|
||||
)
|
||||
@ -297,7 +299,9 @@ def get_config(name=None, group_id=None, region=None, key=None, keyid=None,
|
||||
'''
|
||||
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
|
||||
|
||||
sg = _get_group(conn, name, vpc_id, vpc_name, group_id, region, key, keyid, profile)
|
||||
sg = _get_group(conn, name=name, vpc_id=vpc_id, vpc_name=vpc_name,
|
||||
group_id=group_id, region=region, key=key, keyid=keyid,
|
||||
profile=profile)
|
||||
if sg:
|
||||
ret = odict.OrderedDict()
|
||||
ret['name'] = sg.name
|
||||
@ -329,7 +333,8 @@ def create(name, description, vpc_id=None, vpc_name=None, region=None, key=None,
|
||||
|
||||
if not vpc_id and vpc_name:
|
||||
try:
|
||||
vpc_id = _check_vpc(vpc_id, vpc_name, region, key, keyid, profile)
|
||||
vpc_id = _check_vpc(vpc_id=vpc_id, vpc_name=vpc_name, region=region,
|
||||
key=key, keyid=keyid, profile=profile)
|
||||
except boto.exception.BotoServerError as e:
|
||||
log.debug(e)
|
||||
return False
|
||||
@ -355,7 +360,9 @@ def delete(name=None, group_id=None, region=None, key=None, keyid=None,
|
||||
'''
|
||||
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
|
||||
|
||||
group = _get_group(conn, name, vpc_id, vpc_name, group_id, region, key, keyid, profile)
|
||||
group = _get_group(conn, name=name, vpc_id=vpc_id, vpc_name=vpc_name,
|
||||
group_id=group_id, region=region, key=key, keyid=keyid,
|
||||
profile=profile)
|
||||
if group:
|
||||
deleted = conn.delete_security_group(group_id=group.id)
|
||||
if deleted:
|
||||
@ -385,7 +392,9 @@ def authorize(name=None, source_group_name=None,
|
||||
'''
|
||||
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
|
||||
|
||||
group = _get_group(conn, name, vpc_id, vpc_name, group_id, region, key, keyid, profile)
|
||||
group = _get_group(conn, name=name, vpc_id=vpc_id, vpc_name=vpc_name,
|
||||
group_id=group_id, region=region, key=key, keyid=keyid,
|
||||
profile=profile)
|
||||
if group:
|
||||
try:
|
||||
added = None
|
||||
@ -435,7 +444,9 @@ def revoke(name=None, source_group_name=None,
|
||||
'''
|
||||
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
|
||||
|
||||
group = _get_group(conn, name, vpc_id, vpc_name, group_id, region, key, keyid, profile)
|
||||
group = _get_group(conn, name=name, vpc_id=vpc_id, vpc_name=vpc_name,
|
||||
group_id=group_id, region=region, key=key, keyid=keyid,
|
||||
profile=profile)
|
||||
if group:
|
||||
try:
|
||||
revoked = None
|
||||
@ -474,12 +485,10 @@ def revoke(name=None, source_group_name=None,
|
||||
|
||||
def _find_vpcs(vpc_id=None, vpc_name=None, cidr=None, tags=None,
|
||||
region=None, key=None, keyid=None, profile=None):
|
||||
|
||||
'''
|
||||
Given VPC properties, find and return matching VPC ids.
|
||||
Borrowed from boto_vpc; these could be refactored into a common library
|
||||
'''
|
||||
|
||||
if all((vpc_id, vpc_name)):
|
||||
raise SaltInvocationError('Only one of vpc_name or vpc_id may be '
|
||||
'provided.')
|
||||
@ -562,8 +571,9 @@ def set_tags(tags,
|
||||
salt myminion boto_secgroup.set_tags "{'TAG1': 'Value1', 'TAG2': 'Value2'}" security_group_name vpc_id=vpc-13435 profile=my_aws_profile
|
||||
'''
|
||||
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
|
||||
secgrp = _get_group(conn, name=name, vpc_id=vpc_id, group_id=group_id, region=region, vpc_name=vpc_name,
|
||||
key=key, keyid=keyid, profile=profile)
|
||||
secgrp = _get_group(conn, name=name, vpc_id=vpc_id, vpc_name=vpc_name,
|
||||
group_id=group_id, region=region, key=key, keyid=keyid,
|
||||
profile=profile)
|
||||
|
||||
if secgrp:
|
||||
if isinstance(tags, dict):
|
||||
@ -625,8 +635,9 @@ def delete_tags(tags,
|
||||
salt myminion boto_secgroup.delete_tags ['TAG_TO_DELETE1','TAG_TO_DELETE2'] security_group_name vpc_id=vpc-13435 profile=my_aws_profile
|
||||
'''
|
||||
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
|
||||
secgrp = _get_group(conn, name=name, vpc_id=vpc_id, group_id=group_id, region=region, vpc_name=vpc_name,
|
||||
key=key, keyid=keyid, profile=profile)
|
||||
secgrp = _get_group(conn, name=name, vpc_id=vpc_id, vpc_name=vpc_name,
|
||||
group_id=group_id, region=region, key=key, keyid=keyid,
|
||||
profile=profile)
|
||||
if secgrp:
|
||||
if isinstance(tags, list):
|
||||
tags_to_remove = {}
|
||||
|
@ -131,8 +131,8 @@ def __init__(opts):
|
||||
__utils__['boto.assign_funcs'](__name__, 'vpc')
|
||||
|
||||
|
||||
def check_vpc(vpc_id=None, vpc_name=None, region=None, key=None, keyid=None,
|
||||
profile=None):
|
||||
def check_vpc(vpc_id=None, vpc_name=None, region=None, key=None,
|
||||
keyid=None, profile=None):
|
||||
'''
|
||||
Check whether a VPC with the given name or id exists.
|
||||
Returns the vpc_id or None. Raises SaltInvocationError if
|
||||
@ -783,10 +783,10 @@ def create_subnet(vpc_id=None, cidr_block=None, vpc_name=None,
|
||||
except BotoServerError as e:
|
||||
return {'created': False, 'error': salt.utils.boto.get_error(e)}
|
||||
|
||||
return _create_resource('subnet', name=subnet_name, tags=tags,
|
||||
vpc_id=vpc_id, cidr_block=cidr_block,
|
||||
region=region, key=key, keyid=keyid,
|
||||
profile=profile)
|
||||
return _create_resource('subnet', name=subnet_name, tags=tags, vpc_id=vpc_id,
|
||||
availability_zone=availability_zone,
|
||||
cidr_block=cidr_block, region=region, key=key,
|
||||
keyid=keyid, profile=profile)
|
||||
|
||||
|
||||
def delete_subnet(subnet_id=None, subnet_name=None, region=None, key=None,
|
||||
@ -1227,6 +1227,45 @@ def create_dhcp_options(domain_name=None, domain_name_servers=None, ntp_servers=
|
||||
return {'created': False, 'error': salt.utils.boto.get_error(e)}
|
||||
|
||||
|
||||
def get_dhcp_options(dhcp_options_name=None, dhcp_options_id=None,
|
||||
region=None, key=None, keyid=None, profile=None):
|
||||
'''
|
||||
Return a dict with the current values of the requested DHCP options set
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt myminion boto_vpc.get_dhcp_options 'myfunnydhcpoptionsname'
|
||||
|
||||
.. versionadded:: Boron
|
||||
'''
|
||||
if not any((dhcp_options_name, dhcp_options_id)):
|
||||
raise SaltInvocationError('At least one of the following must be specified: '
|
||||
'dhcp_options_name, dhcp_options_id.')
|
||||
|
||||
if not dhcp_options_id and dhcp_options_name:
|
||||
dhcp_options_id = _get_resource_id('dhcp_options', dhcp_options_name,
|
||||
region=region, key=key,
|
||||
keyid=keyid, profile=profile)
|
||||
if not dhcp_options_id:
|
||||
return {'dhcp_options': {}}
|
||||
|
||||
try:
|
||||
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
|
||||
r = conn.get_all_dhcp_options(dhcp_options_ids=[dhcp_options_id])
|
||||
except BotoServerError as e:
|
||||
return {'error': salt.utils.boto.get_error(e)}
|
||||
|
||||
if not r:
|
||||
return {'dhcp_options': None}
|
||||
|
||||
keys = ('domain_name', 'domain_name_servers', 'ntp_servers',
|
||||
'netbios_name_servers', 'netbios_node_type')
|
||||
|
||||
return {'dhcp_options': dict((k, r[0].options.get(k)) for k in keys)}
|
||||
|
||||
|
||||
def delete_dhcp_options(dhcp_options_id=None, dhcp_options_name=None,
|
||||
region=None, key=None, keyid=None, profile=None):
|
||||
'''
|
||||
|
@ -58,7 +58,7 @@ from time import time, sleep
|
||||
|
||||
# Import salt libs
|
||||
import salt.utils.dictupdate as dictupdate
|
||||
from salt.exceptions import SaltInvocationError
|
||||
from salt.exceptions import SaltInvocationError, CommandExecutionError
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@ -452,3 +452,318 @@ def snapshot_created(name, ami_name, instance_name, wait_until_available=True, w
|
||||
sleep(5)
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
def instance_present(name, instance_name=None, instance_id=None, image_id=None,
|
||||
image_name=None, tags=None, key_name=None,
|
||||
security_groups=None, user_data=None, instance_type=None,
|
||||
placement=None, kernel_id=None, ramdisk_id=None,
|
||||
vpc_id=None, vpc_name=None, monitoring_enabled=None,
|
||||
subnet_id=None, subnet_name=None, private_ip_address=None,
|
||||
block_device_map=None, disable_api_termination=None,
|
||||
instance_initiated_shutdown_behavior=None,
|
||||
placement_group=None, client_token=None,
|
||||
security_group_ids=None, security_group_names=None,
|
||||
additional_info=None, tenancy=None,
|
||||
instance_profile_arn=None, instance_profile_name=None,
|
||||
ebs_optimized=None, network_interfaces=None,
|
||||
attributes=None, target_state=None, region=None, key=None,
|
||||
keyid=None, profile=None):
|
||||
### TODO - implement 'target_state={running, stopped}'
|
||||
### TODO - implement image_name->image_id lookups
|
||||
'''
|
||||
Ensure an EC2 instance is running with the given attributes and state.
|
||||
|
||||
name
|
||||
(string) - The name of the state definition. Recommended that this
|
||||
match the instance_name attribute (generally the FQDN of the instance).
|
||||
instance_name
|
||||
(string) - The name of the instance, generally its FQDN. Exclusive with
|
||||
'instance_id'.
|
||||
instance_id
|
||||
(string) - The ID of the instance (if known). Exclusive with
|
||||
'instance_name'.
|
||||
image_id
|
||||
(string) – The ID of the AMI image to run.
|
||||
image_name
|
||||
(string) – The name of the AMI image to run. NOT IMPLEMENTED.
|
||||
tags
|
||||
(dict) - Tags to apply to the instance.
|
||||
key_name
|
||||
(string) – The name of the key pair with which to launch instances.
|
||||
security_groups
|
||||
(list of strings) – The names of the EC2 classic security groups with
|
||||
which to associate instances
|
||||
user_data
|
||||
(string) – The Base64-encoded MIME user data to be made available to the
|
||||
instance(s) in this reservation.
|
||||
instance_type
|
||||
(string) – The EC2 instance size/type. Note that only certain types are
|
||||
compatible with HVM based AMIs.
|
||||
placement
|
||||
(string) – The Availability Zone to launch the instance into.
|
||||
kernel_id
|
||||
(string) – The ID of the kernel with which to launch the instances.
|
||||
ramdisk_id
|
||||
(string) – The ID of the RAM disk with which to launch the instances.
|
||||
vpc_id
|
||||
(string) - The ID of a VPC to attach the instance to.
|
||||
vpc_name
|
||||
(string) - The name of a VPC to attach the instance to.
|
||||
monitoring_enabled
|
||||
(bool) – Enable detailed CloudWatch monitoring on the instance.
|
||||
subnet_id
|
||||
(string) – The ID of the subnet within which to launch the instances for
|
||||
VPC.
|
||||
subnet_name
|
||||
(string) – The name of the subnet within which to launch the instances
|
||||
for VPC.
|
||||
private_ip_address
|
||||
(string) – If you’re using VPC, you can optionally use this parameter to
|
||||
assign the instance a specific available IP address from the subnet
|
||||
(e.g., 10.0.0.25).
|
||||
block_device_map
|
||||
(boto.ec2.blockdevicemapping.BlockDeviceMapping) – A BlockDeviceMapping
|
||||
data structure describing the EBS volumes associated with the Image.
|
||||
disable_api_termination
|
||||
(bool) – If True, the instances will be locked and will not be able to
|
||||
be terminated via the API.
|
||||
instance_initiated_shutdown_behavior
|
||||
(string) – Specifies whether the instance stops or terminates on
|
||||
instance-initiated shutdown. Valid values are:
|
||||
'stop'
|
||||
'terminate'
|
||||
placement_group
|
||||
(string) – If specified, this is the name of the placement group in
|
||||
which the instance(s) will be launched.
|
||||
client_token
|
||||
(string) – Unique, case-sensitive identifier you provide to ensure
|
||||
idempotency of the request. Maximum 64 ASCII characters.
|
||||
security_group_ids
|
||||
(list of strings) – The IDs of the VPC security groups with which to
|
||||
associate instances.
|
||||
security_group_names
|
||||
(list of strings) – The names of the VPC security groups with which to
|
||||
associate instances.
|
||||
additional_info
|
||||
(string) – Specifies additional information to make available to the
|
||||
instance(s).
|
||||
tenancy
|
||||
(string) – The tenancy of the instance you want to launch. An instance
|
||||
with a tenancy of ‘dedicated’ runs on single-tenant hardware and can
|
||||
only be launched into a VPC. Valid values are:”default” or “dedicated”.
|
||||
NOTE: To use dedicated tenancy you MUST specify a VPC subnet-ID as well.
|
||||
instance_profile_arn
|
||||
(string) – The Amazon resource name (ARN) of the IAM Instance Profile
|
||||
(IIP) to associate with the instances.
|
||||
instance_profile_name
|
||||
(string) – The name of the IAM Instance Profile (IIP) to associate with
|
||||
the instances.
|
||||
ebs_optimized
|
||||
(bool) – Whether the instance is optimized for EBS I/O. This
|
||||
optimization provides dedicated throughput to Amazon EBS and a tuned
|
||||
configuration stack to provide optimal EBS I/O performance. This
|
||||
optimization isn’t available with all instance types.
|
||||
network_interfaces
|
||||
(boto.ec2.networkinterface.NetworkInterfaceCollection) – A
|
||||
NetworkInterfaceCollection data structure containing the ENI
|
||||
specifications for the instance.
|
||||
attributes
|
||||
(dict) - Instance attributes and value to be applied to the instance.
|
||||
Available options are:
|
||||
instanceType - A valid instance type (m1.small)
|
||||
kernel - Kernel ID (None)
|
||||
ramdisk - Ramdisk ID (None)
|
||||
userData - Base64 encoded String (None)
|
||||
disableApiTermination - Boolean (true)
|
||||
instanceInitiatedShutdownBehavior - stop|terminate
|
||||
blockDeviceMapping - List of strings - ie: [‘/dev/sda=false’]
|
||||
sourceDestCheck - Boolean (true)
|
||||
groupSet - Set of Security Groups or IDs
|
||||
ebsOptimized - Boolean (false)
|
||||
sriovNetSupport - String - ie: ‘simple’
|
||||
target_state
|
||||
(string) - The desired target state of the instance. Available options
|
||||
are:
|
||||
running
|
||||
stopped
|
||||
region
|
||||
(string) - Region to connect to.
|
||||
key
|
||||
(string) - Secret key to be used.
|
||||
keyid
|
||||
(string) - Access key to be used.
|
||||
profile
|
||||
(variable) - A dict with region, key and keyid, or a pillar key (string)
|
||||
that contains a dict with region, key and keyid.
|
||||
|
||||
.. versionadded:: Boron
|
||||
'''
|
||||
ret = {'name': name,
|
||||
'result': True,
|
||||
'comment': '',
|
||||
'changes': {}
|
||||
}
|
||||
_create = False
|
||||
running_states = ('pending', 'rebooting', 'running', 'stopping', 'stopped')
|
||||
changed_attrs = {}
|
||||
|
||||
if not instance_id:
|
||||
try:
|
||||
instance_id = __salt__['boto_ec2.get_id'](name=instance_name if instance_name else name,
|
||||
tags=tags, region=region, key=key, keyid=keyid,
|
||||
profile=profile, in_states=running_states)
|
||||
except CommandExecutionError as e:
|
||||
ret['result'] = None
|
||||
ret['comment'] = 'Couldn\'t determine current status of instance {0}.'.format(instance_name)
|
||||
return ret
|
||||
|
||||
exists = __salt__['boto_ec2.exists'](instance_id=instance_id, region=region,
|
||||
key=key, keyid=keyid, profile=profile)
|
||||
if not exists:
|
||||
_create = True
|
||||
else:
|
||||
instances = __salt__['boto_ec2.find_instances'](instance_id=instance_id, region=region,
|
||||
key=key, keyid=keyid, profile=profile,
|
||||
return_objs=True, in_states=running_states)
|
||||
if not len(instances):
|
||||
_create = True
|
||||
|
||||
if _create:
|
||||
if __opts__['test']:
|
||||
ret['comment'] = 'The instance {0} is set to be created.'.format(name)
|
||||
ret['result'] = None
|
||||
return ret
|
||||
r = __salt__['boto_ec2.run'](image_id, instance_name if instance_name else name,
|
||||
tags=tags, key_name=key_name,
|
||||
security_groups=security_groups, user_data=user_data,
|
||||
instance_type=instance_type, placement=placement,
|
||||
kernel_id=kernel_id, ramdisk_id=ramdisk_id, vpc_id=vpc_id,
|
||||
vpc_name=vpc_name, monitoring_enabled=monitoring_enabled,
|
||||
subnet_id=subnet_id, subnet_name=subnet_name,
|
||||
private_ip_address=private_ip_address,
|
||||
block_device_map=block_device_map,
|
||||
disable_api_termination=disable_api_termination,
|
||||
instance_initiated_shutdown_behavior=instance_initiated_shutdown_behavior,
|
||||
placement_group=placement_group, client_token=client_token,
|
||||
security_group_ids=security_group_ids,
|
||||
security_group_names=security_group_names,
|
||||
additional_info=additional_info, tenancy=tenancy,
|
||||
instance_profile_arn=instance_profile_arn,
|
||||
instance_profile_name=instance_profile_name,
|
||||
ebs_optimized=ebs_optimized, network_interfaces=network_interfaces,
|
||||
region=region, key=key, keyid=keyid, profile=profile)
|
||||
if not r or 'instance_id' not in r:
|
||||
ret['result'] = False
|
||||
ret['comment'] = 'Failed to create instance {0}.'.format(instance_name if instance_name else name)
|
||||
return ret
|
||||
|
||||
instance_id = r['instance_id']
|
||||
ret['changes'] = {'old': {}, 'new': {}}
|
||||
ret['changes']['old']['instance_id'] = None
|
||||
ret['changes']['new']['instance_id'] = instance_id
|
||||
|
||||
for k, v in attributes.iteritems():
|
||||
curr = __salt__['boto_ec2.get_attribute'](k, instance_id=instance_id, region=region, key=key,
|
||||
keyid=keyid, profile=profile)
|
||||
if isinstance(curr, dict):
|
||||
curr = {}
|
||||
if curr and curr.get(k) == v:
|
||||
continue
|
||||
else:
|
||||
if __opts__['test']:
|
||||
changed_attrs[k] = 'The instance attribute {0} is set to be changed from \'{1}\' to \'{2}\'.'.format(
|
||||
k, curr.get(k), v)
|
||||
continue
|
||||
try:
|
||||
r = __salt__['boto_ec2.set_attribute'](attribute=k, attribute_value=v,
|
||||
instance_id=instance_id, region=region,
|
||||
key=key, keyid=keyid, profile=profile)
|
||||
except SaltInvocationError as e:
|
||||
ret['result'] = False
|
||||
ret['comment'] = 'Failed to set attribute {0} to {1} on instance {2}.'.format(k, v, instance_name)
|
||||
return ret
|
||||
ret['changes'] = ret['changes'] if ret['changes'] else {'old': {}, 'new': {}}
|
||||
ret['changes']['old'][k] = curr.get(k)
|
||||
ret['changes']['new'][k] = v
|
||||
|
||||
if __opts__['test']:
|
||||
if changed_attrs:
|
||||
ret['changes']['new'] = changed_attrs
|
||||
ret['result'] = None
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
def instance_absent(name, instance_name=None, instance_id=None,
|
||||
region=None, key=None, keyid=None, profile=None):
|
||||
'''
|
||||
Ensure an EC2 instance does not exist (is stopped and removed).
|
||||
|
||||
name
|
||||
(string) - The name of the state definition.
|
||||
instance_name
|
||||
(string) - The name of the instance.
|
||||
instance_id
|
||||
(string) - The ID of the instance.
|
||||
region
|
||||
(string) - Region to connect to.
|
||||
key
|
||||
(string) - Secret key to be used.
|
||||
keyid
|
||||
(string) - Access key to be used.
|
||||
profile
|
||||
(variable) - A dict with region, key and keyid, or a pillar key (string)
|
||||
that contains a dict with region, key and keyid.
|
||||
|
||||
.. versionadded:: Boron
|
||||
'''
|
||||
### TODO - Implement 'force' option?? Would automagically turn off
|
||||
### 'disableApiTermination', as needed before trying to delete.
|
||||
ret = {'name': name,
|
||||
'result': True,
|
||||
'comment': '',
|
||||
'changes': {}
|
||||
}
|
||||
running_states = ('pending', 'rebooting', 'running', 'stopping', 'stopped')
|
||||
|
||||
if not instance_id:
|
||||
try:
|
||||
instance_id = __salt__['boto_ec2.get_id'](name=instance_name if instance_name else name,
|
||||
region=region, key=key, keyid=keyid,
|
||||
profile=profile, in_states=running_states)
|
||||
except CommandExecutionError as e:
|
||||
ret['result'] = None
|
||||
ret['comment'] = 'Couldn\'t determine current status of instance {0}.'.format(instance_name)
|
||||
return ret
|
||||
|
||||
exists = __salt__['boto_ec2.exists'](instance_id=instance_id, region=region,
|
||||
key=key, keyid=keyid, profile=profile)
|
||||
if not exists:
|
||||
ret['result'] = True
|
||||
ret['comment'] = 'Instance {0} is already gone.'.format(instance_id)
|
||||
return ret
|
||||
|
||||
### Honor 'disableApiTermination' - if you want to override it, first use set_attribute() to turn it off
|
||||
no_can_do = __salt__['boto_ec2.get_attribute']('disableApiTermination', instance_id=instance_id,
|
||||
region=region, key=key, keyid=keyid, profile=profile)
|
||||
if no_can_do.get('disableApiTermination') is True:
|
||||
ret['result'] = False
|
||||
ret['comment'] = 'Termination of instance {0} via the API is disabled.'.format(instance_id)
|
||||
return ret
|
||||
|
||||
if __opts__['test']:
|
||||
ret['comment'] = 'The instance {0} is set to be deleted.'.format(name)
|
||||
ret['result'] = None
|
||||
return ret
|
||||
|
||||
r = __salt__['boto_ec2.terminate'](instance_id=instance_id, name=instance_name, region=region,
|
||||
key=key, keyid=keyid, profile=profile)
|
||||
if not r:
|
||||
ret['result'] = False
|
||||
ret['comment'] = 'Failed to terminate instance {0}.'.format(instance_id)
|
||||
return ret
|
||||
|
||||
ret['changes']['old'] = {'instance_id': instance_id}
|
||||
ret['changes']['new'] = None
|
||||
return ret
|
||||
|
@ -128,15 +128,7 @@ def present(
|
||||
The ID of the VPC to create the security group in, if any. Exclusive with vpc_name.
|
||||
|
||||
vpc_name
|
||||
The name of the VPC wherein to create the security group, if any. Exclusive with vpc_id.
|
||||
|
||||
vpc_name
|
||||
The name of the VPC to create the security group in, if any.
|
||||
|
||||
.. versionadded:: Boron
|
||||
|
||||
tags
|
||||
List of key:value pairs of tags to set on the security group
|
||||
The name of the VPC to create the security group in, if any. Exlusive with vpc_id.
|
||||
|
||||
.. versionadded:: Boron
|
||||
|
||||
@ -159,11 +151,15 @@ def present(
|
||||
A dict with region, key and keyid, or a pillar key (string)
|
||||
that contains a dict with region, key and keyid.
|
||||
|
||||
tags
|
||||
List of key:value pairs of tags to set on the security group
|
||||
|
||||
.. versionadded:: Boron
|
||||
'''
|
||||
ret = {'name': name, 'result': True, 'comment': '', 'changes': {}}
|
||||
_ret = _security_group_present(name, description, vpc_id, vpc_name, region, key,
|
||||
keyid, profile)
|
||||
_ret = _security_group_present(name, description, vpc_id=vpc_id,
|
||||
vpc_name=vpc_name, region=region,
|
||||
key=key, keyid=keyid, profile=profile)
|
||||
ret['changes'] = _ret['changes']
|
||||
ret['comment'] = ' '.join([ret['comment'], _ret['comment']])
|
||||
if not _ret['result']:
|
||||
@ -174,20 +170,14 @@ def present(
|
||||
rules = []
|
||||
if not rules_egress:
|
||||
rules_egress = []
|
||||
_ret = _rules_present(name, rules, rules_egress, vpc_id, vpc_name, region, key,
|
||||
keyid, profile)
|
||||
_ret = _rules_present(name, rules, rules_egress, vpc_id=vpc_id, vpc_name=vpc_name,
|
||||
region=region, key=key, keyid=keyid, profile=profile)
|
||||
ret['changes'] = dictupdate.update(ret['changes'], _ret['changes'])
|
||||
ret['comment'] = ' '.join([ret['comment'], _ret['comment']])
|
||||
if not _ret['result']:
|
||||
ret['result'] = _ret['result']
|
||||
_ret = _tags_present(name=name,
|
||||
tags=tags,
|
||||
vpc_id=vpc_id,
|
||||
region=region,
|
||||
key=key,
|
||||
keyid=keyid,
|
||||
profile=profile,
|
||||
vpc_name=vpc_name)
|
||||
_ret = _tags_present(name=name, tags=tags, vpc_id=vpc_id, vpc_name=vpc_name,
|
||||
region=region, key=key, keyid=keyid, profile=profile)
|
||||
ret['changes'] = dictupdate.update(ret['changes'], _ret['changes'])
|
||||
ret['comment'] = ' '.join([ret['comment'], _ret['comment']])
|
||||
if not _ret['result']:
|
||||
@ -195,15 +185,8 @@ def present(
|
||||
return ret
|
||||
|
||||
|
||||
def _security_group_present(
|
||||
name,
|
||||
description,
|
||||
vpc_id=None,
|
||||
vpc_name=None,
|
||||
region=None,
|
||||
key=None,
|
||||
keyid=None,
|
||||
profile=None):
|
||||
def _security_group_present(name, description, vpc_id=None, vpc_name=None,
|
||||
region=None, key=None, keyid=None, profile=None):
|
||||
'''
|
||||
given a group name or a group name and vpc id (or vpc name):
|
||||
1. determine if the group exists
|
||||
@ -212,17 +195,17 @@ def _security_group_present(
|
||||
'''
|
||||
ret = {'result': True, 'comment': '', 'changes': {}}
|
||||
exists = __salt__['boto_secgroup.exists'](name, region, key, keyid,
|
||||
profile, vpc_id,
|
||||
vpc_name=vpc_name)
|
||||
profile, vpc_id, vpc_name)
|
||||
if not exists:
|
||||
if __opts__['test']:
|
||||
msg = 'Security group {0} is set to be created.'.format(name)
|
||||
ret['comment'] = msg
|
||||
ret['result'] = None
|
||||
return ret
|
||||
created = __salt__['boto_secgroup.create'](name, description, vpc_id,
|
||||
vpc_name, region, key, keyid,
|
||||
profile)
|
||||
created = __salt__['boto_secgroup.create'](name=name, description=description,
|
||||
vpc_id=vpc_id, vpc_name=vpc_name,
|
||||
region=region, key=key, keyid=keyid,
|
||||
profile=profile)
|
||||
if created:
|
||||
ret['changes']['old'] = {'secgroup': None}
|
||||
sg = __salt__['boto_secgroup.get_config'](name, None, region, key,
|
||||
@ -372,16 +355,8 @@ def _get_rule_changes(rules, _rules):
|
||||
return (to_delete, to_create)
|
||||
|
||||
|
||||
def _rules_present(
|
||||
name,
|
||||
rules,
|
||||
rules_egress,
|
||||
vpc_id=None,
|
||||
vpc_name=None,
|
||||
region=None,
|
||||
key=None,
|
||||
keyid=None,
|
||||
profile=None):
|
||||
def _rules_present(name, rules, rules_egress, vpc_id=None, vpc_name=None,
|
||||
region=None, key=None, keyid=None, profile=None):
|
||||
'''
|
||||
given a group name or group name and vpc_id (or vpc name):
|
||||
1. get lists of desired rule changes (using _get_rule_changes)
|
||||
@ -405,7 +380,8 @@ def _rules_present(
|
||||
_source_group_name = rule.get('source_group_name', None)
|
||||
if _source_group_name:
|
||||
_group_id = __salt__['boto_secgroup.get_group_id'](
|
||||
_source_group_name, vpc_id, vpc_name, region, key, keyid, profile
|
||||
name=_source_group_name, vpc_id=vpc_id, vpc_name=vpc_name,
|
||||
region=region, key=key, keyid=keyid, profile=profile
|
||||
)
|
||||
if not _group_id:
|
||||
msg = ('source_group_name {0} does not map to a valid'
|
||||
@ -511,10 +487,7 @@ def absent(
|
||||
The ID of the VPC to remove the security group from, if any. Exclusive with vpc_name.
|
||||
|
||||
vpc_name
|
||||
The name of the VPC wherefrom to delete the security group, if any. Exclusive with vpc_id.
|
||||
|
||||
vpc_name
|
||||
The name of the VPC to create the security group in, if any.
|
||||
The name of the VPC to remove the security group from, if any. Exclusive with vpc_name.
|
||||
|
||||
.. versionadded:: Boron
|
||||
|
||||
@ -558,27 +531,15 @@ def absent(
|
||||
return ret
|
||||
|
||||
|
||||
def _tags_present(name,
|
||||
tags,
|
||||
vpc_id=None,
|
||||
region=None,
|
||||
key=None,
|
||||
keyid=None,
|
||||
profile=None,
|
||||
vpc_name=None):
|
||||
def _tags_present(name, tags, vpc_id=None, vpc_name=None, region=None,
|
||||
key=None, keyid=None, profile=None):
|
||||
'''
|
||||
helper function to validate tags are correct
|
||||
'''
|
||||
ret = {'result': True, 'comment': '', 'changes': {}}
|
||||
if tags:
|
||||
sg = __salt__['boto_secgroup.get_config'](name=name,
|
||||
group_id=None,
|
||||
region=region,
|
||||
key=key,
|
||||
keyid=keyid,
|
||||
profile=profile,
|
||||
vpc_id=vpc_id,
|
||||
vpc_name=vpc_name)
|
||||
sg = __salt__['boto_secgroup.get_config'](name, None, region, key,
|
||||
keyid, profile, vpc_id, vpc_name)
|
||||
#existing_tags = sg.get('tags')
|
||||
tags_to_add = tags
|
||||
tags_to_update = {}
|
||||
|
@ -230,6 +230,199 @@ def absent(name, tags=None, region=None, key=None, keyid=None, profile=None):
|
||||
return ret
|
||||
|
||||
|
||||
def dhcp_options_present(name, dhcp_options_id=None, vpc_name=None, vpc_id=None,
|
||||
domain_name=None, domain_name_servers=None, ntp_servers=None,
|
||||
netbios_name_servers=None, netbios_node_type=None,
|
||||
tags=None, region=None, key=None, keyid=None, profile=None):
|
||||
'''
|
||||
Ensure a set of DHCP options with the given settings exist.
|
||||
Note that the current implementation only SETS values during option set
|
||||
creation. It is unable to update option sets in place, and thus merely
|
||||
verifies the set exists via the given name and/or dhcp_options_id param.
|
||||
|
||||
name
|
||||
(string)
|
||||
Name of the DHCP options.
|
||||
|
||||
vpc_name
|
||||
(string)
|
||||
Name of a VPC to which the options should be associated. Either
|
||||
vpc_name or vpc_id must be provided.
|
||||
|
||||
vpc_id
|
||||
(string)
|
||||
Id of a VPC to which the options should be associated. Either
|
||||
vpc_name or vpc_id must be provided.
|
||||
|
||||
domain_name
|
||||
(string)
|
||||
Domain name to be assiciated with this option set.
|
||||
|
||||
domain_name_servers
|
||||
(list of strings)
|
||||
The IP address(es) of up to four domain name servers.
|
||||
|
||||
ntp_servers
|
||||
(list of strings)
|
||||
The IP address(es) of up to four desired NTP servers.
|
||||
|
||||
netbios_name_servers
|
||||
(list of strings)
|
||||
The IP address(es) of up to four NetBIOS name servers.
|
||||
|
||||
netbios_node_type
|
||||
(string)
|
||||
The NetBIOS node type (1, 2, 4, or 8). For more information about
|
||||
the allowed values, see RFC 2132. The recommended is 2 at this
|
||||
time (broadcast and multicast are currently not supported).
|
||||
|
||||
tags
|
||||
(dict of key:value pairs)
|
||||
A set of tags to be added.
|
||||
|
||||
region
|
||||
(string)
|
||||
Region to connect to.
|
||||
|
||||
key
|
||||
(string)
|
||||
Secret key to be used.
|
||||
|
||||
keyid
|
||||
(string)
|
||||
Access key to be used.
|
||||
|
||||
profile
|
||||
(various)
|
||||
A dict with region, key and keyid, or a pillar key (string) that
|
||||
contains a dict with region, key and keyid.
|
||||
|
||||
.. versionadded:: Boron
|
||||
'''
|
||||
ret = {'name': name,
|
||||
'result': True,
|
||||
'comment': '',
|
||||
'changes': {}
|
||||
}
|
||||
_new = {'domain_name': domain_name,
|
||||
'domain_name_servers': domain_name_servers,
|
||||
'ntp_servers': ntp_servers,
|
||||
'netbios_name_servers': netbios_name_servers,
|
||||
'netbios_node_type': netbios_node_type
|
||||
}
|
||||
|
||||
# boto provides no "update_dhcp_options()" functionality, and you can't delete it if
|
||||
# it's attached, and you can't detach it if it's the only one, so just check if it's
|
||||
# there or not, and make no effort to validate it's actual settings... :(
|
||||
### TODO - add support for multiple sets of DHCP options, and then for "swapping out"
|
||||
### sets by creating new, mapping, then deleting the old.
|
||||
r = __salt__['boto_vpc.dhcp_options_exists'](dhcp_options_id=dhcp_options_id,
|
||||
dhcp_options_name=name,
|
||||
region=region, key=key, keyid=keyid,
|
||||
profile=profile)
|
||||
if 'error' in r:
|
||||
ret['result'] = False
|
||||
ret['comment'] = 'Failed to validate DHCP options: {0}.'.format(r['error']['message'])
|
||||
return ret
|
||||
|
||||
if r.get('exists'):
|
||||
ret['comment'] = 'DHCP options already present.'
|
||||
return ret
|
||||
else:
|
||||
if __opts__['test']:
|
||||
ret['comment'] = 'DHCP options {0} are set to be created.'.format(name)
|
||||
ret['result'] = None
|
||||
return ret
|
||||
|
||||
r = __salt__['boto_vpc.create_dhcp_options'](domain_name=domain_name,
|
||||
domain_name_servers=domain_name_servers,
|
||||
ntp_servers=ntp_servers,
|
||||
netbios_name_servers=netbios_name_servers,
|
||||
netbios_node_type=netbios_node_type,
|
||||
dhcp_options_name=name, tags=tags,
|
||||
vpc_id=vpc_id, vpc_name=vpc_name,
|
||||
region=region, key=key, keyid=keyid,
|
||||
profile=profile)
|
||||
if not r.get('created'):
|
||||
ret['result'] = False
|
||||
ret['comment'] = 'Failed to create DHCP options: {1}'.format(r['error']['message'])
|
||||
return ret
|
||||
|
||||
ret['changes']['old'] = {'dhcp_options': None}
|
||||
ret['changes']['new'] = {'dhcp_options': _new}
|
||||
ret['comment'] = 'DHCP options {0} created.'.format(name)
|
||||
return ret
|
||||
|
||||
|
||||
def dhcp_options_absent(name=None, dhcp_options_id=None, region=None, key=None, keyid=None, profile=None):
|
||||
'''
|
||||
Ensure a set of DHCP options with the given settings exist.
|
||||
|
||||
name
|
||||
(string)
|
||||
Name of the DHCP options set.
|
||||
|
||||
dhcp_options_id
|
||||
(string)
|
||||
Id of the DHCP options set.
|
||||
|
||||
region
|
||||
(string)
|
||||
Region to connect to.
|
||||
|
||||
key
|
||||
(string)
|
||||
Secret key to be used.
|
||||
|
||||
keyid
|
||||
(string)
|
||||
Access key to be used.
|
||||
|
||||
profile
|
||||
(various)
|
||||
A dict with region, key and keyid, or a pillar key (string) that
|
||||
contains a dict with region, key and keyid.
|
||||
|
||||
.. versionadded:: Boron
|
||||
'''
|
||||
ret = {'name': name,
|
||||
'result': True,
|
||||
'comment': '',
|
||||
'changes': {}
|
||||
}
|
||||
|
||||
r = __salt__['boto_vpc.get_resource_id']('dhcp_options', name=name,
|
||||
region=region, key=key,
|
||||
keyid=keyid, profile=profile)
|
||||
if 'error' in r:
|
||||
ret['result'] = False
|
||||
ret['comment'] = 'Failed to delete DHCP options: {0}.'.format(r['error']['message'])
|
||||
return ret
|
||||
|
||||
_id = r.get('id')
|
||||
|
||||
if not _id:
|
||||
ret['comment'] = 'DHCP options {0} do not exist.'.format(name)
|
||||
return ret
|
||||
|
||||
if __opts__['test']:
|
||||
ret['comment'] = 'DHCP options {0} are set to be deleted.'.format(name)
|
||||
ret['result'] = None
|
||||
return ret
|
||||
|
||||
r = __salt__['boto_vpc.delete_dhcp_options'](dhcp_options_id=r['id'], region=region,
|
||||
key=key, keyid=keyid, profile=profile)
|
||||
if not r.get('deleted'):
|
||||
ret['result'] = False
|
||||
ret['comment'] = 'Failed to delete DHCP options: {0}'.format(r['error']['message'])
|
||||
return ret
|
||||
|
||||
ret['changes']['old'] = {'dhcp_options': _id}
|
||||
ret['changes']['new'] = {'dhcp_options': None}
|
||||
ret['comment'] = 'DHCP options {0} deleted.'.format(name)
|
||||
return ret
|
||||
|
||||
|
||||
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):
|
||||
@ -576,16 +769,17 @@ def route_table_present(name, vpc_name=None, vpc_id=None, routes=None,
|
||||
ret['result'] = _ret['result']
|
||||
if ret['result'] is False:
|
||||
return ret
|
||||
_ret = _routes_present(route_table_name=name, routes=routes, tags=tags, region=region, key=key,
|
||||
keyid=keyid, profile=profile)
|
||||
_ret = _routes_present(route_table_name=name, routes=routes, tags=tags,
|
||||
region=region, key=key, keyid=keyid, profile=profile)
|
||||
ret['changes'] = dictupdate.update(ret['changes'], _ret['changes'])
|
||||
ret['comment'] = ' '.join([ret['comment'], _ret['comment']])
|
||||
if not _ret['result']:
|
||||
ret['result'] = _ret['result']
|
||||
if ret['result'] is False:
|
||||
return ret
|
||||
_ret = _subnets_present(route_table_name=name, subnet_ids=subnet_ids, subnet_names=subnet_names, tags=tags, region=region, key=key,
|
||||
keyid=keyid, profile=profile)
|
||||
_ret = _subnets_present(route_table_name=name, subnet_ids=subnet_ids,
|
||||
subnet_names=subnet_names, tags=tags, region=region,
|
||||
key=key, keyid=keyid, profile=profile)
|
||||
ret['changes'] = dictupdate.update(ret['changes'], _ret['changes'])
|
||||
ret['comment'] = ' '.join([ret['comment'], _ret['comment']])
|
||||
if not _ret['result']:
|
||||
@ -595,14 +789,16 @@ def route_table_present(name, vpc_name=None, vpc_id=None, routes=None,
|
||||
return ret
|
||||
|
||||
|
||||
def _route_table_present(name, vpc_name=None, vpc_id=None, tags=None, region=None, key=None, keyid=None, profile=None):
|
||||
def _route_table_present(name, vpc_name=None, vpc_id=None, tags=None, region=None,
|
||||
key=None, keyid=None, profile=None):
|
||||
ret = {'name': name,
|
||||
'result': True,
|
||||
'comment': '',
|
||||
'changes': {}
|
||||
}
|
||||
|
||||
r = __salt__['boto_vpc.get_resource_id'](resource='route_table', name=name, region=region, key=key, keyid=keyid,
|
||||
r = __salt__['boto_vpc.get_resource_id'](resource='route_table', name=name,
|
||||
region=region, key=key, keyid=keyid,
|
||||
profile=profile)
|
||||
if 'error' in r:
|
||||
ret['result'] = False
|
||||
@ -618,8 +814,11 @@ def _route_table_present(name, vpc_name=None, vpc_id=None, tags=None, region=Non
|
||||
ret['result'] = None
|
||||
return ret
|
||||
|
||||
r = __salt__['boto_vpc.create_route_table'](route_table_name=name, vpc_name=vpc_name, vpc_id=vpc_id, tags=tags,
|
||||
region=region, key=key, keyid=keyid, profile=profile)
|
||||
r = __salt__['boto_vpc.create_route_table'](route_table_name=name,
|
||||
vpc_name=vpc_name,
|
||||
vpc_id=vpc_id, tags=tags,
|
||||
region=region, key=key,
|
||||
keyid=keyid, profile=profile)
|
||||
if not r.get('created'):
|
||||
ret['result'] = False
|
||||
ret['comment'] = 'Failed to create route table: {0}.'.format(r['error']['message'])
|
||||
@ -640,8 +839,8 @@ def _routes_present(route_table_name, routes, tags=None, region=None, key=None,
|
||||
'changes': {}
|
||||
}
|
||||
|
||||
route_table = __salt__['boto_vpc.describe_route_table'](route_table_name=route_table_name, tags=tags, region=region,
|
||||
key=key, keyid=keyid, profile=profile)
|
||||
route_table = __salt__['boto_vpc.describe_route_table'](route_table_name=route_table_name, tags=tags,
|
||||
region=region, key=key, keyid=keyid, profile=profile)
|
||||
if 'error' in route_table:
|
||||
msg = 'Could not retrieve configuration for route table {0}: {1}`.'.format(route_table_name,
|
||||
route_table['error']['message'])
|
||||
@ -669,6 +868,17 @@ def _routes_present(route_table_name, routes, tags=None, region=None, key=None,
|
||||
ret['result'] = False
|
||||
return ret
|
||||
_r['gateway_id'] = r['id']
|
||||
if i.get('instance_name'):
|
||||
running_states = ('pending', 'rebooting', 'running', 'stopping', 'stopped')
|
||||
r = __salt__['boto_ec2.get_id'](name=i['instance_name'], region=region,
|
||||
key=key, keyid=keyid, profile=profile,
|
||||
in_states=running_states)
|
||||
if r is None:
|
||||
msg = 'Instance {0} does not exist.'.format(i['instance_name'])
|
||||
ret['comment'] = msg
|
||||
ret['result'] = False
|
||||
return ret
|
||||
_r['instance_id'] = r
|
||||
_routes.append(_r)
|
||||
|
||||
to_delete = []
|
||||
|
Loading…
Reference in New Issue
Block a user