Merge branch 'nitrogen' into 'develop'

No conflicts.
This commit is contained in:
rallytime 2017-06-07 09:54:20 -06:00
commit 396b06fdf8
17 changed files with 1313 additions and 609 deletions

File diff suppressed because it is too large Load diff

View file

@ -266,6 +266,82 @@ As well as from salt-api:
{"return": [{"jerry": {"jid": "20170520151531477653", "retcode": 1, "ret": ""}}]}
Jinja
=====
Filters
-------
New filters in Nitrogen:
- :jinja_ref:`to_bool`
- :jinja_ref:`exactly_n_true`
- :jinja_ref:`exactly_one_true`
- :jinja_ref:`quote`
- :jinja_ref:`regex_search`
- :jinja_ref:`regex_match`
- :jinja_ref:`uuid`
- :jinja_ref:`is_list`
- :jinja_ref:`is_iter`
- :jinja_ref:`min`
- :jinja_ref:`max`
- :jinja_ref:`avg`
- :jinja_ref:`union`
- :jinja_ref:`intersect`
- :jinja_ref:`difference`
- :jinja_ref:`symmetric_difference`
- :jinja_ref:`is_sorted`
- :jinja_ref:`compare_lists`
- :jinja_ref:`compare_dicts`
- :jinja_ref:`is_hex`
- :jinja_ref:`contains_whitespace`
- :jinja_ref:`substring_in_list`
- :jinja_ref:`check_whitelist_blacklist`
- :jinja_ref:`date_format`
- :jinja_ref:`str_to_num`
- :jinja_ref:`to_bytes`
- :jinja_ref:`json_decode_list`
- :jinja_ref:`json_decode_dict`
- :jinja_ref:`rand_str`
- :jinja_ref:`md5`
- :jinja_ref:`sha256`
- :jinja_ref:`sha512`
- :jinja_ref:`base64_encode`
- :jinja_ref:`base64_decode`
- :jinja_ref:`hmac`
- :jinja_ref:`http_query`
- :jinja_ref:`is_ip`
- :jinja_ref:`is_ipv4`
- :jinja_ref:`is_ipv6`
- :jinja_ref:`ipaddr`
- :jinja_ref:`ipv4`
- :jinja_ref:`ipv6`
- :jinja_ref:`network_hosts`
- :jinja_ref:`network_size`
- :jinja_ref:`gen_mac`
- :jinja_ref:`mac_str_to_bytes`
- :jinja_ref:`dns_check`
- :jinja_ref:`is_text_file`
- :jinja_ref:`is_binary_file`
- :jinja_ref:`is_empty_file`
- :jinja_ref:`file_hashsum`
- :jinja_ref:`list_files`
- :jinja_ref:`path_join`
- :jinja_ref:`which`
Logs
----
Another new feature - although not limited to Jinja only -
is being able to log debug messages directly from the template:
.. code-block:: jinja
{%- do salt.log.error('logging from jinja') -%}
See the :jinja_ref:`logs` paragraph.
Network Automation
==================
@ -334,6 +410,7 @@ New functions:
(in dBm).
New grains: :mod:`Host <salt.grains.napalm.host>`,
:mod:`Host DNS<salt.grains.napalm.host_dns>`,
:mod:`Username <salt.grains.napalm.username>` and
:mod:`Optional args <salt.grains.napalm.optional_args>`.
@ -465,14 +542,155 @@ Using the new ``roster_order`` configuration syntax it's now possible to compose
of grains, pillar and mine data and even Salt SDB URLs.
The new release is also fully IPv4 and IPv6 enabled and even has support for CIDR ranges.
Additional Features
===================
- The :mod:`mine.update <salt.modules.mine.update>` function
has a new optional argument ``mine_functions`` that can be used
to refresh mine functions at a more specific interval
than scheduled using the ``mine_interval`` option.
However, this argument can be used by explicit schedule.
For example, if we need the mines for ``net.lldp`` to be refreshed
every 12 hours:
.. code-block:: yaml
schedule:
lldp_mine_update:
function: mine.update
kwargs:
mine_functions:
net.lldp: []
hours: 12
- The ``salt`` runner has a new function: :mod:`salt.execute <salt.runners.salt.execute>`.
It is mainly a shortcut to facilitate the execution of various functions
from other runners, e.g.:
.. code-block:: python
ret1 = __salt__['salt.execute']('*', 'mod.fun')
New Modules
===========
Beacons
-------
- :mod:`salt.beacons.log <salt.beacons.log>`
Engines
-------
- :mod:`salt.engines.stalekey <salt.engines.stalekey>`
- :mod:`salt.engines.junos_syslog <salt.engines.junos_syslog>`
- :mod:`salt.engines.napalm_syslog <salt.engines.napalm_syslog>`
Execution modules
-----------------
- :mod:`salt.modules.apk <salt.modules.apk>`
- :mod:`salt.modules.at_solaris <salt.modules.at_solaris>`
- :mod:`salt.modules.boto_kinesis <salt.modules.boto_kinesis>`
- :mod:`salt.modules.boto3_elasticache <salt.modules.boto3_elasticache>`
- :mod:`salt.modules.boto3_route53 <salt.modules.boto3_route53>`
- :mod:`salt.modules.capirca_acl <salt.modules.capirca_acl>`
- :mod:`salt.modules.freebsd_update <salt.modules.freebsd_update>`
- :mod:`salt.modules.grafana4 <salt.modules.grafana4>`
- :mod:`salt.modules.heat <salt.modules.heat>`
- :mod:`salt.modules.icinga2 <salt.modules.icinga2>`
- :mod:`salt.modules.logmod <salt.modules.logmod>`
- :mod:`salt.modules.mattermost <salt.modules.mattermost>`
- :mod:`salt.modules.mattermost <salt.modules.mattermost>`
- :mod:`salt.modules.namecheap_dns <salt.modules.namecheap_dns>`
- :mod:`salt.modules.namecheap_domains <salt.modules.namecheap_domains>`
- :mod:`salt.modules.namecheap_ns <salt.modules.namecheap_ns>`
- :mod:`salt.modules.namecheap_users <salt.modules.namecheap_users>`
- :mod:`salt.modules.namecheap_ssl <salt.modules.namecheap_ssl>`
- :mod:`salt.modules.napalm <salt.modules.napalm>`
- :mod:`salt.modules.napalm_acl <salt.modules.napalm_acl>`
- :mod:`salt.modules.napalm_yang_mod <salt.modules.napalm_yang_mod>`
- :mod:`salt.modules.pdbedit <salt.modules.pdbedit>`
- :mod:`salt.modules.solrcloud <salt.modules.solrcloud>`
- :mod:`salt.modules.statuspage <salt.modules.statuspage>`
- :mod:`salt.modules.zonecfg <salt.modules.zonecfg>`
- :mod:`salt.modules.zoneadm <salt.modules.zoneadm>`
Grains
------
- :mod:`salt.grains.metadata <salt.grains.metadata>`
- :mod:`salt.grains.mdata <salt.grains.mdata>`
Outputters
----------
- :mod:`table <salt.output.table_out>`
- :mod:`profile <salt.output.profile>`
- :mod:`salt.output.table_out <salt.output.table_out>`
Pillar
------
- :mod:`salt.pillar.postgres <salt.pillar.postgres>`
- :mod:`salt.pillar.vmware_pillar <salt.pillar.vmware_pillar>`
Returners
---------
- :mod:`salt.returners.mattermost_returner <salt.returners.mattermost_returner>`
- :mod:`salt.returners.highstate_return <salt.returners.highstate_return>`
Roster
------
- :mod:`salt.roster.cache <salt.roster.cache>`
Runners
-------
- :mod:`salt.runners.bgp <salt.runners.bgp>`
- :mod:`salt.runners.mattermost <salt.runners.mattermost>`
- :mod:`salt.runners.net <salt.runners.net>`
SDB
---
- :mod:`salt.sdb.yaml <salt.sdb.yaml>`
- :mod:`salt.sdb.tism <salt.sdb.tism>`
- :mod:`salt.sdb.cache <salt.sdb.cache>`
States
------
- :mod:`salt.states.boto_kinesis <salt.states.boto_kinesis>`
- :mod:`salt.states.boto_efs <salt.states.boto_efs>`
- :mod:`salt.states.boto3_elasticache <salt.states.boto3_elasticache>`
- :mod:`salt.states.boto3_route53 <salt.states.boto3_route53>`
- :mod:`salt.states.docker_container <salt.states.docker_container>`
- :mod:`salt.states.docker_image <salt.states.docker_image>`
- :mod:`salt.states.docker_network <salt.states.docker_network>`
- :mod:`salt.states.docker_volume <salt.states.docker_volume>`
- :mod:`salt.states.elasticsearch <salt.states.elasticsearch>`
- :mod:`salt.states.grafana4_dashboard <salt.states.grafana4_dashboard>`
- :mod:`salt.states.grafana4_datasource <salt.states.grafana4_datasource>`
- :mod:`salt.states.grafana4_org <salt.states.grafana4_org>`
- :mod:`salt.states.grafana4_user <salt.states.grafana4_user>`
- :mod:`salt.states.heat <salt.states.heat>`
- :mod:`salt.states.icinga2 <salt.states.icinga2>`
- :mod:`salt.states.influxdb_continuous_query <salt.states.influxdb_continuous_query>`
- :mod:`salt.states.influxdb_retention_policy <salt.states.influxdb_retention_policy>`
- :mod:`salt.states.logadm <salt.states.logadm>`
- :mod:`salt.states.logrotate <salt.states.logrotate>`
- :mod:`salt.states.msteams <salt.states.msteams>`
- :mod:`salt.states.netacl <salt.states.netacl>`
- :mod:`salt.states.netconfig <salt.states.netconfig>`
- :mod:`salt.states.netyang <salt.states.netyang>`
- :mod:`salt.states.nix <salt.states.nix>`
- :mod:`salt.states.pdbedit <salt.states.pdbedit>`
- :mod:`salt.states.solrcloud <salt.states.solrcloud>`
- :mod:`salt.states.statuspage <salt.states.statuspage>`
- :mod:`salt.states.vault <salt.states.vault>`
- :mod:`salt.states.win_wua <salt.states.win_wua>`
- :mod:`salt.states.zone <salt.states.zone>`
Deprecations
============
@ -611,41 +829,41 @@ State Deprecations
The ``apache_conf`` state had the following functions removed:
- ``disable``: Please use ``disabled`` instead.
- ``enable``: Please use ``enabled`` instead.
- ``disable``: Please use ``disabled`` instead.
- ``enable``: Please use ``enabled`` instead.
The ``apache_module`` state had the following functions removed:
- ``disable``: Please use ``disabled`` instead.
- ``enable``: Please use ``enabled`` instead.
- ``disable``: Please use ``disabled`` instead.
- ``enable``: Please use ``enabled`` instead.
The ``apache_site`` state had the following functions removed:
- ``disable``: Please use ``disabled`` instead.
- ``enable``: Please use ``enabled`` instead.
- ``disable``: Please use ``disabled`` instead.
- ``enable``: Please use ``enabled`` instead.
The ``chocolatey`` state had the following functions removed:
- ``install``: Please use ``installed`` instead.
- ``uninstall``: Please use ``uninstalled`` instead.
- ``install``: Please use ``installed`` instead.
- ``uninstall``: Please use ``uninstalled`` instead.
The ``git`` state had the following changes:
- The ``config`` function was removed. Please use ``config_set`` instead.
- The ``is_global`` option was removed from the ``config_set`` function.
Please use ``global`` instead.
- The ``always_fetch`` option was removed from the ``latest`` function, as
it no longer has any effect. Please see the :ref:`2015.8.0<release-2015-8-0>`
release notes for more information.
- The ``force`` option was removed from the ``latest`` function. Please
use ``force_clone`` instead.
- The ``remote_name`` option was removed from the ``latest`` function.
Please use ``remote`` instead.
- The ``config`` function was removed. Please use ``config_set`` instead.
- The ``is_global`` option was removed from the ``config_set`` function.
Please use ``global`` instead.
- The ``always_fetch`` option was removed from the ``latest`` function, as
it no longer has any effect. Please see the :ref:`2015.8.0<release-2015-8-0>`
release notes for more information.
- The ``force`` option was removed from the ``latest`` function. Please
use ``force_clone`` instead.
- The ``remote_name`` option was removed from the ``latest`` function.
Please use ``remote`` instead.
The ``glusterfs`` state had the following function removed:
- ``created``: Please use ``volume_present`` instead.
- ``created``: Please use ``volume_present`` instead.
The ``openvswitch_port`` state had the following change:
- The ``type`` option was removed from the ``present`` function. Please use ``tunnel_type`` instead.
- The ``type`` option was removed from the ``present`` function. Please use ``tunnel_type`` instead.

