mirror of
https://github.com/valitydev/salt.git
synced 2024-11-08 01:18:58 +00:00
Merge pull request #12741 from lyft/boto-secgroup
Initial commit of boto_secgroup execution module and state.
This commit is contained in:
commit
92aca12854
320
salt/modules/boto_secgroup.py
Normal file
320
salt/modules/boto_secgroup.py
Normal file
@ -0,0 +1,320 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
'''
|
||||||
|
Connection module for Amazon Security Groups
|
||||||
|
|
||||||
|
.. versionadded:: Helium
|
||||||
|
|
||||||
|
:configuration: This module accepts explicit ec2 credentials but can
|
||||||
|
also utilize IAM roles assigned to the instance trough Instance Profiles.
|
||||||
|
Dynamic credentials are then automatically obtained from AWS API and no
|
||||||
|
further configuration is necessary. More Information available at::
|
||||||
|
|
||||||
|
http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html
|
||||||
|
|
||||||
|
If IAM roles are not used you need to specify them either in a pillar or
|
||||||
|
in the minion's config file::
|
||||||
|
|
||||||
|
secgroup.keyid: GKTADJGHEIQSXMKKRBJ08H
|
||||||
|
secgroup.key: askdjghsdfjkghWupUjasdflkdfklgjsdfjajkghs
|
||||||
|
|
||||||
|
A region may also be specified in the configuration::
|
||||||
|
|
||||||
|
secgroup.region: us-east-1
|
||||||
|
|
||||||
|
If a region is not specified, the default is us-east-1.
|
||||||
|
|
||||||
|
It's also possible to specify key, keyid and region via a profile, either
|
||||||
|
as a passed in dict, or as a string to pull from pillars or minion config:
|
||||||
|
|
||||||
|
myprofile:
|
||||||
|
keyid: GKTADJGHEIQSXMKKRBJ08H
|
||||||
|
key: askdjghsdfjkghWupUjasdflkdfklgjsdfjajkghs
|
||||||
|
region: us-east-1
|
||||||
|
|
||||||
|
:depends: boto
|
||||||
|
'''
|
||||||
|
|
||||||
|
# Import Python libs
|
||||||
|
import logging
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
# Import third party libs
|
||||||
|
try:
|
||||||
|
import boto
|
||||||
|
import boto.ec2
|
||||||
|
logging.getLogger('boto').setLevel(logging.CRITICAL)
|
||||||
|
HAS_BOTO = True
|
||||||
|
except ImportError:
|
||||||
|
HAS_BOTO = False
|
||||||
|
|
||||||
|
from salt._compat import string_types
|
||||||
|
import salt.utils.odict as odict
|
||||||
|
|
||||||
|
|
||||||
|
def __virtual__():
|
||||||
|
'''
|
||||||
|
Only load if boto libraries exist.
|
||||||
|
'''
|
||||||
|
if not HAS_BOTO:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def exists(name, region=None, key=None, keyid=None, profile=None):
|
||||||
|
'''
|
||||||
|
Check to see if an security group exists.
|
||||||
|
|
||||||
|
CLI example::
|
||||||
|
|
||||||
|
salt myminion boto_secgroup.exists mysecgroup
|
||||||
|
'''
|
||||||
|
conn = _get_conn(region, key, keyid, profile)
|
||||||
|
if not conn:
|
||||||
|
return False
|
||||||
|
try:
|
||||||
|
conn.get_all_security_groups([name])
|
||||||
|
return True
|
||||||
|
except boto.exception.BotoServerError as e:
|
||||||
|
log.debug(e)
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def _split_rules(rules):
|
||||||
|
'''
|
||||||
|
Split rules with combined grants into individual rules.
|
||||||
|
|
||||||
|
Amazon returns a set of rules with the same protocol, from and to ports
|
||||||
|
together as a single rule with a set of grants. Authorizing and revoking
|
||||||
|
rules, however, is done as a split set of rules. This function splits the
|
||||||
|
rules up.
|
||||||
|
'''
|
||||||
|
split = []
|
||||||
|
for rule in rules:
|
||||||
|
ip_protocol = rule.get('ip_protocol')
|
||||||
|
to_port = rule.get('to_port')
|
||||||
|
from_port = rule.get('from_port')
|
||||||
|
grants = rule.get('grants')
|
||||||
|
for grant in grants:
|
||||||
|
_rule = {'ip_protocol': ip_protocol,
|
||||||
|
'to_port': to_port,
|
||||||
|
'from_port': from_port}
|
||||||
|
for key, val in grant.iteritems():
|
||||||
|
_rule[key] = val
|
||||||
|
split.append(_rule)
|
||||||
|
return split
|
||||||
|
|
||||||
|
|
||||||
|
def get_config(name=None, group_id=None, region=None, key=None, keyid=None,
|
||||||
|
profile=None):
|
||||||
|
'''
|
||||||
|
Get the configuration for a security group.
|
||||||
|
|
||||||
|
CLI example::
|
||||||
|
|
||||||
|
salt myminion boto_secgroup.get_config mysecgroup
|
||||||
|
'''
|
||||||
|
conn = _get_conn(region, key, keyid, profile)
|
||||||
|
if not conn:
|
||||||
|
return None
|
||||||
|
if not (name or group_id):
|
||||||
|
return None
|
||||||
|
try:
|
||||||
|
if name:
|
||||||
|
sg = conn.get_all_security_groups([name])
|
||||||
|
else:
|
||||||
|
sg = conn.get_all_security_groups(group_ids=[group_id])
|
||||||
|
except boto.exception.BotoServerError as e:
|
||||||
|
msg = 'Failed to get config for security group {0}.'.format(name)
|
||||||
|
log.error(msg)
|
||||||
|
log.debug(e)
|
||||||
|
return {}
|
||||||
|
sg = sg[0]
|
||||||
|
ret = odict.OrderedDict()
|
||||||
|
ret['name'] = name
|
||||||
|
ret['group_id'] = sg.id
|
||||||
|
ret['owner_id'] = sg.owner_id
|
||||||
|
ret['description'] = sg.description
|
||||||
|
# TODO: add support for tags
|
||||||
|
_rules = []
|
||||||
|
for rule in sg.rules:
|
||||||
|
attrs = ['ip_protocol', 'from_port', 'to_port', 'grants']
|
||||||
|
_rule = odict.OrderedDict()
|
||||||
|
for attr in attrs:
|
||||||
|
val = getattr(rule, attr)
|
||||||
|
if not val:
|
||||||
|
continue
|
||||||
|
if attr == 'grants':
|
||||||
|
_grants = []
|
||||||
|
for grant in val:
|
||||||
|
g_attrs = {'name': 'source_group_name',
|
||||||
|
'owner_id': 'source_group_owner_id',
|
||||||
|
'group_id': 'source_group_group_id',
|
||||||
|
'cidr_ip': 'cidr_ip'}
|
||||||
|
_grant = odict.OrderedDict()
|
||||||
|
for g_attr, g_attr_map in g_attrs.iteritems():
|
||||||
|
g_val = getattr(grant, g_attr)
|
||||||
|
if not g_val:
|
||||||
|
continue
|
||||||
|
_grant[g_attr_map] = g_val
|
||||||
|
_grants.append(_grant)
|
||||||
|
_rule['grants'] = _grants
|
||||||
|
elif attr == 'from_port':
|
||||||
|
_rule[attr] = int(val)
|
||||||
|
elif attr == 'to_port':
|
||||||
|
_rule[attr] = int(val)
|
||||||
|
else:
|
||||||
|
_rule[attr] = val
|
||||||
|
_rules.append(_rule)
|
||||||
|
ret['rules'] = _split_rules(_rules)
|
||||||
|
return ret
|
||||||
|
|
||||||
|
|
||||||
|
def create(name, description, vpc_id=None, region=None, key=None, keyid=None,
|
||||||
|
profile=None):
|
||||||
|
'''
|
||||||
|
Create an autoscale group.
|
||||||
|
|
||||||
|
CLI example::
|
||||||
|
|
||||||
|
salt myminion boto_secgroup.create mysecgroup 'My Security Group'
|
||||||
|
'''
|
||||||
|
conn = _get_conn(region, key, keyid, profile)
|
||||||
|
if not conn:
|
||||||
|
return False
|
||||||
|
created = conn.create_security_group(name, description, vpc_id)
|
||||||
|
if created:
|
||||||
|
log.info('Created security group {0}.'.format(name))
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
msg = 'Failed to create security group {0}.'.format(name)
|
||||||
|
log.error(msg)
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def delete(name, group_id=None, region=None, key=None, keyid=None,
|
||||||
|
profile=None):
|
||||||
|
'''
|
||||||
|
Delete an autoscale group.
|
||||||
|
|
||||||
|
CLI example::
|
||||||
|
|
||||||
|
salt myminion boto_secgroup.delete mysecgroup
|
||||||
|
'''
|
||||||
|
conn = _get_conn(region, key, keyid, profile)
|
||||||
|
if not conn:
|
||||||
|
return False
|
||||||
|
deleted = conn.delete_security_group(name, group_id)
|
||||||
|
if deleted:
|
||||||
|
log.info('Deleted security group {0}.'.format(name))
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
msg = 'Failed to delete security group {0}.'.format(name)
|
||||||
|
log.error(msg)
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def authorize(name, source_group_name=None,
|
||||||
|
source_group_owner_id=None, ip_protocol=None,
|
||||||
|
from_port=None, to_port=None, cidr_ip=None, group_id=None,
|
||||||
|
source_group_group_id=None, region=None, key=None,
|
||||||
|
keyid=None, profile=None):
|
||||||
|
'''
|
||||||
|
Add a new rule to an existing security group.
|
||||||
|
|
||||||
|
CLI example::
|
||||||
|
|
||||||
|
salt myminion boto_secgroup.authorize mysecgroup ip_protocol=tcp from_port=80 to_port=80 cidr_ip='["10.0.0.0/0", "192.168.0.0/0"]'
|
||||||
|
'''
|
||||||
|
conn = _get_conn(region, key, keyid, profile)
|
||||||
|
if not conn:
|
||||||
|
return False
|
||||||
|
try:
|
||||||
|
added = conn.authorize_security_group(
|
||||||
|
group_name=name, src_security_group_name=source_group_name,
|
||||||
|
src_security_group_owner_id=source_group_owner_id,
|
||||||
|
ip_protocol=ip_protocol, from_port=from_port, to_port=to_port,
|
||||||
|
cidr_ip=cidr_ip, group_id=group_id,
|
||||||
|
src_security_group_group_id=source_group_group_id)
|
||||||
|
if added:
|
||||||
|
log.info('Added rule to security group {0}.'.format(name))
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
msg = 'Failed to add rule to security group {0}.'.format(name)
|
||||||
|
log.error(msg)
|
||||||
|
return False
|
||||||
|
except boto.exception.EC2ResponseError as e:
|
||||||
|
log.debug(e)
|
||||||
|
msg = 'Failed to add rule to security group {0}.'.format(name)
|
||||||
|
log.error(msg)
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def revoke(name, source_group_name=None,
|
||||||
|
source_group_owner_id=None, ip_protocol=None,
|
||||||
|
from_port=None, to_port=None, cidr_ip=None, group_id=None,
|
||||||
|
source_group_group_id=None, region=None, key=None,
|
||||||
|
keyid=None, profile=None):
|
||||||
|
'''
|
||||||
|
Remove a rule from an existing security group.
|
||||||
|
|
||||||
|
CLI example::
|
||||||
|
|
||||||
|
salt myminion boto_secgroup.revoke mysecgroup ip_protocol=tcp from_port=80 to_port=80 cidr_ip='["10.0.0.0/0", "192.168.0.0/0"]'
|
||||||
|
'''
|
||||||
|
conn = _get_conn(region, key, keyid, profile)
|
||||||
|
if not conn:
|
||||||
|
return False
|
||||||
|
try:
|
||||||
|
revoked = conn.revoke_security_group(
|
||||||
|
group_name=name, src_security_group_name=source_group_name,
|
||||||
|
src_security_group_owner_id=source_group_owner_id,
|
||||||
|
ip_protocol=ip_protocol, from_port=from_port, to_port=to_port,
|
||||||
|
cidr_ip=cidr_ip, group_id=group_id,
|
||||||
|
src_security_group_group_id=source_group_group_id)
|
||||||
|
if revoked:
|
||||||
|
log.info('Removed rule from security group {0}.'.format(name))
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
msg = 'Failed to remove rule from security group {0}.'.format(name)
|
||||||
|
log.error(msg)
|
||||||
|
return False
|
||||||
|
except boto.exception.EC2ResponseError as e:
|
||||||
|
log.debug(e)
|
||||||
|
msg = 'Failed to remove rule from security group {0}.'.format(name)
|
||||||
|
log.error(msg)
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def _get_conn(region, key, keyid, profile):
|
||||||
|
'''
|
||||||
|
Get a boto connection to ec2.
|
||||||
|
'''
|
||||||
|
if profile:
|
||||||
|
if isinstance(profile, string_types):
|
||||||
|
_profile = __salt__['config.option'](profile)
|
||||||
|
elif isinstance(profile, dict):
|
||||||
|
_profile = profile
|
||||||
|
key = _profile.get('key', None)
|
||||||
|
keyid = _profile.get('keyid', None)
|
||||||
|
region = _profile.get('region', None)
|
||||||
|
|
||||||
|
if not region and __salt__['config.option']('secgroup.region'):
|
||||||
|
region = __salt__['config.option']('secgroup.region')
|
||||||
|
|
||||||
|
if not region:
|
||||||
|
region = 'us-east-1'
|
||||||
|
|
||||||
|
if not key and __salt__['config.option']('secgroup.key'):
|
||||||
|
key = __salt__['config.option']('secgroup.key')
|
||||||
|
if not keyid and __salt__['config.option']('secgroup.keyid'):
|
||||||
|
keyid = __salt__['config.option']('secgroup.keyid')
|
||||||
|
|
||||||
|
try:
|
||||||
|
conn = boto.ec2.connect_to_region(region, aws_access_key_id=keyid,
|
||||||
|
aws_secret_access_key=key)
|
||||||
|
except boto.exception.NoAuthHandlerFound:
|
||||||
|
log.error('No authentication credentials found when attempting to'
|
||||||
|
' make ec2 connection for security groups.')
|
||||||
|
return None
|
||||||
|
return conn
|
335
salt/states/boto_secgroup.py
Normal file
335
salt/states/boto_secgroup.py
Normal file
@ -0,0 +1,335 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
'''
|
||||||
|
Manage Security Groups
|
||||||
|
======================
|
||||||
|
|
||||||
|
.. versionadded:: Helium
|
||||||
|
|
||||||
|
Create and destroy Security Groups. Be aware that this interacts with Amazon's
|
||||||
|
services, and so may incur charges.
|
||||||
|
|
||||||
|
This module uses boto, which can be installed via package, or pip.
|
||||||
|
|
||||||
|
This module accepts explicit ec2 credentials but can also utilize
|
||||||
|
IAM roles assigned to the instance trough Instance Profiles. Dynamic
|
||||||
|
credentials are then automatically obtained from AWS API and no further
|
||||||
|
configuration is necessary. More Information available at::
|
||||||
|
|
||||||
|
http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html
|
||||||
|
|
||||||
|
If IAM roles are not used you need to specify them either in a pillar or
|
||||||
|
in the minion's config file::
|
||||||
|
|
||||||
|
secgroup.keyid: GKTADJGHEIQSXMKKRBJ08H
|
||||||
|
secgroup.key: askdjghsdfjkghWupUjasdflkdfklgjsdfjajkghs
|
||||||
|
|
||||||
|
It's also possible to specify key, keyid and region via a profile, either
|
||||||
|
as a passed in dict, or as a string to pull from pillars or minion config:
|
||||||
|
|
||||||
|
myprofile:
|
||||||
|
keyid: GKTADJGHEIQSXMKKRBJ08H
|
||||||
|
key: askdjghsdfjkghWupUjasdflkdfklgjsdfjajkghs
|
||||||
|
region: us-east-1
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
Ensure mysecgroup exists:
|
||||||
|
boto_secgroup.present:
|
||||||
|
- name: mysecgroup
|
||||||
|
- description: My security group
|
||||||
|
- rules:
|
||||||
|
- ip_protocol: tcp
|
||||||
|
from_port: 80
|
||||||
|
to_port: 80
|
||||||
|
cidr_ip:
|
||||||
|
- 10.0.0.0/0
|
||||||
|
- 192.168.0.0/0
|
||||||
|
- region: us-east-1
|
||||||
|
- keyid: GKTADJGHEIQSXMKKRBJ08H
|
||||||
|
- key: askdjghsdfjkghWupUjasdflkdfklgjsdfjajkghs
|
||||||
|
|
||||||
|
# Using a profile from pillars
|
||||||
|
Ensure mysecgroup exists:
|
||||||
|
boto_secgroup.present:
|
||||||
|
- name: mysecgroup
|
||||||
|
- description: My security group
|
||||||
|
- region: us-east-1
|
||||||
|
- profile: myprofile
|
||||||
|
|
||||||
|
# Passing in a profile
|
||||||
|
Ensure mysecgroup exists:
|
||||||
|
boto_secgroup.present:
|
||||||
|
- name: mysecgroup
|
||||||
|
- description: My security group
|
||||||
|
- region: us-east-1
|
||||||
|
- profile:
|
||||||
|
keyid: GKTADJGHEIQSXMKKRBJ08H
|
||||||
|
key: askdjghsdfjkghWupUjasdflkdfklgjsdfjajkghs
|
||||||
|
'''
|
||||||
|
import salt.utils.dictupdate as dictupdate
|
||||||
|
from salt.exceptions import SaltInvocationError
|
||||||
|
|
||||||
|
|
||||||
|
def __virtual__():
|
||||||
|
'''
|
||||||
|
Only load if boto is available.
|
||||||
|
'''
|
||||||
|
return 'boto_secgroup' if 'boto_secgroup.exists' in __salt__ else False
|
||||||
|
|
||||||
|
|
||||||
|
def present(
|
||||||
|
name,
|
||||||
|
description,
|
||||||
|
vpc_id=None,
|
||||||
|
rules=None,
|
||||||
|
region=None,
|
||||||
|
key=None,
|
||||||
|
keyid=None,
|
||||||
|
profile=None):
|
||||||
|
'''
|
||||||
|
Ensure the security group exists with the specified rules.
|
||||||
|
|
||||||
|
name
|
||||||
|
Name of the security group.
|
||||||
|
|
||||||
|
description
|
||||||
|
A description of this security group.
|
||||||
|
|
||||||
|
vpc_id
|
||||||
|
The ID of the VPC to create the security group in, if any.
|
||||||
|
|
||||||
|
rules
|
||||||
|
A list of ingress rule dicts.
|
||||||
|
|
||||||
|
region
|
||||||
|
Region to connect to.
|
||||||
|
|
||||||
|
key
|
||||||
|
Secret key to be used.
|
||||||
|
|
||||||
|
keyid
|
||||||
|
Access key to be used.
|
||||||
|
|
||||||
|
profile
|
||||||
|
A dict with region, key and keyid, or a pillar key (string)
|
||||||
|
that contains a dict with region, key and keyid.
|
||||||
|
'''
|
||||||
|
ret = {'name': name, 'result': None, 'comment': '', 'changes': {}}
|
||||||
|
_ret = _security_group_present(name, description, vpc_id, region, key,
|
||||||
|
keyid, profile)
|
||||||
|
ret['changes'] = _ret['changes']
|
||||||
|
ret['comment'] = ' '.join([ret['comment'], _ret['comment']])
|
||||||
|
if _ret['result'] is not None:
|
||||||
|
ret['result'] = _ret['result']
|
||||||
|
if ret['result'] is False:
|
||||||
|
return ret
|
||||||
|
if not rules:
|
||||||
|
rules = []
|
||||||
|
_ret = _rules_present(name, rules, region, key, keyid, profile)
|
||||||
|
ret['changes'] = dictupdate.update(ret['changes'], _ret['changes'])
|
||||||
|
ret['comment'] = ' '.join([ret['comment'], _ret['comment']])
|
||||||
|
if _ret['result'] is not None:
|
||||||
|
ret['result'] = _ret['result']
|
||||||
|
return ret
|
||||||
|
|
||||||
|
|
||||||
|
def _security_group_present(
|
||||||
|
name,
|
||||||
|
description,
|
||||||
|
vpc_id,
|
||||||
|
region,
|
||||||
|
key,
|
||||||
|
keyid,
|
||||||
|
profile):
|
||||||
|
ret = {'result': None, 'comment': '', 'changes': {}}
|
||||||
|
exists = __salt__['boto_secgroup.exists'](name, region, key, keyid,
|
||||||
|
profile)
|
||||||
|
if not exists:
|
||||||
|
if __opts__['test']:
|
||||||
|
msg = 'Security group {0} is set to be created.'.format(name)
|
||||||
|
ret['comment'] = msg
|
||||||
|
return ret
|
||||||
|
created = __salt__['boto_secgroup.create'](name, description, vpc_id,
|
||||||
|
region, key, keyid, profile)
|
||||||
|
if created:
|
||||||
|
ret['result'] = True
|
||||||
|
ret['changes']['old'] = {'secgroup': None}
|
||||||
|
sg = __salt__['boto_secgroup.get_config'](name, None, region, key,
|
||||||
|
keyid, profile)
|
||||||
|
ret['changes']['new'] = {'secgroup': sg}
|
||||||
|
ret['comment'] = 'Security group {0} created.'.format(name)
|
||||||
|
else:
|
||||||
|
ret['result'] = False
|
||||||
|
msg = 'Failed to create {0} security group.'.format(name)
|
||||||
|
ret['comment'] = msg
|
||||||
|
else:
|
||||||
|
ret['comment'] = 'Security group {0} present.'.format(name)
|
||||||
|
return ret
|
||||||
|
|
||||||
|
|
||||||
|
def _get_rule_changes(rules, _rules):
|
||||||
|
to_delete = []
|
||||||
|
to_create = []
|
||||||
|
for rule in rules:
|
||||||
|
try:
|
||||||
|
ip_protocol = rule.get('ip_protocol')
|
||||||
|
to_port = rule.get('to_port')
|
||||||
|
from_port = rule.get('from_port')
|
||||||
|
except KeyError:
|
||||||
|
raise SaltInvocationError('ip_protocol, to_port, and from_port are'
|
||||||
|
' required arguments for security group'
|
||||||
|
' rules.')
|
||||||
|
supported_protocols = ['tcp', 'udp', 'icmp', 'all']
|
||||||
|
if ip_protocol not in supported_protocols:
|
||||||
|
msg = ('Invalid ip_protocol {0} specified in security group rule.')
|
||||||
|
raise SaltInvocationError(msg.format(ip_protocol))
|
||||||
|
cidr_ip = rule.get('cidr_ip', None)
|
||||||
|
group_name = rule.get('source_group_name', None)
|
||||||
|
group_id = rule.get('source_group_group_id', None)
|
||||||
|
owner_id = rule.get('source_group_owner_id', None)
|
||||||
|
if cidr_ip and (group_id or group_name):
|
||||||
|
raise SaltInvocationError('cidr_ip and source groups can not both'
|
||||||
|
' be specified in security group rules.')
|
||||||
|
if group_id and group_name:
|
||||||
|
raise SaltInvocationError('Either source_group_group_id or'
|
||||||
|
' source_group_name can be specified in'
|
||||||
|
' security group rules, but not both.')
|
||||||
|
if not (cidr_ip or group_id or group_name):
|
||||||
|
raise SaltInvocationError('cidr_ip, source_group_group_id, or'
|
||||||
|
' source_group_name must be provided for'
|
||||||
|
' security group rules.')
|
||||||
|
rule_found = False
|
||||||
|
for _rule in _rules:
|
||||||
|
if (ip_protocol == _rule['ip_protocol'] and
|
||||||
|
from_port == _rule['from_port'] and
|
||||||
|
to_port == _rule['to_port']):
|
||||||
|
_cidr_ip = _rule.get('cidr_ip', None)
|
||||||
|
_owner_id = _rule.get('source_group_owner_id', None)
|
||||||
|
_group_id = _rule.get('source_group_group_id', None)
|
||||||
|
_group_name = _rule.get('source_group_name', None)
|
||||||
|
if (cidr_ip == _cidr_ip or owner_id == _owner_id or
|
||||||
|
group_id == _group_id or group_name == _group_name):
|
||||||
|
rule_found = True
|
||||||
|
if not rule_found:
|
||||||
|
to_create.append(rule)
|
||||||
|
|
||||||
|
for _rule in _rules:
|
||||||
|
_ip_protocol = _rule.get('ip_protocol')
|
||||||
|
_to_port = _rule.get('to_port')
|
||||||
|
_from_port = _rule.get('from_port')
|
||||||
|
_cidr_ip = _rule.get('cidr_ip', None)
|
||||||
|
_owner_id = _rule.get('source_group_owner_id', None)
|
||||||
|
_group_id = _rule.get('source_group_group_id', None)
|
||||||
|
_group_name = _rule.get('source_group_name', None)
|
||||||
|
rule_found = False
|
||||||
|
for rule in rules:
|
||||||
|
cidr_ip = rule.get('cidr_ip', None)
|
||||||
|
group_name = rule.get('source_group_name', None)
|
||||||
|
group_id = rule.get('source_group_group_id', None)
|
||||||
|
owner_id = rule.get('source_group_owner_id', None)
|
||||||
|
if (rule['ip_protocol'] == _ip_protocol and
|
||||||
|
rule['from_port'] == _from_port and
|
||||||
|
rule['to_port'] == _to_port):
|
||||||
|
if (cidr_ip == _cidr_ip or owner_id == _owner_id or
|
||||||
|
group_id == _group_id or group_name == _group_name):
|
||||||
|
rule_found = True
|
||||||
|
if not rule_found:
|
||||||
|
# Can only supply name or id, not both. Since we're deleting
|
||||||
|
# entries, it doesn't matter which we pick.
|
||||||
|
_rule.pop('source_group_name', None)
|
||||||
|
to_delete.append(_rule)
|
||||||
|
|
||||||
|
return (to_delete, to_create)
|
||||||
|
|
||||||
|
|
||||||
|
def _rules_present(
|
||||||
|
name,
|
||||||
|
rules,
|
||||||
|
region,
|
||||||
|
key,
|
||||||
|
keyid,
|
||||||
|
profile):
|
||||||
|
ret = {'result': None, 'comment': '', 'changes': {}}
|
||||||
|
sg = __salt__['boto_secgroup.get_config'](name, None, region, key, keyid,
|
||||||
|
profile)
|
||||||
|
if not sg:
|
||||||
|
msg = '{0} security group configuration could not be retreived.'
|
||||||
|
ret['comment'] = msg.format(name)
|
||||||
|
ret['result'] = False
|
||||||
|
return ret
|
||||||
|
to_delete, to_create = _get_rule_changes(rules, sg['rules'])
|
||||||
|
if to_create or to_delete:
|
||||||
|
if __opts__['test']:
|
||||||
|
msg = 'Security group {0} set to have rules modified.'.format(name)
|
||||||
|
ret['comment'] = msg
|
||||||
|
return ret
|
||||||
|
if to_delete:
|
||||||
|
deleted = True
|
||||||
|
for rule in to_delete:
|
||||||
|
_deleted = __salt__['boto_secgroup.revoke'](
|
||||||
|
name, region=region, key=key, keyid=keyid, profile=profile,
|
||||||
|
**rule)
|
||||||
|
if not _deleted:
|
||||||
|
deleted = False
|
||||||
|
if deleted:
|
||||||
|
msg = 'Removed rules on {0} security group.'.format(name)
|
||||||
|
ret['comment'] = msg
|
||||||
|
ret['result'] = True
|
||||||
|
else:
|
||||||
|
msg = 'Failed to remove rules on {0} security group.'
|
||||||
|
ret['comment'] = msg.format(name)
|
||||||
|
ret['result'] = False
|
||||||
|
if to_create:
|
||||||
|
created = True
|
||||||
|
for rule in to_create:
|
||||||
|
_created = __salt__['boto_secgroup.authorize'](
|
||||||
|
name, region=region, key=key, keyid=keyid, profile=profile,
|
||||||
|
**rule)
|
||||||
|
if not _created:
|
||||||
|
created = False
|
||||||
|
if created:
|
||||||
|
msg = 'Created rules on {0} security group.'
|
||||||
|
ret['comment'] = ' '.join([ret['comment'], msg.format(name)])
|
||||||
|
if ret['result'] is not False:
|
||||||
|
ret['result'] = True
|
||||||
|
else:
|
||||||
|
msg = 'Failed to create rules on {0} security group.'
|
||||||
|
ret['comment'] = ' '.join([ret['comment'], msg.format(name)])
|
||||||
|
ret['result'] = False
|
||||||
|
ret['changes']['old'] = {'rules': sg['rules']}
|
||||||
|
sg = __salt__['boto_secgroup.get_config'](name, None, region, key,
|
||||||
|
keyid, profile)
|
||||||
|
ret['changes']['new'] = {'rules': sg['rules']}
|
||||||
|
return ret
|
||||||
|
|
||||||
|
|
||||||
|
def absent(
|
||||||
|
name,
|
||||||
|
region=None,
|
||||||
|
key=None,
|
||||||
|
keyid=None,
|
||||||
|
profile=None):
|
||||||
|
ret = {'name': name, 'result': None, 'comment': '', 'changes': {}}
|
||||||
|
|
||||||
|
sg = __salt__['boto_secgroup.get_config'](name, None, region, key, keyid,
|
||||||
|
profile)
|
||||||
|
if sg:
|
||||||
|
if __opts__['test']:
|
||||||
|
ret['result'] = None
|
||||||
|
msg = 'Security group {0} is set to be removed.'.format(name)
|
||||||
|
ret['comment'] = msg
|
||||||
|
return ret
|
||||||
|
deleted = __salt__['boto_secgroup.delete'](name, None, region, key,
|
||||||
|
keyid, profile)
|
||||||
|
if deleted:
|
||||||
|
ret['result'] = True
|
||||||
|
ret['changes']['old'] = {'secgroup': sg}
|
||||||
|
ret['changes']['new'] = {'secgroup': None}
|
||||||
|
ret['comment'] = 'Security group {0} deleted.'.format(name)
|
||||||
|
else:
|
||||||
|
ret['result'] = False
|
||||||
|
msg = 'Failed to delete {0} security group.'.format(name)
|
||||||
|
ret['comment'] = msg
|
||||||
|
else:
|
||||||
|
ret['comment'] = '{0} security group does not exist.'.format(name)
|
||||||
|
return ret
|
Loading…
Reference in New Issue
Block a user