File: //usr/lib/python2.7/site-packages/salt/states/ipset.py
# -*- coding: utf-8 -*-
'''
Management of ipsets
======================
This is an ipset-specific module designed to manage IPSets for use
in IPTables Firewalls.
.. code-block:: yaml
setname:
ipset.set_present:
- set_type: bitmap:ip
- range: 192.168.0.0/16
- comment: True
setname:
ipset.set_absent:
- set_type: bitmap:ip
- range: 192.168.0.0/16
- comment: True
setname_entries:
ipset.present:
- set_name: setname
- entry: 192.168.0.3
- comment: Hello
- require:
- ipset: baz
setname_entries:
ipset.present:
- set_name: setname
- entry:
- 192.168.0.3
- 192.168.1.3
- comment: Hello
- require:
- ipset: baz
setname_entries:
ipset.absent:
- set_name: setname
- entry:
- 192.168.0.3
- 192.168.1.3
- comment: Hello
- require:
- ipset: baz
setname:
ipset.flush:
'''
from __future__ import absolute_import, print_function, unicode_literals
import logging
log = logging.getLogger(__name__)
def __virtual__():
'''
Only load if the ipset module is available in __salt__
'''
return 'ipset.version' in __salt__
def set_present(name, set_type, family='ipv4', **kwargs):
'''
.. versionadded:: 2014.7.0
Verify the set exists.
name
A user-defined set name.
set_type
The type for the set.
family
Networking family, either ipv4 or ipv6
'''
ret = {'name': name,
'changes': {},
'result': None,
'comment': ''}
set_check = __salt__['ipset.check_set'](name)
if set_check is True:
ret['result'] = True
ret['comment'] = ('ipset set {0} already exists for {1}'
.format(name, family))
return ret
if __opts__['test']:
ret['comment'] = 'ipset set {0} would be added for {1}'.format(
name,
family)
return ret
command = __salt__['ipset.new_set'](name, set_type, family, **kwargs)
if command is True:
ret['changes'] = {'locale': name}
ret['result'] = True
ret['comment'] = ('ipset set {0} created successfully for {1}'
.format(name, family))
return ret
else:
ret['result'] = False
ret['comment'] = 'Failed to create set {0} for {2}: {1}'.format(
name,
command.strip(),
family
)
return ret
def set_absent(name, family='ipv4', **kwargs):
'''
.. versionadded:: 2014.7.0
Verify the set is absent.
family
Networking family, either ipv4 or ipv6
'''
ret = {'name': name,
'changes': {},
'result': None,
'comment': ''}
set_check = __salt__['ipset.check_set'](name, family)
if not set_check:
ret['result'] = True
ret['comment'] = ('ipset set {0} for {1} is already absent'
.format(name, family))
return ret
if __opts__['test']:
ret['comment'] = 'ipset set {0} for {1} would be removed'.format(
name,
family)
return ret
flush_set = __salt__['ipset.flush'](name, family)
if flush_set:
command = __salt__['ipset.delete_set'](name, family)
if command is True:
ret['changes'] = {'locale': name}
ret['result'] = True
ret['comment'] = ('ipset set {0} deleted successfully for family {1}'
.format(name, family))
else:
ret['result'] = False
ret['comment'] = ('Failed to delete set {0} for {2}: {1}'
.format(name, command.strip(), family))
else:
ret['result'] = False
ret['comment'] = 'Failed to flush set {0} for {2}: {1}'.format(
name,
flush_set.strip(),
family
)
return ret
def present(name, entry=None, family='ipv4', **kwargs):
'''
.. versionadded:: 2014.7.0
Append a entry to a set
name
A user-defined name to call this entry by in another part of a state or
formula. This should not be an actual entry.
entry
A single entry to add to a set or a list of entries to add to a set
family
Network family, ipv4 or ipv6.
'''
ret = {'name': name,
'changes': {},
'result': True,
'comment': ''}
if not entry:
ret['result'] = False
ret['comment'] = ('ipset entry must be specified')
return ret
entries = []
if isinstance(entry, list):
entries = entry
else:
entries.append(entry)
for entry in entries:
entry_opts = ''
if ' ' in entry:
entry, entry_opts = entry.split(' ', 1)
if 'timeout' in kwargs and 'timeout' not in entry_opts:
entry_opts = 'timeout {0} {1}'.format(kwargs['timeout'], entry_opts)
if 'comment' in kwargs and 'comment' not in entry_opts:
entry_opts = '{0} comment "{1}"'.format(entry_opts, kwargs['comment'])
_entry = ' '.join([entry, entry_opts.lstrip()]).strip()
if __salt__['ipset.check'](kwargs['set_name'],
_entry,
family) is True:
ret['comment'] += 'entry for {0} already in set {1} for {2}\n'.format(
entry,
kwargs['set_name'],
family)
else:
if __opts__['test']:
ret['result'] = None
ret['comment'] += 'entry {0} would be added to set {1} for family {2}\n'.format(
entry,
kwargs['set_name'],
family)
else:
command = __salt__['ipset.add'](kwargs['set_name'], _entry, family, **kwargs)
if 'Error' not in command:
ret['changes'] = {'locale': name}
ret['comment'] += 'entry {0} added to set {1} for family {2}\n'.format(
_entry,
kwargs['set_name'],
family)
else:
ret['result'] = False
ret['comment'] = 'Failed to add to entry {1} to set {0} for family {2}.\n{3}'.format(
kwargs['set_name'],
_entry, family, command)
return ret
def absent(name, entry=None, entries=None, family='ipv4', **kwargs):
'''
.. versionadded:: 2014.7.0
Remove a entry or entries from a chain
name
A user-defined name to call this entry by in another part of a state or
formula. This should not be an actual entry.
family
Network family, ipv4 or ipv6.
'''
ret = {'name': name,
'changes': {},
'result': True,
'comment': ''}
if not entry:
ret['result'] = False
ret['comment'] = ('ipset entry must be specified')
return ret
entries = []
if isinstance(entry, list):
entries = entry
else:
entries.append(entry)
for entry in entries:
entry_opts = ''
if ' ' in entry:
entry, entry_opts = entry.split(' ', 1)
if 'timeout' in kwargs and 'timeout' not in entry_opts:
entry_opts = 'timeout {0} {1}'.format(kwargs['timeout'], entry_opts)
if 'comment' in kwargs and 'comment' not in entry_opts:
entry_opts = '{0} comment "{1}"'.format(entry_opts, kwargs['comment'])
_entry = ' '.join([entry, entry_opts]).strip()
log.debug('_entry %s', _entry)
if not __salt__['ipset.check'](kwargs['set_name'],
_entry,
family) is True:
ret['result'] = True
ret['comment'] += 'ipset entry for {0} not present in set {1} for {2}\n'.format(
_entry,
kwargs['set_name'],
family)
else:
if __opts__['test']:
ret['result'] = None
ret['comment'] += 'ipset entry {0} would be removed from set {1} for {2}\n'.format(
entry,
kwargs['set_name'],
family)
else:
command = __salt__['ipset.delete'](kwargs['set_name'], entry, family, **kwargs)
if 'Error' not in command:
ret['changes'] = {'locale': name}
ret['result'] = True
ret['comment'] += 'ipset entry {1} removed from set {0} for {2}\n'.format(
kwargs['set_name'],
_entry,
family)
else:
ret['result'] = False
ret['comment'] = 'Failed to delete ipset entry from set {0} for {2}. ' \
'Attempted entry was {1}.\n' \
'{3}\n'.format(kwargs['set_name'], _entry, family, command)
return ret
def flush(name, family='ipv4', **kwargs):
'''
.. versionadded:: 2014.7.0
Flush current ipset set
family
Networking family, either ipv4 or ipv6
'''
ret = {'name': name,
'changes': {},
'result': None,
'comment': ''}
set_check = __salt__['ipset.check_set'](name)
if set_check is False:
ret['result'] = False
ret['comment'] = ('ipset set {0} does not exist for {1}'
.format(name, family))
return ret
if __opts__['test']:
ret['comment'] = 'ipset entries in set {0} for {1} would be flushed'.format(
name,
family)
return ret
if __salt__['ipset.flush'](name, family):
ret['changes'] = {'locale': name}
ret['result'] = True
ret['comment'] = 'Flushed ipset entries from set {0} for {1}'.format(
name,
family
)
return ret
else:
ret['result'] = False
ret['comment'] = 'Failed to flush ipset entries from set {0} for {1}' \
''.format(name, family)
return ret