1
pkg/rpm/salt-proxy@.service Symbolic link
View file

@ -0,0 +1 @@
../salt-proxy@.service

View file

@ -14,10 +14,10 @@ Set up the cloud configuration at ``/etc/salt/cloud.providers`` or
.. code-block:: yaml
my-vultr-config:
# Vultr account api key
api_key: <supersecretapi_key>
driver: vultr
my-vultr-config:
# Vultr account api key
api_key: <supersecretapi_key>
driver: vultr
Set up the cloud profile at ``/etc/salt/cloud.profiles`` or
``/etc/salt/cloud.profiles.d/vultr.conf``:
@ -38,11 +38,11 @@ from __future__ import absolute_import
import pprint
import logging
import time
import urllib
# Import salt cloud libs
# Import salt libs
import salt.config as config
import salt.ext.six as six
from salt.ext.six.moves.urllib.parse import urlencode as _urlencode # pylint: disable=E0611
from salt.exceptions import (
SaltCloudConfigError,
SaltCloudSystemExit
@ -173,7 +173,7 @@ def destroy(name):
'''
node = show_instance(name, call='action')
params = {'SUBID': node['SUBID']}
result = _query('server/destroy', method='POST', decode=False, data=urllib.urlencode(params))
result = _query('server/destroy', method='POST', decode=False, data=_urlencode(params))
# The return of a destroy call is empty in the case of a success.
# Errors are only indicated via HTTP status code. Status code 200
@ -291,7 +291,7 @@ def create(vm_):
)
try:
data = _query('server/create', method='POST', data=urllib.urlencode(kwargs))
data = _query('server/create', method='POST', data=_urlencode(kwargs))
if int(data.get('status', '200')) >= 300:
log.error('Error creating {0} on Vultr\n\n'
'Vultr API returned {1}\n'.format(vm_['name'], data))

View file

@ -123,7 +123,8 @@ changes on the device(s) firing the event, one is able to
identify the minion ID, using one of the following alternatives, but not limited to:
- :mod:`Host grains <salt.grains.napalm.host>` to match the event tag
- :mod:`Hostname grains <salt.grains.napalm.hostname>` to match the IP address in the event data
- :mod:`Host DNS grain <salt.grains.napalm.host_dns>` to match the IP address in the event data
- :mod:`Hostname grains <salt.grains.napalm.hostname>` to match the event tag
- :ref:`Define static grains <static-custom-grains>`
- :ref:`Write a grains module <writing-grains>`
- :ref:`Targeting minions using pillar data <targeting-pillar>` -- the user

View file

@ -22,6 +22,7 @@ import logging
log = logging.getLogger(__name__)
# Salt lib
import salt.utils.dns
import salt.utils.napalm
# ----------------------------------------------------------------------------------------------------------------------
@ -355,6 +356,72 @@ def host(proxy=None):
return {'host': _get_device_grain('hostname', proxy=proxy)}
def host_dns(proxy=None):
'''
Return the DNS information of the host.
This grain is a dictionary having two keys:
- ``A``
- ``AAAA``
.. note::
This grain is disabled by default, as the proxy startup may be slower
when the lookup fails.
The user can enable it using the ``napalm_host_dns_grain`` option (in
the pillar or proxy configuration file):
.. code-block:: yaml
napalm_host_dns_grain: true
.. versionadded:: Nitrogen
CLI Example:
.. code-block:: bash
salt 'device*' grains.get host_dns
Output:
.. code-block:: yaml
device1:
A:
- 172.31.9.153
AAAA:
- fd52:188c:c068::1
device2:
A:
- 172.31.46.249
AAAA:
- fdca:3b17:31ab::17
device3:
A:
- 172.31.8.167
AAAA:
- fd0f:9fd6:5fab::1
'''
if not __opts__.get('napalm_host_dns_grain', False):
return
device_host = host(proxy=proxy)
if device_host:
device_host_value = device_host['host']
host_dns_ret = {
'host_dns': {
'A': [],
'AAAA': []
}
}
dns_a = salt.utils.dns.query(device_host_value, 'A')
if dns_a:
host_dns_ret['host_dns']['A'] = dns_a
dns_aaaa = salt.utils.dns.query(device_host_value, 'AAAA')
if dns_aaaa:
host_dns_ret['host_dns']['AAAA'] = dns_aaaa
return host_dns_ret
def optional_args(proxy=None):
'''
Return the connection optional args.

View file

@ -53,7 +53,7 @@ if six.PY3:
for suffix in importlib.machinery.BYTECODE_SUFFIXES:
SUFFIXES.append((suffix, 'rb', 2))
for suffix in importlib.machinery.SOURCE_SUFFIXES:
SUFFIXES.append((suffix, 'r', 1))
SUFFIXES.append((suffix, 'rb', 1))
# pylint: enable=no-member,no-name-in-module,import-error
else:
SUFFIXES = imp.get_suffixes()

View file

@ -6,6 +6,7 @@ A module to wrap (non-Windows) archive calls
'''
from __future__ import absolute_import
import contextlib # For < 2.7 compat
import copy
import errno
import glob
import logging
@ -249,13 +250,16 @@ def list_(name,
else:
files.append(path)
for path in files:
_files = copy.deepcopy(files)
for path in _files:
# ZIP files created on Windows do not add entries
# to the archive for directories. So, we'll need to
# manually add them.
dirname = ''.join(path.rpartition('/')[:2])
if dirname:
dirs.add(dirname)
if dirname in files:
files.remove(dirname)
return list(dirs), files, links
except zipfile.BadZipfile:
raise CommandExecutionError('{0} is not a ZIP file'.format(name))
@ -1055,7 +1059,15 @@ def unzip(zip_file,
continue
zfile.extract(target, dest, password)
if extract_perms:
os.chmod(os.path.join(dest, target), zfile.getinfo(target).external_attr >> 16)
perm = zfile.getinfo(target).external_attr >> 16
if perm == 0:
umask_ = os.umask(0)
os.umask(umask_)
if target.endswith('/'):
perm = 0o777 & ~umask_
else:
perm = 0o666 & ~umask_
os.chmod(os.path.join(dest, target), perm)
except Exception as exc:
if runas:
os.seteuid(euid)

View file

@ -816,7 +816,7 @@ def create_floatingip(floating_network, port=None, profile=None):
return conn.create_floatingip(floating_network, port)
def update_floatingip(floatingip_id, port, profile=None):
def update_floatingip(floatingip_id, port=None, profile=None):
'''
Updates a floatingIP
@ -827,7 +827,8 @@ def update_floatingip(floatingip_id, port, profile=None):
salt '*' neutron.update_floatingip network-name port-name
:param floatingip_id: ID of floatingIP
:param port: ID or name of port
:param port: ID or name of port, to associate floatingip to
`None` or do not specify to disassociate the floatingip (Optional)
:param profile: Profile to build on (Optional)
:return: Value of updated floating IP information
'''

View file

@ -34,6 +34,8 @@ def update(tgt,
clear=False,
mine_functions=None):
'''
.. versionadded:: Nitrogen
Update the mine data on a certain group of minions.
tgt

View file

@ -68,7 +68,10 @@ def import_cert(name, cert_format=_DEFAULT_FORMAT, context=_DEFAULT_CONTEXT, sto
cached_source_path = __salt__['cp.cache_file'](name, saltenv)
current_certs = __salt__['win_pki.get_certs'](context=context, store=store)
cert_props = __salt__['win_pki.get_cert_file'](name=cached_source_path)
if password:
cert_props = __salt__['win_pki.get_cert_file'](name=cached_source_path, cert_format=cert_format, password=password)
else:
cert_props = __salt__['win_pki.get_cert_file'](name=cached_source_path, cert_format=cert_format)
if cert_props['thumbprint'] in current_certs:
ret['comment'] = ("Certificate '{0}' already contained in store:"

View file

@ -537,12 +537,16 @@ class SaltNeutron(NeutronShell):
return self.network_conn.create_floatingip(body={'floatingip': body})
def update_floatingip(self, floatingip_id, port):
def update_floatingip(self, floatingip_id, port=None):
'''
Updates a floatingip
Updates a floatingip, disassociates the floating ip if
port is set to `None`
'''
port_id = self._find_port_id(port)
body = {'floatingip': {'port_id': port_id}}
if port is None:
body = {'floatingip': {}}
else:
port_id = self._find_port_id(port)
body = {'floatingip': {'port_id': port_id}}
return self.network_conn.update_floatingip(
floatingip=floatingip_id, body=body)

View file

@ -9,7 +9,7 @@ from __future__ import absolute_import, print_function
# Import Salt Testing libs
from tests.support.case import ModuleCase
from tests.support.unit import skipIf
from tests.support.helpers import destructiveTest, skip_if_not_root
from tests.support.helpers import destructiveTest, skip_if_not_root, flaky
# Import salt libs
import salt.utils
@ -40,6 +40,7 @@ class MacPowerModuleTest(ModuleCase):
self.run_function('power.set_harddisk_sleep', [self.HARD_DISK_SLEEP])
@destructiveTest
@flaky
def test_computer_sleep(self):
'''
Test power.get_computer_sleep

View file

@ -728,40 +728,6 @@ class StateModuleTest(ModuleCase, SaltReturnAssertsMixin):
#ret = self.run_function('state.sls', mods='requisites.fullsls_prereq')
#self.assertEqual(['sls command can only be used with require requisite'], ret)
def test_requisites_full_sls_require_in(self):
'''
Test require_in when including an entire sls
'''
expected_result = {
'cmd_|-A_|-echo A_|-run': {
'__run_num__': 0,
'comment': 'Command "echo A" run',
'result': True,
'changes': True},
'cmd_|-B_|-echo B_|-run': {
'__run_num__': 1,
'comment': 'Command "echo B" run',
'result': True,
'changes': True},
'cmd_|-C_|-echo C_|-run': {
'__run_num__': 2,
'comment': 'Command "echo C" run',
'result': True,
'changes': True},
}
ret = self.run_function('state.sls',
mods='requisites.fullsls_require_in')
self.assertReturnNonEmptySaltType(ret)
result = self.normalize_ret(ret)
self.assertEqual(expected_result, result)
def test_requisites_full_sls_import(self):
'''
Test full sls requisite with nothing but an import
'''
ret = self.run_function('state.sls', mods='requisites.fullsls_require_import')
self.assertSaltTrueReturn(ret)
def test_requisites_prereq_simple_ordering_and_errors(self):
'''
Call sls file containing several prereq_in and prereq.

View file

@ -117,6 +117,10 @@ def _rand_key_name(length):
)
def _windows_or_mac():
return salt.utils.is_windows() or salt.utils.is_darwin()
class GitPythonMixin(object):
'''
GitPython doesn't support anything fancy in terms of authentication
@ -337,7 +341,7 @@ class GitPythonMixin(object):
@destructiveTest
@skipIf(NO_MOCK, NO_MOCK_REASON)
@skipIf(salt.utils.is_windows(), 'minion is windows')
@skipIf(_windows_or_mac(), 'minion is windows or mac')
@skip_if_not_root
@skipIf(not HAS_GITPYTHON, 'GitPython >= {0} required'.format(GITPYTHON_MINVER))
@skipIf(not HAS_SSHD, 'sshd not present')
@ -352,7 +356,7 @@ class TestGitPythonSSH(GitPillarSSHTestBase, GitPythonMixin):
@skipIf(NO_MOCK, NO_MOCK_REASON)
@skipIf(salt.utils.is_windows(), 'minion is windows')
@skipIf(_windows_or_mac(), 'minion is windows or mac')
@skip_if_not_root
@skipIf(not HAS_GITPYTHON, 'GitPython >= {0} required'.format(GITPYTHON_MINVER))
@skipIf(not HAS_NGINX, 'nginx not present')
@ -365,7 +369,7 @@ class TestGitPythonHTTP(GitPillarHTTPTestBase, GitPythonMixin):
@skipIf(NO_MOCK, NO_MOCK_REASON)
@skipIf(salt.utils.is_windows(), 'minion is windows')
@skipIf(_windows_or_mac(), 'minion is windows or mac')
@skip_if_not_root
@skipIf(not HAS_GITPYTHON, 'GitPython >= {0} required'.format(GITPYTHON_MINVER))
@skipIf(not HAS_NGINX, 'nginx not present')
@ -396,7 +400,7 @@ class TestGitPythonAuthenticatedHTTP(TestGitPythonHTTP, GitPythonMixin):
@destructiveTest
@skipIf(NO_MOCK, NO_MOCK_REASON)
@skipIf(salt.utils.is_windows(), 'minion is windows')
@skipIf(_windows_or_mac(), 'minion is windows or mac')
@skip_if_not_root
@skipIf(not HAS_PYGIT2, 'pygit2 >= {0} required'.format(PYGIT2_MINVER))
@skipIf(not HAS_SSHD, 'sshd not present')
@ -1112,7 +1116,7 @@ class TestPygit2SSH(GitPillarSSHTestBase):
@skipIf(NO_MOCK, NO_MOCK_REASON)
@skipIf(salt.utils.is_windows(), 'minion is windows')
@skipIf(_windows_or_mac(), 'minion is windows or mac')
@skip_if_not_root
@skipIf(not HAS_PYGIT2, 'pygit2 >= {0} required'.format(PYGIT2_MINVER))
@skipIf(not HAS_NGINX, 'nginx not present')
@ -1349,7 +1353,7 @@ class TestPygit2HTTP(GitPillarHTTPTestBase):
@skipIf(NO_MOCK, NO_MOCK_REASON)
@skipIf(salt.utils.is_windows(), 'minion is windows')
@skipIf(_windows_or_mac(), 'minion is windows or mac')
@skip_if_not_root
@skipIf(not HAS_PYGIT2, 'pygit2 >= {0} required'.format(PYGIT2_MINVER))
@skipIf(not HAS_NGINX, 'nginx not present')

View file

@ -34,6 +34,10 @@ class VirtualenvTest(ModuleCase, SaltReturnAssertsMixin):
uinfo = self.run_function('user.info', [user])
if salt.utils.is_darwin():
# MacOS does not support createhome with user.present
self.assertSaltTrueReturn(self.run_state('file.directory', name=uinfo['home'], user=user, group=uinfo['groups'][0], dir_mode=755))
venv_dir = os.path.join(
RUNTIME_VARS.SYS_TMP_DIR, 'issue-1959-virtualenv-runas'
)

View file

@ -309,8 +309,11 @@ class TimezoneModuleTestCase(TestCase, LoaderModuleMockMixin):
:return:
'''
# Incomplete
hwclock = 'localtime'
if not os.path.isfile('/etc/environment'):
hwclock = 'UTC'
with patch.dict(timezone.__grains__, {'os_family': ['AIX']}):
assert timezone.get_hwclock() == 'localtime'
assert timezone.get_hwclock() == hwclock
@patch('salt.utils.which', MagicMock(return_value=False))
@patch('os.path.exists', MagicMock(return_value=True))