Merge branch '2016.11' into '2017.7'

Conflicts:
  - salt/key.py
  - salt/modules/yumpkg.py
This commit is contained in:
rallytime 2017-09-06 09:44:34 -04:00
commit 7b07b58396
7 changed files with 72 additions and 25 deletions

View file

@ -1,5 +1,17 @@
{
"alwaysNotifyForPaths": [
{
"name": "ryan-lane",
"files": ["salt/**/*boto*.py"],
"skipTeamPrs": false
},
{
"name": "tkwilliams",
"files": ["salt/**/*boto*.py"],
"skipTeamPrs": false
}
],
"skipTitle": "Merge forward",
"userBlacklist": ["cvrebert", "markusgattol", "olliewalsh"]
"userBlacklist": ["cvrebert", "markusgattol", "olliewalsh", "basepi"]
}

View file

@ -263,9 +263,17 @@ against that branch.
Release Branches
----------------
For each release a branch will be created when we are ready to tag. The branch will be the same name as the tag minus the v. For example, the v2017.7.1 release was created from the 2017.7.1 branch. This branching strategy will allow for more stability when there is a need for a re-tag during the testing phase of our releases.
For each release, a branch will be created when the SaltStack release team is
ready to tag. The release branch is created from the parent branch and will be
the same name as the tag minus the ``v``. For example, the ``2017.7.1`` release
branch was created from the ``2017.7`` parent branch and the ``v2017.7.1``
release was tagged at the ``HEAD`` of the ``2017.7.1`` branch. This branching
strategy will allow for more stability when there is a need for a re-tag during
the testing phase of the release process.
Once the branch is created, the fixes required for a given release, as determined by the SaltStack release team, will be added to this branch. All commits in this branch will be merged forward into the parent branch as well.
Once the release branch is created, the fixes required for a given release, as
determined by the SaltStack release team, will be added to this branch. All
commits in this branch will be merged forward into the parent branch as well.
Keeping Salt Forks in Sync
==========================

View file

@ -4,6 +4,8 @@ Minion data cache plugin for Consul key/value data store.
.. versionadded:: 2016.11.2
:depends: python-consul >= 0.2.0
It is up to the system administrator to set up and configure the Consul
infrastructure. All is needed for this plugin is a working Consul agent
with a read-write access to the key-value store.
@ -81,8 +83,11 @@ def __virtual__():
'verify': __opts__.get('consul.verify', True),
}
global api
api = consul.Consul(**consul_kwargs)
try:
global api
api = consul.Consul(**consul_kwargs)
except AttributeError:
return (False, "Failed to invoke consul.Consul, please make sure you have python-consul >= 0.2.0 installed")
return __virtualname__

View file

@ -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.list(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.list(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)

View file

@ -857,8 +857,8 @@ def list_repo_pkgs(*args, **kwargs):
_parse_output(out['stdout'], strict=True)
else:
for repo in repos:
cmd = [_yum(), '--quiet', 'repository-packages', repo,
'list', '--showduplicates']
cmd = [_yum(), '--quiet', '--showduplicates',
'repository-packages', repo, 'list']
if cacheonly:
cmd.append('-C')
# Can't concatenate because args is a tuple, using list.extend()
@ -2723,7 +2723,7 @@ def _parse_repo_file(filename):
for section in parsed._sections:
section_dict = dict(parsed._sections[section])
section_dict.pop('__name__')
section_dict.pop('__name__', None)
config[section] = section_dict
# Try to extract leading comments

View file

@ -15,6 +15,8 @@ DEVICE="{{name}}"
{%endif%}{% if onparent %}ONPARENT={{onparent}}
{%endif%}{% if ipv4_failure_fatal %}IPV4_FAILURE_FATAL="{{ipv4_failure_fatal}}"
{%endif%}{% if ipaddr %}IPADDR="{{ipaddr}}"
{%endif%}{% if ipaddr_start %}IPADDR_START="{{ipaddr_start}}"
{%endif%}{% if ipaddr_end %}IPADDR_END="{{ipaddr_end}}"
{%endif%}{% if netmask %}NETMASK="{{netmask}}"
{%endif%}{% if prefix %}PREFIX="{{prefix}}"
{%endif%}{% if gateway %}GATEWAY="{{gateway}}"

View file

@ -2359,6 +2359,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'
)
@ -2458,6 +2468,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: