mirror of
https://github.com/saltstack/salt.git
synced 2025-04-17 10:10:20 +00:00
Fix 'preserve_minion_cache: True' functionality (fixes #35840)
- Drop preserve_minions as a a condition used in the check_minion_cache()
logic test. This should be more in line with the intent of the "Optionally,
pass in a list of minions which should have their caches preserved. To
preserve all caches, set __opts__['preserve_minion_cache']" comment
documented in key.py.
- Add --preserve_minions as an optional CLI option to salt-key. This will
allow the user to optionally preserve caches independently of the
preserve_minion_cache option. Option does not override config file.
- This effectively reverts commit 661f5686bf
which introduced the regression with preserve_minion_cache set to True to
fix a regression when preserve_minion_cache is set to False. Prior to that
commit, the preserve_minion_cache option was completely ignored when set to
True and when set to False cache directories were still preserved.
- Functional testing (three minions 'minion1', 'oldminion', and 'minion2')
/etc/salt/master - preserve_minion_cache: False
# salt-key -d minion1
PASS: deletes 'minion1', deletes stale 'oldminion', preserve active 'minion2'
# salt-key -d minion1 --preserve-minions=true
PASS: preserves minion1 as requested, deletes oldminion as it was not in the
match from the delete_key() comment "To preserve the master caches of
minions who are matched", preserves active minion2
/etc/salt/master - preserve_minion_cache: True
# salt-key -d minion1
PASS: no directories deleted per config option
# salt-key -d minion1 --preserve-minions=false
PASS: no directories deleted per config option, does not override config
This commit is contained in:
parent
afc61ffe63
commit
079f097985
2 changed files with 37 additions and 17 deletions
37
salt/key.py
37
salt/key.py
|
@ -489,7 +489,7 @@ class Key(object):
|
|||
minions = []
|
||||
for key, val in six.iteritems(keys):
|
||||
minions.extend(val)
|
||||
if not self.opts.get('preserve_minion_cache', False) or not preserve_minions:
|
||||
if not self.opts.get('preserve_minion_cache', False):
|
||||
m_cache = os.path.join(self.opts['cachedir'], self.ACC)
|
||||
if os.path.isdir(m_cache):
|
||||
for minion in os.listdir(m_cache):
|
||||
|
@ -736,7 +736,7 @@ class Key(object):
|
|||
def delete_key(self,
|
||||
match=None,
|
||||
match_dict=None,
|
||||
preserve_minions=False,
|
||||
preserve_minions=None,
|
||||
revoke_auth=False):
|
||||
'''
|
||||
Delete public keys. If "match" is passed, it is evaluated as a glob.
|
||||
|
@ -774,11 +774,10 @@ class Key(object):
|
|||
salt.utils.event.tagify(prefix='key'))
|
||||
except (OSError, IOError):
|
||||
pass
|
||||
if preserve_minions:
|
||||
preserve_minions_list = matches.get('minions', [])
|
||||
if self.opts.get('preserve_minions') is True:
|
||||
self.check_minion_cache(preserve_minions=matches.get('minions', []))
|
||||
else:
|
||||
preserve_minions_list = []
|
||||
self.check_minion_cache(preserve_minions=preserve_minions_list)
|
||||
self.check_minion_cache()
|
||||
if self.opts.get('rotate_aes_key'):
|
||||
salt.crypt.dropfile(self.opts['cachedir'], self.opts['user'])
|
||||
return (
|
||||
|
@ -969,16 +968,17 @@ class RaetKey(Key):
|
|||
minions.extend(val)
|
||||
|
||||
m_cache = os.path.join(self.opts['cachedir'], 'minions')
|
||||
if os.path.isdir(m_cache):
|
||||
for minion in os.listdir(m_cache):
|
||||
if minion not in minions:
|
||||
shutil.rmtree(os.path.join(m_cache, minion))
|
||||
cache = salt.cache.factory(self.opts)
|
||||
clist = cache.ls(self.ACC)
|
||||
if clist:
|
||||
for minion in clist:
|
||||
if not self.opts.get('preserve_minion_cache', False):
|
||||
if os.path.isdir(m_cache):
|
||||
for minion in os.listdir(m_cache):
|
||||
if minion not in minions and minion not in preserve_minions:
|
||||
cache.flush('{0}/{1}'.format(self.ACC, minion))
|
||||
shutil.rmtree(os.path.join(m_cache, minion))
|
||||
cache = salt.cache.factory(self.opts)
|
||||
clist = cache.ls(self.ACC)
|
||||
if clist:
|
||||
for minion in clist:
|
||||
if minion not in minions and minion not in preserve_minions:
|
||||
cache.flush('{0}/{1}'.format(self.ACC, minion))
|
||||
|
||||
kind = self.opts.get('__role', '') # application kind
|
||||
if kind not in salt.utils.kinds.APPL_KINDS:
|
||||
|
@ -1220,7 +1220,7 @@ class RaetKey(Key):
|
|||
def delete_key(self,
|
||||
match=None,
|
||||
match_dict=None,
|
||||
preserve_minions=False,
|
||||
preserve_minions=None,
|
||||
revoke_auth=False):
|
||||
'''
|
||||
Delete public keys. If "match" is passed, it is evaluated as a glob.
|
||||
|
@ -1251,7 +1251,10 @@ class RaetKey(Key):
|
|||
os.remove(os.path.join(self.opts['pki_dir'], status, key))
|
||||
except (OSError, IOError):
|
||||
pass
|
||||
self.check_minion_cache(preserve_minions=matches.get('minions', []))
|
||||
if self.opts.get('preserve_minions') is True:
|
||||
self.check_minion_cache(preserve_minions=matches.get('minions', []))
|
||||
else:
|
||||
self.check_minion_cache()
|
||||
return (
|
||||
self.name_match(match) if match is not None
|
||||
else self.dict_match(matches)
|
||||
|
|
|
@ -2306,6 +2306,16 @@ class SaltKeyOptionParser(six.with_metaclass(OptionParserMeta,
|
|||
'Default: %default.')
|
||||
)
|
||||
|
||||
self.add_option(
|
||||
'--preserve-minions',
|
||||
default=False,
|
||||
help=('Setting this to True prevents the master from deleting '
|
||||
'the minion cache when keys are deleted, this may have '
|
||||
'security implications if compromised minions auth with '
|
||||
'a previous deleted minion ID. '
|
||||
'Default: %default.')
|
||||
)
|
||||
|
||||
key_options_group = optparse.OptionGroup(
|
||||
self, 'Key Generation Options'
|
||||
)
|
||||
|
@ -2405,6 +2415,13 @@ class SaltKeyOptionParser(six.with_metaclass(OptionParserMeta,
|
|||
elif self.options.rotate_aes_key.lower() == 'false':
|
||||
self.options.rotate_aes_key = False
|
||||
|
||||
def process_preserve_minions(self):
|
||||
if hasattr(self.options, 'preserve_minions') and isinstance(self.options.preserve_minions, str):
|
||||
if self.options.preserve_minions.lower() == 'true':
|
||||
self.options.preserve_minions = True
|
||||
elif self.options.preserve_minions.lower() == 'false':
|
||||
self.options.preserve_minions = False
|
||||
|
||||
def process_list(self):
|
||||
# Filter accepted list arguments as soon as possible
|
||||
if not self.options.list:
|
||||
|
|
Loading…
Add table
Reference in a new issue