mirror of
https://github.com/saltstack/salt.git
synced 2025-04-17 10:10:20 +00:00
Merge pull request #33710 from rallytime/merge-2016.3
[2016.3] Merge forward from 2015.8 to 2016.3
This commit is contained in:
commit
78966f5f30
7 changed files with 267 additions and 39 deletions
|
@ -790,6 +790,8 @@ def free_slave(**connection_args):
|
|||
salt '*' mysql.free_slave
|
||||
'''
|
||||
slave_db = _connect(**connection_args)
|
||||
if slave_db is None:
|
||||
return ''
|
||||
slave_cur = slave_db.cursor(MySQLdb.cursors.DictCursor)
|
||||
slave_cur.execute('show slave status')
|
||||
slave_status = slave_cur.fetchone()
|
||||
|
@ -802,6 +804,8 @@ def free_slave(**connection_args):
|
|||
# servers here, and only overriding the host option in the connect
|
||||
# function.
|
||||
master_db = _connect(**master)
|
||||
if master_db is None:
|
||||
return ''
|
||||
master_cur = master_db.cursor()
|
||||
master_cur.execute('flush logs')
|
||||
master_db.close()
|
||||
|
@ -1900,6 +1904,8 @@ def processlist(**connection_args):
|
|||
ret = []
|
||||
|
||||
dbc = _connect(**connection_args)
|
||||
if dbc is None:
|
||||
return []
|
||||
cur = dbc.cursor()
|
||||
_execute(cur, 'SHOW FULL PROCESSLIST')
|
||||
hdr = [c[0] for c in cur.description]
|
||||
|
@ -1980,6 +1986,8 @@ def get_master_status(**connection_args):
|
|||
mod = sys._getframe().f_code.co_name
|
||||
log.debug('{0}<--'.format(mod))
|
||||
conn = _connect(**connection_args)
|
||||
if conn is None:
|
||||
return []
|
||||
rtnv = __do_query_into_hash(conn, "SHOW MASTER STATUS")
|
||||
conn.close()
|
||||
|
||||
|
@ -2048,6 +2056,8 @@ def get_slave_status(**connection_args):
|
|||
mod = sys._getframe().f_code.co_name
|
||||
log.debug('{0}<--'.format(mod))
|
||||
conn = _connect(**connection_args)
|
||||
if conn is None:
|
||||
return []
|
||||
rtnv = __do_query_into_hash(conn, "SHOW SLAVE STATUS")
|
||||
conn.close()
|
||||
|
||||
|
@ -2076,6 +2086,8 @@ def showvariables(**connection_args):
|
|||
mod = sys._getframe().f_code.co_name
|
||||
log.debug('{0}<--'.format(mod))
|
||||
conn = _connect(**connection_args)
|
||||
if conn is None:
|
||||
return []
|
||||
rtnv = __do_query_into_hash(conn, "SHOW VARIABLES")
|
||||
conn.close()
|
||||
if len(rtnv) == 0:
|
||||
|
@ -2102,6 +2114,8 @@ def showglobal(**connection_args):
|
|||
mod = sys._getframe().f_code.co_name
|
||||
log.debug('{0}<--'.format(mod))
|
||||
conn = _connect(**connection_args)
|
||||
if conn is None:
|
||||
return []
|
||||
rtnv = __do_query_into_hash(conn, "SHOW GLOBAL VARIABLES")
|
||||
conn.close()
|
||||
if len(rtnv) == 0:
|
||||
|
|
|
@ -770,6 +770,7 @@ def mod_repo(repo, **kwargs):
|
|||
# Modify added or existing repo according to the options
|
||||
cmd_opt = []
|
||||
global_cmd_opt = []
|
||||
call_refresh = False
|
||||
|
||||
if 'enabled' in kwargs:
|
||||
cmd_opt.append(kwargs['enabled'] and '--enable' or '--disable')
|
||||
|
@ -793,13 +794,19 @@ def mod_repo(repo, **kwargs):
|
|||
|
||||
if kwargs.get('gpgautoimport') is True:
|
||||
global_cmd_opt.append('--gpg-auto-import-keys')
|
||||
call_refresh = True
|
||||
|
||||
if cmd_opt:
|
||||
cmd_opt = global_cmd_opt + ['mr'] + cmd_opt + [repo]
|
||||
__zypper__.refreshable.xml.call(*cmd_opt)
|
||||
|
||||
# If repo nor added neither modified, error should be thrown
|
||||
if not added and not cmd_opt:
|
||||
if call_refresh:
|
||||
# when used with "zypper ar --refresh" or "zypper mr --refresh"
|
||||
# --gpg-auto-import-keys is not doing anything
|
||||
# so we need to specifically refresh here with --gpg-auto-import-keys
|
||||
refresh_opts = global_cmd_opt + ['refresh'] + [repo]
|
||||
__zypper__.xml.call(*refresh_opts)
|
||||
elif not added and not cmd_opt:
|
||||
raise CommandExecutionError(
|
||||
'Specified arguments did not result in modification of repo'
|
||||
)
|
||||
|
|
|
@ -49,22 +49,13 @@ if HAS_PIP is True:
|
|||
if 'pip' in sys.modules:
|
||||
del sys.modules['pip']
|
||||
|
||||
ver = pip.__version__.split('.')
|
||||
pip_ver = tuple([int(x) for x in ver if x.isdigit()])
|
||||
if pip_ver >= (8, 0, 0):
|
||||
try:
|
||||
from pip.exceptions import InstallationError
|
||||
else:
|
||||
except ImportError:
|
||||
InstallationError = ValueError
|
||||
|
||||
# pylint: enable=import-error
|
||||
|
||||
ver = pip.__version__.split('.')
|
||||
pip_ver = tuple([int(x) for x in ver if x.isdigit()])
|
||||
if pip_ver >= (8, 0, 0):
|
||||
from pip.exceptions import InstallationError
|
||||
else:
|
||||
InstallationError = ValueError
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Define the module's virtual name
|
||||
|
|
|
@ -572,7 +572,16 @@ class ZeroMQReqServerChannel(salt.transport.mixins.auth.AESReqServerMixin, salt.
|
|||
payload = self.serial.loads(payload[0])
|
||||
payload = self._decode_payload(payload)
|
||||
except Exception as exc:
|
||||
log.error('Bad load from minion: %s: %s', type(exc).__name__, exc)
|
||||
exc_type = type(exc).__name__
|
||||
if exc_type == 'AuthenticationError':
|
||||
log.debug(
|
||||
'Minion failed to auth to master. Since the payload is '
|
||||
'encrypted, it is not known which minion failed to '
|
||||
'authenticate. It is likely that this is a transient '
|
||||
'failure due to the master rotating its public key.'
|
||||
)
|
||||
else:
|
||||
log.error('Bad load from minion: %s: %s', exc_type, exc)
|
||||
stream.send(self.serial.dumps('bad load'))
|
||||
raise tornado.gen.Return()
|
||||
|
||||
|
|
|
@ -145,9 +145,8 @@ class CPModuleTest(integration.ModuleCase):
|
|||
|
||||
def test_get_url(self):
|
||||
'''
|
||||
cp.get_url
|
||||
cp.get_url with salt:// source
|
||||
'''
|
||||
# We should add a 'if the internet works download some files'
|
||||
tgt = os.path.join(integration.TMP, 'scene33')
|
||||
self.run_function(
|
||||
'cp.get_url',
|
||||
|
@ -160,6 +159,24 @@ class CPModuleTest(integration.ModuleCase):
|
|||
self.assertIn('KNIGHT: They\'re nervous, sire.', data)
|
||||
self.assertNotIn('bacon', data)
|
||||
|
||||
def test_get_url_https(self):
|
||||
'''
|
||||
cp.get_url with https:// source
|
||||
'''
|
||||
tgt = os.path.join(integration.TMP, 'test_get_url_https')
|
||||
self.run_function(
|
||||
'cp.get_url',
|
||||
[
|
||||
'https://repo.saltstack.com/index.html',
|
||||
tgt,
|
||||
])
|
||||
with salt.utils.fopen(tgt, 'r') as instructions:
|
||||
data = instructions.read()
|
||||
self.assertIn('Bootstrap', data)
|
||||
self.assertIn('Debian', data)
|
||||
self.assertIn('Windows', data)
|
||||
self.assertNotIn('AYBABTU', data)
|
||||
|
||||
def test_cache_file(self):
|
||||
'''
|
||||
cp.cache_file
|
||||
|
|
|
@ -269,6 +269,17 @@ class MySQLTestCase(TestCase):
|
|||
'''
|
||||
self._test_call(mysql.get_slave_status, 'SHOW SLAVE STATUS')
|
||||
|
||||
def test_get_slave_status_bad_server(self):
|
||||
'''
|
||||
Test get_slave_status in the mysql execution module, simulating a broken server
|
||||
'''
|
||||
connect_mock = MagicMock(return_value=None)
|
||||
mysql._connect = connect_mock
|
||||
with patch.dict(mysql.__salt__, {'config.option': MagicMock()}):
|
||||
rslt = mysql.get_slave_status()
|
||||
connect_mock.assert_has_calls([call()])
|
||||
self.assertEqual(rslt, [])
|
||||
|
||||
@skipIf(True, 'MySQL module claims this function is not ready for production')
|
||||
def test_free_slave(self):
|
||||
pass
|
||||
|
|
|
@ -11,6 +11,7 @@ from salttesting import TestCase, skipIf
|
|||
from salttesting.mock import (
|
||||
Mock,
|
||||
MagicMock,
|
||||
call,
|
||||
patch,
|
||||
NO_MOCK,
|
||||
NO_MOCK_REASON
|
||||
|
@ -55,10 +56,26 @@ zypper.rpm = None
|
|||
|
||||
@skipIf(NO_MOCK, NO_MOCK_REASON)
|
||||
class ZypperTestCase(TestCase):
|
||||
|
||||
'''
|
||||
Test cases for salt.modules.zypper
|
||||
'''
|
||||
|
||||
def setUp(self):
|
||||
self.new_repo_config = dict(
|
||||
name='mock-repo-name',
|
||||
url='http://repo.url/some/path'
|
||||
)
|
||||
side_effect = [
|
||||
Mock(**{'sections.return_value': []}),
|
||||
Mock(**{'sections.return_value': [self.new_repo_config['name']]})
|
||||
]
|
||||
self.zypper_patcher_config = {
|
||||
'_get_configured_repos': Mock(side_effect=side_effect),
|
||||
'__zypper__': Mock(),
|
||||
'get_repo': Mock()
|
||||
}
|
||||
|
||||
def test_list_upgrades(self):
|
||||
'''
|
||||
List package upgrades
|
||||
|
@ -438,37 +455,199 @@ class ZypperTestCase(TestCase):
|
|||
self.assertEqual(r_info['enabled'], alias == 'SLE12-SP1-x86_64-Update')
|
||||
self.assertEqual(r_info['autorefresh'], alias == 'SLE12-SP1-x86_64-Update')
|
||||
|
||||
def test_modify_repo_gpg_auto_import_keys_parameter_position(self):
|
||||
def test_repo_add_nomod_noref(self):
|
||||
'''
|
||||
Tests if when modifying a repo, --gpg-auto-import-keys is a global option
|
||||
Test mod_repo adds the new repo and nothing else
|
||||
|
||||
:return:
|
||||
'''
|
||||
zypper_patcher = patch.multiple(
|
||||
'salt.modules.zypper',
|
||||
**{
|
||||
'_get_configured_repos': Mock(
|
||||
**{
|
||||
'return_value.sections.return_value': ['mock-repo-name']
|
||||
}
|
||||
),
|
||||
'__zypper__': Mock(),
|
||||
'get_repo': Mock()
|
||||
}
|
||||
)
|
||||
'salt.modules.zypper', **self.zypper_patcher_config)
|
||||
|
||||
url = self.new_repo_config['url']
|
||||
name = self.new_repo_config['name']
|
||||
with zypper_patcher:
|
||||
zypper.mod_repo(
|
||||
'mock-repo-name',
|
||||
**{
|
||||
'disabled': False,
|
||||
'url': 'http://repo.url/some/path',
|
||||
'gpgkey': 'http://repo.key',
|
||||
'refresh': True,
|
||||
'gpgautoimport': True
|
||||
}
|
||||
zypper.mod_repo(name, **{'url': url})
|
||||
self.assertEqual(
|
||||
zypper.__zypper__.xml.call.call_args_list,
|
||||
[call('ar', url, name)]
|
||||
)
|
||||
zypper.__zypper__.refreshable.xml.call.assert_not_called()
|
||||
|
||||
def test_repo_noadd_nomod_noref(self):
|
||||
'''
|
||||
Test mod_repo detects the repo already exists,
|
||||
no modification was requested and no refresh requested either
|
||||
|
||||
:return:
|
||||
'''
|
||||
url = self.new_repo_config['url']
|
||||
name = self.new_repo_config['name']
|
||||
self.zypper_patcher_config['_get_configured_repos'] = Mock(
|
||||
**{'return_value.sections.return_value': [name]}
|
||||
)
|
||||
zypper_patcher = patch.multiple(
|
||||
'salt.modules.zypper', **self.zypper_patcher_config)
|
||||
|
||||
with zypper_patcher:
|
||||
with self.assertRaisesRegexp(
|
||||
Exception,
|
||||
'Specified arguments did not result in modification of repo'
|
||||
):
|
||||
zypper.mod_repo(name, **{'url': url})
|
||||
with self.assertRaisesRegexp(
|
||||
Exception,
|
||||
'Specified arguments did not result in modification of repo'
|
||||
):
|
||||
zypper.mod_repo(name, **{'url': url, 'gpgautoimport': 'a'})
|
||||
|
||||
zypper.__zypper__.xml.call.assert_not_called()
|
||||
zypper.__zypper__.refreshable.xml.call.assert_not_called()
|
||||
|
||||
def test_repo_add_mod_noref(self):
|
||||
'''
|
||||
Test mod_repo adds the new repo and call modify to update autorefresh
|
||||
|
||||
:return:
|
||||
'''
|
||||
zypper_patcher = patch.multiple(
|
||||
'salt.modules.zypper', **self.zypper_patcher_config)
|
||||
|
||||
url = self.new_repo_config['url']
|
||||
name = self.new_repo_config['name']
|
||||
with zypper_patcher:
|
||||
zypper.mod_repo(name, **{'url': url, 'refresh': True})
|
||||
self.assertEqual(
|
||||
zypper.__zypper__.xml.call.call_args_list,
|
||||
[call('ar', url, name)]
|
||||
)
|
||||
zypper.__zypper__.refreshable.xml.call.assert_called_once_with(
|
||||
'--gpg-auto-import-keys', 'mr', '--refresh', 'mock-repo-name'
|
||||
'mr', '--refresh', name
|
||||
)
|
||||
|
||||
def test_repo_noadd_mod_noref(self):
|
||||
'''
|
||||
Test mod_repo detects the repository exists,
|
||||
calls modify to update 'autorefresh' but does not call refresh
|
||||
|
||||
:return:
|
||||
'''
|
||||
url = self.new_repo_config['url']
|
||||
name = self.new_repo_config['name']
|
||||
self.zypper_patcher_config['_get_configured_repos'] = Mock(
|
||||
**{'return_value.sections.return_value': [name]})
|
||||
zypper_patcher = patch.multiple(
|
||||
'salt.modules.zypper', **self.zypper_patcher_config)
|
||||
with zypper_patcher:
|
||||
zypper.mod_repo(name, **{'url': url, 'refresh': True})
|
||||
zypper.__zypper__.xml.call.assert_not_called()
|
||||
zypper.__zypper__.refreshable.xml.call.assert_called_once_with(
|
||||
'mr', '--refresh', name
|
||||
)
|
||||
|
||||
def test_repo_add_nomod_ref(self):
|
||||
'''
|
||||
Test mod_repo adds the new repo and refreshes the repo with
|
||||
`zypper --gpg-auto-import-keys refresh <repo-name>`
|
||||
|
||||
:return:
|
||||
'''
|
||||
zypper_patcher = patch.multiple(
|
||||
'salt.modules.zypper', **self.zypper_patcher_config)
|
||||
|
||||
url = self.new_repo_config['url']
|
||||
name = self.new_repo_config['name']
|
||||
with zypper_patcher:
|
||||
zypper.mod_repo(name, **{'url': url, 'gpgautoimport': True})
|
||||
self.assertEqual(
|
||||
zypper.__zypper__.xml.call.call_args_list,
|
||||
[
|
||||
call('ar', url, name),
|
||||
call('--gpg-auto-import-keys', 'refresh', name)
|
||||
]
|
||||
)
|
||||
zypper.__zypper__.refreshable.xml.call.assert_not_called()
|
||||
|
||||
def test_repo_noadd_nomod_ref(self):
|
||||
'''
|
||||
Test mod_repo detects the repo already exists,
|
||||
has nothing to modify and refreshes the repo with
|
||||
`zypper --gpg-auto-import-keys refresh <repo-name>`
|
||||
|
||||
:return:
|
||||
'''
|
||||
url = self.new_repo_config['url']
|
||||
name = self.new_repo_config['name']
|
||||
self.zypper_patcher_config['_get_configured_repos'] = Mock(
|
||||
**{'return_value.sections.return_value': [name]}
|
||||
)
|
||||
zypper_patcher = patch.multiple(
|
||||
'salt.modules.zypper', **self.zypper_patcher_config)
|
||||
|
||||
with zypper_patcher:
|
||||
zypper.mod_repo(name, **{'url': url, 'gpgautoimport': True})
|
||||
self.assertEqual(
|
||||
zypper.__zypper__.xml.call.call_args_list,
|
||||
[call('--gpg-auto-import-keys', 'refresh', name)]
|
||||
)
|
||||
zypper.__zypper__.refreshable.xml.call.assert_not_called()
|
||||
|
||||
def test_repo_add_mod_ref(self):
|
||||
'''
|
||||
Test mod_repo adds the new repo,
|
||||
calls modify to update 'autorefresh' and refreshes the repo with
|
||||
`zypper --gpg-auto-import-keys refresh <repo-name>`
|
||||
|
||||
:return:
|
||||
'''
|
||||
zypper_patcher = patch.multiple(
|
||||
'salt.modules.zypper', **self.zypper_patcher_config)
|
||||
|
||||
url = self.new_repo_config['url']
|
||||
name = self.new_repo_config['name']
|
||||
with zypper_patcher:
|
||||
zypper.mod_repo(
|
||||
name,
|
||||
**{'url': url, 'refresh': True, 'gpgautoimport': True}
|
||||
)
|
||||
self.assertEqual(
|
||||
zypper.__zypper__.xml.call.call_args_list,
|
||||
[
|
||||
call('ar', url, name),
|
||||
call('--gpg-auto-import-keys', 'refresh', name)
|
||||
]
|
||||
)
|
||||
zypper.__zypper__.refreshable.xml.call.assert_called_once_with(
|
||||
'--gpg-auto-import-keys', 'mr', '--refresh', name
|
||||
)
|
||||
|
||||
def test_repo_noadd_mod_ref(self):
|
||||
'''
|
||||
Test mod_repo detects the repo already exists,
|
||||
calls modify to update 'autorefresh' and refreshes the repo with
|
||||
`zypper --gpg-auto-import-keys refresh <repo-name>`
|
||||
|
||||
:return:
|
||||
'''
|
||||
url = self.new_repo_config['url']
|
||||
name = self.new_repo_config['name']
|
||||
self.zypper_patcher_config['_get_configured_repos'] = Mock(
|
||||
**{'return_value.sections.return_value': [name]}
|
||||
)
|
||||
zypper_patcher = patch.multiple(
|
||||
'salt.modules.zypper', **self.zypper_patcher_config)
|
||||
|
||||
with zypper_patcher:
|
||||
zypper.mod_repo(
|
||||
name,
|
||||
**{'url': url, 'refresh': True, 'gpgautoimport': True}
|
||||
)
|
||||
self.assertEqual(
|
||||
zypper.__zypper__.xml.call.call_args_list,
|
||||
[call('--gpg-auto-import-keys', 'refresh', name)]
|
||||
)
|
||||
zypper.__zypper__.refreshable.xml.call.assert_called_once_with(
|
||||
'--gpg-auto-import-keys', 'mr', '--refresh', name
|
||||
)
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
Loading…
Add table
Reference in a new issue