mirror of
https://github.com/valitydev/salt.git
synced 2024-11-08 17:33:54 +00:00
Merge pull request #20400 from Azidburn/develop
Fix for feature requests #3817 , #10258 in develop branch
This commit is contained in:
commit
babebdaa9d
@ -394,6 +394,65 @@ def check_key(user, key, enc, comment, options, config='.ssh/authorized_keys',
|
||||
return 'exists'
|
||||
|
||||
|
||||
def rm_auth_key_from_file(user,
|
||||
source,
|
||||
config='.ssh/authorized_keys',
|
||||
saltenv='base',
|
||||
env=None):
|
||||
'''
|
||||
Remove an authorized key from the specified user's authorized key file, using a file as source
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' ssh.rm_auth_key_from_file <user> salt://ssh_keys/<user>.id_rsa.pub
|
||||
'''
|
||||
if env is not None:
|
||||
salt.utils.warn_until(
|
||||
'Boron',
|
||||
'Passing a salt environment should be done using \'saltenv\' '
|
||||
'not \'env\'. This functionality will be removed in Salt Boron.'
|
||||
)
|
||||
# Backwards compatibility
|
||||
saltenv = env
|
||||
|
||||
lfile = __salt__['cp.cache_file'](source, saltenv)
|
||||
if not os.path.isfile(lfile):
|
||||
raise CommandExecutionError(
|
||||
'Failed to pull key file from salt file server'
|
||||
)
|
||||
|
||||
s_keys = _validate_keys(lfile)
|
||||
if not s_keys:
|
||||
err = (
|
||||
'No keys detected in {0}. Is file properly formatted?'.format(
|
||||
source
|
||||
)
|
||||
)
|
||||
log.error(err)
|
||||
__context__['ssh_auth.error'] = err
|
||||
return 'fail'
|
||||
else:
|
||||
rval = ''
|
||||
for key in s_keys:
|
||||
rval += rm_auth_key(
|
||||
user,
|
||||
key,
|
||||
config
|
||||
)
|
||||
# Due to the ability for a single file to have multiple keys, it's
|
||||
# possible for a single call to this function to have both "replace"
|
||||
# and "new" as possible valid returns. I ordered the following as I
|
||||
# thought best.
|
||||
if 'Key not removed' in rval:
|
||||
return 'Key not removed'
|
||||
elif 'Key removed' in rval:
|
||||
return 'Key removed'
|
||||
else:
|
||||
return 'Key not present'
|
||||
|
||||
|
||||
def rm_auth_key(user, key, config='.ssh/authorized_keys'):
|
||||
'''
|
||||
Remove an authorized key from the specified user's authorized key file
|
||||
|
@ -127,6 +127,71 @@ def _present_test(user, name, enc, comment, options, source, config):
|
||||
return result, comment
|
||||
|
||||
|
||||
def _absent_test(user, name, enc, comment, options, source, config):
|
||||
'''
|
||||
Run checks for "absent"
|
||||
'''
|
||||
result = None
|
||||
if source:
|
||||
keys = __salt__['ssh.check_key_file'](
|
||||
user,
|
||||
source,
|
||||
config,
|
||||
saltenv=__env__)
|
||||
if keys:
|
||||
comment = ''
|
||||
for key, status in keys.items():
|
||||
if status == 'exists':
|
||||
continue
|
||||
comment += 'Set to {0}: {1}\n'.format(status, key)
|
||||
if comment:
|
||||
return result, comment
|
||||
err = sys.modules[
|
||||
__salt__['test.ping'].__module__
|
||||
].__context__.pop('ssh_auth.error', None)
|
||||
if err:
|
||||
return False, err
|
||||
else:
|
||||
return (
|
||||
True,
|
||||
'All host keys in file {0} are already absent'.format(source)
|
||||
)
|
||||
else:
|
||||
# check if this is of form {options} {enc} {key} {comment}
|
||||
sshre = re.compile(r'^(.*?)\s?((?:ssh\-|ecds)[\w-]+\s.+)$')
|
||||
fullkey = sshre.search(name)
|
||||
# if it is {key} [comment]
|
||||
if not fullkey:
|
||||
key_and_comment = name.split()
|
||||
name = key_and_comment[0]
|
||||
if len(key_and_comment) == 2:
|
||||
comment = key_and_comment[1]
|
||||
else:
|
||||
# if there are options, set them
|
||||
if fullkey.group(1):
|
||||
options = fullkey.group(1).split(',')
|
||||
# key is of format: {enc} {key} [comment]
|
||||
comps = fullkey.group(2).split()
|
||||
enc = comps[0]
|
||||
name = comps[1]
|
||||
if len(comps) == 3:
|
||||
comment = comps[2]
|
||||
|
||||
check = __salt__['ssh.check_key'](
|
||||
user,
|
||||
name,
|
||||
enc,
|
||||
comment,
|
||||
options,
|
||||
config)
|
||||
if check == 'update' or check == 'exists':
|
||||
comment = ('Key {0} for user {1} is set for removal').format(name, user)
|
||||
else:
|
||||
comment = ('Key is already absent')
|
||||
|
||||
return result, comment
|
||||
|
||||
|
||||
def present(
|
||||
name,
|
||||
user,
|
||||
@ -154,8 +219,8 @@ def present(
|
||||
|
||||
source
|
||||
The source file for the key(s). Can contain any number of public keys,
|
||||
in standard "authorized_keys" format. If this is set, comment, enc,
|
||||
and options will be ignored.
|
||||
in standard "authorized_keys" format. If this is set, comment and enc
|
||||
will be ignored.
|
||||
|
||||
.. note::
|
||||
The source file must contain keys in the format ``<enc> <key>
|
||||
@ -215,11 +280,31 @@ def present(
|
||||
return ret
|
||||
|
||||
if source != '':
|
||||
data = __salt__['ssh.set_auth_key_from_file'](
|
||||
user,
|
||||
key = __salt__['cp.get_file_str'](
|
||||
source,
|
||||
config,
|
||||
saltenv=__env__)
|
||||
filehasoptions = False
|
||||
# check if this is of form {options} {enc} {key} {comment}
|
||||
sshre = re.compile(r'^(ssh\-|ecds).*')
|
||||
key = key.rstrip().split('\n')
|
||||
for keyline in key:
|
||||
filehasoptions = sshre.match(keyline)
|
||||
if not filehasoptions:
|
||||
data = __salt__['ssh.set_auth_key_from_file'](
|
||||
user,
|
||||
source,
|
||||
config,
|
||||
saltenv=__env__)
|
||||
else:
|
||||
# Split keyline to get key und commen
|
||||
keyline = keyline.split(' ')
|
||||
data = __salt__['ssh.set_auth_key'](
|
||||
user,
|
||||
keyline[1],
|
||||
keyline[0],
|
||||
keyline[2],
|
||||
options or [],
|
||||
config)
|
||||
else:
|
||||
data = __salt__['ssh.set_auth_key'](
|
||||
user,
|
||||
@ -263,6 +348,7 @@ def absent(name,
|
||||
user,
|
||||
enc='ssh-rsa',
|
||||
comment='',
|
||||
source='',
|
||||
options=None,
|
||||
config='.ssh/authorized_keys'):
|
||||
'''
|
||||
@ -284,6 +370,11 @@ def absent(name,
|
||||
options
|
||||
The options passed to the key, pass a list object
|
||||
|
||||
source
|
||||
The source file for the key(s). Can contain any number of public keys,
|
||||
in standard "authorized_keys" format. If this is set, comment, enc and
|
||||
options will be ignored.
|
||||
|
||||
config
|
||||
The location of the authorized keys file relative to the user's home
|
||||
directory, defaults to ".ssh/authorized_keys"
|
||||
@ -293,43 +384,61 @@ def absent(name,
|
||||
'result': True,
|
||||
'comment': ''}
|
||||
|
||||
# Get just the key
|
||||
sshre = re.compile(r'^(.*?)\s?((?:ssh\-|ecds)[\w-]+\s.+)$')
|
||||
fullkey = sshre.search(name)
|
||||
# if it is {key} [comment]
|
||||
if not fullkey:
|
||||
key_and_comment = name.split()
|
||||
name = key_and_comment[0]
|
||||
if len(key_and_comment) == 2:
|
||||
comment = key_and_comment[1]
|
||||
# Extract Key from file if source is present
|
||||
if source != '':
|
||||
key = __salt__['cp.get_file_str'](
|
||||
source,
|
||||
saltenv=__env__)
|
||||
filehasoptions = False
|
||||
# check if this is of form {options} {enc} {key} {comment}
|
||||
sshre = re.compile(r'^(ssh\-|ecds).*')
|
||||
key = key.rstrip().split('\n')
|
||||
for keyline in key:
|
||||
filehasoptions = sshre.match(keyline)
|
||||
if not filehasoptions:
|
||||
ret['comment'] = __salt__['ssh.rm_auth_key_from_file'](user,
|
||||
source,
|
||||
config,
|
||||
saltenv=__env__)
|
||||
else:
|
||||
# Split keyline to get key
|
||||
keyline = keyline.split(' ')
|
||||
ret['comment'] = __salt__['ssh.rm_auth_key'](user,
|
||||
keyline[1],
|
||||
config)
|
||||
else:
|
||||
# if there are options, set them
|
||||
if fullkey.group(1):
|
||||
options = fullkey.group(1).split(',')
|
||||
# key is of format: {enc} {key} [comment]
|
||||
comps = fullkey.group(2).split()
|
||||
enc = comps[0]
|
||||
name = comps[1]
|
||||
if len(comps) == 3:
|
||||
comment = comps[2]
|
||||
# Get just the key
|
||||
sshre = re.compile(r'^(.*?)\s?((?:ssh\-|ecds)[\w-]+\s.+)$')
|
||||
fullkey = sshre.search(name)
|
||||
# if it is {key} [comment]
|
||||
if not fullkey:
|
||||
key_and_comment = name.split()
|
||||
name = key_and_comment[0]
|
||||
if len(key_and_comment) == 2:
|
||||
comment = key_and_comment[1]
|
||||
else:
|
||||
# if there are options, set them
|
||||
if fullkey.group(1):
|
||||
options = fullkey.group(1).split(',')
|
||||
# key is of format: {enc} {key} [comment]
|
||||
comps = fullkey.group(2).split()
|
||||
enc = comps[0]
|
||||
name = comps[1]
|
||||
if len(comps) == 3:
|
||||
comment = comps[2]
|
||||
ret['comment'] = __salt__['ssh.rm_auth_key'](user, name, config)
|
||||
|
||||
if __opts__['test']:
|
||||
check = __salt__['ssh.check_key'](
|
||||
ret['result'], ret['comment'] = _absent_test(
|
||||
user,
|
||||
name,
|
||||
enc,
|
||||
comment,
|
||||
options or [],
|
||||
config)
|
||||
if check == 'update' or check == 'exists':
|
||||
ret['result'] = None
|
||||
ret['comment'] = 'Key {0} is set for removal'.format(name)
|
||||
return ret
|
||||
else:
|
||||
ret['comment'] = 'Key is already absent'
|
||||
return ret
|
||||
|
||||
ret['comment'] = __salt__['ssh.rm_auth_key'](user, name, config)
|
||||
source,
|
||||
config,
|
||||
)
|
||||
return ret
|
||||
|
||||
if ret['comment'] == 'User authorized keys file not present':
|
||||
ret['result'] = False
|
||||
|
Loading…
Reference in New Issue
Block a user