mirror of
https://github.com/saltstack/salt.git
synced 2025-04-17 10:10:20 +00:00
Merge branch '2017.7' into '2018.3'
Conflicts: - salt/state.py - salt/utils/hashutils.py - tests/integration/modules/test_state.py
This commit is contained in:
commit
a65c60d862
14 changed files with 531 additions and 176 deletions
|
@ -797,7 +797,7 @@ mod_python.sls
|
|||
- require_in:
|
||||
- service: httpd
|
||||
|
||||
Now the httpd server will only start if php or mod_python are first verified to
|
||||
Now the httpd server will only start if both php and mod_python are first verified to
|
||||
be installed. Thus allowing for a requisite to be defined "after the fact".
|
||||
|
||||
|
||||
|
|
|
@ -247,7 +247,7 @@ def filter_by(lookup_dict,
|
|||
each case to be collected in the base and overridden by the grain
|
||||
selection dictionary and the merge dictionary. Default is None.
|
||||
|
||||
.. versionadded:: 2015.8.11, 2016.3.2
|
||||
.. versionadded:: 2015.8.11,2016.3.2
|
||||
|
||||
CLI Example:
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
'''
|
||||
Generate baseline proxy minion grains for ESXi hosts.
|
||||
|
||||
., versionadded:: 2015.8.4
|
||||
.. versionadded:: 2015.8.4
|
||||
|
||||
'''
|
||||
|
||||
|
|
|
@ -263,7 +263,7 @@ def list_(pkg=None, dir=None, runas=None, env=None, depth=None):
|
|||
depth
|
||||
Limit the depth of the packages listed
|
||||
|
||||
.. versionadded:: 2016.11.6, 2017.7.0
|
||||
.. versionadded:: 2016.11.6,2017.7.0
|
||||
|
||||
CLI Example:
|
||||
|
||||
|
|
|
@ -178,7 +178,9 @@ def enable(iface):
|
|||
'''
|
||||
if is_enabled(iface):
|
||||
return True
|
||||
cmd = ['netsh', 'interface', 'set', 'interface', iface, 'admin=ENABLED']
|
||||
cmd = ['netsh', 'interface', 'set', 'interface',
|
||||
'name={0}'.format(iface),
|
||||
'admin=ENABLED']
|
||||
__salt__['cmd.run'](cmd, python_shell=False)
|
||||
return is_enabled(iface)
|
||||
|
||||
|
@ -195,7 +197,9 @@ def disable(iface):
|
|||
'''
|
||||
if is_disabled(iface):
|
||||
return True
|
||||
cmd = ['netsh', 'interface', 'set', 'interface', iface, 'admin=DISABLED']
|
||||
cmd = ['netsh', 'interface', 'set', 'interface',
|
||||
'name={0}'.format(iface),
|
||||
'admin=DISABLED']
|
||||
__salt__['cmd.run'](cmd, python_shell=False)
|
||||
return is_disabled(iface)
|
||||
|
||||
|
@ -319,6 +323,18 @@ def set_static_dns(iface, *addrs):
|
|||
'''
|
||||
Set static DNS configuration on a Windows NIC
|
||||
|
||||
Args:
|
||||
|
||||
iface (str): The name of the interface to set
|
||||
|
||||
addrs (*):
|
||||
One or more DNS servers to be added. To clear the list of DNS
|
||||
servers pass an empty list (``[]``). If undefined or ``None`` no
|
||||
changes will be made.
|
||||
|
||||
Returns:
|
||||
dict: A dictionary containing the new DNS settings
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
@ -326,17 +342,31 @@ def set_static_dns(iface, *addrs):
|
|||
salt -G 'os_family:Windows' ip.set_static_dns 'Local Area Connection' '192.168.1.1'
|
||||
salt -G 'os_family:Windows' ip.set_static_dns 'Local Area Connection' '192.168.1.252' '192.168.1.253'
|
||||
'''
|
||||
if addrs is () or str(addrs[0]).lower() == 'none':
|
||||
return {'Interface': iface, 'DNS Server': 'No Changes'}
|
||||
# Clear the list of DNS servers if [] is passed
|
||||
if str(addrs[0]).lower() == '[]':
|
||||
log.debug('Clearing list of DNS servers')
|
||||
cmd = ['netsh', 'interface', 'ip', 'set', 'dns',
|
||||
'name={0}'.format(iface),
|
||||
'source=static',
|
||||
'address=none']
|
||||
__salt__['cmd.run'](cmd, python_shell=False)
|
||||
return {'Interface': iface, 'DNS Server': []}
|
||||
addr_index = 1
|
||||
for addr in addrs:
|
||||
if addr_index == 1:
|
||||
cmd = ['netsh', 'int', 'ip', 'set', 'dns',
|
||||
iface, 'static', addrs[0], 'primary']
|
||||
cmd = ['netsh', 'interface', 'ip', 'set', 'dns',
|
||||
'name={0}'.format(iface),
|
||||
'source=static',
|
||||
'address={0}'.format(addr),
|
||||
'register=primary']
|
||||
__salt__['cmd.run'](cmd, python_shell=False)
|
||||
addr_index = addr_index + 1
|
||||
else:
|
||||
cmd = ['netsh', 'interface', 'ip', 'add', 'dns',
|
||||
'name={0}'.format(iface),
|
||||
'addr={0}'.format(addr),
|
||||
'address={0}'.format(addr),
|
||||
'index={0}'.format(addr_index)]
|
||||
__salt__['cmd.run'](cmd, python_shell=False)
|
||||
addr_index = addr_index + 1
|
||||
|
|
|
@ -107,7 +107,7 @@ def _status_wait(service_name, end_time, service_states):
|
|||
Helper function that will wait for the status of the service to match the
|
||||
provided status before an end time expires. Used for service stop and start
|
||||
|
||||
.. versionadded:: 2017.7.9, 2018.3.4
|
||||
.. versionadded:: 2017.7.9,2018.3.4
|
||||
|
||||
Args:
|
||||
service_name (str):
|
||||
|
@ -460,7 +460,7 @@ def start(name, timeout=90):
|
|||
The time in seconds to wait for the service to start before
|
||||
returning. Default is 90 seconds
|
||||
|
||||
.. versionadded:: 2017.7.9, 2018.3.4
|
||||
.. versionadded:: 2017.7.9,2018.3.4
|
||||
|
||||
Returns:
|
||||
bool: ``True`` if successful, otherwise ``False``. Also returns ``True``
|
||||
|
@ -502,7 +502,7 @@ def stop(name, timeout=90):
|
|||
The time in seconds to wait for the service to stop before
|
||||
returning. Default is 90 seconds
|
||||
|
||||
.. versionadded:: 2017.7.9, 2018.3.4
|
||||
.. versionadded:: 2017.7.9,2018.3.4
|
||||
|
||||
Returns:
|
||||
bool: ``True`` if successful, otherwise ``False``. Also returns ``True``
|
||||
|
@ -549,7 +549,7 @@ def restart(name, timeout=90):
|
|||
then to the start command. A timeout of 90 could take up to 180
|
||||
seconds if the service is long in stopping and starting
|
||||
|
||||
.. versionadded:: 2017.7.9, 2018.3.4
|
||||
.. versionadded:: 2017.7.9,2018.3.4
|
||||
|
||||
Returns:
|
||||
bool: ``True`` if successful, otherwise ``False``
|
||||
|
@ -1212,7 +1212,7 @@ def delete(name, timeout=90):
|
|||
returning. This is necessary because a service must be stopped
|
||||
before it can be deleted. Default is 90 seconds
|
||||
|
||||
.. versionadded:: 2017.7.9, 2018.3.4
|
||||
.. versionadded:: 2017.7.9,2018.3.4
|
||||
|
||||
Returns:
|
||||
bool: ``True`` if successful, otherwise ``False``. Also returns ``True``
|
||||
|
|
|
@ -37,6 +37,7 @@ import salt.utils.decorators.state
|
|||
import salt.utils.dictupdate
|
||||
import salt.utils.event
|
||||
import salt.utils.files
|
||||
import salt.utils.hashutils
|
||||
import salt.utils.immutabletypes as immutabletypes
|
||||
import salt.utils.platform
|
||||
import salt.utils.process
|
||||
|
@ -1750,7 +1751,9 @@ class State(object):
|
|||
ret['duration'] = duration
|
||||
|
||||
troot = os.path.join(self.opts['cachedir'], self.jid)
|
||||
tfile = os.path.join(troot, _clean_tag(tag))
|
||||
tfile = os.path.join(
|
||||
troot,
|
||||
salt.utils.hashutils.sha1_digest(tag))
|
||||
if not os.path.isdir(troot):
|
||||
try:
|
||||
os.makedirs(troot)
|
||||
|
@ -2204,7 +2207,10 @@ class State(object):
|
|||
proc = running[tag].get('proc')
|
||||
if proc:
|
||||
if not proc.is_alive():
|
||||
ret_cache = os.path.join(self.opts['cachedir'], self.jid, _clean_tag(tag))
|
||||
ret_cache = os.path.join(
|
||||
self.opts['cachedir'],
|
||||
self.jid,
|
||||
salt.utils.hashutils.sha1_digest(tag))
|
||||
if not os.path.isfile(ret_cache):
|
||||
ret = {'result': False,
|
||||
'comment': 'Parallel process failed to return',
|
||||
|
|
|
@ -102,22 +102,20 @@ def _validate(dns_proto, dns_servers, ip_proto, ip_addrs, gateway):
|
|||
if dns_servers is not None:
|
||||
errors.append(
|
||||
'The dns_servers param cannot be set if unless dns_proto is '
|
||||
'set to \'static\'.'
|
||||
'set to \'static\''
|
||||
)
|
||||
else:
|
||||
if not dns_servers:
|
||||
errors.append(
|
||||
'The dns_servers param is required to set static DNS servers.'
|
||||
)
|
||||
if str(dns_servers).lower() in ['none', '[]']:
|
||||
pass
|
||||
elif not isinstance(dns_servers, list):
|
||||
errors.append(
|
||||
'The dns_servers param must be formatted as a list.'
|
||||
'The dns_servers param must be formatted as a list'
|
||||
)
|
||||
else:
|
||||
bad_ips = [x for x in dns_servers
|
||||
if not salt.utils.validate.net.ipv4_addr(x)]
|
||||
if bad_ips:
|
||||
errors.append('Invalid DNS server IPs: {0}.'
|
||||
errors.append('Invalid DNS server IPs: {0}'
|
||||
.format(', '.join(bad_ips)))
|
||||
|
||||
# Validate IP configuration
|
||||
|
@ -125,33 +123,33 @@ def _validate(dns_proto, dns_servers, ip_proto, ip_addrs, gateway):
|
|||
if ip_addrs is not None:
|
||||
errors.append(
|
||||
'The ip_addrs param cannot be set if unless ip_proto is set '
|
||||
'to \'static\'.'
|
||||
'to \'static\''
|
||||
)
|
||||
if gateway is not None:
|
||||
errors.append(
|
||||
'A gateway IP cannot be set if unless ip_proto is set to '
|
||||
'\'static\'.'
|
||||
'\'static\''
|
||||
)
|
||||
else:
|
||||
if not ip_addrs:
|
||||
errors.append(
|
||||
'The ip_addrs param is required to set static IPs.'
|
||||
'The ip_addrs param is required to set static IPs'
|
||||
)
|
||||
elif not isinstance(ip_addrs, list):
|
||||
errors.append(
|
||||
'The ip_addrs param must be formatted as a list.'
|
||||
'The ip_addrs param must be formatted as a list'
|
||||
)
|
||||
else:
|
||||
bad_ips = [x for x in ip_addrs
|
||||
if not salt.utils.validate.net.ipv4_addr(x)]
|
||||
if bad_ips:
|
||||
errors.append('The following static IPs are invalid: '
|
||||
'{0}.'.format(', '.join(bad_ips)))
|
||||
'{0}'.format(', '.join(bad_ips)))
|
||||
|
||||
# Validate default gateway
|
||||
if gateway is not None:
|
||||
if not salt.utils.validate.net.ipv4_addr(gateway):
|
||||
errors.append('Gateway IP {0} is invalid.'.format(gateway))
|
||||
errors.append('Gateway IP {0} is invalid'.format(gateway))
|
||||
|
||||
return errors
|
||||
|
||||
|
@ -178,7 +176,10 @@ def _changes(cur, dns_proto, dns_servers, ip_proto, ip_addrs, gateway):
|
|||
else 'dhcp'
|
||||
)
|
||||
if cur_dns_proto == 'static':
|
||||
cur_dns_servers = cur['Statically Configured DNS Servers']
|
||||
if isinstance(cur['Statically Configured DNS Servers'], list):
|
||||
cur_dns_servers = cur['Statically Configured DNS Servers']
|
||||
else:
|
||||
cur_dns_servers = [cur['Statically Configured DNS Servers']]
|
||||
if set(dns_servers or ['None']) != set(cur_dns_servers):
|
||||
changes['dns_servers'] = dns_servers
|
||||
elif 'DNS servers configured through DHCP' in cur:
|
||||
|
@ -216,37 +217,66 @@ def managed(name,
|
|||
'''
|
||||
Ensure that the named interface is configured properly.
|
||||
|
||||
name
|
||||
The name of the interface to manage
|
||||
Args:
|
||||
|
||||
dns_proto : None
|
||||
Set to ``static`` and use the ``dns_servers`` parameter to provide a
|
||||
list of DNS nameservers. set to ``dhcp`` to use DHCP to get the DNS
|
||||
servers.
|
||||
name (str):
|
||||
The name of the interface to manage
|
||||
|
||||
dns_servers : None
|
||||
A list of static DNS servers.
|
||||
dns_proto (str): None
|
||||
Set to ``static`` and use the ``dns_servers`` parameter to provide a
|
||||
list of DNS nameservers. set to ``dhcp`` to use DHCP to get the DNS
|
||||
servers.
|
||||
|
||||
ip_proto : None
|
||||
Set to ``static`` and use the ``ip_addrs`` and (optionally) ``gateway``
|
||||
parameters to provide a list of static IP addresses and the default
|
||||
gateway. Set to ``dhcp`` to use DHCP.
|
||||
dns_servers (list): None
|
||||
A list of static DNS servers. To clear the list of DNS servers pass
|
||||
an empty list (``[]``). ``None`` will make no changes.
|
||||
|
||||
ip_addrs : None
|
||||
A list of static IP addresses.
|
||||
ip_proto (str): None
|
||||
Set to ``static`` and use the ``ip_addrs`` and (optionally)
|
||||
``gateway`` parameters to provide a list of static IP addresses and
|
||||
the default gateway. Set to ``dhcp`` to use DHCP.
|
||||
|
||||
gateway : None
|
||||
A list of static IP addresses.
|
||||
ip_addrs (list): None
|
||||
A list of static IP addresses with netmask flag, ie: 192.168.0.11/24
|
||||
|
||||
enabled : True
|
||||
Set to ``False`` to ensure that this interface is disabled.
|
||||
gateway (str): None
|
||||
The gateway to set for the interface
|
||||
|
||||
enabled (bool): True
|
||||
Set to ``False`` to ensure that this interface is disabled.
|
||||
|
||||
Returns:
|
||||
dict: A dictionary of old and new settings
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
Ethernet1:
|
||||
network.managed:
|
||||
- dns_proto: static
|
||||
- dns_servers:
|
||||
- 8.8.8.8
|
||||
- 8.8.8.4
|
||||
- ip_proto: static
|
||||
- ip_addrs:
|
||||
- 192.168.0.100/24
|
||||
|
||||
Clear DNS entries example:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
Ethernet1:
|
||||
network.managed:
|
||||
- dns_proto: static
|
||||
- dns_servers: []
|
||||
- ip_proto: dhcp
|
||||
'''
|
||||
ret = {
|
||||
'name': name,
|
||||
'changes': {},
|
||||
'result': True,
|
||||
'comment': 'Interface \'{0}\' is up to date.'.format(name)
|
||||
'comment': 'Interface \'{0}\' is up to date'.format(name)
|
||||
}
|
||||
|
||||
dns_proto = six.text_type(dns_proto).lower()
|
||||
|
@ -255,16 +285,16 @@ def managed(name,
|
|||
errors = []
|
||||
if dns_proto not in __VALID_PROTO:
|
||||
ret['result'] = False
|
||||
errors.append('dns_proto must be one of the following: {0}.'
|
||||
errors.append('dns_proto must be one of the following: {0}'
|
||||
.format(', '.join(__VALID_PROTO)))
|
||||
|
||||
if ip_proto not in __VALID_PROTO:
|
||||
errors.append('ip_proto must be one of the following: {0}.'
|
||||
errors.append('ip_proto must be one of the following: {0}'
|
||||
.format(', '.join(__VALID_PROTO)))
|
||||
|
||||
if errors:
|
||||
ret['result'] = False
|
||||
ret['comment'] = ' '.join(errors)
|
||||
ret['comment'] = '\n'.join(errors)
|
||||
return ret
|
||||
|
||||
try:
|
||||
|
@ -303,7 +333,7 @@ def managed(name,
|
|||
if errors:
|
||||
ret['result'] = False
|
||||
ret['comment'] = ('The following SLS configuration errors were '
|
||||
'detected: {0}'.format(' '.join(errors)))
|
||||
'detected:\n- {0}'.format('\n- '.join(errors)))
|
||||
return ret
|
||||
|
||||
old = __salt__['ip.get_interface'](name)
|
||||
|
@ -319,49 +349,63 @@ def managed(name,
|
|||
ip_proto,
|
||||
ip_addrs,
|
||||
gateway)
|
||||
|
||||
# If dns_servers is the default `None` make no changes
|
||||
# To clear the list, pass an empty dict
|
||||
if str(dns_servers).lower() == 'none':
|
||||
changes.pop('dns_servers', None)
|
||||
|
||||
if not changes:
|
||||
return ret
|
||||
|
||||
if __opts__['test']:
|
||||
comments = []
|
||||
if 'dns_proto' in changes:
|
||||
comments.append('DNS protocol will be changed to: {0}.'
|
||||
comments.append('DNS protocol will be changed to: {0}'
|
||||
.format(changes['dns_proto']))
|
||||
if dns_proto == 'static' and 'dns_servers' in changes:
|
||||
comments.append(
|
||||
'DNS servers will be set to the following: {0}.'
|
||||
.format(', '.join(changes['dns_servers']))
|
||||
)
|
||||
if len(changes['dns_servers']) == 0:
|
||||
comments.append('The list of DNS servers will be cleared')
|
||||
else:
|
||||
comments.append(
|
||||
'DNS servers will be set to the following: {0}'
|
||||
.format(', '.join(changes['dns_servers']))
|
||||
)
|
||||
if 'ip_proto' in changes:
|
||||
comments.append('IP protocol will be changed to: {0}.'
|
||||
comments.append('IP protocol will be changed to: {0}'
|
||||
.format(changes['ip_proto']))
|
||||
if ip_proto == 'static':
|
||||
if 'ip_addrs' in changes:
|
||||
comments.append(
|
||||
'IP addresses will be set to the following: {0}.'
|
||||
'IP addresses will be set to the following: {0}'
|
||||
.format(', '.join(changes['ip_addrs']))
|
||||
)
|
||||
if 'gateway' in changes:
|
||||
if changes['gateway'] is None:
|
||||
comments.append('Default gateway will be removed.')
|
||||
comments.append('Default gateway will be removed')
|
||||
else:
|
||||
comments.append(
|
||||
'Default gateway will be set to {0}.'
|
||||
'Default gateway will be set to {0}'
|
||||
.format(changes['gateway'])
|
||||
)
|
||||
|
||||
ret['result'] = None
|
||||
ret['comment'] = ('The following changes will be made to '
|
||||
'interface \'{0}\': {1}'
|
||||
.format(name, ' '.join(comments)))
|
||||
'interface \'{0}\':\n- {1}'
|
||||
.format(name, '\n- '.join(comments)))
|
||||
return ret
|
||||
|
||||
if changes.get('dns_proto') == 'dhcp':
|
||||
__salt__['ip.set_dhcp_dns'](name)
|
||||
|
||||
elif changes.get('dns_servers'):
|
||||
if changes.get('dns_servers'):
|
||||
__salt__['ip.set_static_dns'](name, *changes['dns_servers'])
|
||||
elif 'dns_servers' in changes:
|
||||
if len(changes['dns_servers']) == 0:
|
||||
# To clear the list of DNS servers you have to pass []. Later
|
||||
# changes gets passed like *args and a single empty list is
|
||||
# converted to an empty tuple. So, you have to add [] here
|
||||
changes['dns_servers'] = [[]]
|
||||
|
||||
__salt__['ip.set_static_dns'](name, *changes['dns_servers'])
|
||||
|
||||
if changes.get('ip_proto') == 'dhcp':
|
||||
__salt__['ip.set_dhcp_ip'](name)
|
||||
|
|
|
@ -92,6 +92,16 @@ def md5_digest(instr):
|
|||
)
|
||||
|
||||
|
||||
def sha1_digest(instr):
|
||||
'''
|
||||
Generate an sha1 hash of a given string.
|
||||
'''
|
||||
if six.PY3:
|
||||
b = salt.utils.to_bytes(instr)
|
||||
return hashlib.sha1(b).hexdigest()
|
||||
return hashlib.sha1(instr).hexdigest()
|
||||
|
||||
|
||||
@jinja_filter('sha256')
|
||||
def sha256_digest(instr):
|
||||
'''
|
||||
|
|
9
tests/integration/files/file/base/issue-49738/init.sls
Normal file
9
tests/integration/files/file/base/issue-49738/init.sls
Normal file
|
@ -0,0 +1,9 @@
|
|||
test_cmd_too_long:
|
||||
cmd.run:
|
||||
- name: {{ pillar['long_command'] }}
|
||||
- parallel: True
|
||||
|
||||
test_cmd_not_found:
|
||||
cmd.run:
|
||||
- name: {{ pillar['short_command'] }}
|
||||
- parallel: True
|
|
@ -2,8 +2,10 @@
|
|||
|
||||
# Import Python libs
|
||||
from __future__ import absolute_import, print_function, unicode_literals
|
||||
import logging
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
import tempfile
|
||||
import textwrap
|
||||
import threading
|
||||
|
@ -13,10 +15,11 @@ import time
|
|||
from tests.support.case import ModuleCase
|
||||
from tests.support.helpers import with_tempdir
|
||||
from tests.support.unit import skipIf
|
||||
from tests.support.paths import FILES, TMP, TMP_PILLAR_TREE
|
||||
from tests.support.paths import BASE_FILES, TMP, TMP_PILLAR_TREE
|
||||
from tests.support.mixins import SaltReturnAssertsMixin
|
||||
|
||||
# Import Salt libs
|
||||
import salt.utils.atomicfile
|
||||
import salt.utils.files
|
||||
import salt.utils.path
|
||||
import salt.utils.platform
|
||||
|
@ -26,7 +29,6 @@ from salt.modules.virtualenv_mod import KNOWN_BINARY_NAMES
|
|||
# Import 3rd-party libs
|
||||
from salt.ext import six
|
||||
|
||||
import logging
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
|
@ -68,14 +70,22 @@ class StateModuleTest(ModuleCase, SaltReturnAssertsMixin):
|
|||
|
||||
maxDiff = None
|
||||
|
||||
def setUp(self):
|
||||
super(StateModuleTest, self).setUp()
|
||||
destpath = os.path.join(FILES, 'file', 'base', 'testappend', 'firstif')
|
||||
reline(destpath, destpath, force=True)
|
||||
destpath = os.path.join(FILES, 'file', 'base', 'testappend', 'secondif')
|
||||
reline(destpath, destpath, force=True)
|
||||
sls = self.run_function('saltutil.sync_modules')
|
||||
assert isinstance(sls, list)
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
def _reline(path, ending=DEFAULT_ENDING):
|
||||
'''
|
||||
Normalize the line endings of a file.
|
||||
'''
|
||||
with salt.utils.fopen(path, 'rb') as fhr:
|
||||
lines = fhr.read().splitlines()
|
||||
with salt.utils.atomicfile.atomic_open(path, 'wb') as fhw:
|
||||
for line in lines:
|
||||
fhw.write(line + ending)
|
||||
|
||||
destpath = os.path.join(BASE_FILES, 'testappend', 'firstif')
|
||||
_reline(destpath)
|
||||
destpath = os.path.join(BASE_FILES, 'testappend', 'secondif')
|
||||
_reline(destpath)
|
||||
|
||||
def test_show_highstate(self):
|
||||
'''
|
||||
|
@ -1818,18 +1828,50 @@ class StateModuleTest(ModuleCase, SaltReturnAssertsMixin):
|
|||
test state.sls with saltenv using a nonbase environment
|
||||
with a salt source
|
||||
'''
|
||||
file_name = os.path.join(TMP, 'nonbase_env')
|
||||
state_run = self.run_function(
|
||||
filename = os.path.join(TMP, 'nonbase_env')
|
||||
try:
|
||||
ret = self.run_function(
|
||||
'state.sls',
|
||||
mods='non-base-env',
|
||||
saltenv='prod'
|
||||
)
|
||||
ret = ret[next(iter(ret))]
|
||||
assert ret['result']
|
||||
assert ret['comment'] == 'File {0} updated'.format(filename)
|
||||
assert os.path.isfile(filename)
|
||||
finally:
|
||||
try:
|
||||
os.remove(filename)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
@skipIf(sys.platform.startswith('win'), 'Skipped until parallel states can be fixed on Windows')
|
||||
def test_parallel_state_with_long_tag(self):
|
||||
'''
|
||||
This tests the case where the state being executed has a long ID dec or
|
||||
name and states are being run in parallel. The filenames used for the
|
||||
parallel state cache were previously based on the tag for each chunk,
|
||||
and longer ID decs or name params can cause the cache file to be longer
|
||||
than the operating system's max file name length. To counter this we
|
||||
instead generate a SHA1 hash of the chunk's tag to use as the cache
|
||||
filename. This test will ensure that long tags don't cause caching
|
||||
failures.
|
||||
|
||||
See https://github.com/saltstack/salt/issues/49738 for more info.
|
||||
'''
|
||||
short_command = 'helloworld'
|
||||
long_command = short_command * 25
|
||||
|
||||
ret = self.run_function(
|
||||
'state.sls',
|
||||
mods='non-base-env',
|
||||
saltenv='prod'
|
||||
mods='issue-49738',
|
||||
pillar={'short_command': short_command,
|
||||
'long_command': long_command}
|
||||
)
|
||||
state_id = 'file_|-test_file_|-{0}_|-managed'.format(file_name)
|
||||
self.assertEqual(state_run[state_id]['comment'],
|
||||
'File {0} updated'.format(file_name))
|
||||
self.assertTrue(
|
||||
state_run['file_|-test_file_|-{0}_|-managed'.format(file_name)]['result'])
|
||||
self.assertTrue(os.path.isfile(file_name))
|
||||
comments = sorted([x['comment'] for x in six.itervalues(ret)])
|
||||
expected = sorted(['Command "{0}" run'.format(x)
|
||||
for x in (short_command, long_command)])
|
||||
assert comments == expected, '{0} != {1}'.format(comments, expected)
|
||||
|
||||
def _add_runtime_pillar(self, pillar):
|
||||
'''
|
||||
|
|
|
@ -432,7 +432,8 @@ class SaltTestingParser(optparse.OptionParser):
|
|||
if self.options.tests_logfile:
|
||||
filehandler = logging.FileHandler(
|
||||
mode='w', # Not preserved between re-runs
|
||||
filename=self.options.tests_logfile
|
||||
filename=self.options.tests_logfile,
|
||||
encoding='utf-8',
|
||||
)
|
||||
# The logs of the file are the most verbose possible
|
||||
filehandler.setLevel(logging.DEBUG)
|
||||
|
|
|
@ -13,7 +13,8 @@ from tests.support.mock import (
|
|||
MagicMock,
|
||||
patch,
|
||||
NO_MOCK,
|
||||
NO_MOCK_REASON
|
||||
NO_MOCK_REASON,
|
||||
call
|
||||
)
|
||||
|
||||
# Import Salt Libs
|
||||
|
@ -124,13 +125,21 @@ class WinShadowTestCase(TestCase, LoaderModuleMockMixin):
|
|||
'''
|
||||
Test if it enable an interface.
|
||||
'''
|
||||
mock_cmd = MagicMock(return_value=ETHERNET_ENABLE)
|
||||
with patch.dict(win_ip.__salt__, {'cmd.run': mock_cmd}):
|
||||
# Test with enabled interface
|
||||
with patch.object(win_ip, 'is_enabled', return_value=True):
|
||||
self.assertTrue(win_ip.enable('Ethernet'))
|
||||
|
||||
mock_cmd = MagicMock(return_value='Connect state: Disconnected')
|
||||
with patch.dict(win_ip.__salt__, {'cmd.run': mock_cmd}):
|
||||
self.assertFalse(win_ip.enable('Ethernet'))
|
||||
mock_cmd = MagicMock()
|
||||
with patch.object(win_ip, 'is_enabled', side_effect=[False, True]), \
|
||||
patch.dict(win_ip.__salt__, {'cmd.run': mock_cmd}):
|
||||
self.assertTrue(win_ip.enable('Ethernet'))
|
||||
|
||||
mock_cmd.called_once_with(
|
||||
['netsh', 'interface', 'set', 'interface',
|
||||
'name=Ethernet',
|
||||
'admin=ENABLED'],
|
||||
python_shell=False
|
||||
)
|
||||
|
||||
# 'disable' function tests: 1
|
||||
|
||||
|
@ -138,14 +147,21 @@ class WinShadowTestCase(TestCase, LoaderModuleMockMixin):
|
|||
'''
|
||||
Test if it disable an interface.
|
||||
'''
|
||||
mock_cmd = MagicMock(return_value=ETHERNET_ENABLE)
|
||||
with patch.dict(win_ip.__salt__, {'cmd.run': mock_cmd}):
|
||||
self.assertFalse(win_ip.disable('Ethernet'))
|
||||
|
||||
mock_cmd = MagicMock(return_value='Connect state: Disconnected')
|
||||
with patch.dict(win_ip.__salt__, {'cmd.run': mock_cmd}):
|
||||
with patch.object(win_ip, 'is_disabled', return_value=True):
|
||||
self.assertTrue(win_ip.disable('Ethernet'))
|
||||
|
||||
mock_cmd = MagicMock()
|
||||
with patch.object(win_ip, 'is_disabled', side_effect=[False, True]),\
|
||||
patch.dict(win_ip.__salt__, {'cmd.run': mock_cmd}):
|
||||
self.assertTrue(win_ip.disable('Ethernet'))
|
||||
|
||||
mock_cmd.called_once_with(
|
||||
['netsh', 'interface', 'set', 'interface',
|
||||
'name=Ethernet',
|
||||
'admin=DISABLED'],
|
||||
python_shell=False
|
||||
)
|
||||
|
||||
# 'get_subnet_length' function tests: 1
|
||||
|
||||
def test_get_subnet_length(self):
|
||||
|
@ -203,7 +219,7 @@ class WinShadowTestCase(TestCase, LoaderModuleMockMixin):
|
|||
'''
|
||||
Test if it set static DNS configuration on a Windows NIC.
|
||||
'''
|
||||
mock_cmd = MagicMock(return_value=ETHERNET_CONFIG)
|
||||
mock_cmd = MagicMock()
|
||||
with patch.dict(win_ip.__salt__, {'cmd.run': mock_cmd}):
|
||||
self.assertDictEqual(win_ip.set_static_dns('Ethernet',
|
||||
'192.168.1.252',
|
||||
|
@ -211,6 +227,54 @@ class WinShadowTestCase(TestCase, LoaderModuleMockMixin):
|
|||
{'DNS Server': ('192.168.1.252',
|
||||
'192.168.1.253'),
|
||||
'Interface': 'Ethernet'})
|
||||
mock_cmd.assert_has_calls([
|
||||
call(['netsh', 'interface', 'ip', 'set', 'dns',
|
||||
'name=Ethernet',
|
||||
'source=static',
|
||||
'address=192.168.1.252',
|
||||
'register=primary'],
|
||||
python_shell=False),
|
||||
call(['netsh', 'interface', 'ip', 'add', 'dns',
|
||||
'name=Ethernet',
|
||||
'address=192.168.1.253',
|
||||
'index=2'],
|
||||
python_shell=False)]
|
||||
)
|
||||
|
||||
def test_set_static_dns_clear(self):
|
||||
'''
|
||||
Test if it set static DNS configuration on a Windows NIC.
|
||||
'''
|
||||
mock_cmd = MagicMock()
|
||||
with patch.dict(win_ip.__salt__, {'cmd.run': mock_cmd}):
|
||||
self.assertDictEqual(win_ip.set_static_dns('Ethernet', []),
|
||||
{'DNS Server': [],
|
||||
'Interface': 'Ethernet'})
|
||||
mock_cmd.assert_called_once_with(
|
||||
['netsh', 'interface', 'ip', 'set', 'dns',
|
||||
'name=Ethernet',
|
||||
'source=static',
|
||||
'address=none'],
|
||||
python_shell=False
|
||||
)
|
||||
|
||||
def test_set_static_dns_no_action(self):
|
||||
'''
|
||||
Test if it set static DNS configuration on a Windows NIC.
|
||||
'''
|
||||
# Test passing nothing
|
||||
self.assertDictEqual(win_ip.set_static_dns('Ethernet'),
|
||||
{'DNS Server': 'No Changes',
|
||||
'Interface': 'Ethernet'})
|
||||
# Test passing None
|
||||
self.assertDictEqual(win_ip.set_static_dns('Ethernet', None),
|
||||
{'DNS Server': 'No Changes',
|
||||
'Interface': 'Ethernet'})
|
||||
|
||||
# Test passing string None
|
||||
self.assertDictEqual(win_ip.set_static_dns('Ethernet', 'None'),
|
||||
{'DNS Server': 'No Changes',
|
||||
'Interface': 'Ethernet'})
|
||||
|
||||
# 'set_dhcp_dns' function tests: 1
|
||||
|
||||
|
|
|
@ -28,93 +28,242 @@ class WinNetworkTestCase(TestCase, LoaderModuleMockMixin):
|
|||
def setup_loader_modules(self):
|
||||
return {win_network: {}}
|
||||
|
||||
def test_managed(self):
|
||||
def test_managed_missing_parameters(self):
|
||||
'''
|
||||
Test to ensure that the named interface is configured properly.
|
||||
Test to ensure that the named interface is configured properly.
|
||||
'''
|
||||
ret = {'name': 'salt',
|
||||
'changes': {},
|
||||
'result': False,
|
||||
'comment': ''}
|
||||
ret.update({'comment': 'dns_proto must be one of the following:'
|
||||
' static, dhcp. ip_proto must be one of the following:'
|
||||
' static, dhcp.'})
|
||||
'comment': 'dns_proto must be one of the following: static, dhcp\n'
|
||||
'ip_proto must be one of the following: static, dhcp'}
|
||||
self.assertDictEqual(win_network.managed('salt'), ret)
|
||||
|
||||
def test_managed_static_enabled_false(self):
|
||||
ret = {'name': 'salt',
|
||||
'changes': {},
|
||||
'result': True,
|
||||
'comment': 'Interface \'salt\' is up to date (already disabled)'}
|
||||
mock_false = MagicMock(return_value=False)
|
||||
with patch.dict(win_network.__salt__, {"ip.is_enabled": mock_false}):
|
||||
self.assertDictEqual(
|
||||
win_network.managed(
|
||||
'salt', dns_proto='static', ip_proto='static', enabled=False),
|
||||
ret)
|
||||
|
||||
def test_managed_test_true(self):
|
||||
ret = {'name': 'salt',
|
||||
'changes': {},
|
||||
'result': False,
|
||||
'comment': 'Failed to enable interface \'salt\' to make changes'}
|
||||
mock_false = MagicMock(return_value=False)
|
||||
mock_true = MagicMock(return_value=True)
|
||||
mock1 = MagicMock(side_effect=[False, True, True, True, True, True,
|
||||
True])
|
||||
mock2 = MagicMock(side_effect=[False, True, True, {'salt': 'True'},
|
||||
{'salt': 'True'}])
|
||||
with patch.dict(win_network.__salt__, {"ip.is_enabled": mock_false,
|
||||
"ip.is_disabled": mock1,
|
||||
"ip.enable": mock_false,
|
||||
"ip.get_interface": mock2,
|
||||
"ip.set_dhcp_dns": mock_false,
|
||||
"ip.set_dhcp_ip": mock_false}):
|
||||
ret.update({'comment': "Interface 'salt' is up to date."
|
||||
" (already disabled)", 'result': True})
|
||||
self.assertDictEqual(win_network.managed('salt',
|
||||
dns_proto='static',
|
||||
ip_proto='static',
|
||||
enabled=False), ret)
|
||||
"ip.enable": mock_false}), \
|
||||
patch.dict(win_network.__opts__, {"test": False}):
|
||||
self.assertDictEqual(
|
||||
win_network.managed(
|
||||
'salt', dns_proto='static', ip_proto='static'),
|
||||
ret)
|
||||
|
||||
with patch.dict(win_network.__opts__, {"test": False}):
|
||||
ret.update({'comment': "Failed to enable interface 'salt'"
|
||||
" to make changes", 'result': False})
|
||||
self.assertDictEqual(win_network.managed('salt',
|
||||
dns_proto='static',
|
||||
ip_proto='static'),
|
||||
ret)
|
||||
mock_false = MagicMock(side_effect=['True', False, False, False, False,
|
||||
False])
|
||||
def test_managed_validate_errors(self):
|
||||
ret = {'name': 'salt',
|
||||
'changes': {},
|
||||
'result': False,
|
||||
'comment': 'The following SLS configuration errors were '
|
||||
'detected:\n'
|
||||
'- First Error\n'
|
||||
'- Second Error'}
|
||||
mock_true = MagicMock(return_value=True)
|
||||
mock_validate = MagicMock(return_value=['First Error', 'Second Error'])
|
||||
with patch.dict(win_network.__salt__, {"ip.is_enabled": mock_true}),\
|
||||
patch.object(win_network, '_validate', mock_validate):
|
||||
self.assertDictEqual(
|
||||
win_network.managed(
|
||||
'salt', dns_proto='static', ip_proto='static'),
|
||||
ret)
|
||||
|
||||
with patch.dict(win_network.__salt__, {"ip.is_enabled": mock_true}):
|
||||
with patch.object(win_network, '_validate', mock_false):
|
||||
ret.update({'comment': 'The following SLS configuration'
|
||||
' errors were detected: T r u e'})
|
||||
self.assertDictEqual(win_network.managed('salt',
|
||||
dns_proto='static',
|
||||
ip_proto='static'),
|
||||
ret)
|
||||
def test_managed_get_current_config_failed(self):
|
||||
ret = {'name': 'salt',
|
||||
'changes': {},
|
||||
'result': False,
|
||||
'comment': 'Unable to get current configuration for interface '
|
||||
'\'salt\''}
|
||||
mock_true = MagicMock(return_value=True)
|
||||
mock_false = MagicMock(return_value=False)
|
||||
mock_validate = MagicMock(return_value=[])
|
||||
with patch.dict(win_network.__salt__, {'ip.is_enabled': mock_true,
|
||||
'ip.get_interface': mock_false}), \
|
||||
patch.object(win_network, '_validate', mock_validate):
|
||||
|
||||
ret.update({'comment': "Unable to get current"
|
||||
" configuration for interface 'salt'",
|
||||
'result': False})
|
||||
self.assertDictEqual(win_network.managed('salt',
|
||||
dns_proto='dhcp',
|
||||
ip_proto='dhcp'),
|
||||
ret)
|
||||
self.assertDictEqual(
|
||||
win_network.managed('salt', dns_proto='dhcp', ip_proto='dhcp'),
|
||||
ret)
|
||||
|
||||
mock_false = MagicMock(side_effect=[False, [''],
|
||||
{'dns_proto': 'dhcp',
|
||||
'ip_proto': 'dhcp'},
|
||||
{'dns_proto': 'dhcp',
|
||||
'ip_proto': 'dhcp'}])
|
||||
ret.update({'comment': "Interface 'salt' is up to date.",
|
||||
'result': True})
|
||||
with patch.object(win_network, '_changes', mock_false):
|
||||
self.assertDictEqual(win_network.managed('salt',
|
||||
dns_proto='dhcp',
|
||||
ip_proto='dhcp'
|
||||
), ret)
|
||||
def test_managed_test_true_no_changes(self):
|
||||
ret = {'name': 'salt',
|
||||
'changes': {},
|
||||
'result': True,
|
||||
'comment': 'Interface \'salt\' is up to date'}
|
||||
mock_true = MagicMock(return_value=True)
|
||||
mock_validate = MagicMock(return_value=[])
|
||||
mock_get_int = MagicMock(return_value={
|
||||
'DHCP enabled': 'yes',
|
||||
'DNS servers configured through DHCP': '192.168.0.10'})
|
||||
with patch.dict(win_network.__salt__, {'ip.is_enabled': mock_true,
|
||||
'ip.get_interface': mock_get_int}), \
|
||||
patch.dict(win_network.__opts__, {"test": True}), \
|
||||
patch.object(win_network, '_validate', mock_validate):
|
||||
self.assertDictEqual(
|
||||
win_network.managed('salt', dns_proto='dhcp', ip_proto='dhcp'),
|
||||
ret)
|
||||
|
||||
ret.update({'comment': "The following changes will be made"
|
||||
" to interface 'salt': ", 'result': None})
|
||||
with patch.dict(win_network.__opts__, {"test": True}):
|
||||
self.assertDictEqual(win_network.managed('salt',
|
||||
dns_proto='dh'
|
||||
'cp',
|
||||
ip_proto='dhcp'
|
||||
), ret)
|
||||
def test_managed_test_true_changes(self):
|
||||
ret = {'name': 'salt',
|
||||
'changes': {},
|
||||
'result': None,
|
||||
'comment': 'The following changes will be made to interface '
|
||||
'\'salt\':\n'
|
||||
'- DNS protocol will be changed to: dhcp'}
|
||||
mock_true = MagicMock(return_value=True)
|
||||
mock_validate = MagicMock(return_value=[])
|
||||
mock_get_int = MagicMock(return_value={
|
||||
'DHCP enabled': 'no',
|
||||
'Statically Configured DNS Servers': '192.168.0.10'})
|
||||
with patch.dict(win_network.__salt__, {'ip.is_enabled': mock_true,
|
||||
'ip.get_interface': mock_get_int}), \
|
||||
patch.dict(win_network.__opts__, {"test": True}), \
|
||||
patch.object(win_network, '_validate', mock_validate):
|
||||
|
||||
with patch.dict(win_network.__opts__, {"test": False}):
|
||||
ret.update({'comment': "Failed to set desired"
|
||||
" configuration settings for interface"
|
||||
" 'salt'", 'result': False})
|
||||
self.assertDictEqual(win_network.managed('salt',
|
||||
dns_proto='dh'
|
||||
'cp',
|
||||
ip_proto='dhcp'
|
||||
), ret)
|
||||
self.assertDictEqual(
|
||||
win_network.managed('salt', dns_proto='dhcp', ip_proto='dhcp'),
|
||||
ret)
|
||||
|
||||
def test_managed_failed(self):
|
||||
ret = {'name': 'salt',
|
||||
'changes': {},
|
||||
'result': False,
|
||||
'comment': 'Failed to set desired configuration settings for '
|
||||
'interface \'salt\''}
|
||||
mock_true = MagicMock(return_value=True)
|
||||
mock_validate = MagicMock(return_value=[])
|
||||
mock_get_int = MagicMock(return_value={
|
||||
'DHCP enabled': 'no',
|
||||
'Statically Configured DNS Servers': '192.168.0.10'})
|
||||
with patch.dict(win_network.__salt__, {'ip.is_enabled': mock_true,
|
||||
'ip.get_interface': mock_get_int,
|
||||
'ip.set_dhcp_dns': mock_true,
|
||||
'ip.set_dhcp_ip': mock_true}), \
|
||||
patch.dict(win_network.__opts__, {"test": False}), \
|
||||
patch.object(win_network, '_validate', mock_validate):
|
||||
self.assertDictEqual(
|
||||
win_network.managed('salt', dns_proto='dhcp', ip_proto='dhcp'),
|
||||
ret)
|
||||
|
||||
def test_managed(self):
|
||||
ret = {'name': 'salt',
|
||||
'changes': {
|
||||
'DHCP enabled': {
|
||||
'new': 'yes',
|
||||
'old': 'no'},
|
||||
'DNS servers configured through DHCP': {
|
||||
'new': '192.168.0.10',
|
||||
'old': ''},
|
||||
'Statically Configured DNS Servers': {
|
||||
'new': '',
|
||||
'old': '192.168.0.10'
|
||||
}
|
||||
},
|
||||
'result': True,
|
||||
'comment': 'Successfully updated configuration for interface '
|
||||
'\'salt\''}
|
||||
mock_true = MagicMock(return_value=True)
|
||||
mock_validate = MagicMock(return_value=[])
|
||||
mock_get_int = MagicMock(side_effect=[
|
||||
{'DHCP enabled': 'no', 'Statically Configured DNS Servers': '192.168.0.10'},
|
||||
{'DHCP enabled': 'yes', 'DNS servers configured through DHCP': '192.168.0.10'},
|
||||
])
|
||||
with patch.dict(win_network.__salt__, {'ip.is_enabled': mock_true,
|
||||
'ip.get_interface': mock_get_int,
|
||||
'ip.set_dhcp_dns': mock_true,
|
||||
'ip.set_dhcp_ip': mock_true}), \
|
||||
patch.dict(win_network.__opts__, {"test": False}), \
|
||||
patch.object(win_network, '_validate', mock_validate):
|
||||
self.assertDictEqual(
|
||||
win_network.managed('salt', dns_proto='dhcp', ip_proto='dhcp'),
|
||||
ret)
|
||||
|
||||
def test_managed_static_dns_clear(self):
|
||||
expected = {'name': 'salt',
|
||||
'changes': {
|
||||
'Statically Configured DNS Servers': {
|
||||
'new': 'None',
|
||||
'old': '192.168.0.10'
|
||||
}
|
||||
},
|
||||
'result': True,
|
||||
'comment': 'Successfully updated configuration for '
|
||||
'interface \'salt\''}
|
||||
mock_true = MagicMock(return_value=True)
|
||||
mock_validate = MagicMock(return_value=[])
|
||||
mock_get_int = MagicMock(side_effect=[
|
||||
{'DHCP enabled': 'no', 'Statically Configured DNS Servers': '192.168.0.10'},
|
||||
{'DHCP enabled': 'no', 'Statically Configured DNS Servers': 'None'},
|
||||
])
|
||||
with patch.dict(win_network.__salt__, {'ip.is_enabled': mock_true,
|
||||
'ip.get_interface': mock_get_int,
|
||||
'ip.set_static_dns': mock_true}), \
|
||||
patch.dict(win_network.__opts__, {"test": False}), \
|
||||
patch.object(win_network, '_validate', mock_validate):
|
||||
ret = win_network.managed(
|
||||
'salt', dns_proto='static', dns_servers=[], ip_proto='dhcp')
|
||||
self.assertDictEqual(ret, expected)
|
||||
|
||||
def test_managed_static_dns(self):
|
||||
expected = {'name': 'salt',
|
||||
'changes': {
|
||||
'Statically Configured DNS Servers': {
|
||||
'new': '192.168.0.10',
|
||||
'old': 'None'
|
||||
}
|
||||
},
|
||||
'result': True,
|
||||
'comment': 'Successfully updated configuration for '
|
||||
'interface \'salt\''}
|
||||
mock_true = MagicMock(return_value=True)
|
||||
mock_validate = MagicMock(return_value=[])
|
||||
mock_get_int = MagicMock(side_effect=[
|
||||
{'DHCP enabled': 'no', 'Statically Configured DNS Servers': 'None'},
|
||||
{'DHCP enabled': 'no', 'Statically Configured DNS Servers': '192.168.0.10'},
|
||||
])
|
||||
with patch.dict(win_network.__salt__, {'ip.is_enabled': mock_true,
|
||||
'ip.get_interface': mock_get_int,
|
||||
'ip.set_static_dns': mock_true}), \
|
||||
patch.dict(win_network.__opts__, {"test": False}), \
|
||||
patch.object(win_network, '_validate', mock_validate):
|
||||
ret = win_network.managed(
|
||||
'salt', dns_proto='static', dns_servers=['192.168.0.10'], ip_proto='dhcp')
|
||||
self.assertDictEqual(ret, expected)
|
||||
|
||||
def test_managed_static_dns_no_action(self):
|
||||
expected = {'name': 'salt',
|
||||
'changes': {},
|
||||
'result': True,
|
||||
'comment': 'Interface \'salt\' is up to date'}
|
||||
mock_true = MagicMock(return_value=True)
|
||||
mock_validate = MagicMock(return_value=[])
|
||||
mock_get_int = MagicMock(return_value={
|
||||
'DHCP enabled': 'no',
|
||||
'Statically Configured DNS Servers': '192.168.0.10'
|
||||
})
|
||||
with patch.dict(win_network.__salt__, {'ip.is_enabled': mock_true,
|
||||
'ip.get_interface': mock_get_int,
|
||||
'ip.set_static_dns': mock_true}), \
|
||||
patch.dict(win_network.__opts__, {"test": False}), \
|
||||
patch.object(win_network, '_validate', mock_validate):
|
||||
# Don't pass dns_servers
|
||||
ret = win_network.managed('salt', dns_proto='static', ip_proto='dhcp')
|
||||
self.assertDictEqual(ret, expected)
|
||||
# Pass dns_servers=None
|
||||
ret = win_network.managed(
|
||||
'salt', dns_proto='static', dns_servers=None, ip_proto='dhcp')
|
||||
self.assertDictEqual(ret, expected)
|
||||
|
|
Loading…
Add table
Reference in a new issue