File: //usr/lib/python2.7/site-packages/salt/states/cryptdev.py
# -*- coding: utf-8 -*-
'''
Opening of Encrypted Devices
=======================
Ensure that an encrypted device is mapped with the `mapped` function:
.. code-block:: yaml
mappedname:
cryptdev.mapped:
- device: /dev/sdb1
- keyfile: /etc/keyfile.key
- opts:
- size=256
swap:
crypted.mapped:
- device: /dev/sdx4
- keyfile: /dev/urandom
- opts: swap,cipher=aes-cbc-essiv:sha256,size=256
mappedbyuuid:
crypted.mapped:
- device: UUID=066e0200-2867-4ebe-b9e6-f30026ca2314
- keyfile: /etc/keyfile.key
- config: /etc/alternate-crypttab
.. versionadded:: 2018.3.0
'''
from __future__ import absolute_import, print_function, unicode_literals
import logging
log = logging.getLogger(__name__)
def mapped(name,
device,
keyfile=None,
opts=None,
config='/etc/crypttab',
persist=True,
immediate=False,
match_on='name'):
'''
Verify that a device is mapped
name
The name under which the device is to be mapped
device
The device name, typically the device node, such as ``/dev/sdb1``
or ``UUID=066e0200-2867-4ebe-b9e6-f30026ca2314``.
keyfile
Either ``None`` if the password is to be entered manually on boot, or
an absolute path to a keyfile. If the password is to be asked
interactively, the mapping cannot be performed with ``immediate=True``.
opts
A list object of options or a comma delimited list
config
Set an alternative location for the crypttab, if the map is persistent,
Default is ``/etc/crypttab``
persist
Set if the map should be saved in the crypttab, Default is ``True``
immediate
Set if the device mapping should be executed immediately. Requires that
the keyfile not be ``None``, because the password cannot be asked
interactively. Note that options are not passed through on the initial
mapping. Default is ``False``.
match_on
A name or list of crypttab properties on which this state should be applied.
Default is ``name``, meaning that the line is matched only by the name
parameter. If the desired configuration requires two devices mapped to
the same name, supply a list of parameters to match on.
'''
ret = {'name': name,
'changes': {},
'result': True,
'comment': ''}
# If neither option is set, we've been asked to do nothing.
if not immediate and not persist:
ret['result'] = False
ret['comment'] = 'Either persist or immediate must be set, otherwise this state does nothing'
return ret
if immediate and (keyfile is None or keyfile == 'none' or keyfile == '-'):
ret['result'] = False
ret['changes']['cryptsetup'] = 'Device cannot be mapped immediately without a keyfile'
elif immediate:
# Get the active crypt mounts. If ours is listed already, no action is necessary.
active = __salt__['cryptdev.active']()
if name not in active.keys():
# Open the map using cryptsetup. This does not pass any options.
if opts:
log.warning('Ignore cryptdev configuration when mapping immediately')
if __opts__['test']:
ret['result'] = None
ret['commment'] = 'Device would be mapped immediately'
else:
cryptsetup_result = __salt__['cryptdev.open'](name, device, keyfile)
if cryptsetup_result:
ret['changes']['cryptsetup'] = 'Device mapped using cryptsetup'
else:
ret['changes']['cryptsetup'] = 'Device failed to map using cryptsetup'
ret['result'] = False
if persist and not __opts__['test']:
crypttab_result = __salt__['cryptdev.set_crypttab'](name,
device,
password=keyfile,
options=opts,
config=config,
match_on=match_on)
if crypttab_result:
if crypttab_result == 'new':
ret['changes']['crypttab'] = 'Entry added in {0}'.format(config)
if crypttab_result == 'change':
ret['changes']['crypttab'] = 'Existing entry in {0} changed'.format(config)
else:
ret['changes']['crypttab'] = 'Unable to set entry in {0}'.format(config)
ret['result'] = False
return ret
def unmapped(name,
config='/etc/crypttab',
persist=True,
immediate=False):
'''
Ensure that a device is unmapped
name
The name to ensure is not mapped
config
Set an alternative location for the crypttab, if the map is persistent,
Default is ``/etc/crypttab``
persist
Set if the map should be removed from the crypttab. Default is ``True``
immediate
Set if the device should be unmapped immediately. Default is ``False``.
'''
ret = {'name': name,
'changes': {},
'result': True,
'comment': ''}
if immediate:
# Get the active crypt mounts. If ours is not listed already, no action is necessary.
active = __salt__['cryptdev.active']()
if name in active.keys():
# Close the map using cryptsetup.
if __opts__['test']:
ret['result'] = None
ret['commment'] = 'Device would be unmapped immediately'
else:
cryptsetup_result = __salt__['cryptdev.close'](name)
if cryptsetup_result:
ret['changes']['cryptsetup'] = 'Device unmapped using cryptsetup'
else:
ret['changes']['cryptsetup'] = 'Device failed to unmap using cryptsetup'
ret['result'] = False
if persist and not __opts__['test']:
crypttab_result = __salt__['cryptdev.rm_crypttab'](name, config=config)
if crypttab_result:
if crypttab_result == 'change':
ret['changes']['crypttab'] = 'Entry removed from {0}'.format(config)
else:
ret['changes']['crypttab'] = 'Unable to remove entry in {0}'.format(config)
ret['result'] = False
return ret