Merge pull request #48711 from rallytime/merge-2018.3

[2018.3] Merge forward from 2017.7 to 2018.3
This commit is contained in:
Nicole Thomas 2018-07-24 13:38:57 -04:00 committed by GitHub
commit e873621009
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
39 changed files with 906 additions and 358 deletions

View file

@ -1,8 +1,13 @@
pipeline {
agent { label 'docs' }
options {
timestamps()
ansiColor('xterm')
}
environment {
PYENV_ROOT = "/usr/local/pyenv"
PATH = "$PYENV_ROOT/bin:$PATH"
PY_COLORS = 1
}
stages {
stage('github-pending') {

View file

@ -1,5 +1,9 @@
pipeline {
agent { label 'kitchen-slave' }
options {
timestamps()
ansiColor('xterm')
}
environment {
SALT_KITCHEN_PLATFORMS = "/var/jenkins/workspace/platforms.yml"
SALT_KITCHEN_DRIVER = "/var/jenkins/workspace/driver.yml"
@ -7,6 +11,7 @@ pipeline {
RBENV_VERSION = "2.4.2"
TEST_SUITE = "py2"
TEST_PLATFORM = "centos-7"
PY_COLORS = 1
}
stages {
stage('github-pending') {

View file

@ -1,5 +1,9 @@
pipeline {
agent { label 'kitchen-slave' }
options {
timestamps()
ansiColor('xterm')
}
environment {
SALT_KITCHEN_PLATFORMS = "/var/jenkins/workspace/platforms.yml"
SALT_KITCHEN_DRIVER = "/var/jenkins/workspace/driver.yml"
@ -7,6 +11,7 @@ pipeline {
RBENV_VERSION = "2.4.2"
TEST_SUITE = "py3"
TEST_PLATFORM = "centos-7"
PY_COLORS = 1
}
stages {
stage('github-pending') {

View file

@ -1,5 +1,9 @@
pipeline {
agent { label 'kitchen-slave' }
options {
timestamps()
ansiColor('xterm')
}
environment {
SALT_KITCHEN_PLATFORMS = "/var/jenkins/workspace/platforms.yml"
SALT_KITCHEN_DRIVER = "/var/jenkins/workspace/driver.yml"
@ -7,6 +11,7 @@ pipeline {
RBENV_VERSION = "2.4.2"
TEST_SUITE = "py2"
TEST_PLATFORM = "ubuntu-1604"
PY_COLORS = 1
}
stages {
stage('github-pending') {

View file

@ -1,5 +1,9 @@
pipeline {
agent { label 'kitchen-slave' }
options {
timestamps()
ansiColor('xterm')
}
environment {
SALT_KITCHEN_PLATFORMS = "/var/jenkins/workspace/platforms.yml"
SALT_KITCHEN_DRIVER = "/var/jenkins/workspace/driver.yml"
@ -7,6 +11,7 @@ pipeline {
RBENV_VERSION = "2.4.2"
TEST_SUITE = "py3"
TEST_PLATFORM = "ubuntu-1604"
PY_COLORS = 1
}
stages {
stage('github-pending') {

View file

@ -1,8 +1,13 @@
pipeline {
agent { label 'pr-lint-slave' }
options {
timestamps()
ansiColor('xterm')
}
environment {
PYENV_ROOT = "/usr/local/pyenv"
PATH = "$PYENV_ROOT/bin:$PATH"
PY_COLORS = 1
}
stages {
stage('github-pending') {

View file

@ -130,20 +130,18 @@ If Defined ProgramFiles(x86) (
)
@echo.
@echo Copying VCRedist to Prerequisites
@echo ----------------------------------------------------------------------
:: Make sure the "prereq" directory exists
If NOT Exist "%PreDir%" mkdir "%PreDir%"
:: Set the location of the vcredist to download
If %Python%==3 (
Set Url64="http://repo.saltstack.com/windows/dependencies/64/vcredist_x64_2015.exe"
Set Url32="http://repo.saltstack.com/windows/dependencies/32/vcredist_x86_2015.exe"
:: Don't include the vcredist for Py3 installations
If %Python%==3 goto :vcredist_end
) Else (
Set Url64="http://repo.saltstack.com/windows/dependencies/64/vcredist_x64_2008_mfc.exe"
Set Url32="http://repo.saltstack.com/windows/dependencies/32/vcredist_x86_2008_mfc.exe"
)
@echo Copying VCRedist to Prerequisites
@echo ----------------------------------------------------------------------
:: Set the location of the vcredist to download
Set Url64="http://repo.saltstack.com/windows/dependencies/64/vcredist_x64_2008_mfc.exe"
Set Url32="http://repo.saltstack.com/windows/dependencies/32/vcredist_x86_2008_mfc.exe"
:: Check for 64 bit by finding the Program Files (x86) directory
If Defined ProgramFiles(x86) (
@ -153,6 +151,8 @@ If Defined ProgramFiles(x86) (
)
@echo.
:vcredist_end
:: Remove the fixed path in .exe files
@echo Removing fixed path from .exe files
@echo ----------------------------------------------------------------------

View file

@ -415,26 +415,13 @@ Section -Prerequisites
Var /Global CheckVcRedist
StrCpy $CheckVcRedist "False"
# Visual C++ 2015 redist packages
!define PY3_VC_REDIST_NAME "VC_Redist_2015"
!define PY3_VC_REDIST_X64_GUID "{50A2BC33-C9CD-3BF1-A8FF-53C10A0B183C}"
!define PY3_VC_REDIST_X86_GUID "{BBF2AC74-720C-3CB3-8291-5E34039232FA}"
# Visual C++ 2008 SP1 MFC Security Update redist packages
!define PY2_VC_REDIST_NAME "VC_Redist_2008_SP1_MFC"
!define PY2_VC_REDIST_X64_GUID "{5FCE6D76-F5DC-37AB-B2B8-22AB8CEDB1D4}"
!define PY2_VC_REDIST_X86_GUID "{9BE518E6-ECC6-35A9-88E4-87755C07200F}"
${If} ${PYTHON_VERSION} == 3
StrCpy $VcRedistName ${PY3_VC_REDIST_NAME}
${If} ${CPUARCH} == "AMD64"
StrCpy $VcRedistGuid ${PY3_VC_REDIST_X64_GUID}
${Else}
StrCpy $VcRedistGuid ${PY3_VC_REDIST_X86_GUID}
${EndIf}
StrCpy $CheckVcRedist "True"
${Else}
# VCRedist only needs to be installed for Python 2
${If} ${PYTHON_VERSION} == 2
StrCpy $VcRedistName ${PY2_VC_REDIST_NAME}
${If} ${CPUARCH} == "AMD64"

View file

@ -167,7 +167,7 @@ def salt_refs(data, ret=None):
return ret
def prep_trans_tar(opts, file_client, chunks, file_refs, pillar=None, id_=None, roster_grains=None):
def prep_trans_tar(file_client, chunks, file_refs, pillar=None, id_=None, roster_grains=None):
'''
Generate the execution package from the saltenv file refs and a low state
data structure

View file

@ -36,6 +36,59 @@ __func_alias__ = {
log = logging.getLogger(__name__)
def _ssh_state(chunks, st_kwargs,
kwargs, test=False):
'''
Function to run a state with the given chunk via salt-ssh
'''
file_refs = salt.client.ssh.state.lowstate_file_refs(
chunks,
_merge_extra_filerefs(
kwargs.get('extra_filerefs', ''),
__opts__.get('extra_filerefs', '')
)
)
# Create the tar containing the state pkg and relevant files.
trans_tar = salt.client.ssh.state.prep_trans_tar(
__context__['fileclient'],
chunks,
file_refs,
__pillar__,
st_kwargs['id_'])
trans_tar_sum = salt.utils.hashutils.get_hash(trans_tar, __opts__['hash_type'])
cmd = 'state.pkg {0}/salt_state.tgz test={1} pkg_sum={2} hash_type={3}'.format(
__opts__['thin_dir'],
test,
trans_tar_sum,
__opts__['hash_type'])
single = salt.client.ssh.Single(
__opts__,
cmd,
fsclient=__context__['fileclient'],
minion_opts=__salt__.minion_opts,
**st_kwargs)
single.shell.send(
trans_tar,
'{0}/salt_state.tgz'.format(__opts__['thin_dir']))
stdout, stderr, _ = single.cmd_block()
# Clean up our tar
try:
os.remove(trans_tar)
except (OSError, IOError):
pass
# Read in the JSON data and return the data structure
try:
return salt.utils.json.loads(stdout, object_hook=salt.utils.data.encode_dict)
except Exception as e:
log.error("JSON Render failed for: %s\n%s", stdout, stderr)
log.error(str(e))
# If for some reason the json load fails, return the stdout
return stdout
def _set_retcode(ret, highstate=None):
'''
Set the return code based on the data back from the state system
@ -165,7 +218,6 @@ def sls(mods, saltenv='base', test=None, exclude=None, **kwargs):
# Create the tar containing the state pkg and relevant files.
_cleanup_slsmod_low_data(chunks)
trans_tar = salt.client.ssh.state.prep_trans_tar(
opts,
__context__['fileclient'],
chunks,
file_refs,
@ -310,7 +362,6 @@ def low(data, **kwargs):
# Create the tar containing the state pkg and relevant files.
trans_tar = salt.client.ssh.state.prep_trans_tar(
__opts__,
__context__['fileclient'],
chunks,
file_refs,
@ -401,7 +452,6 @@ def high(data, **kwargs):
# Create the tar containing the state pkg and relevant files.
_cleanup_slsmod_low_data(chunks)
trans_tar = salt.client.ssh.state.prep_trans_tar(
opts,
__context__['fileclient'],
chunks,
file_refs,
@ -647,7 +697,6 @@ def highstate(test=None, **kwargs):
# Create the tar containing the state pkg and relevant files.
_cleanup_slsmod_low_data(chunks)
trans_tar = salt.client.ssh.state.prep_trans_tar(
opts,
__context__['fileclient'],
chunks,
file_refs,
@ -730,7 +779,6 @@ def top(topfn, test=None, **kwargs):
# Create the tar containing the state pkg and relevant files.
_cleanup_slsmod_low_data(chunks)
trans_tar = salt.client.ssh.state.prep_trans_tar(
opts,
__context__['fileclient'],
chunks,
file_refs,
@ -849,6 +897,7 @@ def sls_id(id_, mods, test=None, queue=False, **kwargs):
salt '*' state.sls_id my_state my_module,a_common_module
'''
st_kwargs = __salt__.kwargs
conflict = _check_queue(queue, kwargs)
if conflict is not None:
return conflict
@ -861,13 +910,11 @@ def sls_id(id_, mods, test=None, queue=False, **kwargs):
if opts['saltenv'] is None:
opts['saltenv'] = 'base'
try:
st_ = salt.state.HighState(opts,
proxy=__proxy__,
initial_pillar=_get_initial_pillar(opts))
except NameError:
st_ = salt.state.HighState(opts,
initial_pillar=_get_initial_pillar(opts))
st_ = salt.client.ssh.state.SSHHighState(
__opts__,
__pillar__,
__salt__,
__context__['fileclient'])
if not _check_pillar(kwargs, st_.opts['pillar']):
__context__['retcode'] = 5
@ -878,10 +925,7 @@ def sls_id(id_, mods, test=None, queue=False, **kwargs):
if isinstance(mods, six.string_types):
split_mods = mods.split(',')
st_.push_active()
try:
high_, errors = st_.render_highstate({opts['saltenv']: split_mods})
finally:
st_.pop_active()
high_, errors = st_.render_highstate({opts['saltenv']: split_mods})
errors += st_.state.verify_high(high_)
# Apply requisites to high data
high_, req_in_errors = st_.state.requisite_in(high_)
@ -893,17 +937,22 @@ def sls_id(id_, mods, test=None, queue=False, **kwargs):
__context__['retcode'] = 1
return errors
chunks = st_.state.compile_high_data(high_)
ret = {}
for chunk in chunks:
if chunk.get('__id__', '') == id_:
ret.update(st_.state.call_chunk(chunk, {}, chunks))
chunk = [x for x in chunks if x.get('__id__', '') == id_]
_set_retcode(ret, highstate=highstate)
if not ret:
if not chunk:
raise SaltInvocationError(
'No matches for ID \'{0}\' found in SLS \'{1}\' within saltenv '
'\'{2}\''.format(id_, mods, opts['saltenv'])
)
ret = _ssh_state(chunk,
st_kwargs,
kwargs,
test=test)
_set_retcode(ret, highstate=highstate)
# Work around Windows multiprocessing bug, set __opts__['test'] back to
# value from before this function was run.
__opts__['test'] = orig_test
return ret
@ -1093,7 +1142,6 @@ def single(fun, name, test=None, **kwargs):
# Create the tar containing the state pkg and relevant files.
trans_tar = salt.client.ssh.state.prep_trans_tar(
opts,
__context__['fileclient'],
chunks,
file_refs,

View file

@ -608,9 +608,17 @@ class AsyncAuth(object):
error = SaltClientError('Detect mode is on')
break
if self.opts.get('caller'):
print('Minion failed to authenticate with the master, '
'has the minion key been accepted?')
sys.exit(2)
# We have a list of masters, so we should break
# and try the next one in the list.
if self.opts.get('local_masters', None):
error = SaltClientError('Minion failed to authenticate'
' with the master, has the '
'minion key been accepted?')
break
else:
print('Minion failed to authenticate with the master, '
'has the minion key been accepted?')
sys.exit(2)
if acceptance_wait_time:
log.info(
'Waiting %s seconds before retry.', acceptance_wait_time

View file

@ -67,10 +67,10 @@ if USE_IMPORTLIB:
SUFFIXES = []
for suffix in importlib.machinery.EXTENSION_SUFFIXES:
SUFFIXES.append((suffix, 'rb', MODULE_KIND_EXTENSION))
for suffix in importlib.machinery.BYTECODE_SUFFIXES:
SUFFIXES.append((suffix, 'rb', MODULE_KIND_COMPILED))
for suffix in importlib.machinery.SOURCE_SUFFIXES:
SUFFIXES.append((suffix, 'rb', MODULE_KIND_SOURCE))
for suffix in importlib.machinery.BYTECODE_SUFFIXES:
SUFFIXES.append((suffix, 'rb', MODULE_KIND_COMPILED))
MODULE_KIND_MAP = {
MODULE_KIND_SOURCE: importlib.machinery.SourceFileLoader,
MODULE_KIND_COMPILED: importlib.machinery.SourcelessFileLoader,

View file

@ -101,6 +101,7 @@ def cert(name,
server=None,
owner='root',
group='root',
mode='0640',
certname=None):
'''
Obtain/renew a certificate from an ACME CA, probably Let's Encrypt.
@ -113,8 +114,9 @@ def cert(name,
:param renew: True/'force' to force a renewal, or a window of renewal before expiry in days
:param keysize: RSA key bits
:param server: API endpoint to talk to
:param owner: owner of private key
:param group: group of private key
:param owner: owner of the private key file
:param group: group of the private key file
:param mode: mode of the private key file
:param certname: Name of the certificate to save
:return: dict with 'result' True/False/None, 'comment' and certificate's expiry date ('not_after')
@ -170,27 +172,17 @@ def cert(name,
return {'result': False, 'comment': 'Certificate {0} renewal failed with:\n{1}'.format(name, res['stderr'])}
if 'no action taken' in res['stdout']:
return {'result': None,
'comment': 'No action taken on certificate {0}'.format(cert_file),
'not_after': expires(name)}
if renew:
comment = 'Certificate {0} unchanged'.format(cert_file)
elif renew:
comment = 'Certificate {0} renewed'.format(name)
else:
comment = 'Certificate {0} obtained'.format(name)
ret = {'comment': comment, 'not_after': expires(name)}
res = __salt__['file.check_perms'](_cert_file(name, 'privkey'), {}, owner, group, '0600', follow_symlinks=True)
if res is None:
ret['result'] = False
ret['comment'] += ', but setting permissions failed.'
elif not res[0].get('result', False):
ret['result'] = False
ret['comment'] += ', but setting permissions failed with \n{0}'.format(res[0]['comment'])
else:
ret['result'] = True
ret['comment'] += '.'
ret = {'comment': comment, 'not_after': expires(name), 'changes': {}, 'result': True}
ret, _ = __salt__['file.check_perms'](_cert_file(name, 'privkey'),
ret,
owner, group, mode,
follow_symlinks=True)
return ret

View file

@ -6467,7 +6467,6 @@ def _prepare_trans_tar(name, sls_opts, mods=None, pillar=None):
refs = salt.client.ssh.state.lowstate_file_refs(chunks)
_mk_fileclient()
trans_tar = salt.client.ssh.state.prep_trans_tar(
sls_opts,
__context__['cp.fileclient'],
chunks, refs, pillar, name)
return trans_tar

View file

@ -86,6 +86,9 @@ def fire_master(data, tag, preload=None):
channel = salt.transport.Channel.factory(__opts__, master_uri=master)
try:
channel.send(load)
# channel.send was successful.
# Ensure ret is True.
ret = True
except Exception:
ret = False
return ret

View file

@ -5075,7 +5075,7 @@ def manage_file(name,
source
file reference on the master
source_hash
source_sum
sum hash for source
user

View file

@ -162,7 +162,11 @@ def install(pkg=None,
env.update({'SUDO_UID': uid, 'SUDO_USER': ''})
cmd = ' '.join(cmd)
result = __salt__['cmd.run_all'](cmd, python_shell=True, cwd=dir, runas=runas, env=env)
result = __salt__['cmd.run_all'](cmd,
python_shell=True,
cwd=dir,
runas=runas,
env=env)
if result['retcode'] != 0:
raise CommandExecutionError(result['stderr'])
@ -170,33 +174,9 @@ def install(pkg=None,
# npm >1.2.21 is putting the output to stderr even though retcode is 0
npm_output = result['stdout'] or result['stderr']
try:
return salt.utils.json.loads(npm_output)
return salt.utils.json.find_json(npm_output)
except ValueError:
pass
json_npm_output = _extract_json(npm_output)
return json_npm_output or npm_output
def _extract_json(npm_output):
lines = npm_output.splitlines()
log.error(lines)
# Strip all lines until JSON output starts
while lines and not lines[0].startswith('{') and not lines[0].startswith('['):
lines = lines[1:]
while lines and not lines[-1].startswith('}') and not lines[-1].startswith(']'):
lines = lines[:-1]
# macOS with fsevents includes the following line in the return
# when a new module is installed which is invalid JSON:
# [fsevents] Success: "..."
while lines and (lines[0].startswith('[fsevents]') or lines[0].startswith('Pass ')):
lines = lines[1:]
try:
return salt.utils.json.loads(''.join(lines))
except ValueError:
pass
return None
return npm_output
def uninstall(pkg, dir=None, runas=None, env=None):

View file

@ -7,50 +7,56 @@ powercfg.
.. code-block:: bash
# Set monitor to never turn off on Battery power
salt '*' powercfg.set_monitor_timeout 0 power=dc
# Set disk timeout to 120 minutes on AC power
salt '*' powercfg.set_disk_timeout 120 power=ac
'''
# Import Python Libs
from __future__ import absolute_import, unicode_literals, print_function
import re
import logging
# Import Salt Libs
import salt.utils.platform
import salt.utils.versions
log = logging.getLogger(__name__)
__virtualname__ = "powercfg"
__virtualname__ = 'powercfg'
def __virtual__():
'''
Only work on Windows
'''
if __grains__['os'] == 'Windows':
return __virtualname__
return (False, 'Module only works on Windows.')
if not salt.utils.platform.is_windows():
return False, 'PowerCFG: Module only works on Windows'
return __virtualname__
def _get_current_scheme():
cmd = "powercfg /getactivescheme"
cmd = 'powercfg /getactivescheme'
out = __salt__['cmd.run'](cmd, python_shell=False)
matches = re.search(r"GUID: (.*) \(", out)
matches = re.search(r'GUID: (.*) \(', out)
return matches.groups()[0].strip()
def _get_powercfg_minute_values(scheme, guid, subguid, safe_name):
'''
Returns the AC/DC values in an array for a guid and subguid for a the given scheme
Returns the AC/DC values in an dict for a guid and subguid for a the given
scheme
'''
if scheme is None:
scheme = _get_current_scheme()
if __grains__['osrelease'] == '7':
cmd = "powercfg /q {0} {1}".format(scheme, guid)
cmd = 'powercfg /q {0} {1}'.format(scheme, guid)
else:
cmd = "powercfg /q {0} {1} {2}".format(scheme, guid, subguid)
cmd = 'powercfg /q {0} {1} {2}'.format(scheme, guid, subguid)
out = __salt__['cmd.run'](cmd, python_shell=False)
split = out.split("\r\n\r\n")
split = out.split('\r\n\r\n')
if len(split) > 1:
for s in split:
if safe_name in s or subguid in s:
@ -59,172 +65,309 @@ def _get_powercfg_minute_values(scheme, guid, subguid, safe_name):
else:
out = split[0]
raw_settings = re.findall(r"Power Setting Index: ([0-9a-fx]+)", out)
return {"ac": int(raw_settings[0], 0) / 60, "dc": int(raw_settings[1], 0) / 60}
raw_settings = re.findall(r'Power Setting Index: ([0-9a-fx]+)', out)
return {'ac': int(raw_settings[0], 0) / 60,
'dc': int(raw_settings[1], 0) / 60}
def _set_powercfg_value(scheme, sub_group, setting_guid, power, value):
'''
Sets the value of a setting with a given power (ac/dc) to
the given scheme
Sets the AC/DC values of a setting with the given power for the given scheme
'''
salt.utils.versions.warn_until(
'Fluorine',
'This function now expects the timeout value in minutes instead of '
'seconds as stated in the documentation. This warning will be removed '
'in Salt Fluorine.')
if scheme is None:
scheme = _get_current_scheme()
cmd = "powercfg /set{0}valueindex {1} {2} {3} {4}".format(power, scheme, sub_group, setting_guid, value)
return __salt__['cmd.run'](cmd, python_shell=False)
cmd = 'powercfg /set{0}valueindex {1} {2} {3} {4}' \
''.format(power, scheme, sub_group, setting_guid, value * 60)
return __salt__['cmd.retcode'](cmd, python_shell=False) == 0
def set_monitor_timeout(timeout, power="ac", scheme=None):
def set_monitor_timeout(timeout, power='ac', scheme=None):
'''
Set the monitor timeout in minutes for the given power scheme
Args:
timeout (int):
The amount of time in minutes before the monitor will timeout
power (str):
Set the value for AC or DC power. Default is ``ac``. Valid options
are:
- ``ac`` (AC Power)
- ``dc`` (Battery)
scheme (str):
The scheme to use, leave as ``None`` to use the current. Default is
``None``. This can be the GUID or the Alias for the Scheme. Known
Aliases are:
- ``SCHEME_BALANCED`` - Balanced
- ``SCHEME_MAX`` - Power saver
- ``SCHEME_MIN`` - High performance
Returns:
bool: ``True`` if successful, otherwise ``False``
CLI Example:
.. code-block:: bash
salt '*' powercfg.set_monitor_timeout 30 power=ac
timeout
The amount of time in minutes before the monitor will timeout
power
Should we set the value for AC or DC (battery)? Valid options ac,dc.
scheme
The scheme to use, leave as None to use the current.
# Sets the monitor timeout to 30 minutes
salt '*' powercfg.set_monitor_timeout 30
'''
return _set_powercfg_value(scheme, "SUB_VIDEO", "VIDEOIDLE", power, timeout)
return _set_powercfg_value(
scheme=scheme,
sub_group='SUB_VIDEO',
setting_guid='VIDEOIDLE',
power=power,
value=timeout)
def get_monitor_timeout(scheme=None):
'''
Get the current monitor timeout of the given scheme
Args:
scheme (str):
The scheme to use, leave as ``None`` to use the current. Default is
``None``. This can be the GUID or the Alias for the Scheme. Known
Aliases are:
- ``SCHEME_BALANCED`` - Balanced
- ``SCHEME_MAX`` - Power saver
- ``SCHEME_MIN`` - High performance
Returns:
dict: A dictionary of both the AC and DC settings
CLI Example:
.. code-block:: bash
salt '*' powercfg.get_monitor_timeout
scheme
The scheme to use, leave as None to use the current.
'''
return _get_powercfg_minute_values(scheme, "SUB_VIDEO", "VIDEOIDLE", "Turn off display after")
return _get_powercfg_minute_values(
scheme=scheme,
guid='SUB_VIDEO',
subguid='VIDEOIDLE',
safe_name='Turn off display after')
def set_disk_timeout(timeout, power="ac", scheme=None):
def set_disk_timeout(timeout, power='ac', scheme=None):
'''
Set the disk timeout in minutes for the given power scheme
Args:
timeout (int):
The amount of time in minutes before the disk will timeout
power (str):
Set the value for AC or DC power. Default is ``ac``. Valid options
are:
- ``ac`` (AC Power)
- ``dc`` (Battery)
scheme (str):
The scheme to use, leave as ``None`` to use the current. Default is
``None``. This can be the GUID or the Alias for the Scheme. Known
Aliases are:
- ``SCHEME_BALANCED`` - Balanced
- ``SCHEME_MAX`` - Power saver
- ``SCHEME_MIN`` - High performance
Returns:
bool: ``True`` if successful, otherwise ``False``
CLI Example:
.. code-block:: bash
# Sets the disk timeout to 30 minutes on battery
salt '*' powercfg.set_disk_timeout 30 power=dc
timeout
The amount of time in minutes before the disk will timeout
power
Should we set the value for AC or DC (battery)? Valid options ac,dc.
scheme
The scheme to use, leave as None to use the current.
'''
return _set_powercfg_value(scheme, "SUB_DISK", "DISKIDLE", power, timeout)
return _set_powercfg_value(
scheme=scheme,
sub_group='SUB_DISK',
setting_guid='DISKIDLE',
power=power,
value=timeout)
def get_disk_timeout(scheme=None):
'''
Get the current disk timeout of the given scheme
Args:
scheme (str):
The scheme to use, leave as ``None`` to use the current. Default is
``None``. This can be the GUID or the Alias for the Scheme. Known
Aliases are:
- ``SCHEME_BALANCED`` - Balanced
- ``SCHEME_MAX`` - Power saver
- ``SCHEME_MIN`` - High performance
Returns:
dict: A dictionary of both the AC and DC settings
CLI Example:
.. code-block:: bash
salt '*' powercfg.get_disk_timeout
scheme
The scheme to use, leave as None to use the current.
'''
return _get_powercfg_minute_values(scheme, "SUB_DISK", "DISKIDLE", "Turn off hard disk after")
return _get_powercfg_minute_values(
scheme=scheme,
guid='SUB_DISK',
subguid='DISKIDLE',
safe_name='Turn off hard disk after')
def set_standby_timeout(timeout, power="ac", scheme=None):
def set_standby_timeout(timeout, power='ac', scheme=None):
'''
Set the standby timeout in minutes for the given power scheme
Args:
timeout (int):
The amount of time in minutes before the computer sleeps
power (str):
Set the value for AC or DC power. Default is ``ac``. Valid options
are:
- ``ac`` (AC Power)
- ``dc`` (Battery)
scheme (str):
The scheme to use, leave as ``None`` to use the current. Default is
``None``. This can be the GUID or the Alias for the Scheme. Known
Aliases are:
- ``SCHEME_BALANCED`` - Balanced
- ``SCHEME_MAX`` - Power saver
- ``SCHEME_MIN`` - High performance
Returns:
bool: ``True`` if successful, otherwise ``False``
CLI Example:
.. code-block:: bash
# Sets the system standby timeout to 30 minutes on Battery
salt '*' powercfg.set_standby_timeout 30 power=dc
timeout
The amount of time in minutes before the computer sleeps
power
Should we set the value for AC or DC (battery)? Valid options ac,dc.
scheme
The scheme to use, leave as None to use the current.
'''
return _set_powercfg_value(scheme, "SUB_SLEEP", "STANDBYIDLE", power, timeout)
return _set_powercfg_value(
scheme=scheme,
sub_group='SUB_SLEEP',
setting_guid='STANDBYIDLE',
power=power,
value=timeout)
def get_standby_timeout(scheme=None):
'''
Get the current standby timeout of the given scheme
scheme (str):
The scheme to use, leave as ``None`` to use the current. Default is
``None``. This can be the GUID or the Alias for the Scheme. Known
Aliases are:
- ``SCHEME_BALANCED`` - Balanced
- ``SCHEME_MAX`` - Power saver
- ``SCHEME_MIN`` - High performance
Returns:
dict: A dictionary of both the AC and DC settings
CLI Example:
.. code-block:: bash
salt '*' powercfg.get_standby_timeout
scheme
The scheme to use, leave as None to use the current.
'''
return _get_powercfg_minute_values(scheme, "SUB_SLEEP", "STANDBYIDLE", "Sleep after")
return _get_powercfg_minute_values(
scheme=scheme,
guid='SUB_SLEEP',
subguid='STANDBYIDLE',
safe_name='Sleep after')
def set_hibernate_timeout(timeout, power="ac", scheme=None):
def set_hibernate_timeout(timeout, power='ac', scheme=None):
'''
Set the hibernate timeout in minutes for the given power scheme
Args:
timeout (int):
The amount of time in minutes before the computer hibernates
power (str):
Set the value for AC or DC power. Default is ``ac``. Valid options
are:
- ``ac`` (AC Power)
- ``dc`` (Battery)
scheme (str):
The scheme to use, leave as ``None`` to use the current. Default is
``None``. This can be the GUID or the Alias for the Scheme. Known
Aliases are:
- ``SCHEME_BALANCED`` - Balanced
- ``SCHEME_MAX`` - Power saver
- ``SCHEME_MIN`` - High performance
Returns:
bool: ``True`` if successful, otherwise ``False``
CLI Example:
.. code-block:: bash
salt '*' powercfg.set_hibernate_timeout 30 power=pc
timeout
The amount of time in minutes before the computer hibernates
power
Should we set the value for AC or DC (battery)? Valid options ac,dc.
scheme
The scheme to use, leave as None to use the current.
# Sets the hibernate timeout to 30 minutes on Battery
salt '*' powercfg.set_hibernate_timeout 30 power=dc
'''
return _set_powercfg_value(scheme, "SUB_SLEEP", "HIBERNATEIDLE", power, timeout)
return _set_powercfg_value(
scheme=scheme,
sub_group='SUB_SLEEP',
setting_guid='HIBERNATEIDLE',
power=power,
value=timeout)
def get_hibernate_timeout(scheme=None):
'''
Get the current hibernate timeout of the given scheme
scheme (str):
The scheme to use, leave as ``None`` to use the current. Default is
``None``. This can be the GUID or the Alias for the Scheme. Known
Aliases are:
- ``SCHEME_BALANCED`` - Balanced
- ``SCHEME_MAX`` - Power saver
- ``SCHEME_MIN`` - High performance
Returns:
dict: A dictionary of both the AC and DC settings
CLI Example:
.. code-block:: bash
salt '*' powercfg.get_hibernate_timeout
scheme
The scheme to use, leave as None to use the current.
'''
return _get_powercfg_minute_values(scheme, "SUB_SLEEP", "HIBERNATEIDLE", "Hibernate after")
return _get_powercfg_minute_values(
scheme=scheme,
guid='SUB_SLEEP',
subguid='HIBERNATEIDLE',
safe_name='Hibernate after')

View file

@ -584,6 +584,8 @@ def latest_version(*names, **kwargs):
status = pkg_info.get('status', '').lower()
if status.find('not installed') > -1 or status.find('out-of-date') > -1:
ret[name] = pkg_info.get('version')
else:
ret[name] = ''
# Return a string if only one package name passed
if len(names) == 1 and len(ret):

View file

@ -49,6 +49,7 @@ def cert(name,
server=None,
owner='root',
group='root',
mode='0640',
certname=None):
'''
Obtain/renew a certificate from an ACME CA, probably Let's Encrypt.
@ -61,8 +62,9 @@ def cert(name,
:param renew: True/'force' to force a renewal, or a window of renewal before expiry in days
:param keysize: RSA key bits
:param server: API endpoint to talk to
:param owner: owner of private key
:param group: group of private key
:param owner: owner of the private key file
:param group: group of the private key file
:param mode: mode of the private key file
:param certname: Name of the certificate to save
'''
@ -105,7 +107,8 @@ def cert(name,
keysize=keysize,
server=server,
owner=owner,
group=group
group=group,
mode=mode
)
ret = {

View file

@ -275,9 +275,13 @@ def bootstrap(name, user=None, silent=True):
if __opts__['test']:
try:
call = __salt__['npm.install'](dir=name, runas=user, pkg=None, silent=silent, dry_run=True)
ret['result'] = None
ret['changes'] = {'old': [], 'new': call}
ret['comment'] = '{0} is set to be bootstrapped'.format(name)
if call:
ret['result'] = None
ret['changes'] = {'old': [], 'new': call}
ret['comment'] = '{0} is set to be bootstrapped'.format(name)
else:
ret['result'] = True
ret['comment'] = '{0} is already bootstrapped'.format(name)
except (CommandNotFoundError, CommandExecutionError) as err:
ret['result'] = False
ret['comment'] = 'Error Bootstrapping \'{0}\': {1}'.format(name, err)

View file

@ -8,6 +8,7 @@ powercfg.
.. code-block:: yaml
# Set timeout to 30 minutes on battery power
monitor:
powercfg.set_timeout:
- value: 30
@ -18,82 +19,132 @@ powercfg.
from __future__ import absolute_import, unicode_literals, print_function
import logging
# Import Salt Libs
import salt.utils.data
import salt.utils.platform
log = logging.getLogger(__name__)
__virtualname__ = "powercfg"
__virtualname__ = 'powercfg'
def __virtual__():
'''
Only work on Windows
'''
if __grains__['os'] == 'Windows':
return __virtualname__
return False
if not salt.utils.platform.is_windows():
return False, 'PowerCFG: Module only works on Windows'
return __virtualname__
def _check_or_set(check_func, set_func, value, power):
values = check_func()
if values[power] == value:
return True
else:
set_func(value, power)
return False
def set_timeout(name, value, power="ac", scheme=None):
def set_timeout(name, value, power='ac', scheme=None):
'''
Set the sleep timeouts of specific items such as disk, monitor.
Set the sleep timeouts of specific items such as disk, monitor, etc.
Args:
name (str)
The setting to change, can be one of the following:
- ``monitor``
- ``disk``
- ``standby``
- ``hibernate``
value (int):
The amount of time in minutes before the item will timeout
power (str):
Set the value for AC or DC power. Default is ``ac``. Valid options
are:
- ``ac`` (AC Power)
- ``dc`` (Battery)
scheme (str):
The scheme to use, leave as ``None`` to use the current. Default is
``None``. This can be the GUID or the Alias for the Scheme. Known
Aliases are:
- ``SCHEME_BALANCED`` - Balanced
- ``SCHEME_MAX`` - Power saver
- ``SCHEME_MIN`` - High performance
CLI Example:
.. code-block:: yaml
# Set monitor timeout to 30 minutes on Battery
monitor:
powercfg.set_timeout:
- value: 30
- power: dc
powercfg.set_timeout:
- value: 30
- power: dc
# Set disk timeout to 10 minutes on AC Power
disk:
powercfg.set_timeout:
- value: 12
- power: ac
name
The setting to change, can be one of the following: monitor, disk, standby, hibernate
timeout
The amount of time in minutes before the item will timeout i.e the monitor
power
Should we set the value for AC or DC (battery)? Valid options ac,dc.
scheme
The scheme to use, leave as None to use the current.
powercfg.set_timeout:
- value: 10
- power: ac
'''
ret = {'name': name,
'result': True,
'comment': '',
'changes': {}}
comment = []
# Validate name values
name = name.lower()
if name not in ['monitor', 'disk', 'standby', 'hibernate']:
ret['result'] = False
ret['comment'] = '"{0}" is not a valid setting'.format(name)
log.debug(ret['comment'])
return ret
if name not in ["monitor", "disk", "standby", "hibernate"]:
ret["result"] = False
comment.append("{0} is not a valid setting".format(name))
elif power not in ["ac", "dc"]:
ret["result"] = False
comment.append("{0} is not a power type".format(power))
# Validate power values
power = power.lower()
if power not in ['ac', 'dc']:
ret['result'] = False
ret['comment'] = '"{0}" is not a power type'.format(power)
log.debug(ret['comment'])
return ret
# Get current settings
old = __salt__['powercfg.get_{0}_timeout'.format(name)](scheme=scheme)
# Check current settings
if old[power] == value:
ret['comment'] = '{0} timeout on {1} power is already set to {2}' \
''.format(name.capitalize(), power.upper(), value)
return ret
else:
check_func = __salt__["powercfg.get_{0}_timeout".format(name)]
set_func = __salt__["powercfg.set_{0}_timeout".format(name)]
ret['comment'] = '{0} timeout on {1} power will be set to {2}' \
''.format(name.capitalize(), power.upper(), value)
values = check_func(scheme=scheme)
if values[power] == value:
comment.append("{0} {1} is already set with the value {2}.".format(name, power, value))
else:
ret['changes'] = {name: {power: value}}
set_func(value, power, scheme=scheme)
# Check for test=True
if __opts__['test']:
ret['result'] = None
return ret
# Set the timeout value
__salt__['powercfg.set_{0}_timeout'.format(name)](
timeout=value,
power=power,
scheme=scheme)
# Get the setting after the change
new = __salt__['powercfg.get_{0}_timeout'.format(name)](scheme=scheme)
changes = salt.utils.data.compare_dicts(old, new)
if changes:
ret['changes'] = {name: changes}
ret['comment'] = '{0} timeout on {1} power set to {2}' \
''.format(name.capitalize(), power.upper(), value)
log.debug(ret['comment'])
else:
ret['changes'] = {}
ret['comment'] = 'Failed to set {0} timeout on {1} power to {2}' \
''.format(name, power.upper(), value)
log.debug(ret['comment'])
ret['result'] = False
ret['comment'] = ' '.join(comment)
return ret

View file

@ -71,10 +71,9 @@ def _init_libcrypto():
libcrypto.RSA_public_decrypt.argtypes = (c_int, c_char_p, c_char_p, c_void_p, c_int)
try:
if libcrypto.OPENSSL_init_crypto(OPENSSL_INIT_NO_LOAD_CONFIG |
OPENSSL_INIT_ADD_ALL_CIPHERS |
OPENSSL_INIT_ADD_ALL_DIGESTS, None) != 1:
raise OSError("Failed to initialize OpenSSL library (OPENSSL_init_crypto failed)")
libcrypto.OPENSSL_init_crypto(OPENSSL_INIT_NO_LOAD_CONFIG |
OPENSSL_INIT_ADD_ALL_CIPHERS |
OPENSSL_INIT_ADD_ALL_DIGESTS, None)
except AttributeError:
# Support for OpenSSL < 1.1 (OPENSSL_API_COMPAT < 0x10100000L)
libcrypto.OPENSSL_no_config()

View file

@ -162,20 +162,23 @@ def query(key, keyid, method='GET', params=None, headers=None,
headers=headers,
data=data,
verify=verify_ssl,
stream=True)
stream=True,
timeout=300)
elif method == 'GET' and local_file and not return_bin:
result = requests.request(method,
requesturl,
headers=headers,
data=data,
verify=verify_ssl,
stream=True)
stream=True,
timeout=300)
else:
result = requests.request(method,
requesturl,
headers=headers,
data=data,
verify=verify_ssl)
verify=verify_ssl,
timeout=300)
finally:
if fh is not None:
fh.close()

View file

@ -3,3 +3,7 @@ ssh-file-test:
file.managed:
- name: /tmp/{{ jinja }}
- contents: 'test'
second_id:
cmd.run:
- name: echo test

View file

@ -200,11 +200,12 @@ class MacServiceModuleTest(ModuleCase):
self.assertFalse(
self.run_function('service.disabled', [SERVICE_NAME]))
self.assertTrue(self.run_function('service.stop', [SERVICE_NAME]))
self.assertTrue(self.run_function('service.disable', [SERVICE_NAME]))
self.assertTrue(
self.run_function('service.disabled', [SERVICE_NAME]))
self.assertTrue(self.run_function('service.enable', [SERVICE_NAME]))
self.assertTrue(self.run_function('service.disabled', ['spongebob']))
self.assertFalse(self.run_function('service.disabled', ['spongebob']))
def test_get_all(self):
'''

View file

@ -11,7 +11,7 @@ import string
# Import Salt Testing libs
from tests.support.case import ModuleCase
from tests.support.unit import skipIf
from tests.support.helpers import destructiveTest, skip_if_not_root
from tests.support.helpers import destructiveTest, skip_if_not_root, flaky
# Import salt libs
import salt.utils.path
@ -34,6 +34,7 @@ SET_SUBNET_NAME = __random_string()
@skip_if_not_root
@flaky
@skipIf(not salt.utils.platform.is_darwin(), 'Test only available on macOS')
@skipIf(not salt.utils.path.which('systemsetup'), '\'systemsetup\' binary not found in $PATH')
class MacSystemModuleTest(ModuleCase):

View file

@ -17,7 +17,7 @@ import datetime
# Import Salt Testing libs
from tests.support.case import ModuleCase
from tests.support.unit import skipIf
from tests.support.helpers import destructiveTest, skip_if_not_root
from tests.support.helpers import destructiveTest, skip_if_not_root, flaky
# Import Salt libs
import salt.utils.path
@ -28,6 +28,7 @@ from salt.ext import six
@skip_if_not_root
@flaky
@skipIf(not salt.utils.platform.is_darwin(), 'Test only available on macOS')
@skipIf(not salt.utils.path.which('systemsetup'), '\'systemsetup\' binary not found in $PATH')
class MacTimezoneModuleTest(ModuleCase):

View file

@ -0,0 +1,33 @@
# -*- coding: utf-8 -*-
# Import Python libs
from __future__ import absolute_import, print_function, unicode_literals
import re
# Import Salt Testing libs
from tests.support.case import ModuleCase
from tests.support.unit import skipIf
# Import Salt libs
import salt.utils.platform
@skipIf(not salt.utils.platform.is_windows(), 'windows test only')
class WinIPTest(ModuleCase):
'''
Tests for salt.modules.win_ip
'''
def test_get_default_gateway(self):
'''
Test getting default gateway
'''
ip = re.compile(r'^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$')
ret = self.run_function('ip.get_default_gateway')
assert ip.match(ret)
def test_ip_is_enabled(self):
'''
Test ip.is_enabled
'''
assert self.run_function('ip.is_enabled', ['Ethernet'])
assert 'not found' in self.run_function('ip.is_enabled', ['doesnotexist'])

View file

@ -0,0 +1,85 @@
# -*- coding: utf-8 -*-
# Import Python libs
from __future__ import absolute_import, print_function, unicode_literals
import os
import textwrap
# Import Salt Testing libs
from tests.support.case import ModuleCase
from tests.support.unit import skipIf
from tests.support.helpers import destructiveTest
from tests.support.runtests import RUNTIME_VARS
# Import Salt libs
import salt.utils.files
import salt.utils.platform
CURL = os.path.join(RUNTIME_VARS.FILES, 'file', 'base', 'win', 'repo-ng', 'curl.sls')
@skipIf(not salt.utils.platform.is_windows(), 'windows test only')
class WinPKGTest(ModuleCase):
'''
Tests for salt.modules.win_pkg. There are already
some pkg execution module tests in the the test
integration.modules.test_pkg but this will be for
specific windows software respository tests while
using the win_pkg module.
'''
@destructiveTest
def test_adding_removing_pkg_sls(self):
'''
Test add and removing a new pkg sls
in the windows software repository
'''
def _check_pkg(pkgs, exists=True):
self.run_function('pkg.refresh_db')
repo_data = self.run_function('pkg.get_repo_data')
repo_cache = os.path.join(RUNTIME_VARS.TMP, 'rootdir', 'cache', 'files', 'base', 'win', 'repo-ng')
for pkg in pkgs:
if exists:
assert pkg in str(repo_data)
else:
assert pkg not in str(repo_data)
for root, dirs, files in os.walk(repo_cache):
if exists:
assert pkg + '.sls' in files
else:
assert pkg + '.sls' not in files
pkgs = ['putty', '7zip']
# check putty and 7zip are in cache and repo query
_check_pkg(pkgs)
# now add new sls
with salt.utils.files.fopen(CURL, 'w') as fp_:
fp_.write(textwrap.dedent('''
curl:
'7.46.0':
full_name: 'cURL'
{% if grains['cpuarch'] == 'AMD64' %}
installer: 'salt://win/repo-ng/curl/curl-7.46.0-win64.msi'
uninstaller: 'salt://win/repo-ng/curl/curl-7.46.0-win64.msi'
{% else %}
installer: 'salt://win/repo-ng/curl/curl-7.46.0-win32.msi'
uninstaller: 'salt://win/repo-ng/curl/curl-7.46.0-win32.msi'
{% endif %}
install_flags: '/qn /norestart'
uninstall_flags: '/qn /norestart'
msiexec: True
locale: en_US
reboot: False
'''))
# now check if curl is also in cache and repo query
pkgs.append('curl')
_check_pkg(pkgs)
# remove curl sls and check its not in cache and repo query
os.remove(CURL)
_check_pkg(['curl'], exists=False)
def tearDown(self):
if os.path.isfile(CURL):
os.remove(CURL)

View file

@ -27,11 +27,14 @@ class SSHStateTest(SSHCase):
'''
testing the state system with salt-ssh
'''
def _check_dict_ret(self, ret, val, exp_ret):
def _check_dict_ret(self, ret, val, exp_ret, equal=True):
self.assertIsInstance(ret, dict)
for key, value in ret.items():
self.assertIsInstance(value, dict)
self.assertEqual(value[val], exp_ret)
if equal:
self.assertEqual(value[val], exp_ret)
else:
self.assertNotEqual(value[val], exp_ret)
def _check_request(self, empty=False):
check = self.run_function('state.check_request', wipe=False)
@ -55,12 +58,31 @@ class SSHStateTest(SSHCase):
'''
test state.sls_id with salt-ssh
'''
# check state.sls_id with test=True
ret = self.run_function('state.sls_id', ['ssh-file-test', SSH_SLS,
'test=True'])
self._check_dict_ret(ret=ret, val='comment',
exp_ret='The file /tmp/test is set to be changed')
# check state.sls_id without test=True
ret = self.run_function('state.sls_id', ['ssh-file-test', SSH_SLS])
self._check_dict_ret(ret=ret, val='__sls__', exp_ret=SSH_SLS)
# make sure the other id in the state was not run
self._check_dict_ret(ret=ret, val='__id__',
exp_ret='second_id', equal=False)
check_file = self.run_function('file.file_exists', ['/tmp/test'])
self.assertTrue(check_file)
def test_state_sls_wrong_id(self):
'''
test state.sls_id when id does not exist
'''
# check state.sls_id with test=True
ret = self.run_function('state.sls_id', ['doesnotexist', SSH_SLS])
assert 'No matches for ID' in ret
def test_state_show_sls(self):
'''
test state.show_sls with salt-ssh

View file

@ -22,6 +22,11 @@ from tests.support.mixins import SaltReturnAssertsMixin
# Import Salt libs
import salt.utils.platform
try:
import grp
except ImportError:
grp = None
if salt.utils.platform.is_darwin():
USER = 'macuser'
GROUP = 'macuser'
@ -32,13 +37,11 @@ elif salt.utils.platform.is_windows():
GROUP = 'winuser'
GID = randint(400, 500)
NOGROUPGID = randint(400, 500)
grp = None
else:
USER = 'nobody'
GROUP = 'nobody'
GID = 'nobody'
NOGROUPGID = 'nogroup'
import grp
@destructiveTest

View file

@ -14,6 +14,7 @@ import logging
import os
import shutil
import signal
import socket
import subprocess
import sys
import tempfile
@ -590,8 +591,24 @@ class TestSaltProgram(six.with_metaclass(TestSaltProgramMeta, TestProgram)):
'log_dir',
'script_dir',
])
pub_port = 4505
ret_port = 4506
for port in [pub_port, ret_port]:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
connect = sock.bind(('localhost', port))
except:
# these ports are already in use, use different ones
pub_port = 4606
ret_port = 4607
break
sock.close()
config_base = {
'root_dir': '{test_dir}',
'publish_port': pub_port,
'ret_port': ret_port,
}
configs = {}
config_dir = os.path.join('etc', 'salt')

View file

@ -5,6 +5,7 @@
# Import Python Libs
from __future__ import absolute_import, unicode_literals, print_function
import textwrap
# Import Salt Testing Libs
from tests.support.mixins import LoaderModuleMockMixin
@ -34,43 +35,87 @@ class NpmTestCase(TestCase, LoaderModuleMockMixin):
self.addCleanup(patcher.stop)
return {npm: {}}
# 'install' function tests: 1
# 'install' function tests: 4
def test_install(self):
'''
Test if it install an NPM package.
Test if it installs an NPM package.
'''
mock = MagicMock(return_value={'retcode': 1, 'stderr': 'error'})
with patch.dict(npm.__salt__, {'cmd.run_all': mock}):
self.assertRaises(CommandExecutionError, npm.install,
'coffee-script')
mock = MagicMock(return_value={'retcode': 0, 'stderr': 'error',
'stdout': '{"salt": ["SALT"]}'})
with patch.dict(npm.__salt__, {'cmd.run_all': mock}):
mock_err = MagicMock(return_value='SALT')
with patch.object(salt.utils.json, 'loads', mock_err):
self.assertEqual(npm.install('coffee-script'), 'SALT')
# This is at least somewhat closer to the actual output format.
mock_json_out = textwrap.dedent('''\
[
{
"salt": "SALT"
}
]''')
mock = MagicMock(return_value={'retcode': 0, 'stderr': 'error',
'stdout': '{"salt": ["SALT"]}'})
# Successful run, expected output format
mock = MagicMock(return_value={'retcode': 0, 'stderr': '',
'stdout': mock_json_out})
with patch.dict(npm.__salt__, {'cmd.run_all': mock}):
self.assertEqual(npm.install('coffee-script'),
[{u'salt': u'SALT'}])
mock_json_out_extra = textwrap.dedent('''\
Compilation output here
[bcrypt] Success: "/tmp/node_modules/bcrypt/foo" is installed via remote"
[grpc] Success: "/usr/lib/node_modules/@foo/bar" is installed via remote"
[
{
"from" : "express@",
"name" : "express",
"dependencies" : {
"escape-html" : {
"from" : "escape-html@~1.0.3",
"dependencies" : {},
"version" : "1.0.3"
}
},
"version" : "4.16.3"
}
]''')
extra_expected = [{u'dependencies':
{u'escape-html': {
u'dependencies': {},
u'from': u'escape-html@~1.0.3',
u'version': u'1.0.3'}
},
u'from': u'express@',
u'name': u'express',
u'version': u'4.16.3'}]
# Successful run, expected output format with additional leading text
mock = MagicMock(return_value={'retcode': 0, 'stderr': '',
'stdout': mock_json_out_extra})
with patch.dict(npm.__salt__, {'cmd.run_all': mock}):
self.assertEqual(npm.install('coffee-script'), extra_expected)
# Successful run, unexpected output format
mock = MagicMock(return_value={'retcode': 0, 'stderr': '',
'stdout': 'SALT'})
with patch.dict(npm.__salt__, {'cmd.run_all': mock}):
mock_err = MagicMock(side_effect=ValueError())
# When JSON isn't successfully parsed, return should equal input
with patch.object(salt.utils.json, 'loads', mock_err):
self.assertEqual(npm.install('coffee-script'),
'{"salt": ["SALT"]}')
self.assertEqual(npm.install('coffee-script'), 'SALT')
# 'uninstall' function tests: 1
def test_uninstall(self):
'''
Test if it uninstall an NPM package.
Test if it uninstalls an NPM package.
'''
mock = MagicMock(return_value={'retcode': 1, 'stderr': 'error'})
with patch.dict(npm.__salt__, {'cmd.run_all': mock}):
self.assertFalse(npm.uninstall('coffee-script'))
mock = MagicMock(return_value={'retcode': 0, 'stderr': 'error'})
mock = MagicMock(return_value={'retcode': 0, 'stderr': ''})
with patch.dict(npm.__salt__, {'cmd.run_all': mock}):
self.assertTrue(npm.uninstall('coffee-script'))

View file

@ -21,7 +21,7 @@ from tests.support.mock import (
@skipIf(NO_MOCK, NO_MOCK_REASON)
class PowerCfgTestCase(TestCase, LoaderModuleMockMixin):
'''
Validate the powercfg state
Validate the powercfg state
'''
def setup_loader_modules(self):
@ -40,76 +40,103 @@ class PowerCfgTestCase(TestCase, LoaderModuleMockMixin):
def test_set_monitor_timeout(self):
'''
Test to make sure we can set the monitor timeout value
Test to make sure we can set the monitor timeout value
'''
mock = MagicMock()
mock.side_effect = ["Power Scheme GUID: 381b4222-f694-41f0-9685-ff5bb260df2e (Balanced)", self.query_output]
mock = MagicMock(return_value=0)
mock.side_effect = [
'Power Scheme GUID: 381b4222-f694-41f0-9685-ff5bb260df2e (Balanced)',
self.query_output]
mock_retcode = MagicMock(return_value=0)
with patch.dict(powercfg.__salt__, {'cmd.run': mock}):
powercfg.set_monitor_timeout(0, "dc")
calls = [
call('powercfg /getactivescheme', python_shell=False),
call('powercfg /setdcvalueindex 381b4222-f694-41f0-9685-ff5bb260df2e SUB_VIDEO VIDEOIDLE 0', python_shell=False)
]
mock.assert_has_calls(calls)
with patch.dict(powercfg.__salt__, {'cmd.retcode': mock_retcode}):
powercfg.set_monitor_timeout(0, 'dc')
mock.assert_called_once_with(
'powercfg /getactivescheme',
python_shell=False)
mock_retcode.assert_called_once_with(
'powercfg /setdcvalueindex 381b4222-f694-41f0-9685-ff5bb260df2e SUB_VIDEO VIDEOIDLE 0',
python_shell=False)
def test_set_disk_timeout(self):
'''
Test to make sure we can set the disk timeout value
Test to make sure we can set the disk timeout value
'''
mock = MagicMock()
mock.side_effect = ["Power Scheme GUID: 381b4222-f694-41f0-9685-ff5bb260df2e (Balanced)", self.query_output]
mock.side_effect = [
'Power Scheme GUID: 381b4222-f694-41f0-9685-ff5bb260df2e (Balanced)',
self.query_output]
mock_retcode = MagicMock(return_value=0)
with patch.dict(powercfg.__salt__, {'cmd.run': mock}):
powercfg.set_disk_timeout(0, "dc")
calls = [
call('powercfg /getactivescheme', python_shell=False),
call('powercfg /setdcvalueindex 381b4222-f694-41f0-9685-ff5bb260df2e SUB_DISK DISKIDLE 0', python_shell=False)
]
mock.assert_has_calls(calls)
with patch.dict(powercfg.__salt__, {'cmd.retcode': mock_retcode}):
powercfg.set_disk_timeout(0, 'dc')
mock.assert_called_once_with(
'powercfg /getactivescheme',
python_shell=False)
mock_retcode.assert_called_once_with(
'powercfg /setdcvalueindex 381b4222-f694-41f0-9685-ff5bb260df2e SUB_DISK DISKIDLE 0',
python_shell=False)
def test_set_standby_timeout(self):
'''
Test to make sure we can set the standby timeout value
Test to make sure we can set the standby timeout value
'''
mock = MagicMock()
mock.side_effect = ["Power Scheme GUID: 381b4222-f694-41f0-9685-ff5bb260df2e (Balanced)", self.query_output]
mock = MagicMock(return_value=0)
mock.side_effect = [
'Power Scheme GUID: 381b4222-f694-41f0-9685-ff5bb260df2e (Balanced)',
self.query_output]
mock_retcode = MagicMock(return_value=0)
with patch.dict(powercfg.__salt__, {'cmd.run': mock}):
powercfg.set_standby_timeout(0, "dc")
calls = [
call('powercfg /getactivescheme', python_shell=False),
call('powercfg /setdcvalueindex 381b4222-f694-41f0-9685-ff5bb260df2e SUB_SLEEP STANDBYIDLE 0', python_shell=False)
]
mock.assert_has_calls(calls)
with patch.dict(powercfg.__salt__, {'cmd.retcode': mock_retcode}):
powercfg.set_standby_timeout(0, 'dc')
mock.assert_called_once_with(
'powercfg /getactivescheme',
python_shell=False)
mock_retcode.assert_called_once_with(
'powercfg /setdcvalueindex 381b4222-f694-41f0-9685-ff5bb260df2e SUB_SLEEP STANDBYIDLE 0',
python_shell=False)
def test_set_hibernate_timeout(self):
'''
Test to make sure we can set the hibernate timeout value
Test to make sure we can set the hibernate timeout value
'''
mock = MagicMock()
mock.side_effect = ["Power Scheme GUID: 381b4222-f694-41f0-9685-ff5bb260df2e (Balanced)", self.query_output]
mock = MagicMock(return_value=0)
mock.side_effect = [
'Power Scheme GUID: 381b4222-f694-41f0-9685-ff5bb260df2e (Balanced)',
self.query_output]
mock_retcode = MagicMock(return_value=0)
with patch.dict(powercfg.__salt__, {'cmd.run': mock}):
powercfg.set_hibernate_timeout(0, "dc")
calls = [
call('powercfg /getactivescheme', python_shell=False),
call('powercfg /setdcvalueindex 381b4222-f694-41f0-9685-ff5bb260df2e SUB_SLEEP HIBERNATEIDLE 0', python_shell=False)
]
mock.assert_has_calls(calls)
with patch.dict(powercfg.__salt__, {'cmd.retcode': mock_retcode}):
powercfg.set_hibernate_timeout(0, 'dc')
mock.assert_called_once_with(
'powercfg /getactivescheme',
python_shell=False)
mock_retcode.assert_called_once_with(
'powercfg /setdcvalueindex 381b4222-f694-41f0-9685-ff5bb260df2e SUB_SLEEP HIBERNATEIDLE 0',
python_shell=False)
def test_get_monitor_timeout(self):
'''
Test to make sure we can get the monitor timeout value
Test to make sure we can get the monitor timeout value
'''
mock = MagicMock()
mock.side_effect = ["Power Scheme GUID: 381b4222-f694-41f0-9685-ff5bb260df2e (Balanced)", self.query_output]
mock.side_effect = [
'Power Scheme GUID: 381b4222-f694-41f0-9685-ff5bb260df2e (Balanced)',
self.query_output]
with patch.dict(powercfg.__salt__, {'cmd.run': mock}):
ret = powercfg.get_monitor_timeout()
calls = [
call('powercfg /getactivescheme', python_shell=False),
call('powercfg /q 381b4222-f694-41f0-9685-ff5bb260df2e SUB_VIDEO VIDEOIDLE', python_shell=False)
call('powercfg /q 381b4222-f694-41f0-9685-ff5bb260df2e SUB_VIDEO VIDEOIDLE',
python_shell=False)
]
mock.assert_has_calls(calls)
@ -117,16 +144,19 @@ class PowerCfgTestCase(TestCase, LoaderModuleMockMixin):
def test_get_disk_timeout(self):
'''
Test to make sure we can get the disk timeout value
Test to make sure we can get the disk timeout value
'''
mock = MagicMock()
mock.side_effect = ["Power Scheme GUID: 381b4222-f694-41f0-9685-ff5bb260df2e (Balanced)", self.query_output]
mock.side_effect = [
'Power Scheme GUID: 381b4222-f694-41f0-9685-ff5bb260df2e (Balanced)',
self.query_output]
with patch.dict(powercfg.__salt__, {'cmd.run': mock}):
ret = powercfg.get_disk_timeout()
calls = [
call('powercfg /getactivescheme', python_shell=False),
call('powercfg /q 381b4222-f694-41f0-9685-ff5bb260df2e SUB_DISK DISKIDLE', python_shell=False)
call('powercfg /q 381b4222-f694-41f0-9685-ff5bb260df2e SUB_DISK DISKIDLE',
python_shell=False)
]
mock.assert_has_calls(calls)
@ -134,16 +164,19 @@ class PowerCfgTestCase(TestCase, LoaderModuleMockMixin):
def test_get_standby_timeout(self):
'''
Test to make sure we can get the standby timeout value
Test to make sure we can get the standby timeout value
'''
mock = MagicMock()
mock.side_effect = ["Power Scheme GUID: 381b4222-f694-41f0-9685-ff5bb260df2e (Balanced)", self.query_output]
mock.side_effect = [
'Power Scheme GUID: 381b4222-f694-41f0-9685-ff5bb260df2e (Balanced)',
self.query_output]
with patch.dict(powercfg.__salt__, {'cmd.run': mock}):
ret = powercfg.get_standby_timeout()
calls = [
call('powercfg /getactivescheme', python_shell=False),
call('powercfg /q 381b4222-f694-41f0-9685-ff5bb260df2e SUB_SLEEP STANDBYIDLE', python_shell=False)
call('powercfg /q 381b4222-f694-41f0-9685-ff5bb260df2e SUB_SLEEP STANDBYIDLE',
python_shell=False)
]
mock.assert_has_calls(calls)
@ -151,16 +184,19 @@ class PowerCfgTestCase(TestCase, LoaderModuleMockMixin):
def test_get_hibernate_timeout(self):
'''
Test to make sure we can get the hibernate timeout value
Test to make sure we can get the hibernate timeout value
'''
mock = MagicMock()
mock.side_effect = ["Power Scheme GUID: 381b4222-f694-41f0-9685-ff5bb260df2e (Balanced)", self.query_output]
mock.side_effect = [
'Power Scheme GUID: 381b4222-f694-41f0-9685-ff5bb260df2e (Balanced)',
self.query_output]
with patch.dict(powercfg.__salt__, {'cmd.run': mock}):
ret = powercfg.get_hibernate_timeout()
calls = [
call('powercfg /getactivescheme', python_shell=False),
call('powercfg /q 381b4222-f694-41f0-9685-ff5bb260df2e SUB_SLEEP HIBERNATEIDLE', python_shell=False)
call('powercfg /q 381b4222-f694-41f0-9685-ff5bb260df2e SUB_SLEEP HIBERNATEIDLE',
python_shell=False)
]
mock.assert_has_calls(calls)
@ -168,17 +204,20 @@ class PowerCfgTestCase(TestCase, LoaderModuleMockMixin):
def test_windows_7(self):
'''
Test to make sure we can get the hibernate timeout value on windows 7
Test to make sure we can get the hibernate timeout value on windows 7
'''
mock = MagicMock()
mock.side_effect = ["Power Scheme GUID: 381b4222-f694-41f0-9685-ff5bb260df2e (Balanced)", self.query_output]
mock.side_effect = [
'Power Scheme GUID: 381b4222-f694-41f0-9685-ff5bb260df2e (Balanced)',
self.query_output]
with patch.dict(powercfg.__salt__, {'cmd.run': mock}):
with patch.dict(powercfg.__grains__, {'osrelease': '7'}):
ret = powercfg.get_hibernate_timeout()
calls = [
call('powercfg /getactivescheme', python_shell=False),
call('powercfg /q 381b4222-f694-41f0-9685-ff5bb260df2e SUB_SLEEP', python_shell=False)
call('powercfg /q 381b4222-f694-41f0-9685-ff5bb260df2e SUB_SLEEP',
python_shell=False)
]
mock.assert_has_calls(calls)
@ -186,30 +225,29 @@ class PowerCfgTestCase(TestCase, LoaderModuleMockMixin):
def test_set_hibernate_timeout_scheme(self):
'''
Test to make sure we can set the hibernate timeout value
Test to make sure we can set the hibernate timeout value
'''
mock = MagicMock()
mock = MagicMock(return_value=0)
mock.side_effect = [self.query_output]
with patch.dict(powercfg.__salt__, {'cmd.run': mock}):
powercfg.set_hibernate_timeout(0, "dc", scheme="SCHEME_MIN")
calls = [
call('powercfg /setdcvalueindex SCHEME_MIN SUB_SLEEP HIBERNATEIDLE 0', python_shell=False)
]
mock.assert_has_calls(calls)
with patch.dict(powercfg.__salt__, {'cmd.retcode': mock}):
powercfg.set_hibernate_timeout(0, 'dc', scheme='SCHEME_MIN')
mock.assert_called_once_with(
'powercfg /setdcvalueindex SCHEME_MIN SUB_SLEEP HIBERNATEIDLE 0',
python_shell=False)
def test_get_hibernate_timeout_scheme(self):
'''
Test to make sure we can get the hibernate timeout value with a specified scheme
Test to make sure we can get the hibernate timeout value with a
specified scheme
'''
mock = MagicMock()
mock.side_effect = [self.query_output]
with patch.dict(powercfg.__salt__, {'cmd.run': mock}):
ret = powercfg.get_hibernate_timeout(scheme="SCHEME_MIN")
calls = [
call('powercfg /q SCHEME_MIN SUB_SLEEP HIBERNATEIDLE', python_shell=False)
]
mock.assert_has_calls(calls)
ret = powercfg.get_hibernate_timeout(scheme='SCHEME_MIN')
mock.assert_called_once_with(
'powercfg /q SCHEME_MIN SUB_SLEEP HIBERNATEIDLE',
python_shell=False)
self.assertEqual({'ac': 30, 'dc': 15}, ret)

View file

@ -362,6 +362,7 @@ class ZypperTestCase(TestCase, LoaderModuleMockMixin):
ZyppCallMock(return_value=get_test_data('zypper-available.txt'))), \
patch('salt.modules.zypper.refresh_db', MagicMock(return_value=True)):
self.assertEqual(zypper.latest_version('vim'), '7.4.326-2.62')
self.assertDictEqual(zypper.latest_version('vim', 'fakepkg'), {'vim': '7.4.326-2.62', 'fakepkg': ''})
def test_upgrade_success(self):
'''

View file

@ -59,6 +59,15 @@ class TestFileState(TestCase, LoaderModuleMockMixin):
}
}
def tearDown(self):
remove_dir = '/tmp/etc'
if salt.utils.platform.is_windows():
remove_dir = 'c:\\tmp\\etc'
try:
salt.utils.files.rm_rf(remove_dir)
except OSError:
pass
def test_serialize(self):
def returner(contents, *args, **kwargs):
returner.returned = contents
@ -1177,9 +1186,10 @@ class TestFileState(TestCase, LoaderModuleMockMixin):
'''
Test to ensure that some text appears at the beginning of a file.
'''
name = '/etc/motd'
name = '/tmp/etc/motd'
if salt.utils.platform.is_windows():
name = 'c:\\etc\\motd'
name = 'c:\\tmp\\etc\\motd'
assert not os.path.exists(os.path.split(name)[0])
source = ['salt://motd/hr-messages.tmpl']
sources = ['salt://motd/devops-messages.tmpl']
text = ['Trust no one unless you have eaten much salt with him.']
@ -1205,16 +1215,15 @@ class TestFileState(TestCase, LoaderModuleMockMixin):
{'file.directory_exists': mock_f,
'file.makedirs': mock_t,
'file.stats': mock_f,
'file.touch': mock_t,
'cp.get_template': mock_f,
'file.search': mock_f,
'file.prepend': mock_t}):
comt = ('The following files will be changed:\n/etc:'
comt = ('The following files will be changed:\n/tmp/etc:'
' directory - new\n')
pchanges = {'/etc': {'directory': 'new'}}
pchanges = {'/tmp/etc': {'directory': 'new'}}
if salt.utils.platform.is_windows():
comt = 'The directory "c:\\etc" will be changed'
pchanges = {'c:\\etc': {'directory': 'new'}}
comt = 'The directory "c:\\tmp\\etc" will be changed'
pchanges = {'c:\\tmp\\etc': {'directory': 'new'}}
ret.update({'comment': comt, 'name': name, 'pchanges': pchanges})
self.assertDictEqual(filestate.prepend(name, makedirs=True),
ret)

View file

@ -27,36 +27,71 @@ class PowerCfgTestCase(TestCase, LoaderModuleMockMixin):
def test_set_monitor(self):
'''
Test to make sure we can set the monitor timeout value
Test to make sure we can set the monitor timeout value
'''
ret = {'changes': {'monitor': {'ac': 0}}, 'comment': '', 'name': 'monitor', 'result': True}
monitor_val = {"ac": 45, "dc": 22}
with patch.dict(powercfg.__salt__, {"powercfg.get_monitor_timeout": MagicMock(return_value=monitor_val),
"powercfg.set_monitor_timeout": MagicMock(return_value=True)}):
self.assertEqual(powercfg.set_timeout("monitor", 0), ret)
ret = {
'changes': {
'monitor': {
'ac': {
'new': 0,
'old': 45
}
}
},
'comment': 'Monitor timeout on AC power set to 0',
'name': 'monitor',
'result': True}
get_monitor_side_effect = MagicMock(side_effect=[{"ac": 45, "dc": 22},
{"ac": 0, "dc": 22}])
with patch.dict(powercfg.__salt__,
{"powercfg.get_monitor_timeout": get_monitor_side_effect,
"powercfg.set_monitor_timeout": MagicMock(return_value=True)}):
with patch.dict(powercfg.__opts__, {"test": False}):
self.assertEqual(powercfg.set_timeout("monitor", 0), ret)
def test_set_monitor_already_set(self):
'''
Test to make sure we can set the monitor timeout value
Test to make sure we can set the monitor timeout value
'''
ret = {'changes': {}, 'comment': 'monitor ac is already set with the value 0.', 'name': 'monitor', 'result': True}
monitor_val = {"ac": 0, "dc": 0}
with patch.dict(powercfg.__salt__, {"powercfg.get_monitor_timeout": MagicMock(return_value=monitor_val),
"powercfg.set_monitor_timeout": MagicMock(return_value=True)}):
ret = {'changes': {},
'comment': 'Monitor timeout on AC power is already set to 0',
'name': 'monitor',
'result': True}
monitor_val = MagicMock(return_value={"ac": 0, "dc": 0})
with patch.dict(powercfg.__salt__, {"powercfg.get_monitor_timeout": monitor_val}):
self.assertEqual(powercfg.set_timeout("monitor", 0), ret)
def test_set_monitor_test_true_with_change(self):
'''
Test to make sure set monitor works correctly with test=True with
changes
'''
ret = {'changes': {},
'comment': 'Monitor timeout on AC power will be set to 0',
'name': 'monitor',
'result': None}
get_monitor_return_value = MagicMock(return_value={"ac": 45, "dc": 22})
with patch.dict(powercfg.__salt__, {"powercfg.get_monitor_timeout": get_monitor_return_value}):
with patch.dict(powercfg.__opts__, {"test": True}):
self.assertEqual(powercfg.set_timeout("monitor", 0), ret)
def test_fail_invalid_setting(self):
'''
Test to make sure we can set the monitor timeout value
Test to make sure we can set the monitor timeout value
'''
ret = {'changes': {}, 'comment': 'fakesetting is not a valid setting', 'name': 'fakesetting', 'result': False}
ret = {'changes': {},
'comment': '"fakesetting" is not a valid setting',
'name': 'fakesetting',
'result': False}
self.assertEqual(powercfg.set_timeout("fakesetting", 0), ret)
def test_fail_invalid_power(self):
'''
Test to make sure we can set the monitor timeout value
Test to make sure we can set the monitor timeout value
'''
ret = {'changes': {}, 'comment': 'fakepower is not a power type', 'name': 'monitor', 'result': False}
self.assertEqual(powercfg.set_timeout("monitor", 0, power="fakepower"), ret)
ret = {'changes': {},
'comment': '"fakepower" is not a power type',
'name': 'monitor',
'result': False}
self.assertEqual(powercfg.set_timeout("monitor", 0, power="fakepower"),
ret)

View file

@ -30,6 +30,7 @@ integration.modules.test_system
integration.modules.test_test
integration.modules.test_useradd
integration.modules.test_win_dns_client
integration.modules.test_win_pkg
integration.reactor.test_reactor
integration.renderers.test_pydsl
integration.returners.test_librato_return