Reverted back the `--key-logfile` deprecation.
On the parsers cleanup branch, I though about making the available options as equal as possible. Since the log_file setting for the master and the minion could be separately set, I made the logfile option for the key also log_file. Yet, since there's no key specific config file, it shares master, one could only specify the log_file settings from the cli, it could not be hardcoded on the config file, unless, we made a separate config file just for key.
So, in order to reduce required changes, and keep it all as backwards compatible as possible, the key log file options is now, once again, `--key-logfile` which will allow us to hardcode it in the masters config file as `key_logfile`.
This will also, hopefully make travis behave better too.
2012-08-08 00:08:38 +00:00
|
|
|
# -*- coding: utf-8 -*-
|
2012-12-11 10:23:37 +00:00
|
|
|
'''
|
|
|
|
:codeauthor: :email:`Pedro Algarvio (pedro@algarvio.me)`
|
2013-09-16 16:24:00 +00:00
|
|
|
|
|
|
|
|
|
|
|
tests.unit.config_test
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~
|
2012-12-11 10:23:37 +00:00
|
|
|
'''
|
Reverted back the `--key-logfile` deprecation.
On the parsers cleanup branch, I though about making the available options as equal as possible. Since the log_file setting for the master and the minion could be separately set, I made the logfile option for the key also log_file. Yet, since there's no key specific config file, it shares master, one could only specify the log_file settings from the cli, it could not be hardcoded on the config file, unless, we made a separate config file just for key.
So, in order to reduce required changes, and keep it all as backwards compatible as possible, the key log file options is now, once again, `--key-logfile` which will allow us to hardcode it in the masters config file as `key_logfile`.
This will also, hopefully make travis behave better too.
2012-08-08 00:08:38 +00:00
|
|
|
|
2012-11-18 18:57:10 +00:00
|
|
|
# Import python libs
|
2014-11-21 19:05:13 +00:00
|
|
|
from __future__ import absolute_import
|
2014-02-25 05:46:00 +00:00
|
|
|
import logging
|
Reverted back the `--key-logfile` deprecation.
On the parsers cleanup branch, I though about making the available options as equal as possible. Since the log_file setting for the master and the minion could be separately set, I made the logfile option for the key also log_file. Yet, since there's no key specific config file, it shares master, one could only specify the log_file settings from the cli, it could not be hardcoded on the config file, unless, we made a separate config file just for key.
So, in order to reduce required changes, and keep it all as backwards compatible as possible, the key log file options is now, once again, `--key-logfile` which will allow us to hardcode it in the masters config file as `key_logfile`.
This will also, hopefully make travis behave better too.
2012-08-08 00:08:38 +00:00
|
|
|
import os
|
2012-09-07 17:04:14 +00:00
|
|
|
import shutil
|
Reverted back the `--key-logfile` deprecation.
On the parsers cleanup branch, I though about making the available options as equal as possible. Since the log_file setting for the master and the minion could be separately set, I made the logfile option for the key also log_file. Yet, since there's no key specific config file, it shares master, one could only specify the log_file settings from the cli, it could not be hardcoded on the config file, unless, we made a separate config file just for key.
So, in order to reduce required changes, and keep it all as backwards compatible as possible, the key log file options is now, once again, `--key-logfile` which will allow us to hardcode it in the masters config file as `key_logfile`.
This will also, hopefully make travis behave better too.
2012-08-08 00:08:38 +00:00
|
|
|
import tempfile
|
2014-02-25 05:46:00 +00:00
|
|
|
from contextlib import contextmanager
|
2012-11-18 18:57:10 +00:00
|
|
|
|
2013-06-27 00:30:49 +00:00
|
|
|
# Import Salt Testing libs
|
|
|
|
from salttesting import TestCase
|
2014-02-25 06:02:25 +00:00
|
|
|
from salttesting.mock import MagicMock, patch
|
2013-10-15 21:54:15 +00:00
|
|
|
from salttesting.helpers import ensure_in_syspath, TestsLoggingHandler
|
2014-02-25 05:46:00 +00:00
|
|
|
from salt.exceptions import CommandExecutionError
|
|
|
|
|
2014-02-25 06:02:25 +00:00
|
|
|
ensure_in_syspath('../')
|
|
|
|
|
|
|
|
# Import salt libs
|
|
|
|
import salt.minion
|
|
|
|
import salt.utils
|
2014-03-20 21:37:23 +00:00
|
|
|
import salt.utils.network
|
2014-02-25 06:02:25 +00:00
|
|
|
import integration
|
2014-07-16 12:41:28 +00:00
|
|
|
from salt import config as sconfig
|
2014-09-03 20:17:27 +00:00
|
|
|
from salt.exceptions import SaltCloudConfigError
|
2014-02-25 06:02:25 +00:00
|
|
|
|
2014-06-19 15:20:38 +00:00
|
|
|
# Import Third-Party Libs
|
|
|
|
import yaml
|
|
|
|
|
2014-02-25 05:46:00 +00:00
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
|
2014-05-03 02:24:13 +00:00
|
|
|
# mock hostname should be more complex than the systems FQDN
|
2014-05-06 22:00:40 +00:00
|
|
|
MOCK_HOSTNAME = 'very.long.complex.fqdn.that.is.crazy.extra.long.example.com'
|
2014-02-25 06:02:25 +00:00
|
|
|
|
|
|
|
MOCK_ETC_HOSTS = (
|
2014-02-25 05:46:00 +00:00
|
|
|
'##\n'
|
|
|
|
'# Host Database\n'
|
|
|
|
'#\n'
|
|
|
|
'# localhost is used to configure the loopback interface\n'
|
|
|
|
'# when the system is booting. Do not change this entry.\n'
|
|
|
|
'##\n'
|
2014-02-25 17:48:17 +00:00
|
|
|
'\n' # This empty line MUST STAY HERE, it factors into the tests
|
2014-05-03 02:24:13 +00:00
|
|
|
'127.0.0.1 localhost ' + MOCK_HOSTNAME + '\n'
|
|
|
|
'10.0.0.100 ' + MOCK_HOSTNAME + '\n'
|
|
|
|
'200.200.200.2 other.host.alias.com\n'
|
|
|
|
'::1 ip6-localhost ip6-loopback\n'
|
|
|
|
'fe00::0 ip6-localnet\n'
|
|
|
|
'ff00::0 ip6-mcastprefix\n'
|
2014-02-25 05:46:00 +00:00
|
|
|
)
|
2014-05-03 02:24:13 +00:00
|
|
|
MOCK_ETC_HOSTNAME = '{0}\n'.format(MOCK_HOSTNAME)
|
2014-06-18 23:15:15 +00:00
|
|
|
PATH = 'path/to/some/cloud/conf/file'
|
|
|
|
DEFAULT = {'default_include': PATH}
|
2014-02-25 05:46:00 +00:00
|
|
|
|
2014-06-18 23:47:05 +00:00
|
|
|
|
2014-02-25 08:27:35 +00:00
|
|
|
def _unhandled_mock_read(filename):
|
|
|
|
'''
|
|
|
|
Raise an error because we should not be calling salt.utils.fopen()
|
|
|
|
'''
|
|
|
|
raise CommandExecutionError('Unhandled mock read for {0}'.format(filename))
|
|
|
|
|
|
|
|
|
|
|
|
@contextmanager
|
|
|
|
def _fopen_side_effect_etc_hostname(filename):
|
|
|
|
'''
|
|
|
|
Mock reading from /etc/hostname
|
|
|
|
'''
|
|
|
|
log.debug('Mock-reading {0}'.format(filename))
|
|
|
|
if filename == '/etc/hostname':
|
|
|
|
mock_open = MagicMock()
|
|
|
|
mock_open.read.return_value = MOCK_ETC_HOSTNAME
|
|
|
|
yield mock_open
|
2014-05-03 02:24:13 +00:00
|
|
|
elif filename == '/etc/hosts':
|
|
|
|
raise IOError(2, "No such file or directory: '{0}'".format(filename))
|
2014-02-25 08:27:35 +00:00
|
|
|
else:
|
|
|
|
_unhandled_mock_read(filename)
|
|
|
|
|
|
|
|
|
2014-02-25 05:46:00 +00:00
|
|
|
@contextmanager
|
|
|
|
def _fopen_side_effect_etc_hosts(filename):
|
2014-02-25 08:27:35 +00:00
|
|
|
'''
|
|
|
|
Mock /etc/hostname not existing, and falling back to reading /etc/hosts
|
|
|
|
'''
|
2014-02-25 05:46:00 +00:00
|
|
|
log.debug('Mock-reading {0}'.format(filename))
|
|
|
|
if filename == '/etc/hostname':
|
2014-05-03 02:24:13 +00:00
|
|
|
raise IOError(2, "No such file or directory: '{0}'".format(filename))
|
2014-02-25 05:46:00 +00:00
|
|
|
elif filename == '/etc/hosts':
|
2014-02-25 07:17:04 +00:00
|
|
|
mock_open = MagicMock()
|
|
|
|
mock_open.__iter__.return_value = MOCK_ETC_HOSTS.splitlines()
|
2014-02-25 06:02:25 +00:00
|
|
|
yield mock_open
|
|
|
|
else:
|
2014-02-25 08:27:35 +00:00
|
|
|
_unhandled_mock_read(filename)
|
Reverted back the `--key-logfile` deprecation.
On the parsers cleanup branch, I though about making the available options as equal as possible. Since the log_file setting for the master and the minion could be separately set, I made the logfile option for the key also log_file. Yet, since there's no key specific config file, it shares master, one could only specify the log_file settings from the cli, it could not be hardcoded on the config file, unless, we made a separate config file just for key.
So, in order to reduce required changes, and keep it all as backwards compatible as possible, the key log file options is now, once again, `--key-logfile` which will allow us to hardcode it in the masters config file as `key_logfile`.
This will also, hopefully make travis behave better too.
2012-08-08 00:08:38 +00:00
|
|
|
|
2012-09-07 17:04:14 +00:00
|
|
|
|
2014-06-02 00:12:46 +00:00
|
|
|
class ConfigTestCase(TestCase, integration.AdaptedConfigurationTestCaseMixIn):
|
Reverted back the `--key-logfile` deprecation.
On the parsers cleanup branch, I though about making the available options as equal as possible. Since the log_file setting for the master and the minion could be separately set, I made the logfile option for the key also log_file. Yet, since there's no key specific config file, it shares master, one could only specify the log_file settings from the cli, it could not be hardcoded on the config file, unless, we made a separate config file just for key.
So, in order to reduce required changes, and keep it all as backwards compatible as possible, the key log file options is now, once again, `--key-logfile` which will allow us to hardcode it in the masters config file as `key_logfile`.
This will also, hopefully make travis behave better too.
2012-08-08 00:08:38 +00:00
|
|
|
def test_proper_path_joining(self):
|
|
|
|
fpath = tempfile.mktemp()
|
2013-06-28 19:39:37 +00:00
|
|
|
try:
|
|
|
|
salt.utils.fopen(fpath, 'w').write(
|
|
|
|
"root_dir: /\n"
|
|
|
|
"key_logfile: key\n"
|
|
|
|
)
|
|
|
|
config = sconfig.master_config(fpath)
|
2014-07-13 18:43:33 +00:00
|
|
|
# os.path.join behavior
|
2013-06-28 19:39:37 +00:00
|
|
|
self.assertEqual(config['key_logfile'], os.path.join('/', 'key'))
|
2014-07-13 18:43:33 +00:00
|
|
|
# os.sep.join behavior
|
2013-06-28 19:39:37 +00:00
|
|
|
self.assertNotEqual(config['key_logfile'], '//key')
|
|
|
|
finally:
|
|
|
|
if os.path.isfile(fpath):
|
|
|
|
os.unlink(fpath)
|
Reverted back the `--key-logfile` deprecation.
On the parsers cleanup branch, I though about making the available options as equal as possible. Since the log_file setting for the master and the minion could be separately set, I made the logfile option for the key also log_file. Yet, since there's no key specific config file, it shares master, one could only specify the log_file settings from the cli, it could not be hardcoded on the config file, unless, we made a separate config file just for key.
So, in order to reduce required changes, and keep it all as backwards compatible as possible, the key log file options is now, once again, `--key-logfile` which will allow us to hardcode it in the masters config file as `key_logfile`.
This will also, hopefully make travis behave better too.
2012-08-08 00:08:38 +00:00
|
|
|
|
2012-09-07 17:04:14 +00:00
|
|
|
def test_common_prefix_stripping(self):
|
2013-08-27 15:31:58 +00:00
|
|
|
tempdir = tempfile.mkdtemp(dir=integration.SYS_TMP_DIR)
|
2013-06-28 19:39:37 +00:00
|
|
|
try:
|
|
|
|
root_dir = os.path.join(tempdir, 'foo', 'bar')
|
|
|
|
os.makedirs(root_dir)
|
|
|
|
fpath = os.path.join(root_dir, 'config')
|
|
|
|
salt.utils.fopen(fpath, 'w').write(
|
|
|
|
'root_dir: {0}\n'
|
|
|
|
'log_file: {1}\n'.format(root_dir, fpath)
|
|
|
|
)
|
|
|
|
config = sconfig.master_config(fpath)
|
|
|
|
self.assertEqual(config['log_file'], fpath)
|
|
|
|
finally:
|
|
|
|
if os.path.isdir(tempdir):
|
|
|
|
shutil.rmtree(tempdir)
|
|
|
|
|
|
|
|
def test_load_master_config_from_environ_var(self):
|
|
|
|
original_environ = os.environ.copy()
|
|
|
|
|
2013-08-27 15:31:58 +00:00
|
|
|
tempdir = tempfile.mkdtemp(dir=integration.SYS_TMP_DIR)
|
2013-06-28 19:39:37 +00:00
|
|
|
try:
|
|
|
|
env_root_dir = os.path.join(tempdir, 'foo', 'env')
|
|
|
|
os.makedirs(env_root_dir)
|
|
|
|
env_fpath = os.path.join(env_root_dir, 'config-env')
|
|
|
|
|
|
|
|
salt.utils.fopen(env_fpath, 'w').write(
|
|
|
|
'root_dir: {0}\n'
|
|
|
|
'log_file: {1}\n'.format(env_root_dir, env_fpath)
|
|
|
|
)
|
|
|
|
|
|
|
|
os.environ['SALT_MASTER_CONFIG'] = env_fpath
|
|
|
|
# Should load from env variable, not the default configuration file.
|
|
|
|
config = sconfig.master_config('/etc/salt/master')
|
|
|
|
self.assertEqual(config['log_file'], env_fpath)
|
|
|
|
os.environ.clear()
|
|
|
|
os.environ.update(original_environ)
|
|
|
|
|
|
|
|
root_dir = os.path.join(tempdir, 'foo', 'bar')
|
|
|
|
os.makedirs(root_dir)
|
|
|
|
fpath = os.path.join(root_dir, 'config')
|
|
|
|
salt.utils.fopen(fpath, 'w').write(
|
|
|
|
'root_dir: {0}\n'
|
|
|
|
'log_file: {1}\n'.format(root_dir, fpath)
|
|
|
|
)
|
|
|
|
# Let's set the environment variable, yet, since the configuration
|
2014-11-05 21:57:47 +00:00
|
|
|
# file path is not the default one, i.e., the user has passed an
|
2013-06-28 19:39:37 +00:00
|
|
|
# alternative configuration file form the CLI parser, the
|
|
|
|
# environment variable will be ignored.
|
|
|
|
os.environ['SALT_MASTER_CONFIG'] = env_fpath
|
|
|
|
config = sconfig.master_config(fpath)
|
|
|
|
self.assertEqual(config['log_file'], fpath)
|
|
|
|
os.environ.clear()
|
|
|
|
os.environ.update(original_environ)
|
|
|
|
|
|
|
|
finally:
|
|
|
|
if os.path.isdir(tempdir):
|
|
|
|
shutil.rmtree(tempdir)
|
|
|
|
|
|
|
|
def test_load_minion_config_from_environ_var(self):
|
|
|
|
original_environ = os.environ.copy()
|
|
|
|
|
2013-08-27 15:31:58 +00:00
|
|
|
tempdir = tempfile.mkdtemp(dir=integration.SYS_TMP_DIR)
|
2013-06-28 19:39:37 +00:00
|
|
|
try:
|
|
|
|
env_root_dir = os.path.join(tempdir, 'foo', 'env')
|
|
|
|
os.makedirs(env_root_dir)
|
|
|
|
env_fpath = os.path.join(env_root_dir, 'config-env')
|
|
|
|
|
|
|
|
salt.utils.fopen(env_fpath, 'w').write(
|
|
|
|
'root_dir: {0}\n'
|
|
|
|
'log_file: {1}\n'.format(env_root_dir, env_fpath)
|
|
|
|
)
|
|
|
|
|
|
|
|
os.environ['SALT_MINION_CONFIG'] = env_fpath
|
|
|
|
# Should load from env variable, not the default configuration file
|
|
|
|
config = sconfig.minion_config('/etc/salt/minion')
|
|
|
|
self.assertEqual(config['log_file'], env_fpath)
|
|
|
|
os.environ.clear()
|
|
|
|
os.environ.update(original_environ)
|
|
|
|
|
|
|
|
root_dir = os.path.join(tempdir, 'foo', 'bar')
|
|
|
|
os.makedirs(root_dir)
|
|
|
|
fpath = os.path.join(root_dir, 'config')
|
|
|
|
salt.utils.fopen(fpath, 'w').write(
|
|
|
|
'root_dir: {0}\n'
|
|
|
|
'log_file: {1}\n'.format(root_dir, fpath)
|
|
|
|
)
|
|
|
|
# Let's set the environment variable, yet, since the configuration
|
2014-11-05 21:57:47 +00:00
|
|
|
# file path is not the default one, i.e., the user has passed an
|
2013-06-28 19:39:37 +00:00
|
|
|
# alternative configuration file form the CLI parser, the
|
|
|
|
# environment variable will be ignored.
|
|
|
|
os.environ['SALT_MINION_CONFIG'] = env_fpath
|
|
|
|
config = sconfig.minion_config(fpath)
|
|
|
|
self.assertEqual(config['log_file'], fpath)
|
|
|
|
os.environ.clear()
|
|
|
|
os.environ.update(original_environ)
|
|
|
|
finally:
|
|
|
|
if os.path.isdir(tempdir):
|
|
|
|
shutil.rmtree(tempdir)
|
|
|
|
|
|
|
|
def test_load_client_config_from_environ_var(self):
|
|
|
|
original_environ = os.environ.copy()
|
|
|
|
try:
|
2013-08-27 15:31:58 +00:00
|
|
|
tempdir = tempfile.mkdtemp(dir=integration.SYS_TMP_DIR)
|
2013-06-28 19:39:37 +00:00
|
|
|
env_root_dir = os.path.join(tempdir, 'foo', 'env')
|
|
|
|
os.makedirs(env_root_dir)
|
|
|
|
|
|
|
|
# Let's populate a master configuration file which should not get
|
|
|
|
# picked up since the client configuration tries to load the master
|
|
|
|
# configuration settings using the provided client configuration
|
|
|
|
# file
|
|
|
|
master_config = os.path.join(env_root_dir, 'master')
|
|
|
|
salt.utils.fopen(master_config, 'w').write(
|
|
|
|
'blah: true\n'
|
|
|
|
'root_dir: {0}\n'
|
|
|
|
'log_file: {1}\n'.format(env_root_dir, master_config)
|
|
|
|
)
|
|
|
|
os.environ['SALT_MASTER_CONFIG'] = master_config
|
|
|
|
|
|
|
|
# Now the client configuration file
|
|
|
|
env_fpath = os.path.join(env_root_dir, 'config-env')
|
|
|
|
salt.utils.fopen(env_fpath, 'w').write(
|
|
|
|
'root_dir: {0}\n'
|
|
|
|
'log_file: {1}\n'.format(env_root_dir, env_fpath)
|
|
|
|
)
|
|
|
|
|
|
|
|
os.environ['SALT_CLIENT_CONFIG'] = env_fpath
|
|
|
|
# Should load from env variable, not the default configuration file
|
|
|
|
config = sconfig.client_config(os.path.expanduser('~/.salt'))
|
|
|
|
self.assertEqual(config['log_file'], env_fpath)
|
|
|
|
self.assertTrue('blah' not in config)
|
|
|
|
os.environ.clear()
|
|
|
|
os.environ.update(original_environ)
|
|
|
|
|
|
|
|
root_dir = os.path.join(tempdir, 'foo', 'bar')
|
|
|
|
os.makedirs(root_dir)
|
|
|
|
fpath = os.path.join(root_dir, 'config')
|
|
|
|
salt.utils.fopen(fpath, 'w').write(
|
|
|
|
'root_dir: {0}\n'
|
|
|
|
'log_file: {1}\n'.format(root_dir, fpath)
|
|
|
|
)
|
|
|
|
# Let's set the environment variable, yet, since the configuration
|
2014-11-05 21:57:47 +00:00
|
|
|
# file path is not the default one, i.e., the user has passed an
|
2013-06-28 19:39:37 +00:00
|
|
|
# alternative configuration file form the CLI parser, the
|
|
|
|
# environment variable will be ignored.
|
|
|
|
os.environ['SALT_MASTER_CONFIG'] = env_fpath
|
|
|
|
config = sconfig.master_config(fpath)
|
|
|
|
self.assertEqual(config['log_file'], fpath)
|
|
|
|
os.environ.clear()
|
|
|
|
os.environ.update(original_environ)
|
|
|
|
|
|
|
|
finally:
|
|
|
|
if os.path.isdir(tempdir):
|
|
|
|
shutil.rmtree(tempdir)
|
2012-09-07 17:04:14 +00:00
|
|
|
|
2013-07-06 11:48:13 +00:00
|
|
|
def test_issue_5970_minion_confd_inclusion(self):
|
|
|
|
try:
|
2013-08-27 15:31:58 +00:00
|
|
|
tempdir = tempfile.mkdtemp(dir=integration.SYS_TMP_DIR)
|
2013-07-06 11:48:13 +00:00
|
|
|
minion_config = os.path.join(tempdir, 'minion')
|
|
|
|
minion_confd = os.path.join(tempdir, 'minion.d')
|
|
|
|
os.makedirs(minion_confd)
|
|
|
|
|
|
|
|
# Let's populate a minion configuration file with some basic
|
|
|
|
# settings
|
|
|
|
salt.utils.fopen(minion_config, 'w').write(
|
|
|
|
'blah: false\n'
|
|
|
|
'root_dir: {0}\n'
|
|
|
|
'log_file: {1}\n'.format(tempdir, minion_config)
|
|
|
|
)
|
|
|
|
|
|
|
|
# Now, let's populate an extra configuration file under minion.d
|
2015-01-07 00:55:28 +00:00
|
|
|
# Notice that above we've set blah as False and below as True.
|
2013-07-06 11:48:13 +00:00
|
|
|
# Since the minion.d files are loaded after the main configuration
|
|
|
|
# file so overrides can happen, the final value of blah should be
|
|
|
|
# True.
|
|
|
|
extra_config = os.path.join(minion_confd, 'extra.conf')
|
|
|
|
salt.utils.fopen(extra_config, 'w').write(
|
|
|
|
'blah: true\n'
|
|
|
|
)
|
|
|
|
|
|
|
|
# Let's load the configuration
|
|
|
|
config = sconfig.minion_config(minion_config)
|
|
|
|
|
|
|
|
self.assertEqual(config['log_file'], minion_config)
|
|
|
|
# As proven by the assertion below, blah is True
|
|
|
|
self.assertTrue(config['blah'])
|
|
|
|
finally:
|
|
|
|
if os.path.isdir(tempdir):
|
|
|
|
shutil.rmtree(tempdir)
|
|
|
|
|
|
|
|
def test_master_confd_inclusion(self):
|
|
|
|
try:
|
2013-08-27 15:31:58 +00:00
|
|
|
tempdir = tempfile.mkdtemp(dir=integration.SYS_TMP_DIR)
|
2013-07-06 11:48:13 +00:00
|
|
|
master_config = os.path.join(tempdir, 'master')
|
|
|
|
master_confd = os.path.join(tempdir, 'master.d')
|
|
|
|
os.makedirs(master_confd)
|
|
|
|
|
|
|
|
# Let's populate a master configuration file with some basic
|
|
|
|
# settings
|
|
|
|
salt.utils.fopen(master_config, 'w').write(
|
|
|
|
'blah: false\n'
|
|
|
|
'root_dir: {0}\n'
|
|
|
|
'log_file: {1}\n'.format(tempdir, master_config)
|
|
|
|
)
|
|
|
|
|
|
|
|
# Now, let's populate an extra configuration file under master.d
|
2015-01-07 00:55:28 +00:00
|
|
|
# Notice that above we've set blah as False and below as True.
|
2013-07-06 11:48:13 +00:00
|
|
|
# Since the master.d files are loaded after the main configuration
|
|
|
|
# file so overrides can happen, the final value of blah should be
|
|
|
|
# True.
|
|
|
|
extra_config = os.path.join(master_confd, 'extra.conf')
|
|
|
|
salt.utils.fopen(extra_config, 'w').write(
|
|
|
|
'blah: true\n'
|
|
|
|
)
|
|
|
|
|
|
|
|
# Let's load the configuration
|
|
|
|
config = sconfig.master_config(master_config)
|
|
|
|
|
|
|
|
self.assertEqual(config['log_file'], master_config)
|
|
|
|
# As proven by the assertion below, blah is True
|
|
|
|
self.assertTrue(config['blah'])
|
|
|
|
finally:
|
|
|
|
if os.path.isdir(tempdir):
|
|
|
|
shutil.rmtree(tempdir)
|
|
|
|
|
2013-07-17 15:43:18 +00:00
|
|
|
def test_syndic_config(self):
|
2014-06-02 00:12:46 +00:00
|
|
|
syndic_conf_path = self.get_config_file_path('syndic')
|
|
|
|
minion_conf_path = self.get_config_file_path('minion')
|
2013-07-17 15:43:18 +00:00
|
|
|
syndic_opts = sconfig.syndic_config(
|
2014-06-02 00:12:46 +00:00
|
|
|
syndic_conf_path, minion_conf_path
|
2013-07-17 15:43:18 +00:00
|
|
|
)
|
|
|
|
syndic_opts.update(salt.minion.resolve_dns(syndic_opts))
|
2014-06-02 00:12:46 +00:00
|
|
|
root_dir = syndic_opts['root_dir']
|
2013-07-17 15:43:18 +00:00
|
|
|
# id & pki dir are shared & so configured on the minion side
|
2013-10-24 09:39:04 +00:00
|
|
|
self.assertEqual(syndic_opts['id'], 'minion')
|
2014-06-02 00:12:46 +00:00
|
|
|
self.assertEqual(syndic_opts['pki_dir'], os.path.join(root_dir, 'pki'))
|
2013-07-17 15:43:18 +00:00
|
|
|
# the rest is configured master side
|
2013-10-24 09:39:04 +00:00
|
|
|
self.assertEqual(syndic_opts['master_uri'], 'tcp://127.0.0.1:54506')
|
|
|
|
self.assertEqual(syndic_opts['master_port'], 54506)
|
|
|
|
self.assertEqual(syndic_opts['master_ip'], '127.0.0.1')
|
|
|
|
self.assertEqual(syndic_opts['master'], 'localhost')
|
2014-06-02 00:12:46 +00:00
|
|
|
self.assertEqual(syndic_opts['sock_dir'], os.path.join(root_dir, 'minion_sock'))
|
2015-03-18 21:17:39 +00:00
|
|
|
self.assertEqual(syndic_opts['cachedir'], os.path.join(root_dir, 'cache'))
|
2015-05-05 14:20:41 +00:00
|
|
|
self.assertEqual(syndic_opts['log_file'], os.path.join(root_dir, 'var/log/salt/syndic'))
|
|
|
|
self.assertEqual(syndic_opts['pidfile'], os.path.join(root_dir, 'var/run/salt-syndic.pid'))
|
2013-07-17 15:43:18 +00:00
|
|
|
# Show that the options of localclient that repub to local master
|
|
|
|
# are not merged with syndic ones
|
2014-06-02 00:12:46 +00:00
|
|
|
self.assertEqual(syndic_opts['_master_conf_file'], minion_conf_path)
|
2013-10-24 09:39:04 +00:00
|
|
|
self.assertEqual(syndic_opts['_minion_conf_file'], syndic_conf_path)
|
2013-07-17 15:43:18 +00:00
|
|
|
|
2013-10-15 21:54:15 +00:00
|
|
|
def test_issue_6714_parsing_errors_logged(self):
|
|
|
|
try:
|
|
|
|
tempdir = tempfile.mkdtemp(dir=integration.SYS_TMP_DIR)
|
|
|
|
test_config = os.path.join(tempdir, 'config')
|
|
|
|
|
|
|
|
# Let's populate a master configuration file with some basic
|
|
|
|
# settings
|
|
|
|
salt.utils.fopen(test_config, 'w').write(
|
|
|
|
'root_dir: {0}\n'
|
|
|
|
'log_file: {0}/foo.log\n'.format(tempdir) +
|
|
|
|
'\n\n\n'
|
|
|
|
'blah:false\n'
|
|
|
|
)
|
|
|
|
|
|
|
|
with TestsLoggingHandler() as handler:
|
|
|
|
# Let's load the configuration
|
|
|
|
config = sconfig.master_config(test_config)
|
|
|
|
for message in handler.messages:
|
|
|
|
if message.startswith('ERROR:Error parsing configuration'):
|
|
|
|
break
|
|
|
|
else:
|
|
|
|
raise AssertionError(
|
|
|
|
'No parsing error message was logged'
|
|
|
|
)
|
|
|
|
finally:
|
|
|
|
if os.path.isdir(tempdir):
|
|
|
|
shutil.rmtree(tempdir)
|
|
|
|
|
2014-03-20 21:37:23 +00:00
|
|
|
@patch('salt.utils.network.get_fqhostname', MagicMock(return_value='localhost'))
|
2014-02-25 08:27:35 +00:00
|
|
|
def test_get_id_etc_hostname(self):
|
|
|
|
'''
|
|
|
|
Test calling salt.config.get_id() and falling back to looking at
|
|
|
|
/etc/hostname.
|
|
|
|
'''
|
|
|
|
with patch('salt.utils.fopen', _fopen_side_effect_etc_hostname):
|
|
|
|
self.assertEqual(
|
2014-07-14 19:46:45 +00:00
|
|
|
sconfig.get_id({'root_dir': None, 'minion_id_caching': False}), (MOCK_HOSTNAME, False)
|
2014-02-25 08:27:35 +00:00
|
|
|
)
|
|
|
|
|
2014-03-20 21:37:23 +00:00
|
|
|
@patch('salt.utils.network.get_fqhostname', MagicMock(return_value='localhost'))
|
2014-02-25 05:46:00 +00:00
|
|
|
def test_get_id_etc_hosts(self):
|
|
|
|
'''
|
|
|
|
Test calling salt.config.get_id() and falling back all the way to
|
|
|
|
looking up data from /etc/hosts.
|
|
|
|
'''
|
2014-02-25 07:17:04 +00:00
|
|
|
with patch('salt.utils.fopen', _fopen_side_effect_etc_hosts):
|
2014-02-25 05:46:00 +00:00
|
|
|
self.assertEqual(
|
2014-07-14 19:46:45 +00:00
|
|
|
sconfig.get_id({'root_dir': None, 'minion_id_caching': False}), (MOCK_HOSTNAME, False)
|
2014-02-25 05:46:00 +00:00
|
|
|
)
|
|
|
|
|
2014-06-20 21:47:00 +00:00
|
|
|
# <---- Salt Cloud Configuration Tests ---------------------------------------------
|
|
|
|
|
|
|
|
# cloud_config tests
|
|
|
|
|
2014-06-19 22:03:59 +00:00
|
|
|
@patch('salt.config.load_config', MagicMock(return_value={}))
|
|
|
|
def test_cloud_config_double_master_path(self):
|
|
|
|
'''
|
|
|
|
Tests passing in master_config_path and master_config kwargs.
|
|
|
|
'''
|
|
|
|
self.assertRaises(SaltCloudConfigError, sconfig.cloud_config, PATH,
|
|
|
|
master_config_path='foo', master_config='bar')
|
|
|
|
|
|
|
|
@patch('salt.config.load_config', MagicMock(return_value={}))
|
|
|
|
def test_cloud_config_double_providers_path(self):
|
|
|
|
'''
|
|
|
|
Tests passing in providers_config_path and providers_config kwargs.
|
|
|
|
'''
|
|
|
|
self.assertRaises(SaltCloudConfigError, sconfig.cloud_config, PATH,
|
|
|
|
providers_config_path='foo', providers_config='bar')
|
|
|
|
|
|
|
|
@patch('salt.config.load_config', MagicMock(return_value={}))
|
|
|
|
def test_cloud_config_double_profiles_path(self):
|
|
|
|
'''
|
|
|
|
Tests passing in profiles_config_path and profiles_config kwargs.
|
|
|
|
'''
|
|
|
|
self.assertRaises(SaltCloudConfigError, sconfig.cloud_config, PATH,
|
|
|
|
profiles_config_path='foo', profiles_config='bar')
|
|
|
|
|
|
|
|
@patch('salt.config.load_config', MagicMock(return_value={}))
|
2014-06-20 21:29:18 +00:00
|
|
|
@patch('salt.config.apply_cloud_config',
|
|
|
|
MagicMock(return_value={'providers': 'foo'}))
|
2014-06-19 22:03:59 +00:00
|
|
|
def test_cloud_config_providers_in_opts(self):
|
|
|
|
'''
|
|
|
|
Tests mixing old cloud providers with pre-configured providers configurations
|
|
|
|
using the providers_config kwarg
|
|
|
|
'''
|
|
|
|
self.assertRaises(SaltCloudConfigError, sconfig.cloud_config, PATH,
|
|
|
|
providers_config='bar')
|
|
|
|
|
|
|
|
@patch('salt.config.load_config', MagicMock(return_value={}))
|
2014-06-20 21:29:18 +00:00
|
|
|
@patch('salt.config.apply_cloud_config',
|
|
|
|
MagicMock(return_value={'providers': 'foo'}))
|
2014-06-19 22:03:59 +00:00
|
|
|
@patch('os.path.isfile', MagicMock(return_value=True))
|
|
|
|
def test_cloud_config_providers_in_opts_path(self):
|
|
|
|
'''
|
|
|
|
Tests mixing old cloud providers with pre-configured providers configurations
|
|
|
|
using the providers_config_path kwarg
|
|
|
|
'''
|
|
|
|
self.assertRaises(SaltCloudConfigError, sconfig.cloud_config, PATH,
|
|
|
|
providers_config_path='bar')
|
|
|
|
|
2014-06-24 16:59:46 +00:00
|
|
|
# apply_cloud_config tests
|
|
|
|
|
|
|
|
def test_apply_cloud_config_no_provider_detail_list(self):
|
|
|
|
'''
|
|
|
|
Tests when the provider is not contained in a list of details
|
|
|
|
'''
|
|
|
|
overrides = {'providers': {'foo': [{'bar': 'baz'}]}}
|
|
|
|
self.assertRaises(SaltCloudConfigError, sconfig.apply_cloud_config,
|
|
|
|
overrides, defaults=DEFAULT)
|
|
|
|
|
|
|
|
def test_apply_cloud_config_no_provider_detail_dict(self):
|
|
|
|
'''
|
|
|
|
Tests when the provider is not contained in the details dictionary
|
|
|
|
'''
|
|
|
|
overrides = {'providers': {'foo': {'bar': 'baz'}}}
|
|
|
|
self.assertRaises(SaltCloudConfigError, sconfig.apply_cloud_config,
|
|
|
|
overrides, defaults=DEFAULT)
|
|
|
|
|
|
|
|
@patch('salt.config.old_to_new',
|
|
|
|
MagicMock(return_value={'default_include': 'path/to/some/cloud/conf/file',
|
|
|
|
'providers': {'foo': {'bar': {
|
|
|
|
'provider': 'foo:bar'}}}}))
|
|
|
|
def test_apply_cloud_config_success_list(self):
|
|
|
|
'''
|
|
|
|
Tests success when valid data is passed into the function as a list
|
|
|
|
'''
|
|
|
|
overrides = {'providers': {'foo': [{'provider': 'bar'}]}}
|
|
|
|
ret = {'default_include': 'path/to/some/cloud/conf/file',
|
|
|
|
'providers': {'foo': {'bar': {'provider': 'foo:bar'}}}}
|
|
|
|
self.assertEqual(sconfig.apply_cloud_config(overrides, defaults=DEFAULT), ret)
|
|
|
|
|
|
|
|
@patch('salt.config.old_to_new',
|
|
|
|
MagicMock(return_value={'default_include': 'path/to/some/cloud/conf/file',
|
|
|
|
'providers': {'foo': {'bar': {
|
|
|
|
'provider': 'foo:bar'}}}}))
|
|
|
|
def test_apply_cloud_config_success_dict(self):
|
|
|
|
'''
|
|
|
|
Tests success when valid data is passed into function as a dictionary
|
|
|
|
'''
|
|
|
|
overrides = {'providers': {'foo': {'provider': 'bar'}}}
|
|
|
|
ret = {'default_include': 'path/to/some/cloud/conf/file',
|
|
|
|
'providers': {'foo': {'bar': {'provider': 'foo:bar'}}}}
|
|
|
|
self.assertEqual(sconfig.apply_cloud_config(overrides, defaults=DEFAULT), ret)
|
|
|
|
|
2014-06-23 18:17:26 +00:00
|
|
|
# apply_vm_profiles_config tests
|
|
|
|
|
|
|
|
def test_apply_vm_profiles_config_bad_profile_format(self):
|
|
|
|
'''
|
|
|
|
Tests passing in a bad profile format in overrides
|
|
|
|
'''
|
|
|
|
overrides = {'foo': 'bar', 'conf_file': PATH}
|
|
|
|
self.assertRaises(SaltCloudConfigError, sconfig.apply_vm_profiles_config,
|
|
|
|
PATH, overrides, defaults=DEFAULT)
|
|
|
|
|
2014-06-23 21:19:11 +00:00
|
|
|
def test_apply_vm_profiles_config_success(self):
|
|
|
|
'''
|
|
|
|
Tests passing in valid provider and profile config files successfully
|
|
|
|
'''
|
|
|
|
providers = {'test-provider':
|
|
|
|
{'digital_ocean':
|
|
|
|
{'provider': 'digital_ocean', 'profiles': {}}}}
|
|
|
|
overrides = {'test-profile':
|
|
|
|
{'provider': 'test-provider',
|
|
|
|
'image': 'Ubuntu 12.10 x64',
|
|
|
|
'size': '512MB'},
|
|
|
|
'conf_file': PATH}
|
|
|
|
ret = {'test-profile':
|
|
|
|
{'profile': 'test-profile',
|
|
|
|
'provider': 'test-provider:digital_ocean',
|
|
|
|
'image': 'Ubuntu 12.10 x64',
|
|
|
|
'size': '512MB'}}
|
|
|
|
self.assertEqual(sconfig.apply_vm_profiles_config(providers,
|
|
|
|
overrides,
|
|
|
|
defaults=DEFAULT), ret)
|
|
|
|
|
|
|
|
def test_apply_vm_profiles_config_extend_success(self):
|
|
|
|
'''
|
|
|
|
Tests profile extends functionality with valid provider and profile configs
|
|
|
|
'''
|
|
|
|
providers = {'test-config': {'ec2': {'profiles': {}, 'provider': 'ec2'}}}
|
|
|
|
overrides = {'Amazon': {'image': 'test-image-1',
|
|
|
|
'extends': 'dev-instances'},
|
|
|
|
'Fedora': {'image': 'test-image-2',
|
|
|
|
'extends': 'dev-instances'},
|
|
|
|
'conf_file': PATH,
|
|
|
|
'dev-instances': {'ssh_username': 'test_user',
|
|
|
|
'provider': 'test-config'}}
|
|
|
|
ret = {'Amazon': {'profile': 'Amazon',
|
|
|
|
'ssh_username': 'test_user',
|
|
|
|
'image': 'test-image-1',
|
|
|
|
'provider': 'test-config:ec2'},
|
|
|
|
'Fedora': {'profile': 'Fedora',
|
|
|
|
'ssh_username': 'test_user',
|
|
|
|
'image': 'test-image-2',
|
|
|
|
'provider': 'test-config:ec2'},
|
|
|
|
'dev-instances': {'profile': 'dev-instances',
|
|
|
|
'ssh_username': 'test_user',
|
|
|
|
'provider': 'test-config:ec2'}}
|
|
|
|
self.assertEqual(sconfig.apply_vm_profiles_config(providers,
|
|
|
|
overrides,
|
|
|
|
defaults=DEFAULT), ret)
|
|
|
|
|
2014-06-20 21:47:00 +00:00
|
|
|
# apply_cloud_providers_config tests
|
2014-06-19 15:20:38 +00:00
|
|
|
|
2014-06-18 23:15:15 +00:00
|
|
|
def test_apply_cloud_providers_config_same_providers(self):
|
|
|
|
'''
|
|
|
|
Tests when two providers are given with the same provider name
|
|
|
|
'''
|
|
|
|
overrides = {'my-dev-envs':
|
|
|
|
[{'id': 'ABCDEFGHIJKLMNOP',
|
|
|
|
'key': 'supersecretkeysupersecretkey',
|
|
|
|
'provider': 'ec2'},
|
|
|
|
{'apikey': 'abcdefghijklmnopqrstuvwxyz',
|
|
|
|
'password': 'supersecret',
|
|
|
|
'provider': 'ec2'}],
|
|
|
|
'conf_file': PATH}
|
|
|
|
self.assertRaises(SaltCloudConfigError,
|
|
|
|
sconfig.apply_cloud_providers_config,
|
|
|
|
overrides,
|
|
|
|
DEFAULT)
|
|
|
|
|
|
|
|
def test_apply_cloud_providers_config_extend(self):
|
|
|
|
'''
|
|
|
|
Tests the successful extension of a cloud provider
|
|
|
|
'''
|
|
|
|
overrides = {'my-production-envs':
|
|
|
|
[{'extends': 'my-dev-envs:ec2',
|
|
|
|
'location': 'us-east-1',
|
|
|
|
'user': 'ec2-user@mycorp.com'
|
|
|
|
}],
|
|
|
|
'my-dev-envs':
|
|
|
|
[{'id': 'ABCDEFGHIJKLMNOP',
|
|
|
|
'user': 'user@mycorp.com',
|
|
|
|
'location': 'ap-southeast-1',
|
|
|
|
'key': 'supersecretkeysupersecretkey',
|
|
|
|
'provider': 'ec2'
|
|
|
|
},
|
|
|
|
{'apikey': 'abcdefghijklmnopqrstuvwxyz',
|
|
|
|
'password': 'supersecret',
|
|
|
|
'provider': 'linode'
|
|
|
|
}],
|
|
|
|
'conf_file': PATH}
|
2014-06-17 21:12:23 +00:00
|
|
|
ret = {'my-production-envs':
|
|
|
|
{'ec2':
|
2014-06-18 23:15:15 +00:00
|
|
|
{'profiles': {},
|
2014-06-17 21:12:23 +00:00
|
|
|
'location': 'us-east-1',
|
|
|
|
'key': 'supersecretkeysupersecretkey',
|
|
|
|
'provider': 'ec2',
|
|
|
|
'id': 'ABCDEFGHIJKLMNOP',
|
2014-06-18 23:15:15 +00:00
|
|
|
'user': 'ec2-user@mycorp.com'}},
|
2014-06-17 21:12:23 +00:00
|
|
|
'my-dev-envs':
|
|
|
|
{'linode':
|
|
|
|
{'apikey': 'abcdefghijklmnopqrstuvwxyz',
|
|
|
|
'password': 'supersecret',
|
|
|
|
'profiles': {},
|
2014-06-18 23:15:15 +00:00
|
|
|
'provider': 'linode'},
|
2014-06-17 21:12:23 +00:00
|
|
|
'ec2':
|
2014-06-18 23:15:15 +00:00
|
|
|
{'profiles': {},
|
2014-06-17 21:12:23 +00:00
|
|
|
'location': 'ap-southeast-1',
|
|
|
|
'key': 'supersecretkeysupersecretkey',
|
|
|
|
'provider': 'ec2',
|
|
|
|
'id': 'ABCDEFGHIJKLMNOP',
|
2014-06-18 23:15:15 +00:00
|
|
|
'user': 'user@mycorp.com'}}}
|
2014-06-20 21:29:18 +00:00
|
|
|
self.assertEqual(ret,
|
|
|
|
sconfig.apply_cloud_providers_config(
|
|
|
|
overrides,
|
|
|
|
defaults=DEFAULT))
|
2014-06-17 21:12:23 +00:00
|
|
|
|
2014-06-18 23:15:15 +00:00
|
|
|
def test_apply_cloud_providers_config_extend_multiple(self):
|
|
|
|
'''
|
|
|
|
Tests the successful extension of two cloud providers
|
|
|
|
'''
|
|
|
|
overrides = {'my-production-envs':
|
|
|
|
[{'extends': 'my-dev-envs:ec2',
|
|
|
|
'location': 'us-east-1',
|
|
|
|
'user': 'ec2-user@mycorp.com'},
|
|
|
|
{'password': 'new-password',
|
|
|
|
'extends': 'my-dev-envs:linode',
|
|
|
|
'location': 'Salt Lake City'
|
|
|
|
}],
|
|
|
|
'my-dev-envs':
|
|
|
|
[{'id': 'ABCDEFGHIJKLMNOP',
|
|
|
|
'user': 'user@mycorp.com',
|
|
|
|
'location': 'ap-southeast-1',
|
|
|
|
'key': 'supersecretkeysupersecretkey',
|
|
|
|
'provider': 'ec2'},
|
|
|
|
{'apikey': 'abcdefghijklmnopqrstuvwxyz',
|
|
|
|
'password': 'supersecret',
|
|
|
|
'provider': 'linode'}],
|
|
|
|
'conf_file': PATH}
|
|
|
|
ret = {'my-production-envs':
|
|
|
|
{'linode':
|
|
|
|
{'apikey': 'abcdefghijklmnopqrstuvwxyz',
|
|
|
|
'profiles': {},
|
|
|
|
'location': 'Salt Lake City',
|
|
|
|
'provider': 'linode',
|
|
|
|
'password': 'new-password'},
|
|
|
|
'ec2':
|
|
|
|
{'user': 'ec2-user@mycorp.com',
|
|
|
|
'key': 'supersecretkeysupersecretkey',
|
|
|
|
'provider': 'ec2',
|
|
|
|
'id': 'ABCDEFGHIJKLMNOP',
|
|
|
|
'profiles': {},
|
|
|
|
'location': 'us-east-1'}},
|
|
|
|
'my-dev-envs':
|
|
|
|
{'linode':
|
|
|
|
{'apikey': 'abcdefghijklmnopqrstuvwxyz',
|
|
|
|
'password': 'supersecret',
|
|
|
|
'profiles': {},
|
|
|
|
'provider': 'linode'},
|
|
|
|
'ec2':
|
|
|
|
{'profiles': {},
|
|
|
|
'user': 'user@mycorp.com',
|
|
|
|
'key': 'supersecretkeysupersecretkey',
|
|
|
|
'provider': 'ec2',
|
|
|
|
'id': 'ABCDEFGHIJKLMNOP',
|
|
|
|
'location': 'ap-southeast-1'}}}
|
|
|
|
self.assertEqual(ret, sconfig.apply_cloud_providers_config(
|
|
|
|
overrides,
|
|
|
|
defaults=DEFAULT))
|
|
|
|
|
|
|
|
def test_apply_cloud_providers_config_extends_bad_alias(self):
|
|
|
|
'''
|
|
|
|
Tests when the extension contains an alias not found in providers list
|
|
|
|
'''
|
|
|
|
overrides = {'my-production-envs':
|
|
|
|
[{'extends': 'test-alias:ec2',
|
|
|
|
'location': 'us-east-1',
|
|
|
|
'user': 'ec2-user@mycorp.com'}],
|
|
|
|
'my-dev-envs':
|
|
|
|
[{'id': 'ABCDEFGHIJKLMNOP',
|
|
|
|
'user': 'user@mycorp.com',
|
|
|
|
'location': 'ap-southeast-1',
|
|
|
|
'key': 'supersecretkeysupersecretkey',
|
|
|
|
'provider': 'ec2'}],
|
|
|
|
'conf_file': PATH}
|
|
|
|
self.assertRaises(SaltCloudConfigError,
|
|
|
|
sconfig.apply_cloud_providers_config,
|
|
|
|
overrides,
|
|
|
|
DEFAULT)
|
|
|
|
|
|
|
|
def test_apply_cloud_providers_config_extends_bad_provider(self):
|
|
|
|
'''
|
|
|
|
Tests when the extension contains a provider not found in providers list
|
|
|
|
'''
|
|
|
|
overrides = {'my-production-envs':
|
|
|
|
[{'extends': 'my-dev-envs:linode',
|
|
|
|
'location': 'us-east-1',
|
|
|
|
'user': 'ec2-user@mycorp.com'}],
|
|
|
|
'my-dev-envs':
|
|
|
|
[{'id': 'ABCDEFGHIJKLMNOP',
|
|
|
|
'user': 'user@mycorp.com',
|
|
|
|
'location': 'ap-southeast-1',
|
|
|
|
'key': 'supersecretkeysupersecretkey',
|
|
|
|
'provider': 'ec2'}],
|
|
|
|
'conf_file': PATH}
|
|
|
|
self.assertRaises(SaltCloudConfigError,
|
|
|
|
sconfig.apply_cloud_providers_config,
|
|
|
|
overrides,
|
|
|
|
DEFAULT)
|
|
|
|
|
|
|
|
def test_apply_cloud_providers_config_extends_no_provider(self):
|
2014-06-19 15:20:38 +00:00
|
|
|
'''
|
|
|
|
Tests when no provider is supplied in the extends statement
|
|
|
|
'''
|
2014-06-18 23:15:15 +00:00
|
|
|
overrides = {'my-production-envs':
|
|
|
|
[{'extends': 'my-dev-envs',
|
|
|
|
'location': 'us-east-1',
|
|
|
|
'user': 'ec2-user@mycorp.com'}],
|
|
|
|
'my-dev-envs':
|
|
|
|
[{'id': 'ABCDEFGHIJKLMNOP',
|
|
|
|
'user': 'user@mycorp.com',
|
|
|
|
'location': 'ap-southeast-1',
|
|
|
|
'key': 'supersecretkeysupersecretkey',
|
|
|
|
'provider': 'linode'}],
|
|
|
|
'conf_file': PATH}
|
|
|
|
self.assertRaises(SaltCloudConfigError,
|
|
|
|
sconfig.apply_cloud_providers_config,
|
|
|
|
overrides,
|
|
|
|
DEFAULT)
|
|
|
|
|
|
|
|
def test_apply_cloud_providers_extends_not_in_providers(self):
|
|
|
|
'''
|
|
|
|
Tests when extends is not in the list of providers
|
|
|
|
'''
|
|
|
|
overrides = {'my-production-envs':
|
|
|
|
[{'extends': 'my-dev-envs ec2',
|
|
|
|
'location': 'us-east-1',
|
|
|
|
'user': 'ec2-user@mycorp.com'}],
|
|
|
|
'my-dev-envs':
|
|
|
|
[{'id': 'ABCDEFGHIJKLMNOP',
|
|
|
|
'user': 'user@mycorp.com',
|
|
|
|
'location': 'ap-southeast-1',
|
|
|
|
'key': 'supersecretkeysupersecretkey',
|
|
|
|
'provider': 'linode'}],
|
|
|
|
'conf_file': PATH}
|
|
|
|
self.assertRaises(SaltCloudConfigError,
|
|
|
|
sconfig.apply_cloud_providers_config,
|
|
|
|
overrides,
|
|
|
|
DEFAULT)
|
Reverted back the `--key-logfile` deprecation.
On the parsers cleanup branch, I though about making the available options as equal as possible. Since the log_file setting for the master and the minion could be separately set, I made the logfile option for the key also log_file. Yet, since there's no key specific config file, it shares master, one could only specify the log_file settings from the cli, it could not be hardcoded on the config file, unless, we made a separate config file just for key.
So, in order to reduce required changes, and keep it all as backwards compatible as possible, the key log file options is now, once again, `--key-logfile` which will allow us to hardcode it in the masters config file as `key_logfile`.
This will also, hopefully make travis behave better too.
2012-08-08 00:08:38 +00:00
|
|
|
|
2014-06-20 21:47:00 +00:00
|
|
|
# is_provider_configured tests
|
|
|
|
|
2014-06-20 21:29:18 +00:00
|
|
|
def test_is_provider_configured_no_alias(self):
|
|
|
|
'''
|
|
|
|
Tests when provider alias is not in opts
|
|
|
|
'''
|
|
|
|
opts = {'providers': 'test'}
|
|
|
|
provider = 'foo:bar'
|
|
|
|
self.assertFalse(sconfig.is_provider_configured(opts, provider))
|
|
|
|
|
|
|
|
def test_is_provider_configured_no_driver(self):
|
|
|
|
'''
|
|
|
|
Tests when provider driver is not in opts
|
|
|
|
'''
|
|
|
|
opts = {'providers': {'foo': 'baz'}}
|
|
|
|
provider = 'foo:bar'
|
|
|
|
self.assertFalse(sconfig.is_provider_configured(opts, provider))
|
|
|
|
|
|
|
|
def test_is_provider_configured_key_is_none(self):
|
|
|
|
'''
|
|
|
|
Tests when a required configuration key is not set
|
|
|
|
'''
|
|
|
|
opts = {'providers': {'foo': {'bar': {'api_key': None}}}}
|
|
|
|
provider = 'foo:bar'
|
|
|
|
self.assertFalse(
|
|
|
|
sconfig.is_provider_configured(opts,
|
|
|
|
provider,
|
|
|
|
required_keys=('api_key',)))
|
|
|
|
|
|
|
|
def test_is_provider_configured_success(self):
|
|
|
|
'''
|
|
|
|
Tests successful cloud provider configuration
|
|
|
|
'''
|
|
|
|
opts = {'providers': {'foo': {'bar': {'api_key': 'baz'}}}}
|
|
|
|
provider = 'foo:bar'
|
|
|
|
ret = {'api_key': 'baz'}
|
|
|
|
self.assertEqual(
|
|
|
|
sconfig.is_provider_configured(opts,
|
|
|
|
provider,
|
|
|
|
required_keys=('api_key',)), ret)
|
|
|
|
|
|
|
|
def test_is_provider_configured_multiple_driver_not_provider(self):
|
|
|
|
'''
|
|
|
|
Tests when the drive is not the same as the provider when
|
|
|
|
searching through multiple providers
|
|
|
|
'''
|
|
|
|
opts = {'providers': {'foo': {'bar': {'api_key': 'baz'}}}}
|
|
|
|
provider = 'foo'
|
|
|
|
self.assertFalse(sconfig.is_provider_configured(opts, provider))
|
|
|
|
|
|
|
|
def test_is_provider_configured_multiple_key_is_none(self):
|
|
|
|
'''
|
|
|
|
Tests when a required configuration key is not set when
|
|
|
|
searching through multiple providers
|
|
|
|
'''
|
|
|
|
opts = {'providers': {'foo': {'bar': {'api_key': None}}}}
|
|
|
|
provider = 'bar'
|
|
|
|
self.assertFalse(
|
|
|
|
sconfig.is_provider_configured(opts,
|
|
|
|
provider,
|
|
|
|
required_keys=('api_key',)))
|
|
|
|
|
|
|
|
def test_is_provider_configured_multiple_success(self):
|
|
|
|
'''
|
|
|
|
Tests successful cloud provider configuration when searching
|
|
|
|
through multiple providers
|
|
|
|
'''
|
|
|
|
opts = {'providers': {'foo': {'bar': {'api_key': 'baz'}}}}
|
|
|
|
provider = 'bar'
|
|
|
|
ret = {'api_key': 'baz'}
|
|
|
|
self.assertEqual(
|
|
|
|
sconfig.is_provider_configured(opts,
|
|
|
|
provider,
|
|
|
|
required_keys=('api_key',)), ret)
|
|
|
|
|
2014-06-20 21:47:00 +00:00
|
|
|
# other cloud configuration tests
|
|
|
|
|
|
|
|
def test_load_cloud_config_from_environ_var(self):
|
|
|
|
original_environ = os.environ.copy()
|
|
|
|
|
|
|
|
tempdir = tempfile.mkdtemp(dir=integration.SYS_TMP_DIR)
|
|
|
|
try:
|
|
|
|
env_root_dir = os.path.join(tempdir, 'foo', 'env')
|
|
|
|
os.makedirs(env_root_dir)
|
|
|
|
env_fpath = os.path.join(env_root_dir, 'config-env')
|
|
|
|
|
|
|
|
salt.utils.fopen(env_fpath, 'w').write(
|
|
|
|
'root_dir: {0}\n'
|
|
|
|
'log_file: {1}\n'.format(env_root_dir, env_fpath)
|
|
|
|
)
|
|
|
|
|
|
|
|
os.environ['SALT_CLOUD_CONFIG'] = env_fpath
|
|
|
|
# Should load from env variable, not the default configuration file
|
|
|
|
config = sconfig.cloud_config('/etc/salt/cloud')
|
|
|
|
self.assertEqual(config['log_file'], env_fpath)
|
|
|
|
os.environ.clear()
|
|
|
|
os.environ.update(original_environ)
|
|
|
|
|
|
|
|
root_dir = os.path.join(tempdir, 'foo', 'bar')
|
|
|
|
os.makedirs(root_dir)
|
|
|
|
fpath = os.path.join(root_dir, 'config')
|
|
|
|
salt.utils.fopen(fpath, 'w').write(
|
|
|
|
'root_dir: {0}\n'
|
|
|
|
'log_file: {1}\n'.format(root_dir, fpath)
|
|
|
|
)
|
|
|
|
# Let's set the environment variable, yet, since the configuration
|
2014-11-05 21:57:47 +00:00
|
|
|
# file path is not the default one, i.e., the user has passed an
|
2014-06-20 21:47:00 +00:00
|
|
|
# alternative configuration file form the CLI parser, the
|
|
|
|
# environment variable will be ignored.
|
|
|
|
os.environ['SALT_CLOUD_CONFIG'] = env_fpath
|
|
|
|
config = sconfig.cloud_config(fpath)
|
|
|
|
self.assertEqual(config['log_file'], fpath)
|
|
|
|
finally:
|
|
|
|
# Reset the environ
|
|
|
|
os.environ.clear()
|
|
|
|
os.environ.update(original_environ)
|
|
|
|
|
|
|
|
if os.path.isdir(tempdir):
|
|
|
|
shutil.rmtree(tempdir)
|
|
|
|
|
|
|
|
def test_deploy_search_path_as_string(self):
|
|
|
|
temp_conf_dir = os.path.join(integration.TMP, 'issue-8863')
|
|
|
|
config_file_path = os.path.join(temp_conf_dir, 'cloud')
|
|
|
|
deploy_dir_path = os.path.join(temp_conf_dir, 'test-deploy.d')
|
|
|
|
try:
|
|
|
|
for directory in (temp_conf_dir, deploy_dir_path):
|
|
|
|
if not os.path.isdir(directory):
|
|
|
|
os.makedirs(directory)
|
|
|
|
|
|
|
|
default_config = sconfig.cloud_config(config_file_path)
|
|
|
|
default_config['deploy_scripts_search_path'] = deploy_dir_path
|
|
|
|
with salt.utils.fopen(config_file_path, 'w') as cfd:
|
|
|
|
cfd.write(yaml.dump(default_config))
|
|
|
|
|
|
|
|
default_config = sconfig.cloud_config(config_file_path)
|
|
|
|
|
|
|
|
# Our custom deploy scripts path was correctly added to the list
|
|
|
|
self.assertIn(
|
|
|
|
deploy_dir_path,
|
|
|
|
default_config['deploy_scripts_search_path']
|
|
|
|
)
|
|
|
|
|
|
|
|
# And it's even the first occurrence as it should
|
|
|
|
self.assertEqual(
|
|
|
|
deploy_dir_path,
|
|
|
|
default_config['deploy_scripts_search_path'][0]
|
|
|
|
)
|
|
|
|
finally:
|
|
|
|
if os.path.isdir(temp_conf_dir):
|
|
|
|
shutil.rmtree(temp_conf_dir)
|
|
|
|
|
|
|
|
def test_includes_load(self):
|
|
|
|
'''
|
|
|
|
Tests that cloud.{providers,profiles}.d directories are loaded, even if not
|
|
|
|
directly passed in through path
|
|
|
|
'''
|
|
|
|
config = sconfig.cloud_config(self.get_config_file_path('cloud'))
|
|
|
|
self.assertIn('ec2-config', config['providers'])
|
2014-09-10 18:23:34 +00:00
|
|
|
self.assertIn('ec2-test', config['profiles'])
|
2014-06-20 21:47:00 +00:00
|
|
|
|
|
|
|
# <---- Salt Cloud Configuration Tests ---------------------------------------------
|
|
|
|
|
2013-06-24 22:53:59 +00:00
|
|
|
if __name__ == '__main__':
|
|
|
|
from integration import run_tests
|
|
|
|
run_tests(ConfigTestCase, needs_daemon=False)
|