Merge branch '2019.2.1' into fix_test_system

This commit is contained in:
Shane Lee 2019-07-17 12:14:26 -06:00 committed by GitHub
commit f95f0e7d2b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
34 changed files with 745 additions and 329 deletions

View file

@ -74,7 +74,7 @@ node('kitchen-slave') {
stage('Create VM') {
retry(3) {
sh '''
t=$(shuf -i 1-15 -n 1); echo "Sleeping $t seconds"; sleep $t
t=$(shuf -i 30-120 -n 1); echo "Sleeping $t seconds"; sleep $t
bundle exec kitchen create $TEST_SUITE-$TEST_PLATFORM; echo "ExitCode: $?;"
'''
}

View file

@ -74,7 +74,7 @@ node('kitchen-slave') {
stage('Create VM') {
retry(3) {
sh '''
t=$(shuf -i 1-15 -n 1); echo "Sleeping $t seconds"; sleep $t
t=$(shuf -i 30-120 -n 1); echo "Sleeping $t seconds"; sleep $t
bundle exec kitchen create $TEST_SUITE-$TEST_PLATFORM; echo "ExitCode: $?;"
'''
}

View file

@ -74,7 +74,7 @@ node('kitchen-slave') {
stage('Create VM') {
retry(3) {
sh '''
t=$(shuf -i 1-15 -n 1); echo "Sleeping $t seconds"; sleep $t
t=$(shuf -i 30-120 -n 1); echo "Sleeping $t seconds"; sleep $t
bundle exec kitchen create $TEST_SUITE-$TEST_PLATFORM; echo "ExitCode: $?;"
'''
}

View file

@ -74,7 +74,7 @@ node('kitchen-slave') {
stage('Create VM') {
retry(3) {
sh '''
t=$(shuf -i 1-15 -n 1); echo "Sleeping $t seconds"; sleep $t
t=$(shuf -i 30-120 -n 1); echo "Sleeping $t seconds"; sleep $t
bundle exec kitchen create $TEST_SUITE-$TEST_PLATFORM; echo "ExitCode: $?;"
'''
}

View file

@ -74,7 +74,7 @@ node('kitchen-slave') {
stage('Create VM') {
retry(3) {
sh '''
t=$(shuf -i 1-15 -n 1); echo "Sleeping $t seconds"; sleep $t
t=$(shuf -i 30-120 -n 1); echo "Sleeping $t seconds"; sleep $t
bundle exec kitchen create $TEST_SUITE-$TEST_PLATFORM; echo "ExitCode: $?;"
'''
}

View file

@ -74,7 +74,7 @@ node('kitchen-slave') {
stage('Create VM') {
retry(3) {
sh '''
t=$(shuf -i 1-15 -n 1); echo "Sleeping $t seconds"; sleep $t
t=$(shuf -i 30-120 -n 1); echo "Sleeping $t seconds"; sleep $t
bundle exec kitchen create $TEST_SUITE-$TEST_PLATFORM; echo "ExitCode: $?;"
'''
}

View file

@ -74,7 +74,7 @@ node('kitchen-slave') {
stage('Create VM') {
retry(3) {
sh '''
t=$(shuf -i 1-15 -n 1); echo "Sleeping $t seconds"; sleep $t
t=$(shuf -i 30-120 -n 1); echo "Sleeping $t seconds"; sleep $t
bundle exec kitchen create $TEST_SUITE-$TEST_PLATFORM; echo "ExitCode: $?;"
'''
}

View file

@ -74,7 +74,7 @@ node('kitchen-slave') {
stage('Create VM') {
retry(3) {
sh '''
t=$(shuf -i 1-15 -n 1); echo "Sleeping $t seconds"; sleep $t
t=$(shuf -i 30-120 -n 1); echo "Sleeping $t seconds"; sleep $t
bundle exec kitchen create $TEST_SUITE-$TEST_PLATFORM; echo "ExitCode: $?;"
'''
}

View file

@ -74,7 +74,7 @@ node('kitchen-slave') {
stage('Create VM') {
retry(3) {
sh '''
t=$(shuf -i 1-15 -n 1); echo "Sleeping $t seconds"; sleep $t
t=$(shuf -i 30-120 -n 1); echo "Sleeping $t seconds"; sleep $t
bundle exec kitchen create $TEST_SUITE-$TEST_PLATFORM; echo "ExitCode: $?;"
'''
}

View file

@ -74,7 +74,7 @@ node('kitchen-slave') {
stage('Create VM') {
retry(3) {
sh '''
t=$(shuf -i 1-15 -n 1); echo "Sleeping $t seconds"; sleep $t
t=$(shuf -i 30-120 -n 1); echo "Sleeping $t seconds"; sleep $t
bundle exec kitchen create $TEST_SUITE-$TEST_PLATFORM; echo "ExitCode: $?;"
'''
}

View file

@ -74,7 +74,7 @@ node('kitchen-slave') {
stage('Create VM') {
retry(3) {
sh '''
t=$(shuf -i 1-15 -n 1); echo "Sleeping $t seconds"; sleep $t
t=$(shuf -i 30-120 -n 1); echo "Sleeping $t seconds"; sleep $t
bundle exec kitchen create $TEST_SUITE-$TEST_PLATFORM; echo "ExitCode: $?;"
'''
}

View file

@ -74,7 +74,7 @@ node('kitchen-slave') {
stage('Create VM') {
retry(3) {
sh '''
t=$(shuf -i 1-15 -n 1); echo "Sleeping $t seconds"; sleep $t
t=$(shuf -i 30-120 -n 1); echo "Sleeping $t seconds"; sleep $t
bundle exec kitchen create $TEST_SUITE-$TEST_PLATFORM; echo "ExitCode: $?;"
'''
}

View file

@ -74,7 +74,7 @@ node('kitchen-slave') {
stage('Create VM') {
retry(3) {
sh '''
t=$(shuf -i 1-15 -n 1); echo "Sleeping $t seconds"; sleep $t
t=$(shuf -i 30-120 -n 1); echo "Sleeping $t seconds"; sleep $t
bundle exec kitchen create $TEST_SUITE-$TEST_PLATFORM; echo "ExitCode: $?;"
'''
}

View file

@ -74,7 +74,7 @@ node('kitchen-slave') {
stage('Create VM') {
retry(3) {
sh '''
t=$(shuf -i 1-15 -n 1); echo "Sleeping $t seconds"; sleep $t
t=$(shuf -i 30-120 -n 1); echo "Sleeping $t seconds"; sleep $t
bundle exec kitchen create $TEST_SUITE-$TEST_PLATFORM; echo "ExitCode: $?;"
'''
}

View file

@ -74,7 +74,7 @@ node('kitchen-slave') {
stage('Create VM') {
retry(3) {
sh '''
t=$(shuf -i 1-15 -n 1); echo "Sleeping $t seconds"; sleep $t
t=$(shuf -i 30-120 -n 1); echo "Sleeping $t seconds"; sleep $t
bundle exec kitchen create $TEST_SUITE-$TEST_PLATFORM; echo "ExitCode: $?;"
'''
}

View file

@ -74,7 +74,7 @@ node('kitchen-slave') {
stage('Create VM') {
retry(3) {
sh '''
t=$(shuf -i 1-15 -n 1); echo "Sleeping $t seconds"; sleep $t
t=$(shuf -i 30-120 -n 1); echo "Sleeping $t seconds"; sleep $t
bundle exec kitchen create $TEST_SUITE-$TEST_PLATFORM; echo "ExitCode: $?;"
'''
}

View file

@ -74,7 +74,7 @@ node('kitchen-slave') {
stage('Create VM') {
retry(3) {
sh '''
t=$(shuf -i 1-15 -n 1); echo "Sleeping $t seconds"; sleep $t
t=$(shuf -i 30-120 -n 1); echo "Sleeping $t seconds"; sleep $t
bundle exec kitchen create $TEST_SUITE-$TEST_PLATFORM; echo "ExitCode: $?;"
'''
}

View file

@ -18,6 +18,7 @@ Refer to :mod:`junos <salt.proxy.junos>` for information on connecting to junos
from __future__ import absolute_import, print_function, unicode_literals
import logging
import os
from functools import wraps
try:
from lxml import etree
@ -69,6 +70,29 @@ def __virtual__():
'junos-eznc or jxmlease or proxy could not be loaded.')
def timeoutDecorator(function):
@wraps(function)
def wrapper(*args, **kwargs):
if 'dev_timeout' in kwargs:
conn = __proxy__['junos.conn']()
restore_timeout = conn.timeout
conn.timeout = kwargs.pop('dev_timeout', None)
try:
result = function(*args, **kwargs)
conn.timeout = restore_timeout
return result
except Exception:
conn.timeout = restore_timeout
raise
else:
try:
return function(*args, **kwargs)
except Exception:
raise
return wrapper
def facts_refresh():
'''
Reload the facts dictionary from the device. Usually only needed if,
@ -82,7 +106,7 @@ def facts_refresh():
salt 'device_name' junos.facts_refresh
'''
conn = __proxy__['junos.conn']()
ret = dict()
ret = {}
ret['out'] = True
try:
conn.facts_refresh()
@ -111,7 +135,7 @@ def facts():
salt 'device_name' junos.facts
'''
ret = dict()
ret = {}
try:
ret['facts'] = __proxy__['junos.get_serialized_facts']()
ret['out'] = True
@ -122,6 +146,7 @@ def facts():
return ret
@timeoutDecorator
def rpc(cmd=None, dest=None, **kwargs):
'''
This function executes the RPC provided as arguments on the junos device.
@ -160,7 +185,7 @@ def rpc(cmd=None, dest=None, **kwargs):
'''
conn = __proxy__['junos.conn']()
ret = dict()
ret = {}
ret['out'] = True
if cmd is None:
@ -183,7 +208,6 @@ def rpc(cmd=None, dest=None, **kwargs):
op[key] = value
else:
op.update(kwargs)
op['dev_timeout'] = six.text_type(op.pop('timeout', conn.timeout))
if cmd in ['get-config', 'get_config']:
filter_reply = None
@ -204,7 +228,6 @@ def rpc(cmd=None, dest=None, **kwargs):
ret['out'] = False
return ret
else:
op['dev_timeout'] = int(op['dev_timeout'])
if 'filter' in op:
log.warning(
'Filter ignored as it is only used with "get-config" rpc')
@ -242,6 +265,7 @@ def rpc(cmd=None, dest=None, **kwargs):
return ret
@timeoutDecorator
def set_hostname(hostname=None, **kwargs):
'''
Set the device's hostname
@ -267,7 +291,7 @@ def set_hostname(hostname=None, **kwargs):
salt 'device_name' junos.set_hostname salt-device
'''
conn = __proxy__['junos.conn']()
ret = dict()
ret = {}
if hostname is None:
ret['message'] = 'Please provide the hostname.'
ret['out'] = False
@ -318,6 +342,7 @@ def set_hostname(hostname=None, **kwargs):
return ret
@timeoutDecorator
def commit(**kwargs):
'''
To commit the changes loaded in the candidate configuration.
@ -403,6 +428,7 @@ def commit(**kwargs):
return ret
@timeoutDecorator
def rollback(**kwargs):
'''
Roll back the last committed configuration changes and commit
@ -435,7 +461,7 @@ def rollback(**kwargs):
'''
id_ = kwargs.pop('id', 0)
ret = dict()
ret = {}
conn = __proxy__['junos.conn']()
op = dict()
@ -512,7 +538,7 @@ def diff(**kwargs):
salt.utils.args.invalid_kwargs(kwargs)
conn = __proxy__['junos.conn']()
ret = dict()
ret = {}
ret['out'] = True
try:
ret['message'] = conn.cu.diff(rb_id=id_)
@ -524,6 +550,7 @@ def diff(**kwargs):
return ret
@timeoutDecorator
def ping(dest_ip=None, **kwargs):
'''
Send a ping RPC to a device
@ -558,7 +585,7 @@ def ping(dest_ip=None, **kwargs):
salt 'device_name' junos.ping '8.8.8.8' ttl=1 rapid=True
'''
conn = __proxy__['junos.conn']()
ret = dict()
ret = {}
if dest_ip is None:
ret['message'] = 'Please specify the destination ip to ping.'
@ -586,6 +613,7 @@ def ping(dest_ip=None, **kwargs):
return ret
@timeoutDecorator
def cli(command=None, **kwargs):
'''
Executes the CLI commands and returns the output in specified format. \
@ -619,7 +647,7 @@ def cli(command=None, **kwargs):
if not format_:
format_ = 'text'
ret = dict()
ret = {}
if command is None:
ret['message'] = 'Please provide the CLI command to be executed.'
ret['out'] = False
@ -688,10 +716,10 @@ def shutdown(**kwargs):
salt 'device_name' junos.shutdown shutdown=True
'''
conn = __proxy__['junos.conn']()
ret = dict()
ret = {}
sw = SW(conn)
op = dict()
op = {}
if '__pub_arg' in kwargs:
if kwargs['__pub_arg']:
if isinstance(kwargs['__pub_arg'][-1], dict):
@ -729,6 +757,7 @@ def shutdown(**kwargs):
return ret
@timeoutDecorator
def install_config(path=None, **kwargs):
'''
Installs the given configuration file into the candidate configuration.
@ -803,7 +832,7 @@ def install_config(path=None, **kwargs):
salt 'device_name' junos.install_config 'salt://syslog_template.conf' template_vars='{"syslog_host": "10.180.222.7"}'
'''
conn = __proxy__['junos.conn']()
ret = dict()
ret = {}
ret['out'] = True
if path is None:
@ -812,7 +841,7 @@ def install_config(path=None, **kwargs):
ret['out'] = False
return ret
op = dict()
op = {}
if '__pub_arg' in kwargs:
if kwargs['__pub_arg']:
if isinstance(kwargs['__pub_arg'][-1], dict):
@ -820,7 +849,8 @@ def install_config(path=None, **kwargs):
else:
op.update(kwargs)
template_vars = dict()
test = op.pop('test', False)
template_vars = {}
if "template_vars" in op:
template_vars = op["template_vars"]
@ -874,7 +904,7 @@ def install_config(path=None, **kwargs):
except Exception as exception:
ret['message'] = 'Could not load configuration due to : "{0}"'.format(
exception)
ret['format'] = template_format
ret['format'] = op['format']
ret['out'] = False
return ret
@ -903,7 +933,7 @@ def install_config(path=None, **kwargs):
ret['out'] = False
return ret
if check:
if check and not test:
try:
cu.commit(**commit_params)
ret['message'] = 'Successfully loaded and committed!'
@ -913,10 +943,14 @@ def install_config(path=None, **kwargs):
.format(exception)
ret['out'] = False
return ret
else:
ret['message'] = 'Loaded configuration but commit check failed.'
ret['out'] = False
elif not check:
cu.rollback()
ret['message'] = 'Loaded configuration but commit check failed, hence rolling back configuration.'
ret['out'] = False
else:
cu.rollback()
ret['message'] = 'Commit check passed, but skipping commit for dry-run and rolling back configuration.'
ret['out'] = True
try:
if write_diff and config_diff is not None:
@ -941,7 +975,7 @@ def zeroize():
salt 'device_name' junos.zeroize
'''
conn = __proxy__['junos.conn']()
ret = dict()
ret = {}
ret['out'] = True
try:
conn.cli('request system zeroize')
@ -953,6 +987,7 @@ def zeroize():
return ret
@timeoutDecorator
def install_os(path=None, **kwargs):
'''
Installs the given image on the device. After the installation is complete\
@ -962,8 +997,19 @@ def install_os(path=None, **kwargs):
path (required)
Path where the image file is present on the proxy minion
remote_path :
If the value of path is a file path on the local
(Salt host's) filesystem, then the image is copied from the local
filesystem to the :remote_path: directory on the target Junos
device. The default is ``/var/tmp``. If the value of :path: or
is a URL, then the value of :remote_path: is unused.
dev_timeout : 30
The NETCONF RPC timeout (in seconds)
The NETCONF RPC timeout (in seconds). This argument was added since most of
the time the "package add" RPC takes a significant amount of time. The default
RPC timeout is 30 seconds. So this :timeout: value will be
used in the context of the SW installation process. Defaults to
30 minutes (30*60=1800)
reboot : False
Whether to reboot after installation
@ -971,6 +1017,23 @@ def install_os(path=None, **kwargs):
no_copy : False
If ``True`` the software package will not be SCPd to the device
bool validate:
When ``True`` this method will perform a config validation against
the new image
bool issu:
When ``True`` allows unified in-service software upgrade
(ISSU) feature enables you to upgrade between two different Junos OS
releases with no disruption on the control plane and with minimal
disruption of traffic.
bool nssu:
When ``True`` allows nonstop software upgrade (NSSU)
enables you to upgrade the software running on a Juniper Networks
EX Series Virtual Chassis or a Juniper Networks EX Series Ethernet
Switch with redundant Routing Engines with a single command and
minimal disruption to network traffic.
CLI Examples:
.. code-block:: bash
@ -979,30 +1042,10 @@ def install_os(path=None, **kwargs):
salt 'device_name' junos.install_os 'salt://junos_16_1.tgz' dev_timeout=300
'''
conn = __proxy__['junos.conn']()
ret = dict()
ret = {}
ret['out'] = True
if path is None:
ret['message'] = \
'Please provide the salt path where the junos image is present.'
ret['out'] = False
return ret
image_cached_path = salt.utils.files.mkstemp()
__salt__['cp.get_file'](path, image_cached_path)
if not os.path.isfile(image_cached_path):
ret['message'] = 'Invalid image path.'
ret['out'] = False
return ret
if os.path.getsize(image_cached_path) == 0:
ret['message'] = 'Failed to copy image'
ret['out'] = False
return ret
path = image_cached_path
op = dict()
op = {}
if '__pub_arg' in kwargs:
if kwargs['__pub_arg']:
if isinstance(kwargs['__pub_arg'][-1], dict):
@ -1010,15 +1053,39 @@ def install_os(path=None, **kwargs):
else:
op.update(kwargs)
no_copy_ = op.get('no_copy', False)
if path is None:
ret['message'] = \
'Please provide the salt path where the junos image is present.'
ret['out'] = False
return ret
if not no_copy_:
image_cached_path = salt.utils.files.mkstemp()
__salt__['cp.get_file'](path, image_cached_path)
if not os.path.isfile(image_cached_path):
ret['message'] = 'Invalid image path.'
ret['out'] = False
return ret
if os.path.getsize(image_cached_path) == 0:
ret['message'] = 'Failed to copy image'
ret['out'] = False
return ret
path = image_cached_path
try:
conn.sw.install(path, progress=True)
conn.sw.install(path, progress=True, **op)
ret['message'] = 'Installed the os.'
except Exception as exception:
ret['message'] = 'Installation failed due to: "{0}"'.format(exception)
ret['out'] = False
return ret
finally:
salt.utils.files.safe_rm(image_cached_path)
if not no_copy_:
salt.utils.files.safe_rm(image_cached_path)
if 'reboot' in op and op['reboot'] is True:
try:
@ -1050,7 +1117,7 @@ def file_copy(src=None, dest=None):
salt 'device_name' junos.file_copy /home/m2/info.txt info_copy.txt
'''
conn = __proxy__['junos.conn']()
ret = dict()
ret = {}
ret['out'] = True
if src is None:
@ -1098,7 +1165,7 @@ def lock():
salt 'device_name' junos.lock
'''
conn = __proxy__['junos.conn']()
ret = dict()
ret = {}
ret['out'] = True
try:
conn.cu.lock()
@ -1121,7 +1188,7 @@ def unlock():
salt 'device_name' junos.unlock
'''
conn = __proxy__['junos.conn']()
ret = dict()
ret = {}
ret['out'] = True
try:
conn.cu.unlock()
@ -1188,7 +1255,7 @@ def load(path=None, **kwargs):
salt 'device_name' junos.load 'salt://syslog_template.conf' template_vars='{"syslog_host": "10.180.222.7"}'
'''
conn = __proxy__['junos.conn']()
ret = dict()
ret = {}
ret['out'] = True
if path is None:
@ -1197,7 +1264,7 @@ def load(path=None, **kwargs):
ret['out'] = False
return ret
op = dict()
op = {}
if '__pub_arg' in kwargs:
if kwargs['__pub_arg']:
if isinstance(kwargs['__pub_arg'][-1], dict):
@ -1205,7 +1272,7 @@ def load(path=None, **kwargs):
else:
op.update(kwargs)
template_vars = dict()
template_vars = {}
if "template_vars" in op:
template_vars = op["template_vars"]
@ -1252,7 +1319,7 @@ def load(path=None, **kwargs):
except Exception as exception:
ret['message'] = 'Could not load configuration due to : "{0}"'.format(
exception)
ret['format'] = template_format
ret['format'] = op['format']
ret['out'] = False
return ret
finally:
@ -1272,7 +1339,7 @@ def commit_check():
salt 'device_name' junos.commit_check
'''
conn = __proxy__['junos.conn']()
ret = dict()
ret = {}
ret['out'] = True
try:
conn.cu.commit_check()

View file

@ -5517,7 +5517,7 @@ def _getAdmlPresentationRefId(adml_data, ref_id):
if prepended_text:
prepended_text = ' '.join((text for text in (prepended_text, getattr(p_item, 'text', '').rstrip()) if text))
else:
prepended_text = getattr(p_item, 'text', '').rstrip()
prepended_text = getattr(p_item, 'text', '').rstrip() if getattr(p_item, 'text', '') else ''
else:
prepended_text = ''
if prepended_text.endswith('.'):

View file

@ -46,10 +46,9 @@ try:
import jnpr.junos.utils
import jnpr.junos.utils.config
import jnpr.junos.utils.sw
from jnpr.junos.exception import RpcTimeoutError
from jnpr.junos.exception import ConnectClosedError
from jnpr.junos.exception import RpcError
from jnpr.junos.exception import ConnectError
from jnpr.junos.exception import RpcTimeoutError, ConnectClosedError,\
RpcError, ConnectError, ProbeError, ConnectAuthError,\
ConnectRefusedError, ConnectTimeoutError
from ncclient.operations.errors import TimeoutExpiredError
except ImportError:
HAS_JUNOS = False
@ -106,9 +105,32 @@ def init(opts):
args[arg] = opts['proxy'][arg]
thisproxy['conn'] = jnpr.junos.Device(**args)
thisproxy['conn'].open()
thisproxy['conn'].bind(cu=jnpr.junos.utils.config.Config)
thisproxy['conn'].bind(sw=jnpr.junos.utils.sw.SW)
try:
thisproxy['conn'].open()
except (ProbeError, ConnectAuthError, ConnectRefusedError, ConnectTimeoutError,
ConnectError) as ex:
log.error("{} : not able to initiate connection to the device".format(str(ex)))
thisproxy['initialized'] = False
return
if 'timeout' in proxy_keys:
timeout = int(opts['proxy']['timeout'])
try:
thisproxy['conn'].timeout = timeout
except Exception as ex:
log.error('Not able to set timeout due to: %s', str(ex))
else:
log.debug('RPC timeout set to %d seconds', timeout)
try:
thisproxy['conn'].bind(cu=jnpr.junos.utils.config.Config)
except Exception as ex:
log.error('Bind failed with Config class due to: {}'.format(str(ex)))
try:
thisproxy['conn'].bind(sw=jnpr.junos.utils.sw.SW)
except Exception as ex:
log.error('Bind failed with SW class due to: {}'.format(str(ex)))
thisproxy['initialized'] = True
@ -129,6 +151,20 @@ def alive(opts):
dev = conn()
thisproxy['conn'].connected = ping()
if not dev.connected:
__salt__['event.fire_master']({}, 'junos/proxy/{}/stop'.format(
opts['proxy']['host']))
return dev.connected
def ping():
'''
Ping? Pong!
'''
dev = conn()
# Check that the underlying netconf connection still exists.
if dev._conn is None:
return False
@ -137,16 +173,35 @@ def alive(opts):
# rpc call is going on.
if hasattr(dev._conn, '_session'):
if dev._conn._session._transport.is_active():
# there is no on going rpc call.
if dev._conn._session._q.empty():
thisproxy['conn'].connected = ping()
# there is no on going rpc call. buffer tell can be 1 as it stores
# remaining char after "]]>]]>" which can be a new line char
if dev._conn._session._buffer.tell() <= 1 and \
dev._conn._session._q.empty():
return _rpc_file_list(dev)
else:
log.debug('skipped ping() call as proxy already getting data')
return True
else:
# ssh connection is lost
dev.connected = False
return False
else:
# other connection modes, like telnet
thisproxy['conn'].connected = ping()
return dev.connected
return _rpc_file_list(dev)
def _rpc_file_list(dev):
try:
dev.rpc.file_list(path='/dev/null', dev_timeout=5)
return True
except (RpcTimeoutError, ConnectClosedError):
try:
dev.close()
return False
except (RpcError, ConnectError, TimeoutExpiredError):
return False
except AttributeError as ex:
if "'NoneType' object has no attribute 'timeout'" in ex:
return False
def proxytype():
@ -170,22 +225,6 @@ def get_serialized_facts():
return facts
def ping():
'''
Ping? Pong!
'''
dev = conn()
try:
dev.rpc.file_list(path='/dev/null', dev_timeout=2)
return True
except (RpcTimeoutError, ConnectClosedError):
try:
dev.close()
except (RpcError, ConnectError, TimeoutExpiredError):
return False
def shutdown(opts):
'''
This is called when the proxy-minion is exiting to make sure the

View file

@ -16,10 +16,22 @@ Refer to :mod:`junos <salt.proxy.junos>` for information on connecting to junos
# Import Python libs
from __future__ import absolute_import, print_function, unicode_literals
import logging
from functools import wraps
log = logging.getLogger()
def resultdecorator(function):
@wraps(function)
def wrapper(*args, **kwargs):
ret = function(*args, **kwargs)
ret['result'] = ret['changes']['out']
return ret
return wrapper
@resultdecorator
def rpc(name, dest=None, format='xml', args=None, **kwargs):
'''
Executes the given rpc. The returned data can be stored in a file
@ -71,6 +83,7 @@ def rpc(name, dest=None, format='xml', args=None, **kwargs):
return ret
@resultdecorator
def set_hostname(name, **kwargs):
'''
Changes the hostname of the device.
@ -104,6 +117,7 @@ def set_hostname(name, **kwargs):
return ret
@resultdecorator
def commit(name, **kwargs):
'''
Commits the changes loaded into the candidate configuration.
@ -147,6 +161,7 @@ def commit(name, **kwargs):
return ret
@resultdecorator
def rollback(name, id, **kwargs):
'''
Rollbacks the committed changes.
@ -181,6 +196,7 @@ def rollback(name, id, **kwargs):
return ret
@resultdecorator
def diff(name, d_id):
'''
Gets the difference between the candidate and the current configuration.
@ -202,6 +218,7 @@ def diff(name, d_id):
return ret
@resultdecorator
def cli(name, **kwargs):
'''
Executes the CLI commands and reuturns the text output.
@ -234,6 +251,7 @@ def cli(name, **kwargs):
return ret
@resultdecorator
def shutdown(name, **kwargs):
'''
Shuts down the device.
@ -260,6 +278,7 @@ def shutdown(name, **kwargs):
return ret
@resultdecorator
def install_config(name, **kwargs):
'''
Loads and commits the configuration provided.
@ -331,6 +350,7 @@ def install_config(name, **kwargs):
return ret
@resultdecorator
def zeroize(name):
'''
Resets the device to default factory settings.
@ -347,6 +367,7 @@ def zeroize(name):
return ret
@resultdecorator
def install_os(name, **kwargs):
'''
Installs the given image on the device. After the installation is complete
@ -382,6 +403,7 @@ def install_os(name, **kwargs):
return ret
@resultdecorator
def file_copy(name, dest=None, **kwargs):
'''
Copies the file from the local device to the junos device.
@ -405,6 +427,7 @@ def file_copy(name, dest=None, **kwargs):
return ret
@resultdecorator
def lock(name):
'''
Attempts an exclusive lock on the candidate configuration. This
@ -426,6 +449,7 @@ def lock(name):
return ret
@resultdecorator
def unlock(name):
'''
Unlocks the candidate configuration.
@ -441,6 +465,7 @@ def unlock(name):
return ret
@resultdecorator
def load(name, **kwargs):
'''
Loads the configuration provided onto the junos device.
@ -502,6 +527,7 @@ def load(name, **kwargs):
return ret
@resultdecorator
def commit_check(name):
'''

View file

@ -177,6 +177,7 @@ class PkgModuleTest(ModuleCase, SaltReturnAssertsMixin):
test_install()
test_remove()
@skipIf(True, 'WAR ROOM TEMPORARY SKIP') # needs to be rewritten to allow for dnf on Fedora 30 and RHEL 8
@skipIf(salt.utils.platform.is_windows(), "Skip on windows")
@requires_salt_modules('pkg.hold', 'pkg.unhold')
@requires_network()

View file

@ -102,11 +102,12 @@ class WinLgpoTest(ModuleCase):
re.IGNORECASE | re.MULTILINE)
self.assertIsNotNone(match, 'Failed validating policy "{0}" configuration, regex "{1}" not found in secedit output'.format(policy_name, expected_regex))
def _testComputerAdmxPolicy(self,
policy_name,
policy_config,
expected_regexes,
assert_true=True):
def _testAdmxPolicy(self,
policy_name,
policy_config,
expected_regexes,
assert_true=True,
policy_class='Machine'):
'''
Takes a ADMX policy name and config and validates that the expected
output is returned from lgpo looking at the Registry.pol file
@ -119,14 +120,24 @@ class WinLgpoTest(ModuleCase):
the expected regexes to be found in the lgpo parse output
assert_true
set to false if expecting the module run to fail
policy_class
the policy class this policy belongs to, either Machine or User
'''
ret = self.run_function('lgpo.set_computer_policy',
lgpo_function = 'set_computer_policy'
lgpo_class = '/m'
lgpo_folder = 'Machine'
if policy_class.lower() == 'user':
lgpo_function = 'set_user_policy'
lgpo_class = '/u'
lgpo_folder = 'User'
ret = self.run_function('lgpo.{0}'.format(lgpo_function),
(policy_name, policy_config))
log.debug('lgpo set_computer_policy ret == %s', ret)
cmd = ['lgpo.exe',
'/parse',
'/m',
r'c:\Windows\System32\GroupPolicy\Machine\Registry.pol']
lgpo_class,
r'c:\Windows\System32\GroupPolicy\{}\Registry.pol'.format(lgpo_folder)]
if assert_true:
self.assertTrue(ret)
lgpo_output = self.run_function('cmd.run', (), cmd=' '.join(cmd))
@ -178,47 +189,92 @@ class WinLgpoTest(ModuleCase):
enforce_toplevel=False)
log.debug('ret from archive.unzip == %s', ret)
@destructiveTest
def test_set_user_policy_point_and_print_restrictions(self):
'''
Test setting/unsetting/changing the PointAndPrint_Restrictions user policy
'''
# Disable Point and Print Restrictions
self._testAdmxPolicy(
r'Control Panel\Printers\Point and Print Restrictions',
'Disabled',
[
r'User[\s]*Software\\Policies\\Microsoft\\Windows NT\\Printers\\PointAndPrint[\s]*Restricted[\s]*DWORD:0',
r'User[\s]*Software\\Policies\\Microsoft\\Windows NT\\Printers\\PointAndPrint[\s]*TrustedServers[\s]*DELETE',
r'User[\s]*Software\\Policies\\Microsoft\\Windows NT\\Printers\\PointAndPrint[\s]*ServerList[\s]*DELETE',
r'User[\s]*Software\\Policies\\Microsoft\\Windows NT\\Printers\\PointAndPrint[\s]*InForest[\s]*DELETE',
r'User[\s]*Software\\Policies\\Microsoft\\Windows NT\\Printers\\PointAndPrint[\s]*NoWarningNoElevationOnInstall[\s]*DELETE',
r'User[\s]*Software\\Policies\\Microsoft\\Windows NT\\Printers\\PointAndPrint[\s]*UpdatePromptSettings[\s]*DELETE',
],
policy_class='User')
# Enable Point and Print Restrictions
self._testAdmxPolicy(
r'Control Panel\Printers\Point and Print Restrictions',
{
'Users can only point and print to these servers': True,
'Enter fully qualified server names separated by semicolons': 'fakeserver1;fakeserver2',
'Users can only point and print to machines in their forest': True,
'Security Prompts: When installing drivers for a new connection': 'Show warning and elevation prompt',
'When updating drivers for an existing connection': 'Do not show warning or elevation prompt',
},
[
r'User[\s]*Software\\Policies\\Microsoft\\Windows NT\\Printers\\PointAndPrint[\s]*Restricted[\s]*DWORD:1',
r'User[\s]*Software\\Policies\\Microsoft\\Windows NT\\Printers\\PointAndPrint[\s]*TrustedServers[\s]*DWORD:1',
r'User[\s]*Software\\Policies\\Microsoft\\Windows NT\\Printers\\PointAndPrint[\s]*ServerList[\s]*SZ:fakeserver1;fakeserver2',
r'User[\s]*Software\\Policies\\Microsoft\\Windows NT\\Printers\\PointAndPrint[\s]*InForest[\s]*DWORD:1',
r'User[\s]*Software\\Policies\\Microsoft\\Windows NT\\Printers\\PointAndPrint[\s]*NoWarningNoElevationOnInstall[\s]*DWORD:0',
r'User[\s]*Software\\Policies\\Microsoft\\Windows NT\\Printers\\PointAndPrint[\s]*UpdatePromptSettings[\s]*DWORD:2',
],
policy_class='User')
# set Point and Print Restrictions to 'Not Configured'
self._testAdmxPolicy(
r'Control Panel\Printers\Point and Print Restrictions',
'Not Configured',
[
r'; Source file: c:\\windows\\system32\\grouppolicy\\user\\registry.pol[\s]*; PARSING COMPLETED.'],
policy_class='User')
@destructiveTest
def test_set_computer_policy_NTP_Client(self):
'''
Test setting/unsetting/changing NTP Client policies
'''
# Disable Configure NTP Client
self._testComputerAdmxPolicy(r'System\Windows Time Service\Time Providers\Configure Windows NTP Client',
'Disabled',
[
r'Computer[\s]*Software\\Policies\\Microsoft\\W32time\\Parameters[\s]*NtpServer[\s]*DELETE',
r'Computer[\s]*Software\\Policies\\Microsoft\\W32time\\Parameters[\s]*Type[\s]*DELETE',
r'Computer[\s]*Software\\Policies\\Microsoft\\W32time\\TimeProviders\\NtpClient[\s]*CrossSiteSyncFlags[\s]*DELETE',
r'Computer[\s]*Software\\Policies\\Microsoft\\W32time\\TimeProviders\\NtpClient[\s]*ResolvePeerBackoffMinutes[\s]*DELETE',
r'Computer[\s]*Software\\Policies\\Microsoft\\W32time\\TimeProviders\\NtpClient[\s]*ResolvePeerBackoffMaxTimes[\s]*DELETE',
r'Computer[\s]*Software\\Policies\\Microsoft\\W32time\\TimeProviders\\NtpClient[\s]*SpecialPollInterval[\s]*DELETE',
r'Computer[\s]*Software\\Policies\\Microsoft\\W32time\\TimeProviders\\NtpClient[\s]*EventLogFlags[\s]*DELETE'
])
self._testAdmxPolicy(r'System\Windows Time Service\Time Providers\Configure Windows NTP Client',
'Disabled',
[
r'Computer[\s]*Software\\Policies\\Microsoft\\W32time\\Parameters[\s]*NtpServer[\s]*DELETE',
r'Computer[\s]*Software\\Policies\\Microsoft\\W32time\\Parameters[\s]*Type[\s]*DELETE',
r'Computer[\s]*Software\\Policies\\Microsoft\\W32time\\TimeProviders\\NtpClient[\s]*CrossSiteSyncFlags[\s]*DELETE',
r'Computer[\s]*Software\\Policies\\Microsoft\\W32time\\TimeProviders\\NtpClient[\s]*ResolvePeerBackoffMinutes[\s]*DELETE',
r'Computer[\s]*Software\\Policies\\Microsoft\\W32time\\TimeProviders\\NtpClient[\s]*ResolvePeerBackoffMaxTimes[\s]*DELETE',
r'Computer[\s]*Software\\Policies\\Microsoft\\W32time\\TimeProviders\\NtpClient[\s]*SpecialPollInterval[\s]*DELETE',
r'Computer[\s]*Software\\Policies\\Microsoft\\W32time\\TimeProviders\\NtpClient[\s]*EventLogFlags[\s]*DELETE'
])
# Enable Configure NTP Client
self._testComputerAdmxPolicy(r'System\Windows Time Service\Time Providers\Configure Windows NTP Client',
{
'NtpServer': 'time.windows.com,0x9',
'Type': 'NT5DS',
'CrossSiteSyncFlags': 2,
'ResolvePeerBackoffMinutes': 15,
'ResolvePeerBackoffMaxTimes': 7,
'W32TIME_SpecialPollInterval': 3600,
'W32TIME_NtpClientEventLogFlags': 0
},
[
r'Computer[\s]*Software\\Policies\\Microsoft\\W32time\\Parameters[\s]*NtpServer[\s]*SZ:time.windows.com,0x9',
r'Computer[\s]*Software\\Policies\\Microsoft\\W32time\\Parameters[\s]*Type[\s]*SZ:NT5DS',
r'Computer[\s]*Software\\Policies\\Microsoft\\W32time\\TimeProviders\\NtpClient[\s]*CrossSiteSyncFlags[\s]*DWORD:2',
r'Computer[\s]*Software\\Policies\\Microsoft\\W32time\\TimeProviders\\NtpClient[\s]*ResolvePeerBackoffMinutes[\s]*DWORD:15',
r'Computer[\s]*Software\\Policies\\Microsoft\\W32time\\TimeProviders\\NtpClient[\s]*ResolvePeerBackoffMaxTimes[\s]*DWORD:7',
r'Computer[\s]*Software\\Policies\\Microsoft\\W32time\\TimeProviders\\NtpClient[\s]*SpecialPollInterval[\s]*DWORD:3600',
r'Computer[\s]*Software\\Policies\\Microsoft\\W32time\\TimeProviders\\NtpClient[\s]*EventLogFlags[\s]*DWORD:0',
])
self._testAdmxPolicy(r'System\Windows Time Service\Time Providers\Configure Windows NTP Client',
{
'NtpServer': 'time.windows.com,0x9',
'Type': 'NT5DS',
'CrossSiteSyncFlags': 2,
'ResolvePeerBackoffMinutes': 15,
'ResolvePeerBackoffMaxTimes': 7,
'W32TIME_SpecialPollInterval': 3600,
'W32TIME_NtpClientEventLogFlags': 0
},
[
r'Computer[\s]*Software\\Policies\\Microsoft\\W32time\\Parameters[\s]*NtpServer[\s]*SZ:time.windows.com,0x9',
r'Computer[\s]*Software\\Policies\\Microsoft\\W32time\\Parameters[\s]*Type[\s]*SZ:NT5DS',
r'Computer[\s]*Software\\Policies\\Microsoft\\W32time\\TimeProviders\\NtpClient[\s]*CrossSiteSyncFlags[\s]*DWORD:2',
r'Computer[\s]*Software\\Policies\\Microsoft\\W32time\\TimeProviders\\NtpClient[\s]*ResolvePeerBackoffMinutes[\s]*DWORD:15',
r'Computer[\s]*Software\\Policies\\Microsoft\\W32time\\TimeProviders\\NtpClient[\s]*ResolvePeerBackoffMaxTimes[\s]*DWORD:7',
r'Computer[\s]*Software\\Policies\\Microsoft\\W32time\\TimeProviders\\NtpClient[\s]*SpecialPollInterval[\s]*DWORD:3600',
r'Computer[\s]*Software\\Policies\\Microsoft\\W32time\\TimeProviders\\NtpClient[\s]*EventLogFlags[\s]*DWORD:0',
])
# set Configure NTP Client to 'Not Configured'
self._testComputerAdmxPolicy(r'System\Windows Time Service\Time Providers\Configure Windows NTP Client',
'Not Configured',
[r'; Source file: c:\\windows\\system32\\grouppolicy\\machine\\registry.pol[\s]*; PARSING COMPLETED.'])
self._testAdmxPolicy(r'System\Windows Time Service\Time Providers\Configure Windows NTP Client',
'Not Configured',
[r'; Source file: c:\\windows\\system32\\grouppolicy\\machine\\registry.pol[\s]*; PARSING COMPLETED.'])
@destructiveTest
def test_set_computer_policy_RA_Unsolicit(self):
@ -228,44 +284,44 @@ class WinLgpoTest(ModuleCase):
# Disable RA_Unsolicit
log.debug('Attempting to disable RA_Unsolicit')
self._testComputerAdmxPolicy('RA_Unsolicit',
'Disabled',
[
r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services[\s]*fAllowUnsolicited[\s]*DWORD:0',
r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services[\s]*fAllowUnsolicitedFullControl[\s]*DELETE',
r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services\\RAUnsolicit[\s]*\*[\s]*DELETEALLVALUES',
])
self._testAdmxPolicy('RA_Unsolicit',
'Disabled',
[
r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services[\s]*fAllowUnsolicited[\s]*DWORD:0',
r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services[\s]*fAllowUnsolicitedFullControl[\s]*DELETE',
r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services\\RAUnsolicit[\s]*\*[\s]*DELETEALLVALUES',
])
# configure RA_Unsolicit
log.debug('Attempting to configure RA_Unsolicit')
self._testComputerAdmxPolicy('RA_Unsolicit',
{
'Configure Offer Remote Access': 'Enabled',
'Permit remote control of this computer': 'Allow helpers to remotely control the computer',
'Helpers': ['administrators', 'user1']
},
[
r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services\\RAUnsolicit[\s]*user1[\s]*SZ:user1[\s]*',
r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services\\RAUnsolicit[\s]*administrators[\s]*SZ:administrators[\s]*',
r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services[\s]*fAllowUnsolicited[\s]*DWORD:1',
r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services[\s]*fAllowUnsolicitedFullControl[\s]*DWORD:1',
])
self._testAdmxPolicy('RA_Unsolicit',
{
'Configure Offer Remote Access': 'Enabled',
'Permit remote control of this computer': 'Allow helpers to remotely control the computer',
'Helpers': ['administrators', 'user1']
},
[
r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services\\RAUnsolicit[\s]*user1[\s]*SZ:user1[\s]*',
r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services\\RAUnsolicit[\s]*administrators[\s]*SZ:administrators[\s]*',
r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services[\s]*fAllowUnsolicited[\s]*DWORD:1',
r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services[\s]*fAllowUnsolicitedFullControl[\s]*DWORD:1',
])
# Not Configure RA_Unsolicit
log.debug('Attempting to set RA_Unsolicit to Not Configured')
self._testComputerAdmxPolicy('RA_Unsolicit',
'Not Configured',
[r'; Source file: c:\\windows\\system32\\grouppolicy\\machine\\registry.pol[\s]*; PARSING COMPLETED.'])
self._testAdmxPolicy('RA_Unsolicit',
'Not Configured',
[r'; Source file: c:\\windows\\system32\\grouppolicy\\machine\\registry.pol[\s]*; PARSING COMPLETED.'])
@destructiveTest
def test_set_computer_policy_Pol_HardenedPaths(self):
# Disable Pol_HardenedPaths
log.debug('Attempting to disable Pol_HardenedPaths')
self._testComputerAdmxPolicy(
self._testAdmxPolicy(
'Pol_HardenedPaths',
'Disabled',
[r'Computer[\s]*Software\\policies\\Microsoft\\Windows\\NetworkProvider\\HardenedPaths[\s]*\*[\s]*DELETEALLVALUES'])
# Configure Pol_HardenedPaths
log.debug('Attempting to configure Pol_HardenedPaths')
self._testComputerAdmxPolicy(
self._testAdmxPolicy(
'Pol_HardenedPaths',
{
'Hardened UNC Paths': {
@ -279,7 +335,7 @@ class WinLgpoTest(ModuleCase):
])
# Not Configure Pol_HardenedPaths
log.debug('Attempting to set Pol_HardenedPaths to Not Configured')
self._testComputerAdmxPolicy(
self._testAdmxPolicy(
'Pol_HardenedPaths',
'Not Configured',
[r'; Source file: c:\\windows\\system32\\grouppolicy\\machine\\registry.pol[\s]*; PARSING COMPLETED.'])
@ -323,9 +379,9 @@ class WinLgpoTest(ModuleCase):
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*ScheduledInstallTime[\s]*DWORD:17',
]
# test as False
self._testComputerAdmxPolicy(r'Windows Components\Windows Update\Configure Automatic Updates',
the_policy,
the_policy_check)
self._testAdmxPolicy(r'Windows Components\Windows Update\Configure Automatic Updates',
the_policy,
the_policy_check)
# configure as True for "enable Automatic Updates" test below
the_policy = {
'Configure automatic updating': '4 - Auto download and schedule the install',
@ -342,25 +398,25 @@ class WinLgpoTest(ModuleCase):
]
# enable Automatic Updates
self._testComputerAdmxPolicy(r'Windows Components\Windows Update\Configure Automatic Updates',
the_policy,
the_policy_check)
self._testAdmxPolicy(r'Windows Components\Windows Update\Configure Automatic Updates',
the_policy,
the_policy_check)
# disable Configure Automatic Updates
self._testComputerAdmxPolicy(r'Windows Components\Windows Update\Configure Automatic Updates',
'Disabled',
[
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*NoAutoUpdate[\s]*DWORD:1',
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*AUOptions[\s]*DELETE',
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*AutomaticMaintenanceEnabled[\s]*DELETE',
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*ScheduledInstallDay[\s]*DELETE',
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*ScheduledInstallTime[\s]*DELETE',
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*AllowMUUpdateService[\s]*DELETE'
])
self._testAdmxPolicy(r'Windows Components\Windows Update\Configure Automatic Updates',
'Disabled',
[
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*NoAutoUpdate[\s]*DWORD:1',
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*AUOptions[\s]*DELETE',
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*AutomaticMaintenanceEnabled[\s]*DELETE',
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*ScheduledInstallDay[\s]*DELETE',
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*ScheduledInstallTime[\s]*DELETE',
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*AllowMUUpdateService[\s]*DELETE'
])
# set Configure Automatic Updates to 'Not Configured'
self._testComputerAdmxPolicy(r'Windows Components\Windows Update\Configure Automatic Updates',
'Not Configured',
[r'; Source file: c:\\windows\\system32\\grouppolicy\\machine\\registry.pol[\s]*; PARSING COMPLETED.'])
self._testAdmxPolicy(r'Windows Components\Windows Update\Configure Automatic Updates',
'Not Configured',
[r'; Source file: c:\\windows\\system32\\grouppolicy\\machine\\registry.pol[\s]*; PARSING COMPLETED.'])
@destructiveTest
def test_set_computer_policy_ClipboardRedirection(self):
@ -368,15 +424,15 @@ class WinLgpoTest(ModuleCase):
Test setting/unsetting/changing ClipboardRedirection policy
'''
# Enable/Disable/Not Configured "Do not allow Clipboard redirection"
self._testComputerAdmxPolicy(r'Windows Components\Remote Desktop Services\Remote Desktop Session Host\Device and Resource Redirection\Do not allow Clipboard redirection',
'Enabled',
[r'Computer[\s]*Software\\Policies\\Microsoft\\Windows NT\\Terminal Services[\s]*fDisableClip[\s]*DWORD:1'])
self._testComputerAdmxPolicy(r'Windows Components\Remote Desktop Services\Remote Desktop Session Host\Device and Resource Redirection\Do not allow Clipboard redirection',
'Disabled',
[r'Computer[\s]*Software\\Policies\\Microsoft\\Windows NT\\Terminal Services[\s]*fDisableClip[\s]*DWORD:0'])
self._testComputerAdmxPolicy(r'Windows Components\Remote Desktop Services\Remote Desktop Session Host\Device and Resource Redirection\Do not allow Clipboard redirection',
'Not Configured',
[r'; Source file: c:\\windows\\system32\\grouppolicy\\machine\\registry.pol[\s]*; PARSING COMPLETED.'])
self._testAdmxPolicy(r'Windows Components\Remote Desktop Services\Remote Desktop Session Host\Device and Resource Redirection\Do not allow Clipboard redirection',
'Enabled',
[r'Computer[\s]*Software\\Policies\\Microsoft\\Windows NT\\Terminal Services[\s]*fDisableClip[\s]*DWORD:1'])
self._testAdmxPolicy(r'Windows Components\Remote Desktop Services\Remote Desktop Session Host\Device and Resource Redirection\Do not allow Clipboard redirection',
'Disabled',
[r'Computer[\s]*Software\\Policies\\Microsoft\\Windows NT\\Terminal Services[\s]*fDisableClip[\s]*DWORD:0'])
self._testAdmxPolicy(r'Windows Components\Remote Desktop Services\Remote Desktop Session Host\Device and Resource Redirection\Do not allow Clipboard redirection',
'Not Configured',
[r'; Source file: c:\\windows\\system32\\grouppolicy\\machine\\registry.pol[\s]*; PARSING COMPLETED.'])
@destructiveTest
def test_set_computer_policy_PasswordComplexity(self):
@ -427,40 +483,40 @@ class WinLgpoTest(ModuleCase):
Tests setting several ADMX policies in succession and validating the configuration w/lgop
'''
# set one policy
self._testComputerAdmxPolicy(r'Windows Components\Remote Desktop Services\Remote Desktop Session Host\Device and Resource Redirection\Do not allow Clipboard redirection',
'Disabled',
[r'Computer[\s]*Software\\Policies\\Microsoft\\Windows NT\\Terminal Services[\s]*fDisableClip[\s]*DWORD:0'])
self._testAdmxPolicy(r'Windows Components\Remote Desktop Services\Remote Desktop Session Host\Device and Resource Redirection\Do not allow Clipboard redirection',
'Disabled',
[r'Computer[\s]*Software\\Policies\\Microsoft\\Windows NT\\Terminal Services[\s]*fDisableClip[\s]*DWORD:0'])
# set another policy and make sure both this policy and the previous are okay
self._testComputerAdmxPolicy('RA_Unsolicit',
{
'Configure Offer Remote Access': 'Enabled',
'Permit remote control of this computer': 'Allow helpers to remotely control the computer',
'Helpers': ['administrators', 'user1']
},
[
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows NT\\Terminal Services[\s]*fDisableClip[\s]*DWORD:0',
r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services\\RAUnsolicit[\s]*user1[\s]*SZ:user1[\s]*',
r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services\\RAUnsolicit[\s]*administrators[\s]*SZ:administrators[\s]*',
r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services[\s]*fAllowUnsolicited[\s]*DWORD:1',
r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services[\s]*fAllowUnsolicitedFullControl[\s]*DWORD:1',
])
self._testAdmxPolicy('RA_Unsolicit',
{
'Configure Offer Remote Access': 'Enabled',
'Permit remote control of this computer': 'Allow helpers to remotely control the computer',
'Helpers': ['administrators', 'user1']
},
[
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows NT\\Terminal Services[\s]*fDisableClip[\s]*DWORD:0',
r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services\\RAUnsolicit[\s]*user1[\s]*SZ:user1[\s]*',
r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services\\RAUnsolicit[\s]*administrators[\s]*SZ:administrators[\s]*',
r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services[\s]*fAllowUnsolicited[\s]*DWORD:1',
r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services[\s]*fAllowUnsolicitedFullControl[\s]*DWORD:1',
])
# Configure Automatic Updates and validate everything is still okay
self._testComputerAdmxPolicy(r'Windows Components\Windows Update\Configure Automatic Updates',
'Disabled',
[
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows NT\\Terminal Services[\s]*fDisableClip[\s]*DWORD:0',
r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services\\RAUnsolicit[\s]*user1[\s]*SZ:user1[\s]*',
r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services\\RAUnsolicit[\s]*administrators[\s]*SZ:administrators[\s]*',
r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services[\s]*fAllowUnsolicited[\s]*DWORD:1',
r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services[\s]*fAllowUnsolicitedFullControl[\s]*DWORD:1',
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*NoAutoUpdate[\s]*DWORD:1',
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*AUOptions[\s]*DELETE',
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*AutomaticMaintenanceEnabled[\s]*DELETE',
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*ScheduledInstallDay[\s]*DELETE',
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*ScheduledInstallTime[\s]*DELETE',
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*AllowMUUpdateService[\s]*DELETE'
])
self._testAdmxPolicy(r'Windows Components\Windows Update\Configure Automatic Updates',
'Disabled',
[
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows NT\\Terminal Services[\s]*fDisableClip[\s]*DWORD:0',
r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services\\RAUnsolicit[\s]*user1[\s]*SZ:user1[\s]*',
r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services\\RAUnsolicit[\s]*administrators[\s]*SZ:administrators[\s]*',
r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services[\s]*fAllowUnsolicited[\s]*DWORD:1',
r'Computer[\s]*Software\\policies\\Microsoft\\Windows NT\\Terminal Services[\s]*fAllowUnsolicitedFullControl[\s]*DWORD:1',
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*NoAutoUpdate[\s]*DWORD:1',
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*AUOptions[\s]*DELETE',
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*AutomaticMaintenanceEnabled[\s]*DELETE',
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*ScheduledInstallDay[\s]*DELETE',
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*ScheduledInstallTime[\s]*DELETE',
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU[\s]*AllowMUUpdateService[\s]*DELETE'
])
@destructiveTest
def test_set_computer_policy_DisableDomainCreds(self):
@ -511,34 +567,34 @@ class WinLgpoTest(ModuleCase):
if self.osrelease not in valid_osreleases:
self.skipTest('DisableUXWUAccess policy is only applicable if the osrelease grain is {0}'.format(' or '.join(valid_osreleases)))
else:
self._testComputerAdmxPolicy(r'DisableUXWUAccess',
'Enabled',
[r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate[\s]*SetDisableUXWUAccess[\s]*DWORD:1'])
self._testComputerAdmxPolicy(r'Remove access to use all Windows Update features',
'Disabled',
[r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate[\s]*SetDisableUXWUAccess[\s]*DWORD:0'])
self._testComputerAdmxPolicy(r'Windows Components\Windows Update\Remove access to use all Windows Update features',
'Not Configured',
[r'; Source file: c:\\windows\\system32\\grouppolicy\\machine\\registry.pol[\s]*; PARSING COMPLETED.'])
self._testAdmxPolicy(r'DisableUXWUAccess',
'Enabled',
[r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate[\s]*SetDisableUXWUAccess[\s]*DWORD:1'])
self._testAdmxPolicy(r'Remove access to use all Windows Update features',
'Disabled',
[r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate[\s]*SetDisableUXWUAccess[\s]*DWORD:0'])
self._testAdmxPolicy(r'Windows Components\Windows Update\Remove access to use all Windows Update features',
'Not Configured',
[r'; Source file: c:\\windows\\system32\\grouppolicy\\machine\\registry.pol[\s]*; PARSING COMPLETED.'])
@destructiveTest
def test_set_computer_policy_Access_data_sources_across_domains(self):
'''
Tests that a policy that has multiple names
'''
self._testComputerAdmxPolicy(r'Access data sources across domains',
'Enabled',
[],
assert_true=False)
self._testComputerAdmxPolicy(r'Windows Components\Internet Explorer\Internet Control Panel\Security Page\Internet Zone\Access data sources across domains',
{'Access data sources across domains': 'Prompt'},
[r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Zones\\3[\s]*1406[\s]*DWORD:1'])
self._testComputerAdmxPolicy(r'Windows Components\Internet Explorer\Internet Control Panel\Security Page\Internet Zone\Access data sources across domains',
{'Access data sources across domains': 'Enable'},
[r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Zones\\3[\s]*1406[\s]*DWORD:0'])
self._testComputerAdmxPolicy(r'Windows Components\Internet Explorer\Internet Control Panel\Security Page\Internet Zone\Access data sources across domains',
'Disabled',
[r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Zones\\3[\s]*1406[\s]*DELETE'])
self._testAdmxPolicy(r'Access data sources across domains',
'Enabled',
[],
assert_true=False)
self._testAdmxPolicy(r'Windows Components\Internet Explorer\Internet Control Panel\Security Page\Internet Zone\Access data sources across domains',
{'Access data sources across domains': 'Prompt'},
[r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Zones\\3[\s]*1406[\s]*DWORD:1'])
self._testAdmxPolicy(r'Windows Components\Internet Explorer\Internet Control Panel\Security Page\Internet Zone\Access data sources across domains',
{'Access data sources across domains': 'Enable'},
[r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Zones\\3[\s]*1406[\s]*DWORD:0'])
self._testAdmxPolicy(r'Windows Components\Internet Explorer\Internet Control Panel\Security Page\Internet Zone\Access data sources across domains',
'Disabled',
[r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Zones\\3[\s]*1406[\s]*DELETE'])
@destructiveTest
def test_set_computer_policy_ActiveHours(self):
@ -557,30 +613,30 @@ class WinLgpoTest(ModuleCase):
if self.osrelease not in valid_osreleases:
self.skipTest('ActiveHours policy is only applicable if the osrelease grain is {0}'.format(' or '.join(valid_osreleases)))
else:
self._testComputerAdmxPolicy(r'ActiveHours',
{'ActiveHoursStartTime': '8 AM', 'ActiveHoursEndTime': '7 PM'},
[
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate[\s]*SetActiveHours[\s]*DWORD:1',
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate[\s]*ActiveHoursStart[\s]*DWORD:8',
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate[\s]*ActiveHoursEnd[\s]*DWORD:19'
])
self._testComputerAdmxPolicy(r'ActiveHours',
{'ActiveHoursStartTime': '5 AM', 'ActiveHoursEndTime': '10 PM'},
[
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate[\s]*SetActiveHours[\s]*DWORD:1',
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate[\s]*ActiveHoursStart[\s]*DWORD:5',
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate[\s]*ActiveHoursEnd[\s]*DWORD:22'
])
self._testComputerAdmxPolicy('Turn off auto-restart for updates during active hours',
'Disabled',
[
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate[\s]*SetActiveHours[\s]*DWORD:0',
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate[\s]*ActiveHoursStart[\s]*DELETE',
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate[\s]*ActiveHoursEnd[\s]*DELETE'
])
self._testComputerAdmxPolicy(r'Windows Components\Windows Update\Turn off auto-restart for updates during active hours',
'Not Configured',
[r'; Source file: c:\\windows\\system32\\grouppolicy\\machine\\registry.pol[\s]*; PARSING COMPLETED.'])
self._testAdmxPolicy(r'ActiveHours',
{'ActiveHoursStartTime': '8 AM', 'ActiveHoursEndTime': '7 PM'},
[
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate[\s]*SetActiveHours[\s]*DWORD:1',
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate[\s]*ActiveHoursStart[\s]*DWORD:8',
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate[\s]*ActiveHoursEnd[\s]*DWORD:19'
])
self._testAdmxPolicy(r'ActiveHours',
{'ActiveHoursStartTime': '5 AM', 'ActiveHoursEndTime': '10 PM'},
[
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate[\s]*SetActiveHours[\s]*DWORD:1',
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate[\s]*ActiveHoursStart[\s]*DWORD:5',
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate[\s]*ActiveHoursEnd[\s]*DWORD:22'
])
self._testAdmxPolicy('Turn off auto-restart for updates during active hours',
'Disabled',
[
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate[\s]*SetActiveHours[\s]*DWORD:0',
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate[\s]*ActiveHoursStart[\s]*DELETE',
r'Computer[\s]*Software\\Policies\\Microsoft\\Windows\\WindowsUpdate[\s]*ActiveHoursEnd[\s]*DELETE'
])
self._testAdmxPolicy(r'Windows Components\Windows Update\Turn off auto-restart for updates during active hours',
'Not Configured',
[r'; Source file: c:\\windows\\system32\\grouppolicy\\machine\\registry.pol[\s]*; PARSING COMPLETED.'])
def tearDown(self):
'''

View file

@ -1068,6 +1068,7 @@ class PkgTest(ModuleCase, SaltReturnAssertsMixin):
ret = self.run_state('pkg.removed', name=realpkg)
self.assertSaltTrueReturn(ret)
@skipIf(True, 'WAR ROOM TEMPORARY SKIP') # needs to be rewritten to allow for dnf on Fedora 30 and RHEL 8
@requires_salt_modules('pkg.hold', 'pkg.unhold')
@requires_system_grains
def test_pkg_015_installed_held(self, grains=None): # pylint: disable=unused-argument

View file

@ -1215,6 +1215,8 @@ def _terminate_process_list(process_list, kill=False, slow_stop=False):
except psutil.AccessDenied:
# OSX is more restrictive about the above information
cmdline = None
except OSError:
cmdline = None
if not cmdline:
try:
cmdline = process.as_dict()

View file

@ -31,11 +31,12 @@ class StatusBeaconTestCase(TestCase, LoaderModuleMockMixin):
def setup_loader_modules(self):
opts = salt.config.DEFAULT_MINION_OPTS
opts['grains'] = salt.loader.grains(opts)
module_globals = {
'__opts__': opts,
'__salt__': 'autoload',
'__context__': {},
'__grains__': {'kernel': 'Linux'}
'__grains__': opts['grains']
}
return {
status: module_globals,

View file

@ -7,7 +7,7 @@ from __future__ import absolute_import, print_function, unicode_literals
# Import test libs
from tests.support.mixins import LoaderModuleMockMixin, XMLEqualityMixin
from tests.support.mock import patch, mock_open
from tests.support.mock import patch, mock_open, PropertyMock, call, ANY
from tests.support.unit import skipIf, TestCase
# Import 3rd-party libs
@ -20,8 +20,8 @@ try:
from jnpr.junos.utils.config import Config
from jnpr.junos.utils.sw import SW
from jnpr.junos.device import Device
from jnpr.junos.device import Device
import jxmlease # pylint: disable=unused-import
from jnpr.junos.exception import LockError, UnlockError
HAS_JUNOS = True
except ImportError:
HAS_JUNOS = False
@ -50,7 +50,7 @@ class Test_Junos_Module(TestCase, LoaderModuleMockMixin, XMLEqualityMixin):
def make_connect(self):
with patch('ncclient.manager.connect') as mock_connect:
self.dev = self.dev = Device(
self.dev = Device(
host='1.1.1.1',
user='test',
password='test123',
@ -130,6 +130,18 @@ class Test_Junos_Module(TestCase, LoaderModuleMockMixin, XMLEqualityMixin):
'virtual': True}
return facts
def test_timeout_decorator(self):
with patch('jnpr.junos.Device.timeout',
new_callable=PropertyMock) as mock_timeout:
mock_timeout.return_value = 30
def function(x):
return x
decorator = junos.timeoutDecorator(function)
decorator("Test Mock", dev_timeout=10)
calls = [call(), call(10), call(30)]
mock_timeout.assert_has_calls(calls)
def test_facts_refresh(self):
with patch('salt.modules.saltutil.sync_grains') as mock_sync_grains:
ret = dict()
@ -514,10 +526,9 @@ class Test_Junos_Module(TestCase, LoaderModuleMockMixin, XMLEqualityMixin):
mock_commit_check.return_value = True
args = {'comment': 'Comitted via salt',
'__pub_user': 'root',
'dev_timeout': 40,
'__pub_arg': [2,
{'comment': 'Comitted via salt',
'timeout': 40,
'dev_timeout': 40,
'confirm': 1}],
'confirm': 1,
'__pub_fun': 'junos.rollback',
@ -528,7 +539,7 @@ class Test_Junos_Module(TestCase, LoaderModuleMockMixin, XMLEqualityMixin):
junos.rollback(id=2, **args)
mock_rollback.assert_called_with(2)
mock_commit.assert_called_with(
comment='Comitted via salt', confirm=1, timeout=40)
comment='Comitted via salt', confirm=1, dev_timeout=40)
def test_rollback_with_only_single_arg(self):
with patch('jnpr.junos.utils.config.Config.commit_check') as mock_commit_check, \
@ -1154,25 +1165,6 @@ class Test_Junos_Module(TestCase, LoaderModuleMockMixin, XMLEqualityMixin):
ret)
mock_commit.assert_called_with(comment='comitted via salt', confirm=3)
def test_install_config_commit_check_exception(self):
with patch('jnpr.junos.utils.config.Config.commit_check') as mock_commit_check, \
patch('jnpr.junos.utils.config.Config.diff') as mock_diff, \
patch('jnpr.junos.utils.config.Config.load') as mock_load, \
patch('salt.utils.files.safe_rm') as mock_safe_rm, \
patch('salt.utils.files.mkstemp') as mock_mkstemp, \
patch('os.path.isfile') as mock_isfile, \
patch('os.path.getsize') as mock_getsize:
mock_isfile.return_value = True
mock_getsize.return_value = 10
mock_mkstemp.return_value = 'test/path/config'
mock_diff.return_value = 'diff'
mock_commit_check.side_effect = self.raise_exception
ret = dict()
ret['message'] = 'Commit check threw the following exception: "Test exception"'
ret['out'] = False
self.assertEqual(junos.install_config('actual/path/config.xml'), ret)
def test_install_config_commit_check_fails(self):
with patch('jnpr.junos.utils.config.Config.commit_check') as mock_commit_check, \
patch('jnpr.junos.utils.config.Config.diff') as mock_diff, \
@ -1188,7 +1180,7 @@ class Test_Junos_Module(TestCase, LoaderModuleMockMixin, XMLEqualityMixin):
mock_commit_check.return_value = False
ret = dict()
ret['message'] = 'Loaded configuration but commit check failed.'
ret['message'] = 'Loaded configuration but commit check failed, hence rolling back configuration.'
ret['out'] = False
self.assertEqual(junos.install_config('actual/path/config.xml'), ret)
@ -1322,6 +1314,51 @@ class Test_Junos_Module(TestCase, LoaderModuleMockMixin, XMLEqualityMixin):
ret['out'] = False
self.assertEqual(junos.install_os('path', **args), ret)
def test_install_os_no_copy(self):
with patch('jnpr.junos.utils.sw.SW.install') as mock_install, \
patch('salt.utils.files.safe_rm') as mock_safe_rm, \
patch('salt.utils.files.mkstemp') as mock_mkstemp, \
patch('os.path.isfile') as mock_isfile, \
patch('os.path.getsize') as mock_getsize:
mock_getsize.return_value = 10
mock_isfile.return_value = True
ret = dict()
ret['out'] = True
ret['message'] = 'Installed the os.'
self.assertEqual(junos.install_os('path', no_copy=True), ret)
mock_install.assert_called_with(u'path', no_copy=True, progress=True)
mock_mkstemp.assert_not_called()
mock_safe_rm.assert_not_called()
def test_install_os_issu(self):
with patch('jnpr.junos.utils.sw.SW.install') as mock_install, \
patch('salt.utils.files.safe_rm') as mock_safe_rm, \
patch('salt.utils.files.mkstemp') as mock_mkstemp, \
patch('os.path.isfile') as mock_isfile, \
patch('os.path.getsize') as mock_getsize:
mock_getsize.return_value = 10
mock_isfile.return_value = True
ret = dict()
ret['out'] = True
ret['message'] = 'Installed the os.'
self.assertEqual(junos.install_os('path', issu=True), ret)
mock_install.assert_called_with(ANY, issu=True, progress=True)
def test_install_os_add_params(self):
with patch('jnpr.junos.utils.sw.SW.install') as mock_install, \
patch('salt.utils.files.safe_rm') as mock_safe_rm, \
patch('salt.utils.files.mkstemp') as mock_mkstemp, \
patch('os.path.isfile') as mock_isfile, \
patch('os.path.getsize') as mock_getsize:
mock_getsize.return_value = 10
mock_isfile.return_value = True
ret = dict()
ret['out'] = True
ret['message'] = 'Installed the os.'
remote_path = '/path/to/file'
self.assertEqual(junos.install_os('path', remote_path=remote_path, nssu=True, validate=True), ret)
mock_install.assert_called_with(ANY, nssu=True, remote_path=remote_path, progress=True, validate=True)
def test_file_copy_without_args(self):
ret = dict()
ret['message'] = \
@ -1425,7 +1462,6 @@ class Test_Junos_Module(TestCase, LoaderModuleMockMixin, XMLEqualityMixin):
args = mock_execute.call_args
expected_rpc = '<get-interface-information format="json"/>'
self.assertEqualXML(args[0][0], expected_rpc)
self.assertEqual(args[1], {'dev_timeout': 30})
def test_rpc_get_interface_information_with_kwargs(self):
with patch('jnpr.junos.device.Device.execute') as mock_execute:
@ -1496,3 +1532,163 @@ class Test_Junos_Module(TestCase, LoaderModuleMockMixin, XMLEqualityMixin):
junos.rpc('get-chassis-inventory', '/path/to/file')
writes = m_open.write_calls()
assert writes == ['xml rpc reply'], writes
def test_lock_success(self):
ret_exp = {'out': True, 'message': 'Successfully locked the configuration.'}
ret = junos.lock()
self.assertEqual(ret, ret_exp)
def test_lock_error(self):
ret_exp = {'out': False, 'message': 'Could not gain lock due to : "LockError"'}
with patch('jnpr.junos.utils.config.Config.lock') as mock_lock:
mock_lock.side_effect = LockError(None)
ret = junos.lock()
self.assertEqual(ret, ret_exp)
def test_unlock_success(self):
ret_exp = {'out': True, 'message': 'Successfully unlocked the configuration.'}
ret = junos.unlock()
self.assertEqual(ret, ret_exp)
def test_unlock_error(self):
ret_exp = {'out': False, 'message': 'Could not unlock configuration due to : "UnlockError"'}
with patch('jnpr.junos.utils.config.Config.unlock') as mock_unlock:
mock_unlock.side_effect = UnlockError(None)
ret = junos.unlock()
self.assertEqual(ret, ret_exp)
def test_load_none_path(self):
ret_exp = {'out': False,
'message': 'Please provide the salt path where the configuration is present'}
ret = junos.load()
self.assertEqual(ret, ret_exp)
def test_load_wrong_tmp_file(self):
ret_exp = {'out': False, 'message': 'Invalid file path.'}
with patch('salt.utils.files.mkstemp') as mock_mkstemp:
mock_mkstemp.return_value = '/pat/to/tmp/file'
ret = junos.load('/path/to/file')
self.assertEqual(ret, ret_exp)
def test_load_invalid_path(self):
ret_exp = {'out': False, 'message': 'Template failed to render'}
ret = junos.load('/path/to/file')
self.assertEqual(ret, ret_exp)
def test_load_no_extension(self):
ret_exp = {'out': True, 'message': 'Successfully loaded the configuration.'}
with patch('os.path.getsize') as mock_getsize, \
patch('jnpr.junos.utils.config.Config.load') as mock_load, \
patch('salt.utils.files.mkstemp') as mock_mkstmp, \
patch('os.path.isfile') as mock_isfile:
mock_getsize.return_value = 1000
mock_mkstmp.return_value = '/path/to/file'
mock_isfile.return_value = True
ret = junos.load('/path/to/file')
mock_load.assert_called_with(format='text', path='/path/to/file')
self.assertEqual(ret, ret_exp)
def test_load_xml_extension(self):
ret_exp = {'out': True, 'message': 'Successfully loaded the configuration.'}
with patch('os.path.getsize') as mock_getsize, \
patch('jnpr.junos.utils.config.Config.load') as mock_load, \
patch('salt.utils.files.mkstemp') as mock_mkstmp, \
patch('os.path.isfile') as mock_isfile:
mock_getsize.return_value = 1000
mock_mkstmp.return_value = '/path/to/file'
mock_isfile.return_value = True
ret = junos.load('/path/to/file.xml')
mock_load.assert_called_with(format='xml', path='/path/to/file')
self.assertEqual(ret, ret_exp)
def test_load_set_extension(self):
ret_exp = {'out': True, 'message': 'Successfully loaded the configuration.'}
with patch('os.path.getsize') as mock_getsize, \
patch('jnpr.junos.utils.config.Config.load') as mock_load, \
patch('salt.utils.files.mkstemp') as mock_mkstmp, \
patch('os.path.isfile') as mock_isfile:
mock_getsize.return_value = 1000
mock_mkstmp.return_value = '/path/to/file'
mock_isfile.return_value = True
ret = junos.load('/path/to/file.set')
mock_load.assert_called_with(format='set', path='/path/to/file')
self.assertEqual(ret, ret_exp)
def test_load_replace_true(self):
ret_exp = {'out': True, 'message': 'Successfully loaded the configuration.'}
with patch('os.path.getsize') as mock_getsize, \
patch('jnpr.junos.utils.config.Config.load') as mock_load, \
patch('salt.utils.files.mkstemp') as mock_mkstmp, \
patch('os.path.isfile') as mock_isfile:
mock_getsize.return_value = 1000
mock_mkstmp.return_value = '/path/to/file'
mock_isfile.return_value = True
ret = junos.load('/path/to/file', replace=True)
mock_load.assert_called_with(format='text', merge=False, path='/path/to/file')
self.assertEqual(ret, ret_exp)
def test_load_replace_false(self):
ret_exp = {'out': True, 'message': 'Successfully loaded the configuration.'}
with patch('os.path.getsize') as mock_getsize, \
patch('jnpr.junos.utils.config.Config.load') as mock_load, \
patch('salt.utils.files.mkstemp') as mock_mkstmp, \
patch('os.path.isfile') as mock_isfile:
mock_getsize.return_value = 1000
mock_mkstmp.return_value = '/path/to/file'
mock_isfile.return_value = True
ret = junos.load('/path/to/file', replace=False)
mock_load.assert_called_with(format='text', replace=False, path='/path/to/file')
self.assertEqual(ret, ret_exp)
def test_load_overwrite_true(self):
ret_exp = {'out': True, 'message': 'Successfully loaded the configuration.'}
with patch('os.path.getsize') as mock_getsize, \
patch('jnpr.junos.utils.config.Config.load') as mock_load, \
patch('salt.utils.files.mkstemp') as mock_mkstmp, \
patch('os.path.isfile') as mock_isfile:
mock_getsize.return_value = 1000
mock_mkstmp.return_value = '/path/to/file'
mock_isfile.return_value = True
ret = junos.load('/path/to/file', overwrite=True)
mock_load.assert_called_with(format='text', overwrite=True, path='/path/to/file')
self.assertEqual(ret, ret_exp)
def test_load_overwrite_false(self):
ret_exp = {'out': True, 'message': 'Successfully loaded the configuration.'}
with patch('os.path.getsize') as mock_getsize, \
patch('jnpr.junos.utils.config.Config.load') as mock_load, \
patch('salt.utils.files.mkstemp') as mock_mkstmp, \
patch('os.path.isfile') as mock_isfile:
mock_getsize.return_value = 1000
mock_mkstmp.return_value = '/path/to/file'
mock_isfile.return_value = True
ret = junos.load('/path/to/file', overwrite=False)
mock_load.assert_called_with(format='text', merge=True, path='/path/to/file')
self.assertEqual(ret, ret_exp)
def test_load_error(self):
ret_exp = {'out': False,
'format': 'text',
'message': 'Could not load configuration due to : "Test Error"'}
with patch('os.path.getsize') as mock_getsize, \
patch('jnpr.junos.utils.config.Config.load') as mock_load, \
patch('salt.utils.files.mkstemp') as mock_mkstmp, \
patch('os.path.isfile') as mock_isfile:
mock_getsize.return_value = 1000
mock_mkstmp.return_value = '/path/to/file'
mock_isfile.return_value = True
mock_load.side_effect = Exception('Test Error')
ret = junos.load('/path/to/file')
self.assertEqual(ret, ret_exp)
def test_commit_check_success(self):
ret_exp = {'out': True, 'message': 'Commit check succeeded.'}
ret = junos.commit_check()
self.assertEqual(ret, ret_exp)
def test_commit_check_error(self):
ret_exp = {'out': False, 'message': 'Commit check failed with '}
with patch('jnpr.junos.utils.config.Config.commit_check') as mock_check:
mock_check.side_effect = Exception
ret = junos.commit_check()
self.assertEqual(ret, ret_exp)

View file

@ -408,7 +408,7 @@ class BotoApiGatewayStateTestCaseBase(TestCase, LoaderModuleMockMixin):
context = {}
utils = salt.loader.utils(
self.opts,
whitelist=['boto', 'boto3', 'args', 'systemd', 'path', 'platform'],
whitelist=['boto', 'boto3', 'args', 'systemd', 'path', 'platform', 'reg'],
context=context)
serializers = salt.loader.serializers(self.opts)
self.funcs = salt.loader.minion_mods(self.opts, context=context, utils=utils, whitelist=['boto_apigateway'])

View file

@ -110,7 +110,7 @@ class BotoCloudTrailStateTestCaseBase(TestCase, LoaderModuleMockMixin):
ctx = {}
utils = salt.loader.utils(
self.opts,
whitelist=['boto', 'boto3', 'args', 'systemd', 'path', 'platform'],
whitelist=['boto', 'boto3', 'args', 'systemd', 'path', 'platform', 'reg'],
context=ctx)
serializers = salt.loader.serializers(self.opts)
self.funcs = funcs = salt.loader.minion_mods(self.opts, context=ctx, utils=utils, whitelist=['boto_cloudtrail'])

View file

@ -132,7 +132,7 @@ class BotoCognitoIdentityStateTestCaseBase(TestCase, LoaderModuleMockMixin):
ctx = {}
utils = salt.loader.utils(
self.opts,
whitelist=['boto', 'boto3', 'args', 'systemd', 'path', 'platform'],
whitelist=['boto', 'boto3', 'args', 'systemd', 'path', 'platform', 'reg'],
context=ctx)
serializers = salt.loader.serializers(self.opts)
self.funcs = funcs = salt.loader.minion_mods(self.opts, context=ctx, utils=utils, whitelist=['boto_cognitoidentity'])

View file

@ -109,7 +109,7 @@ class BotoLambdaStateTestCaseBase(TestCase, LoaderModuleMockMixin):
ctx = {}
utils = salt.loader.utils(
self.opts,
whitelist=['boto', 'boto3', 'args', 'systemd', 'path', 'platform'],
whitelist=['boto', 'boto3', 'args', 'systemd', 'path', 'platform', 'reg'],
context=ctx)
serializers = salt.loader.serializers(self.opts)
self.funcs = funcs = salt.loader.minion_mods(self.opts, context=ctx, utils=utils, whitelist=['boto_lambda'])

View file

@ -272,7 +272,7 @@ class BotoS3BucketStateTestCaseBase(TestCase, LoaderModuleMockMixin):
ctx = {}
utils = salt.loader.utils(
self.opts,
whitelist=['boto', 'boto3', 'args', 'systemd', 'path', 'platform'],
whitelist=['boto', 'boto3', 'args', 'systemd', 'path', 'platform', 'reg'],
context=ctx)
serializers = salt.loader.serializers(self.opts)
self.funcs = funcs = salt.loader.minion_mods(self.opts, context=ctx, utils=utils, whitelist=['boto_s3_bucket'])

View file

@ -91,7 +91,7 @@ class BotoVpcStateTestCaseBase(TestCase, LoaderModuleMockMixin):
ctx = {}
utils = salt.loader.utils(
self.opts,
whitelist=['boto', 'boto3', 'args', 'systemd', 'path', 'platform'],
whitelist=['boto', 'boto3', 'args', 'systemd', 'path', 'platform', 'reg'],
context=ctx)
serializers = salt.loader.serializers(self.opts)
self.funcs = salt.loader.minion_mods(self.opts, context=ctx, utils=utils, whitelist=['boto_vpc', 'config'])

View file

@ -46,6 +46,8 @@ class MockRunnerClient(object):
'''
Mock cmd method
'''
# TODO: Figure out how to have this return an empty dict or a dict
# TODO: with expected data
return []
@ -64,29 +66,54 @@ class WinrepoTestCase(TestCase, LoaderModuleMockMixin):
'''
Test to refresh the winrepo.p file of the repository
'''
ret = {'name': 'salt',
'changes': {},
'result': False,
'comment': ''}
ret.update({'comment': '{0} is missing'.format(
os.sep.join([BASE_FILE_ROOTS_DIR, 'win', 'repo']))})
self.assertDictEqual(winrepo.genrepo('salt'), ret)
expected = {'name': 'salt',
'changes': {},
'result': False,
'comment': ''}
mock_config = MagicMock(return_value={'winrepo_dir': 'salt',
'winrepo_cachefile': 'abc'})
mock_stat = MagicMock(return_value=[0, 1, 2, 3, 4, 5, 6, 7, 8])
mock_empty_list = MagicMock(return_value=[])
with patch.object(salt.config, 'master_config', mock_config), \
patch.object(os, 'stat', mock_stat), \
patch.object(salt.utils.path, 'os_walk', mock_empty_list), \
patch.dict(winrepo.__opts__, {'test': True}):
# With test=True
expected.update({'comment': '', 'result': None})
self.assertDictEqual(winrepo.genrepo('salt'), expected)
mock = MagicMock(return_value={'winrepo_dir': 'salt',
'winrepo_cachefile': 'abc'})
with patch.object(salt.config, 'master_config', mock):
mock = MagicMock(return_value=[0, 1, 2, 3, 4, 5, 6, 7, 8])
with patch.object(os, 'stat', mock):
mock = MagicMock(return_value=[])
with patch.object(salt.utils.path, 'os_walk', mock):
with patch.dict(winrepo.__opts__, {'test': True}):
ret.update({'comment': '', 'result': None})
self.assertDictEqual(winrepo.genrepo('salt'), ret)
with patch.dict(winrepo.__opts__, {'test': False}):
# With test=False
expected.update({'result': True})
self.assertDictEqual(winrepo.genrepo('salt'), expected)
with patch.dict(winrepo.__opts__, {'test': False}):
ret.update({'result': True})
self.assertDictEqual(winrepo.genrepo('salt'), ret)
# Now with no changes, existing winrepo.p
expected.update({'changes': {'winrepo': []}})
self.assertDictEqual(winrepo.genrepo('salt', True), expected)
ret.update({'changes': {'winrepo': []}})
self.assertDictEqual(winrepo.genrepo('salt', True),
ret)
def test_genrepo_no_dir(self):
'''
Test genrepo when the dir does not exist
'''
expected = {'name': 'salt',
'changes': {},
'result': False,
'comment': '{0} is missing'.format(
os.sep.join([BASE_FILE_ROOTS_DIR, 'win', 'repo']))}
with patch.dict(winrepo.__opts__, {'test': False}), \
patch('os.path.exists', MagicMock(return_value=False)):
ret = winrepo.genrepo('salt')
self.assertDictEqual(ret, expected)
def test_genrepo_no_dir_force(self):
'''
Test genrepo when the dir does not exist and force=True
'''
expected = {'name': 'salt',
'changes': {'winrepo': []},
'result': True,
'comment': ''}
with patch.dict(winrepo.__opts__, {'test': False}), \
patch('os.path.exists', MagicMock(return_value=False)):
ret = winrepo.genrepo('salt', force=True)
self.assertDictEqual(ret, expected)