mirror of
https://github.com/saltstack/salt.git
synced 2025-04-17 10:10:20 +00:00
Merge pull request #38182 from rallytime/merge-2016.11
[2016.11] Merge forward from 2016.3 to 2016.11
This commit is contained in:
commit
23c039347e
5 changed files with 137 additions and 17 deletions
|
@ -1719,7 +1719,7 @@ def _absolute_path(path, relative_to=None):
|
|||
return path
|
||||
|
||||
|
||||
def load_config(path, env_var, default_path=None):
|
||||
def load_config(path, env_var, default_path=None, exit_on_config_errors=True):
|
||||
'''
|
||||
Returns configuration dict from parsing either the file described by
|
||||
``path`` or the environment variable described by ``env_var`` as YAML.
|
||||
|
@ -1767,17 +1767,20 @@ def load_config(path, env_var, default_path=None):
|
|||
ifile.readline() # skip first line
|
||||
out.write(ifile.read())
|
||||
|
||||
opts = {}
|
||||
|
||||
if salt.utils.validate.path.is_readable(path):
|
||||
try:
|
||||
opts = _read_conf_file(path)
|
||||
opts['conf_file'] = path
|
||||
return opts
|
||||
except salt.exceptions.SaltConfigurationError as error:
|
||||
log.error(error)
|
||||
sys.exit(salt.defaults.exitcodes.EX_GENERIC)
|
||||
if exit_on_config_errors:
|
||||
sys.exit(salt.defaults.exitcodes.EX_GENERIC)
|
||||
else:
|
||||
log.debug('Missing configuration file: {0}'.format(path))
|
||||
|
||||
log.debug('Missing configuration file: {0}'.format(path))
|
||||
return {}
|
||||
return opts
|
||||
|
||||
|
||||
def include_config(include, orig_path, verbose, exit_on_config_errors=False):
|
||||
|
@ -1822,6 +1825,9 @@ def include_config(include, orig_path, verbose, exit_on_config_errors=False):
|
|||
log.error(error)
|
||||
if exit_on_config_errors:
|
||||
sys.exit(salt.defaults.exitcodes.EX_GENERIC)
|
||||
else:
|
||||
# Initialize default config if we wish to skip config errors
|
||||
opts = {}
|
||||
|
||||
include = opts.get('include', [])
|
||||
if include:
|
||||
|
@ -3213,8 +3219,10 @@ def master_config(path, env_var='SALT_MASTER_CONFIG', defaults=None, exit_on_con
|
|||
defaults['default_include'])
|
||||
include = overrides.get('include', [])
|
||||
|
||||
overrides.update(include_config(default_include, path, verbose=False), exit_on_config_errors=exit_on_config_errors)
|
||||
overrides.update(include_config(include, path, verbose=True), exit_on_config_errors=exit_on_config_errors)
|
||||
overrides.update(include_config(default_include, path, verbose=False),
|
||||
exit_on_config_errors=exit_on_config_errors)
|
||||
overrides.update(include_config(include, path, verbose=True),
|
||||
exit_on_config_errors=exit_on_config_errors)
|
||||
opts = apply_master_config(overrides, defaults)
|
||||
_validate_opts(opts)
|
||||
# If 'nodegroups:' is uncommented in the master config file, and there are
|
||||
|
|
|
@ -331,7 +331,8 @@ def get_url(path, dest='', saltenv='base', makedirs=False):
|
|||
|
||||
def get_file_str(path, saltenv='base'):
|
||||
'''
|
||||
Return the contents of a file from a URL
|
||||
Download a file from a URL to the Minion cache directory and return the
|
||||
contents of that file
|
||||
|
||||
Returns ``False`` if Salt was unable to cache a file from a URL.
|
||||
|
||||
|
@ -351,8 +352,9 @@ def get_file_str(path, saltenv='base'):
|
|||
|
||||
def cache_file(path, saltenv='base'):
|
||||
'''
|
||||
Used to cache a single file on the salt-minion
|
||||
Returns the location of the new cached file on the minion
|
||||
Used to cache a single file on the Minion
|
||||
|
||||
Returns the location of the new cached file on the Minion.
|
||||
|
||||
CLI Example:
|
||||
|
||||
|
@ -413,9 +415,9 @@ def cache_file(path, saltenv='base'):
|
|||
|
||||
def cache_files(paths, saltenv='base'):
|
||||
'''
|
||||
Used to gather many files from the master, the gathered files will be
|
||||
Used to gather many files from the Master, the gathered files will be
|
||||
saved in the minion cachedir reflective to the paths retrieved from the
|
||||
master.
|
||||
Master
|
||||
|
||||
CLI Example:
|
||||
|
||||
|
|
|
@ -14,7 +14,6 @@ import integration
|
|||
from salt.config import cloud_providers_config
|
||||
|
||||
# Import Salt Testing Libs
|
||||
from salttesting import skipIf
|
||||
from salttesting.helpers import ensure_in_syspath, expensiveTest
|
||||
|
||||
ensure_in_syspath('../../../')
|
||||
|
@ -37,7 +36,6 @@ INSTANCE_NAME = __random_name()
|
|||
PROVIDER_NAME = 'ec2'
|
||||
|
||||
|
||||
@skipIf(True, 'Skipping until we can figure out why the testrunner bails.')
|
||||
class EC2Test(integration.ShellCase):
|
||||
'''
|
||||
Integration tests for the EC2 cloud provider in Salt-Cloud
|
||||
|
|
|
@ -149,6 +149,8 @@ class CPModuleTest(integration.ModuleCase):
|
|||
self.assertIn('empty', os.listdir(os.path.join(tgt, 'grail')))
|
||||
self.assertIn('scene', os.listdir(os.path.join(tgt, 'grail', '36')))
|
||||
|
||||
# cp.get_url tests
|
||||
|
||||
def test_get_url(self):
|
||||
'''
|
||||
cp.get_url with salt:// source given
|
||||
|
@ -305,6 +307,62 @@ class CPModuleTest(integration.ModuleCase):
|
|||
self.assertIn('KNIGHT: They\'re nervous, sire.', ret)
|
||||
self.assertNotIn('bacon', ret)
|
||||
|
||||
# cp.get_file_str tests
|
||||
|
||||
def test_get_file_str_salt(self):
|
||||
'''
|
||||
cp.get_file_str with salt:// source given
|
||||
'''
|
||||
src = 'salt://grail/scene33'
|
||||
ret = self.run_function(
|
||||
'cp.get_file_str',
|
||||
[
|
||||
src,
|
||||
])
|
||||
self.assertIn('KNIGHT: They\'re nervous, sire.', ret)
|
||||
|
||||
def test_get_file_str_nonexistent_source(self):
|
||||
'''
|
||||
cp.get_file_str with nonexistent salt:// source given
|
||||
'''
|
||||
src = 'salt://grail/nonexistent_scene'
|
||||
ret = self.run_function(
|
||||
'cp.get_file_str',
|
||||
[
|
||||
src,
|
||||
])
|
||||
self.assertEqual(ret, False)
|
||||
|
||||
def test_get_file_str_https(self):
|
||||
'''
|
||||
cp.get_file_str with https:// source given
|
||||
'''
|
||||
src = 'https://repo.saltstack.com/index.html'
|
||||
ret = self.run_function(
|
||||
'cp.get_file_str',
|
||||
[
|
||||
src,
|
||||
])
|
||||
self.assertIn('Bootstrap', ret)
|
||||
self.assertIn('Debian', ret)
|
||||
self.assertIn('Windows', ret)
|
||||
self.assertNotIn('AYBABTU', ret)
|
||||
|
||||
def test_get_file_str_local(self):
|
||||
'''
|
||||
cp.get_file_str with file:// source given
|
||||
'''
|
||||
src = os.path.join('file://', integration.FILES, 'file/base/file.big')
|
||||
ret = self.run_function(
|
||||
'cp.get_file_str',
|
||||
[
|
||||
src,
|
||||
])
|
||||
self.assertIn('KNIGHT: They\'re nervous, sire.', ret)
|
||||
self.assertNotIn('bacon', ret)
|
||||
|
||||
# caching tests
|
||||
|
||||
def test_cache_file(self):
|
||||
'''
|
||||
cp.cache_file
|
||||
|
|
|
@ -18,17 +18,20 @@ import tempfile
|
|||
from salttesting import TestCase
|
||||
from salttesting.mock import MagicMock, patch
|
||||
from salttesting.helpers import ensure_in_syspath
|
||||
from salt.exceptions import CommandExecutionError
|
||||
|
||||
ensure_in_syspath('../')
|
||||
|
||||
# Import salt libs
|
||||
# Import Salt libs
|
||||
import salt.minion
|
||||
import salt.utils
|
||||
import salt.utils.network
|
||||
import integration
|
||||
from salt import config as sconfig
|
||||
from salt.exceptions import SaltCloudConfigError
|
||||
from salt.exceptions import (
|
||||
CommandExecutionError,
|
||||
SaltConfigurationError,
|
||||
SaltCloudConfigError
|
||||
)
|
||||
|
||||
# Import Third-Party Libs
|
||||
import yaml
|
||||
|
@ -65,6 +68,13 @@ def _unhandled_mock_read(filename):
|
|||
raise CommandExecutionError('Unhandled mock read for {0}'.format(filename))
|
||||
|
||||
|
||||
def _salt_configuration_error(filename):
|
||||
'''
|
||||
Raise an error to indicate error in the Salt configuration file
|
||||
'''
|
||||
raise SaltConfigurationError('Configuration error in {0}'.format(filename))
|
||||
|
||||
|
||||
class ConfigTestCase(TestCase, integration.AdaptedConfigurationTestCaseMixIn):
|
||||
|
||||
def test_sha256_is_default_for_master(self):
|
||||
|
@ -905,6 +915,50 @@ class ConfigTestCase(TestCase, integration.AdaptedConfigurationTestCaseMixIn):
|
|||
|
||||
# <---- Salt Cloud Configuration Tests ---------------------------------------------
|
||||
|
||||
def test_include_config_without_errors(self):
|
||||
'''
|
||||
Tests that include_config function returns valid configuration
|
||||
'''
|
||||
include_file = 'minion.d/my.conf'
|
||||
config_path = '/etc/salt/minion'
|
||||
config_opts = {'id': 'myminion.example.com'}
|
||||
|
||||
with patch('glob.glob', MagicMock(return_value=include_file)):
|
||||
with patch('salt.config._read_conf_file', MagicMock(return_value=config_opts)):
|
||||
configuration = sconfig.include_config(include_file, config_path, verbose=False)
|
||||
|
||||
self.assertEqual(config_opts, configuration)
|
||||
|
||||
def test_include_config_with_errors(self):
|
||||
'''
|
||||
Tests that include_config function returns valid configuration even on errors
|
||||
'''
|
||||
include_file = 'minion.d/my.conf'
|
||||
config_path = '/etc/salt/minion'
|
||||
config_opts = {}
|
||||
|
||||
with patch('glob.glob', MagicMock(return_value=include_file)):
|
||||
with patch('salt.config._read_conf_file', _salt_configuration_error):
|
||||
configuration = sconfig.include_config(include_file, config_path, verbose=False)
|
||||
|
||||
self.assertEqual(config_opts, configuration)
|
||||
|
||||
def test_include_config_with_errors_exit(self):
|
||||
'''
|
||||
Tests that include_config exits on errors
|
||||
'''
|
||||
include_file = 'minion.d/my.conf'
|
||||
config_path = '/etc/salt/minion'
|
||||
|
||||
with patch('glob.glob', MagicMock(return_value=include_file)):
|
||||
with patch('salt.config._read_conf_file', _salt_configuration_error):
|
||||
with self.assertRaises(SystemExit):
|
||||
sconfig.include_config(include_file,
|
||||
config_path,
|
||||
verbose=False,
|
||||
exit_on_config_errors=True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from integration import run_tests
|
||||
run_tests(ConfigTestCase, needs_daemon=False)
|
||||
|
|
Loading…
Add table
Reference in a new issue