Skip to content

Commit

Permalink
Put slsvars changes behind a feature flag
Browse files Browse the repository at this point in the history
  • Loading branch information
dwoz committed Oct 6, 2020
1 parent d841bc5 commit 9380b56
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 13 deletions.
2 changes: 2 additions & 0 deletions salt/config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -944,6 +944,8 @@ def _gather_buffer_space():
# client via the Salt API
"netapi_allow_raw_shell": bool,
"disabled_requisites": (str, list),
# Feature flag config
"features": dict,
}
)

Expand Down
27 changes: 27 additions & 0 deletions salt/features.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import logging


log = logging.getLogger(__name__)


class Features(object):

def __init__(self, _features=None):
if _features is None:
self.features = {}
else:
self.features = _features
self.setup = False

def setup_features(self, opts):
if not self.setup:
self.features.update(opts.get('features', {}))
else:
log.warn("Features already setup")

def get(self, key, default=None):
return self.features.get(key, default)


features = Features()
setup_features = features.setup_features
46 changes: 35 additions & 11 deletions salt/utils/parsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
import salt.utils.xdg
import salt.utils.yaml
import salt.version as version
import salt.features
from salt.defaults import DEFAULT_TARGET_DELIM
from salt.ext import six
from salt.ext.six.moves import range # pylint: disable=import-error,redefined-builtin
Expand Down Expand Up @@ -1960,7 +1961,9 @@ class MasterOptionParser(
_setup_mp_logging_listener_ = True

def setup_config(self):
return config.master_config(self.get_config_file_path())
opts = config.master_config(self.get_config_file_path())
salt.features.setup_features(opts)
return opts


class MinionOptionParser(
Expand Down Expand Up @@ -1989,6 +1992,7 @@ def setup_config(self):
and self.options.daemon
): # pylint: disable=no-member
self._setup_mp_logging_listener_ = False
salt.features.setup_features(opts)
return opts


Expand Down Expand Up @@ -2022,9 +2026,11 @@ def setup_config(self):
except AttributeError:
minion_id = None

return config.proxy_config(
opts = config.proxy_config(
self.get_config_file_path(), cache_minion_id=False, minion_id=minion_id
)
salt.features.setup_features(opts)
return opts


class SyndicOptionParser(
Expand Down Expand Up @@ -2056,9 +2062,11 @@ class SyndicOptionParser(
_setup_mp_logging_listener_ = True

def setup_config(self):
return config.syndic_config(
opts = config.syndic_config(
self.get_config_file_path(), self.get_config_file_path("minion")
)
salt.features.setup_features(opts)
return opts


class SaltCMDOptionParser(
Expand Down Expand Up @@ -2398,7 +2406,9 @@ def _mixin_after_parsed(self):
self.exit(42, "\nIncomplete options passed.\n\n")

def setup_config(self):
return config.client_config(self.get_config_file_path())
opts = config.client_config(self.get_config_file_path())
salt.features.setup_features(opts)
return opts


class SaltCPOptionParser(
Expand Down Expand Up @@ -2469,7 +2479,9 @@ def _mixin_after_parsed(self):
self.config["dest"] = self.args[-1]

def setup_config(self):
return config.master_config(self.get_config_file_path())
opts = config.master_config(self.get_config_file_path())
salt.features.setup_features(opts)
return opts


class SaltKeyOptionParser(
Expand Down Expand Up @@ -2758,7 +2770,7 @@ def setup_config(self):
# or tweaked
keys_config[self._logfile_config_setting_name_] = os.devnull
keys_config["pki_dir"] = self.options.gen_keys_dir

salt.features.setup_features(keys_config)
return keys_config

def process_rotate_aes_key(self):
Expand Down Expand Up @@ -3009,6 +3021,7 @@ def setup_config(self):
opts = config.minion_config(
self.get_config_file_path(), cache_minion_id=True
)
salt.features.setup_features(opts)
return opts

def process_module_dirs(self):
Expand Down Expand Up @@ -3111,7 +3124,10 @@ def _mixin_after_parsed(self):
self.config["arg"] = []

def setup_config(self):
return config.client_config(self.get_config_file_path())
opts = config.client_config(self.get_config_file_path())
salt.features.setup_features(opts)
return opts



class SaltSSHOptionParser(
Expand Down Expand Up @@ -3437,7 +3453,9 @@ def _mixin_after_parsed(self):
break

def setup_config(self):
return config.master_config(self.get_config_file_path())
opts = config.master_config(self.get_config_file_path())
salt.features.setup_features(opts)
return opts

def process_jid(self):
if self.options.jid is not None:
Expand Down Expand Up @@ -3505,9 +3523,11 @@ def _mixin_after_parsed(self):

def setup_config(self):
try:
return config.cloud_config(self.get_config_file_path())
opts = config.cloud_config(self.get_config_file_path())
except salt.exceptions.SaltCloudConfigError as exc:
self.error(exc)
salt.features.setup_features(opts)
return opts


class SPMParser(
Expand Down Expand Up @@ -3565,7 +3585,9 @@ def _mixin_after_parsed(self):
self.error("Insufficient arguments")

def setup_config(self):
return salt.config.spm_config(self.get_config_file_path())
opts = salt.config.spm_config(self.get_config_file_path())
salt.features.setup_features(opts)
return opts


class SaltAPIParser(
Expand Down Expand Up @@ -3593,6 +3615,8 @@ class SaltAPIParser(
_default_logging_logfile_ = config.DEFAULT_API_OPTS[_logfile_config_setting_name_]

def setup_config(self):
return salt.config.api_config(
opts = salt.config.api_config(
self.get_config_file_path()
) # pylint: disable=no-member
salt.features.setup_features(opts)
return opts
59 changes: 58 additions & 1 deletion salt/utils/templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import salt.utils.platform
import salt.utils.stringutils
import salt.utils.yamlencoding
from salt.features import features
from salt import __path__ as saltpath
from salt.exceptions import CommandExecutionError, SaltInvocationError, SaltRenderError
from salt.ext import six
Expand Down Expand Up @@ -93,7 +94,42 @@ def __getattr__(self, name):
return getattr(self.wrapped, name)


def generate_sls_context(tmplpath, sls):
def _generate_sls_context_legacy(tmplpath, sls):
"""
Legacy version of generate_sls_context, this method should be remove in the
Phosphorus release.
"""
salt.utils.versions.warn_until(
"Phosphorus",
"There have been significant improvement to template variables. "
"To enable these improvements set features.enable_slsvars_fixes "
"to True in your config file. This feature will become the default "
"in the Phoshorus release."
)
context = {}
slspath = sls.replace(".", "/")
if tmplpath is not None:
context["tplpath"] = tmplpath
if not tmplpath.lower().replace("\\", "/").endswith("/init.sls"):
slspath = os.path.dirname(slspath)
template = tmplpath.replace("\\", "/")
i = template.rfind(slspath.replace(".", "/"))
if i != -1:
template = template[i:]
tpldir = os.path.dirname(template).replace("\\", "/")
tpldata = {
"tplfile": template,
"tpldir": "." if tpldir == "" else tpldir,
"tpldot": tpldir.replace("/", "."),
}
context.update(tpldata)
context["slsdotpath"] = slspath.replace("/", ".")
context["slscolonpath"] = slspath.replace("/", ":")
context["sls_path"] = slspath.replace("/", "_")
context["slspath"] = slspath
return context

def _generate_sls_context(tmplpath, sls):
"""
Generate SLS/Template Context Items
Expand Down Expand Up @@ -154,6 +190,27 @@ def generate_sls_context(tmplpath, sls):
return sls_context


def generate_sls_context(tmplpath, sls):
"""
Generate SLS/Template Context Items
Return values:
tplpath - full path to template on filesystem including filename
tplfile - relative path to template -- relative to file roots
tpldir - directory of the template relative to file roots. If none, "."
tpldot - tpldir using dots instead of slashes, if none, ""
slspath - directory containing current sls - (same as tpldir), if none, ""
sls_path - slspath with underscores separating parts, if none, ""
slsdotpath - slspath with dots separating parts, if none, ""
slscolonpath- slspath with colons separating parts, if none, ""
"""
if not features.get('enable_slsvars_fixes', False):
return _generate_sls_context_legacy(tmplpath, sls)
_generate_sls_context(tmplpath, sls)


def wrap_tmpl_func(render_str):
def render_tmpl(
tmplsrc, from_str=False, to_str=False, context=None, tmplpath=None, **kws
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/utils/test_templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ def _test_generated_sls_context(self, tmplpath, sls, **expected):
if tmplpath.startswith("\\"):
tmplpath = "C:{}".format(tmplpath)
expected["tplpath"] = tmplpath
actual = salt.utils.templates.generate_sls_context(tmplpath, sls)
actual = salt.utils.templates._generate_sls_context(tmplpath, sls)
self.assertDictContainsAll(actual, **expected)

@mock.patch("salt.utils.templates.generate_sls_context")
Expand Down

0 comments on commit 9380b56

Please sign in to comment.