mirror of
https://github.com/saltstack/salt.git
synced 2025-04-16 17:50:20 +00:00
Merge 3003 changes forward to the master branch (#59879)
* Merge 3002.6 bugfix changes (#59822)
* Pass `CI_RUN` as an environment variable to the test run.
This allows us to know if we're running the test suite under a CI
environment or not and adapt/adjust if needed
* Migrate `unit.setup` to PyTest
* Backport ae36b15
just for test_install.py
* Only skip tests on CI runs
* Always store git sha in _version.py during installation
* Fix PEP440 compliance.
The wheel metadata version 1.2 states that the package version MUST be
PEP440 compliant.
This means that instead of `3002.2-511-g033c53eccb`, the salt version
string should look like `3002.2+511.g033c53eccb`, a post release of
`3002.2` ahead by 511 commits with the git sha `033c53eccb`
* Fix and migrate `tests/unit/test_version.py` to PyTest
* Skip test if `easy_install` is not available
* We also need to be PEP440 compliant when there's no git history
* Allow extra_filerefs as sanitized kwargs for SSH client
* Fix regression on cmd.run when passing tuples as cmd
Co-authored-by: Alexander Graul <agraul@suse.com>
* Add unit tests to ensure cmd.run accepts tuples
* Add unit test to check for extra_filerefs on SSH opts
* Add changelog file
* Fix comment for test case
* Fix unit test to avoid failing on Windows
* Skip failing test on windows
* Fix test to work on Windows
* Add all ssh kwargs to sanitize_kwargs method
* Run pre-commit
* Fix pylint
* Fix cmdmod loglevel and module_names tests
* Fix pre-commit
* Skip ssh tests if binary does not exist
* Use setup_loader for cmdmod test
* Prevent argument injection in restartcheck
* Add changelog for restartcheck fix
* docs_3002.6
* Add back tests removed in merge
Co-authored-by: Pedro Algarvio <pedro@algarvio.me>
Co-authored-by: Megan Wilhite <megan.wilhite@gmail.com>
Co-authored-by: Bryce Larson <brycel@vmware.com>
Co-authored-by: Pablo Suárez Hernández <psuarezhernandez@suse.com>
Co-authored-by: Alexander Graul <agraul@suse.com>
Co-authored-by: Frode Gundersen <fgundersen@saltstack.com>
* Remove glance state module in favor of glance_image
* update wording in changelog
* bump deprecation warning to Silicon.
* Updating warnutil version to Phosphorous.
* Update salt/modules/keystone.py
Co-authored-by: Megan Wilhite <megan.wilhite@gmail.com>
* Check $HOMEBREW_PREFIX when linking against libcrypto
When loading `libcrypto`, Salt checks for a Homebrew installation of `openssl`
at Homebrew's default prefix of `/usr/local`. However, on Apple Silicon Macs,
Homebrew's default installation prefix is `/opt/homebrew`. On all platforms,
the prefix is configurable. If Salt doesn't find one of those `libcrypto`s,
it will fall back on the un-versioned `/usr/lib/libcrypto.dylib`, which will
cause the following crash:
Application Specific Information:
/usr/lib/libcrypto.dylib
abort() called
Invalid dylib load. Clients should not load the unversioned libcrypto dylib as it does not have a stable ABI.
This commit checks $HOMEBREW_PREFIX instead of hard-coding `/usr/local`.
* Add test case
* Add changelog for 59808
* Add changelog entry
* Make _find_libcrypto fail on Big Sur if it can't find a library
Right now, if `_find_libcrypto` can't find any externally-managed versions of
libcrypto, it will fall back on the pre-Catalina un-versioned system libcrypto.
This does not exist on Big Sur and it would be better to raise an exception
here rather than crashing later when trying to open it.
* Update _find_libcrypto tests
This commit simplifies the unit tests for _find_libcrypto by mocking out the
host's filesystem and testing the common libcrypto installations (brew, ports,
etc.) on Big Sur. It simplifies the tests for falling back on system versions
of libcrypto on previous versions of macOS.
* Fix description of test_find_libcrypto_with_system_before_catalina
* Patch sys.platform for test_rsax931 tests
* modules/match: add missing "minion_id" in Pillar example
The documented Pillar example for `match.filter_by` lacks the `minion_id` parameter. Without it, the assignment won't work as expected.
- fix documentation
- add tests:
- to prove the misbehavior of the documented example
- to prove the proper behaviour when supplying `minion_id`
- to ensure some misbehaviour observed with compound matchers doesn't occur
* Fix for issue #59773
- When instantiating the loader grab values of grains and pillars if
they are NamedLoaderContext instances.
- The loader uses a copy of opts.
- Impliment deepcopy on NamedLoaderContext instances.
* Add changelog for #59773
* _get_initial_pillar function returns pillar
* Fix linter issues
* Clean up test
* Bump deprecation release for neutron
* Uncomment Sulfur release name
* Removing the _ext_nodes deprecation warning and alias.
* Adding changelog.
* Renaming changelog file.
* Update 59804.removed
* Initial pass at fips_mode config option
* Fix pre-commit
* Fix tests and add changelog
* update docs 3003
* update docs 3003 - newline
* Fix warts in changelog
Co-authored-by: Pedro Algarvio <pedro@algarvio.me>
Co-authored-by: Megan Wilhite <megan.wilhite@gmail.com>
Co-authored-by: Bryce Larson <brycel@vmware.com>
Co-authored-by: Pablo Suárez Hernández <psuarezhernandez@suse.com>
Co-authored-by: Alexander Graul <agraul@suse.com>
Co-authored-by: Frode Gundersen <fgundersen@saltstack.com>
Co-authored-by: Gareth J. Greenaway <gareth@saltstack.com>
Co-authored-by: Gareth J. Greenaway <gareth@wiked.org>
Co-authored-by: Hoa-Long Tam <hoalong@apple.com>
Co-authored-by: krionbsd <krion@freebsd.org>
Co-authored-by: Elias Probst <e.probst@ssc-services.de>
Co-authored-by: Frode Gundersen <frogunder@gmail.com>
This commit is contained in:
parent
10c4da25c2
commit
0b5a3536c5
37 changed files with 707 additions and 123 deletions
50
CHANGELOG.md
50
CHANGELOG.md
|
@ -13,6 +13,9 @@ Salt 3003 (2021-03-05)
|
|||
Removed
|
||||
-------
|
||||
|
||||
- Removed the deprecated glance state and execution module in favor of the glance_image
|
||||
state module and the glanceng execution module. (#59079)
|
||||
- Removing the _ext_nodes deprecation warning and alias to the master_tops function. This change will break compatibility with a Salt master running versions 2017.7.8 and older and Salt minions running versions 3003 and newer. (#59804)
|
||||
- removed the arg `managed_private_key` from 'salt.states.x509.certificate_managed' (#59247)
|
||||
- Drop support for python 3.5 on Windows (#59479)
|
||||
|
||||
|
@ -22,7 +25,6 @@ Deprecated
|
|||
|
||||
- Added deprecation warning for grains.get_or_set_hash (#59425)
|
||||
|
||||
|
||||
Changed
|
||||
-------
|
||||
|
||||
|
@ -35,6 +37,9 @@ Changed
|
|||
Fixed
|
||||
-----
|
||||
|
||||
- When instantiating the loader grab values of grains and pillars if
|
||||
they are NamedLoaderContext instances. (#59773)
|
||||
- Fixed installation on Apple Silicon Macs by checking $HOMEBREW_PREFIX for `libcrypto` instead of assuming /usr/local. (#59808)
|
||||
- Fix incorrect documentation for pillar_source_merging_strategy (#26396)
|
||||
- Don't iterate through cloud map errors (#34033)
|
||||
- Supress noisy warnings when very old pyzmq is used. (#50327)
|
||||
|
@ -135,6 +140,7 @@ Fixed
|
|||
Added
|
||||
-----
|
||||
|
||||
- Added "fips_mode" config option to master and minion configs. (#59427)
|
||||
- Adding the ability to clear and show the pillar cache enabled when pillar_cache is True. (#37080)
|
||||
- SCRAM-SHA-256 support for PostgreSQL passwords.
|
||||
Pass encrypted=scram-sha-256 to the postgres_user.present (or postgres_group.present) state. (#51271)
|
||||
|
@ -169,6 +175,24 @@ Added
|
|||
binary ELF files in the package. (#59569)
|
||||
|
||||
|
||||
Salt 3002.6 (2021-03-10)
|
||||
========================
|
||||
|
||||
Changed
|
||||
-------
|
||||
|
||||
- Store git sha in salt/_version.py when installing from a tag so it can be found if needed later. (#59137)
|
||||
|
||||
Fixed
|
||||
-----
|
||||
|
||||
- Fix argument injection bug in restartcheck.restartcheck. This change hardens
|
||||
the fix for CVE-2020-28243. (#200)
|
||||
- Allow "extra_filerefs" as sanitized kwargs for SSH client.
|
||||
Fix regression on "cmd.run" when passing tuples as cmd. (#59664)
|
||||
- Allow all ssh kwargs as sanitized kwargs for SSH client. (#59748)
|
||||
|
||||
|
||||
Salt 3002.5 (2021-02-25)
|
||||
========================
|
||||
|
||||
|
@ -480,6 +504,18 @@ Added
|
|||
This flag will be deprecated in the Phosphorus release when this functionality
|
||||
becomes the default. (#58652)
|
||||
|
||||
Salt 3001.7 (2021-03-10)
|
||||
========================
|
||||
|
||||
Fixed
|
||||
-----
|
||||
|
||||
- Fix argument injection bug in restartcheck.restartcheck. This change hardens
|
||||
the fix for CVE-2020-28243. (#200)
|
||||
- Allow "extra_filerefs" as sanitized kwargs for SSH client.
|
||||
Fix regression on "cmd.run" when passing tuples as cmd. (#59664)
|
||||
- Allow all ssh kwargs as sanitized kwargs for SSH client. (#59748)
|
||||
|
||||
Salt 3001.6 (2021-02-09)
|
||||
========================
|
||||
|
||||
|
@ -971,6 +1007,18 @@ Added
|
|||
- [#56637](https://github.com/saltstack/salt/pull/56637) - Add ``win_wua.installed`` to the ``win_wua`` execution module
|
||||
- Clarify how to get the master fingerprint (#54699)
|
||||
|
||||
Salt 3000.9 (2021-03-10)
|
||||
========================
|
||||
|
||||
Fixed
|
||||
-----
|
||||
|
||||
- Allow "extra_filerefs" as sanitized kwargs for SSH client.
|
||||
Fix regression on "cmd.run" when passing tuples as cmd. (#59664)
|
||||
- Allow all ssh kwargs as sanitized kwargs for SSH client. (#59748)
|
||||
- Fix argument injection bug in restartcheck.restartcheck. This change hardens
|
||||
the fix for CVE-2020-28243.
|
||||
|
||||
Salt 3000.8 (2021-02-09)
|
||||
========================
|
||||
|
||||
|
|
17
doc/topics/releases/3000.9.rst
Normal file
17
doc/topics/releases/3000.9.rst
Normal file
|
@ -0,0 +1,17 @@
|
|||
.. _release-3000-9:
|
||||
|
||||
===========================
|
||||
Salt 3000.9 Release Notes
|
||||
===========================
|
||||
|
||||
Version 3000.9 is a bug fix release for :ref:`3000 <release-3000>`.
|
||||
|
||||
|
||||
Fixed
|
||||
-----
|
||||
|
||||
- Allow "extra_filerefs" as sanitized kwargs for SSH client.
|
||||
Fix regression on "cmd.run" when passing tuples as cmd. (#59664)
|
||||
- Allow all ssh kwargs as sanitized kwargs for SSH client. (#59748)
|
||||
- Fix argument injection bug in restartcheck.restartcheck. This change hardens
|
||||
the fix for CVE-2020-28243.
|
17
doc/topics/releases/3001.7.rst
Normal file
17
doc/topics/releases/3001.7.rst
Normal file
|
@ -0,0 +1,17 @@
|
|||
.. _release-3001-7:
|
||||
|
||||
=========================
|
||||
Salt 3001.7 Release Notes
|
||||
=========================
|
||||
|
||||
Version 3001.7 is a bug fix release for :ref:`3001 <release-3001>`.
|
||||
|
||||
|
||||
Fixed
|
||||
-----
|
||||
|
||||
- Allow "extra_filerefs" as sanitized kwargs for SSH client.
|
||||
Fix regression on "cmd.run" when passing tuples as cmd. (#59664)
|
||||
- Allow all ssh kwargs as sanitized kwargs for SSH client. (#59748)
|
||||
- Fix argument injection bug in restartcheck.restartcheck. This change hardens
|
||||
the fix for CVE-2020-28243.
|
24
doc/topics/releases/3002.6.rst
Normal file
24
doc/topics/releases/3002.6.rst
Normal file
|
@ -0,0 +1,24 @@
|
|||
.. _release-3002-6:
|
||||
|
||||
=========================
|
||||
Salt 3002.6 Release Notes
|
||||
=========================
|
||||
|
||||
Version 3002.6 is a bug fix release for :ref:`3002 <release-3002>`.
|
||||
|
||||
|
||||
Changed
|
||||
-------
|
||||
|
||||
- Store git sha in salt/_version.py when installing from a tag so it can be found if needed later. (#59137)
|
||||
|
||||
|
||||
Fixed
|
||||
-----
|
||||
|
||||
- Fix argument injection bug in restartcheck.restartcheck. This change hardens
|
||||
the fix for CVE-2020-28243. (#200)
|
||||
- Allow "extra_filerefs" as sanitized kwargs for SSH client.
|
||||
Fix regression on "cmd.run" when passing tuples as cmd. (#59664)
|
||||
- Allow all ssh kwargs as sanitized kwargs for SSH client. (#59748)
|
||||
|
|
@ -4,8 +4,6 @@
|
|||
Salt 3003 Release Notes - Codename Aluminium
|
||||
============================================
|
||||
|
||||
Salt 3003 is an *unreleased* upcoming feature release.
|
||||
|
||||
New Features
|
||||
============
|
||||
|
||||
|
@ -22,6 +20,9 @@ previous storage methods.
|
|||
Removed
|
||||
-------
|
||||
|
||||
- Removed the deprecated glance state and execution module in favor of the glance_image
|
||||
state module and the glanceng execution module. (#59079)
|
||||
- Removing the _ext_nodes deprecation warning and alias to the master_tops function. This change will break compatibility with a Salt master running versions 2017.7.8 and older and Salt minions running versions 3003 and newer. (#59804)
|
||||
- removed the arg `managed_private_key` from 'salt.states.x509.certificate_managed' (#59247)
|
||||
- Drop support for python 3.5 on Windows (#59479)
|
||||
|
||||
|
@ -50,6 +51,9 @@ Changed
|
|||
Fixed
|
||||
-----
|
||||
|
||||
- When instantiating the loader grab values of grains and pillars if
|
||||
they are NamedLoaderContext instances. (#59773)
|
||||
- Fixed installation on Apple Silicon Macs by checking $HOMEBREW_PREFIX for `libcrypto` instead of assuming /usr/local. (#59808)
|
||||
- The Google Cloud Engine salt-cloud provider now requires `apache-libcloud>=2.5.0`. Service account authentication is broken on older versions.
|
||||
- Fix incorrect documentation for pillar_source_merging_strategy (#26396)
|
||||
- Don't iterate through cloud map errors (#34033)
|
||||
|
@ -151,6 +155,7 @@ Fixed
|
|||
Added
|
||||
-----
|
||||
|
||||
- Added "fips_mode" config option to master and minion configs. (#59427)
|
||||
- Firewall groups support to Vultr Salt Cloud provider
|
||||
- Adding the ability to clear and show the pillar cache enabled when pillar_cache is True. (#37080)
|
||||
- SCRAM-SHA-256 support for PostgreSQL passwords.
|
||||
|
|
|
@ -52,11 +52,34 @@ class SSHClient:
|
|||
("ssh_identities_only", bool),
|
||||
("ssh_remote_port_forwards", str),
|
||||
("ssh_options", list),
|
||||
("ssh_max_procs", int),
|
||||
("ssh_askpass", bool),
|
||||
("ssh_key_deploy", bool),
|
||||
("ssh_update_roster", bool),
|
||||
("ssh_scan_ports", str),
|
||||
("ssh_scan_timeout", int),
|
||||
("ssh_timeout", int),
|
||||
("ssh_log_file", str),
|
||||
("raw_shell", bool),
|
||||
("refresh_cache", bool),
|
||||
("roster", str),
|
||||
("roster_file", str),
|
||||
("rosters", list),
|
||||
("ignore_host_keys", bool),
|
||||
("raw_shell", bool),
|
||||
("extra_filerefs", str),
|
||||
("min_extra_mods", str),
|
||||
("thin_extra_mods", str),
|
||||
("verbose", bool),
|
||||
("static", bool),
|
||||
("ssh_wipe", bool),
|
||||
("rand_thin_dir", bool),
|
||||
("regen_thin", bool),
|
||||
("python2_bin", str),
|
||||
("python3_bin", str),
|
||||
("ssh_run_pre_flight", bool),
|
||||
("no_host_keys", bool),
|
||||
("saltfile", str),
|
||||
]
|
||||
sane_kwargs = {}
|
||||
for name, kind in roster_vals:
|
||||
|
|
|
@ -952,6 +952,7 @@ VALID_OPTS = immutabletypes.freeze(
|
|||
"disabled_requisites": (str, list),
|
||||
# Feature flag config
|
||||
"features": dict,
|
||||
"fips_mode": bool,
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -1254,6 +1255,7 @@ DEFAULT_MINION_OPTS = immutabletypes.freeze(
|
|||
"ssh_merge_pillar": True,
|
||||
"disabled_requisites": [],
|
||||
"reactor_niceness": None,
|
||||
"fips_mode": False,
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -1590,6 +1592,7 @@ DEFAULT_MASTER_OPTS = immutabletypes.freeze(
|
|||
"minion_data_cache_events": True,
|
||||
"enable_ssh_minions": False,
|
||||
"netapi_allow_raw_shell": False,
|
||||
"fips_mode": False,
|
||||
}
|
||||
)
|
||||
|
||||
|
|
|
@ -1404,15 +1404,7 @@ class RemoteClient(Client):
|
|||
"""
|
||||
Return the metadata derived from the master_tops system
|
||||
"""
|
||||
log.debug(
|
||||
"The _ext_nodes master function has been renamed to _master_tops. "
|
||||
"To ensure compatibility when using older Salt masters we will "
|
||||
"continue to invoke the function as _ext_nodes until the "
|
||||
"3002 release."
|
||||
)
|
||||
# TODO: Change back to _master_tops
|
||||
# for 3002 release
|
||||
load = {"cmd": "_ext_nodes", "id": self.opts["id"], "opts": self.opts}
|
||||
load = {"cmd": "_master_tops", "id": self.opts["id"], "opts": self.opts}
|
||||
if self.auth:
|
||||
load["tok"] = self.auth.gen_token(b"salt")
|
||||
return self.channel.send(load)
|
||||
|
|
|
@ -1314,6 +1314,12 @@ class LazyLoader(salt.utils.lazy.LazyDict):
|
|||
self.pack[i] = self.pack[i].value()
|
||||
if opts is None:
|
||||
opts = {}
|
||||
opts = copy.deepcopy(opts)
|
||||
for i in ["pillar", "grains"]:
|
||||
if i in opts and isinstance(
|
||||
opts[i], salt.loader_context.NamedLoaderContext
|
||||
):
|
||||
opts[i] = opts[i].value()
|
||||
threadsafety = not opts.get("multiprocessing")
|
||||
self.context_dict = salt.utils.context.ContextDict(threadsafe=threadsafety)
|
||||
self.opts = self.__prep_mod_opts(opts)
|
||||
|
|
|
@ -4,6 +4,7 @@ Manage the context a module loaded by Salt's loader
|
|||
import collections.abc
|
||||
import contextlib
|
||||
import contextvars
|
||||
import copy
|
||||
|
||||
DEFAULT_CTX_VAR = "loader_ctxvar"
|
||||
|
||||
|
@ -112,6 +113,10 @@ class NamedLoaderContext(collections.abc.MutableMapping):
|
|||
def __getattr__(self, name):
|
||||
return getattr(self.value(), name)
|
||||
|
||||
def __deepcopy__(self, memo):
|
||||
default = copy.deepcopy(self.default)
|
||||
return self.__class__(self.name, self.loader_context, default)
|
||||
|
||||
def missing_fun_string(self, name):
|
||||
return self.loader().missing_fun_string(name)
|
||||
|
||||
|
|
|
@ -1204,7 +1204,6 @@ class AESFuncs(TransportMethods):
|
|||
expose_methods = (
|
||||
"verify_minion",
|
||||
"_master_tops",
|
||||
"_ext_nodes",
|
||||
"_master_opts",
|
||||
"_mine_get",
|
||||
"_mine",
|
||||
|
@ -1429,9 +1428,6 @@ class AESFuncs(TransportMethods):
|
|||
return {}
|
||||
return self.masterapi._master_tops(load, skip_verify=True)
|
||||
|
||||
# Needed so older minions can request master_tops
|
||||
_ext_nodes = _master_tops
|
||||
|
||||
def _master_opts(self, load):
|
||||
"""
|
||||
Return the master options to the minion
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
This module helps include encrypted passwords in pillars, grains and salt state files.
|
||||
|
||||
|
@ -150,16 +149,15 @@ Optional small program to encrypt data without needing salt modules.
|
|||
|
||||
"""
|
||||
|
||||
# Import Python libs
|
||||
from __future__ import absolute_import, print_function, unicode_literals
|
||||
|
||||
# Import Salt libs
|
||||
import salt.utils.nacl
|
||||
|
||||
__virtualname__ = "nacl"
|
||||
|
||||
|
||||
def __virtual__():
|
||||
if __opts__["fips_mode"] is True:
|
||||
return False, "nacl module not available in FIPS mode"
|
||||
return salt.utils.nacl.check_requirements()
|
||||
|
||||
|
||||
|
|
|
@ -11,7 +11,6 @@ https://packages.debian.org/debian-goodies) and psdel by Sam Morris.
|
|||
"""
|
||||
import os
|
||||
import re
|
||||
import shlex
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
|
@ -495,17 +494,17 @@ def restartcheck(ignorelist=None, blacklist=None, excludepid=None, **kwargs):
|
|||
verbose = kwargs.pop("verbose", True)
|
||||
timeout = kwargs.pop("timeout", 5)
|
||||
if __grains__.get("os_family") == "Debian":
|
||||
cmd_pkg_query = "dpkg-query --listfiles "
|
||||
cmd_pkg_query = ["dpkg-query", "--listfiles"]
|
||||
systemd_folder = "/lib/systemd/system/"
|
||||
systemd = "/bin/systemd"
|
||||
kernel_versions = _kernel_versions_debian()
|
||||
elif __grains__.get("os_family") == "RedHat":
|
||||
cmd_pkg_query = "repoquery -l "
|
||||
cmd_pkg_query = ["repoquery", "-l"]
|
||||
systemd_folder = "/usr/lib/systemd/system/"
|
||||
systemd = "/usr/bin/systemctl"
|
||||
kernel_versions = _kernel_versions_redhat()
|
||||
elif __grains__.get("os_family") == NILRT_FAMILY_NAME:
|
||||
cmd_pkg_query = "opkg files "
|
||||
cmd_pkg_query = ["opkg", "files"]
|
||||
systemd = ""
|
||||
kernel_versions = _kernel_versions_nilrt()
|
||||
else:
|
||||
|
@ -613,8 +612,8 @@ def restartcheck(ignorelist=None, blacklist=None, excludepid=None, **kwargs):
|
|||
|
||||
for package in packages:
|
||||
_check_timeout(start_time, timeout)
|
||||
cmd = cmd_pkg_query + package
|
||||
cmd = shlex.split(cmd)
|
||||
cmd = cmd_pkg_query[:]
|
||||
cmd.append(package)
|
||||
paths = subprocess.Popen(cmd, stdout=subprocess.PIPE)
|
||||
|
||||
while True:
|
||||
|
|
|
@ -425,7 +425,7 @@ def _check_queue(queue, kwargs):
|
|||
|
||||
def _get_initial_pillar(opts):
|
||||
return (
|
||||
__pillar__
|
||||
__pillar__.value()
|
||||
if __opts__.get("__cli", None) == "salt-call"
|
||||
and opts["pillarenv"] == __opts__["pillarenv"]
|
||||
else None
|
||||
|
|
|
@ -568,7 +568,6 @@ def read_certificate(certificate):
|
|||
"Key Size": cert.get_pubkey().size() * 8,
|
||||
"Serial Number": _dec2hex(cert.get_serial_number()),
|
||||
"SHA-256 Finger Print": _pretty_hex(cert.get_fingerprint(md="sha256")),
|
||||
"MD5 Finger Print": _pretty_hex(cert.get_fingerprint(md="md5")),
|
||||
"SHA1 Finger Print": _pretty_hex(cert.get_fingerprint(md="sha1")),
|
||||
"Subject": _parse_subject(cert.get_subject()),
|
||||
"Subject Hash": _dec2hex(cert.get_subject().as_hash()),
|
||||
|
@ -580,7 +579,8 @@ def read_certificate(certificate):
|
|||
"Not After": cert.get_not_after().get_datetime().strftime("%Y-%m-%d %H:%M:%S"),
|
||||
"Public Key": get_public_key(cert),
|
||||
}
|
||||
|
||||
if __opts__["fips_mode"] is False:
|
||||
ret["MD5 Finger Print"] = _pretty_hex(cert.get_fingerprint(md="md5"))
|
||||
exts = OrderedDict()
|
||||
for ext_index in range(0, cert.get_ext_count()):
|
||||
ext = cert.get_ext_at(ext_index)
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
Decrypt pillar data through the builtin NACL renderer
|
||||
|
||||
|
@ -20,10 +18,17 @@ Set ``nacl.config`` in your config.
|
|||
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import, print_function, unicode_literals
|
||||
|
||||
import salt
|
||||
|
||||
__virtualname__ = "nacl"
|
||||
|
||||
|
||||
def __virtual__():
|
||||
if __opts__["fips_mode"] is True:
|
||||
return False, "nacl pillar data not available in FIPS mode"
|
||||
return __virtualname__
|
||||
|
||||
|
||||
def ext_pillar(minion_id, pillar, *args, **kwargs):
|
||||
render_function = salt.loader.render(__opts__, __salt__).get("nacl")
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
This module helps include encrypted passwords in pillars, grains and salt state files.
|
||||
|
||||
|
@ -112,16 +111,15 @@ Larger files like certificates can be encrypted with:
|
|||
|
||||
"""
|
||||
|
||||
# Import Python libs
|
||||
from __future__ import absolute_import, print_function, unicode_literals
|
||||
|
||||
# Import Salt libs
|
||||
import salt.utils.nacl
|
||||
|
||||
__virtualname__ = "nacl"
|
||||
|
||||
|
||||
def __virtual__():
|
||||
if __opts__["fips_mode"] is True:
|
||||
return False, "nacl runner not available in FIPS mode"
|
||||
return salt.utils.nacl.check_requirements()
|
||||
|
||||
|
||||
|
|
|
@ -321,7 +321,7 @@ def private_key_managed(
|
|||
name, bits=bits, passphrase=passphrase, new=new, overwrite=overwrite
|
||||
):
|
||||
file_args["contents"] = __salt__["x509.get_pem_entry"](
|
||||
name, pem_type="RSA PRIVATE KEY"
|
||||
name, pem_type="(?:RSA )?PRIVATE KEY"
|
||||
)
|
||||
else:
|
||||
new_key = True
|
||||
|
@ -399,12 +399,13 @@ def _certificate_info_matches(cert_info, required_cert_info, check_serial=False)
|
|||
ignored_keys = [
|
||||
"Not Before",
|
||||
"Not After",
|
||||
"MD5 Finger Print",
|
||||
"SHA1 Finger Print",
|
||||
"SHA-256 Finger Print",
|
||||
# The integrity of the issuer is checked elsewhere
|
||||
"Issuer Public Key",
|
||||
]
|
||||
if __opts__["fips_mode"] is False:
|
||||
ignored_keys.append("MD5 Finger Print")
|
||||
for key in ignored_keys:
|
||||
cert_info.pop(key, None)
|
||||
required_cert_info.pop(key, None)
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Common code shared between the nacl module and runner.
|
||||
"""
|
||||
|
||||
# Import Python libs
|
||||
from __future__ import absolute_import, print_function, unicode_literals
|
||||
|
||||
import base64
|
||||
import logging
|
||||
|
@ -18,9 +15,6 @@ import salt.utils.versions
|
|||
import salt.utils.win_dacl
|
||||
import salt.utils.win_functions
|
||||
|
||||
# Import Salt libs
|
||||
from salt.ext import six
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
REQ_ERROR = None
|
||||
|
@ -36,6 +30,8 @@ __virtualname__ = "nacl"
|
|||
|
||||
|
||||
def __virtual__():
|
||||
if __opts__["fips_mode"] is True:
|
||||
return False, "nacl utils not available in FIPS mode"
|
||||
return check_requirements()
|
||||
|
||||
|
||||
|
@ -66,7 +62,7 @@ def _get_config(**kwargs):
|
|||
"pk_file": pk_file,
|
||||
}
|
||||
|
||||
config_key = "{0}.config".format(__virtualname__)
|
||||
config_key = "{}.config".format(__virtualname__)
|
||||
try:
|
||||
config.update(__salt__["config.get"](config_key, {}))
|
||||
except (NameError, KeyError) as e:
|
||||
|
@ -91,7 +87,7 @@ def _get_sk(**kwargs):
|
|||
try:
|
||||
with salt.utils.files.fopen(sk_file, "rb") as keyf:
|
||||
key = salt.utils.stringutils.to_unicode(keyf.read()).rstrip("\n")
|
||||
except (IOError, OSError):
|
||||
except OSError:
|
||||
raise Exception("no key or sk_file found")
|
||||
return base64.b64decode(key)
|
||||
|
||||
|
@ -109,9 +105,9 @@ def _get_pk(**kwargs):
|
|||
try:
|
||||
with salt.utils.files.fopen(pk_file, "rb") as keyf:
|
||||
pubkey = salt.utils.stringutils.to_unicode(keyf.read()).rstrip("\n")
|
||||
except (IOError, OSError):
|
||||
except OSError:
|
||||
raise Exception("no pubkey or pk_file found")
|
||||
pubkey = six.text_type(pubkey)
|
||||
pubkey = str(pubkey)
|
||||
return base64.b64decode(pubkey)
|
||||
|
||||
|
||||
|
@ -151,7 +147,7 @@ def keygen(sk_file=None, pk_file=None, **kwargs):
|
|||
return {"sk": base64.b64encode(kp.sk), "pk": base64.b64encode(kp.pk)}
|
||||
|
||||
if pk_file is None:
|
||||
pk_file = "{0}.pub".format(sk_file)
|
||||
pk_file = "{}.pub".format(sk_file)
|
||||
|
||||
if sk_file and pk_file is None:
|
||||
if not os.path.isfile(sk_file):
|
||||
|
@ -172,16 +168,16 @@ def keygen(sk_file=None, pk_file=None, **kwargs):
|
|||
else:
|
||||
# chmod 0600 file
|
||||
os.chmod(sk_file, 1536)
|
||||
return "saved sk_file: {0}".format(sk_file)
|
||||
return "saved sk_file: {}".format(sk_file)
|
||||
else:
|
||||
raise Exception("sk_file:{0} already exist.".format(sk_file))
|
||||
raise Exception("sk_file:{} already exist.".format(sk_file))
|
||||
|
||||
if sk_file is None and pk_file:
|
||||
raise Exception("sk_file: Must be set inorder to generate a public key.")
|
||||
|
||||
if os.path.isfile(sk_file) and os.path.isfile(pk_file):
|
||||
raise Exception(
|
||||
"sk_file:{0} and pk_file:{1} already exist.".format(sk_file, pk_file)
|
||||
"sk_file:{} and pk_file:{} already exist.".format(sk_file, pk_file)
|
||||
)
|
||||
|
||||
if os.path.isfile(sk_file) and not os.path.isfile(pk_file):
|
||||
|
@ -192,7 +188,7 @@ def keygen(sk_file=None, pk_file=None, **kwargs):
|
|||
kp = libnacl.public.SecretKey(sk)
|
||||
with salt.utils.files.fopen(pk_file, "wb") as keyf:
|
||||
keyf.write(base64.b64encode(kp.pk))
|
||||
return "saved pk_file: {0}".format(pk_file)
|
||||
return "saved pk_file: {}".format(pk_file)
|
||||
|
||||
kp = libnacl.public.SecretKey()
|
||||
with salt.utils.files.fopen(sk_file, "wb") as keyf:
|
||||
|
@ -208,7 +204,7 @@ def keygen(sk_file=None, pk_file=None, **kwargs):
|
|||
os.chmod(sk_file, 1536)
|
||||
with salt.utils.files.fopen(pk_file, "wb") as keyf:
|
||||
keyf.write(base64.b64encode(kp.pk))
|
||||
return "saved sk_file:{0} pk_file: {1}".format(sk_file, pk_file)
|
||||
return "saved sk_file:{} pk_file: {}".format(sk_file, pk_file)
|
||||
|
||||
|
||||
def enc(data, **kwargs):
|
||||
|
@ -275,10 +271,10 @@ def enc_file(name, out=None, **kwargs):
|
|||
d = enc(data, **kwargs)
|
||||
if out:
|
||||
if os.path.isfile(out):
|
||||
raise Exception("file:{0} already exist.".format(out))
|
||||
raise Exception("file:{} already exist.".format(out))
|
||||
with salt.utils.files.fopen(out, "wb") as f:
|
||||
f.write(salt.utils.stringutils.to_bytes(d))
|
||||
return "Wrote: {0}".format(out)
|
||||
return "Wrote: {}".format(out)
|
||||
return d
|
||||
|
||||
|
||||
|
@ -346,10 +342,10 @@ def dec_file(name, out=None, **kwargs):
|
|||
d = dec(data, **kwargs)
|
||||
if out:
|
||||
if os.path.isfile(out):
|
||||
raise Exception("file:{0} already exist.".format(out))
|
||||
raise Exception("file:{} already exist.".format(out))
|
||||
with salt.utils.files.fopen(out, "wb") as f:
|
||||
f.write(salt.utils.stringutils.to_bytes(d))
|
||||
return "Wrote: {0}".format(out)
|
||||
return "Wrote: {}".format(out)
|
||||
return d
|
||||
|
||||
|
||||
|
|
|
@ -1,22 +1,13 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Neutron class
|
||||
"""
|
||||
|
||||
|
||||
# Import python libs
|
||||
from __future__ import absolute_import, print_function, unicode_literals, with_statement
|
||||
|
||||
import logging
|
||||
|
||||
import salt.utils.versions
|
||||
|
||||
# Import salt libs
|
||||
from salt import exceptions
|
||||
|
||||
# Import third party libs
|
||||
from salt.ext import six
|
||||
|
||||
# pylint: disable=import-error
|
||||
HAS_NEUTRON = False
|
||||
try:
|
||||
|
@ -73,7 +64,7 @@ def sanitize_neutronclient(kwargs):
|
|||
"auth",
|
||||
)
|
||||
ret = {}
|
||||
for var in six.iterkeys(kwargs):
|
||||
for var in kwargs.keys():
|
||||
if var in variables:
|
||||
ret[var] = kwargs[var]
|
||||
|
||||
|
@ -103,7 +94,7 @@ class SaltNeutron(NeutronShell):
|
|||
Set up neutron credentials
|
||||
"""
|
||||
salt.utils.versions.warn_until(
|
||||
"Aluminium",
|
||||
"Sulfur",
|
||||
(
|
||||
"The neutron module has been deprecated and will be removed in {version}. "
|
||||
"Please update to using the neutronng module"
|
||||
|
|
|
@ -32,17 +32,23 @@ def _find_libcrypto():
|
|||
# look in salts pkg install location.
|
||||
lib = glob.glob("/opt/salt/lib/libcrypto.dylib")
|
||||
# Find library symlinks in Homebrew locations.
|
||||
lib = lib or glob.glob("/usr/local/opt/openssl/lib/libcrypto.dylib")
|
||||
lib = lib or glob.glob("/usr/local/opt/openssl@*/lib/libcrypto.dylib")
|
||||
brew_prefix = os.getenv("HOMEBREW_PREFIX", "/usr/local")
|
||||
lib = lib or glob.glob(
|
||||
os.path.join(brew_prefix, "opt/openssl/lib/libcrypto.dylib")
|
||||
)
|
||||
lib = lib or glob.glob(
|
||||
os.path.join(brew_prefix, "opt/openssl@*/lib/libcrypto.dylib")
|
||||
)
|
||||
# look in macports.
|
||||
lib = lib or glob.glob("/opt/local/lib/libcrypto.dylib")
|
||||
# check if 10.15, regular libcrypto.dylib is just a false pointer.
|
||||
if platform.mac_ver()[0].split(".")[:2] == ["10", "15"]:
|
||||
lib = lib or glob.glob("/usr/lib/libcrypto.*.dylib")
|
||||
lib = list(reversed(sorted(lib)))
|
||||
# last but not least all the other macOS versions should work here.
|
||||
# including Big Sur.
|
||||
lib = lib[0] if lib else "/usr/lib/libcrypto.dylib"
|
||||
elif int(platform.mac_ver()[0].split(".")[0]) < 11:
|
||||
# Fall back on system libcrypto (only works before Big Sur)
|
||||
lib = lib or ["/usr/lib/libcrypto.dylib"]
|
||||
lib = lib[0] if lib else None
|
||||
elif getattr(sys, "frozen", False) and salt.utils.platform.is_smartos():
|
||||
lib = glob.glob(os.path.join(os.path.dirname(sys.executable), "libcrypto.so*"))
|
||||
lib = lib[0] if lib else None
|
||||
|
|
|
@ -96,8 +96,8 @@ class SaltStackVersion:
|
|||
"Aluminium": (3003,),
|
||||
"Silicon": (MAX_SIZE - 95, 0),
|
||||
"Phosphorus": (MAX_SIZE - 94, 0),
|
||||
"Sulfur": (MAX_SIZE - 93, 0),
|
||||
# pylint: disable=E8265
|
||||
#'Sulfur' : (MAX_SIZE - 93, 0),
|
||||
#'Chlorine' : (MAX_SIZE - 92, 0),
|
||||
#'Argon' : (MAX_SIZE - 91, 0),
|
||||
#'Potassium' : (MAX_SIZE - 90, 0),
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
import pytest
|
||||
import salt.client.ssh.client
|
||||
import salt.utils.msgpack
|
||||
from salt.client import ssh
|
||||
from tests.support.mock import MagicMock, patch
|
||||
|
||||
pytestmark = [pytest.mark.skip_if_binaries_missing("ssh", "ssh-keygen", check_all=True)]
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def ssh_target(tmpdir):
|
||||
|
@ -57,3 +60,76 @@ def test_cmd_block_python_version_error(ssh_target):
|
|||
with patch_shim:
|
||||
ret = single.cmd_block()
|
||||
assert "ERROR: Python version error. Recommendation(s) follow:" in ret[0]
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"test_opts",
|
||||
[
|
||||
("extra_filerefs", "salt://foobar", True),
|
||||
("host", "testhost", False),
|
||||
("ssh_user", "testuser", True),
|
||||
("ssh_passwd", "testpasswd", True),
|
||||
("ssh_port", 23, False),
|
||||
("ssh_sudo", True, True),
|
||||
("ssh_sudo_user", "sudouser", False),
|
||||
("ssh_priv", "test_priv", True),
|
||||
("ssh_priv_passwd", "sshpasswd", True),
|
||||
("ssh_identities_only", True, True),
|
||||
("ssh_remote_port_forwards", "test", True),
|
||||
("ssh_options", ["test1", "test2"], True),
|
||||
("ssh_max_procs", 2, True),
|
||||
("ssh_askpass", True, True),
|
||||
("ssh_key_deploy", True, True),
|
||||
("ssh_update_roster", True, True),
|
||||
("ssh_scan_ports", "test", True),
|
||||
("ssh_scan_timeout", 1.0, True),
|
||||
("ssh_timeout", 1, False),
|
||||
("ssh_log_file", "/tmp/test", True),
|
||||
("raw_shell", True, True),
|
||||
("refresh_cache", True, True),
|
||||
("roster", "/test", True),
|
||||
("roster_file", "/test1", True),
|
||||
("rosters", ["test1"], False),
|
||||
("ignore_host_keys", True, True),
|
||||
("min_extra_mods", "test", True),
|
||||
("thin_extra_mods", "test1", True),
|
||||
("verbose", True, True),
|
||||
("static", True, True),
|
||||
("ssh_wipe", True, True),
|
||||
("rand_thin_dir", True, True),
|
||||
("regen_thin", True, True),
|
||||
("python2_bin", "python2", True),
|
||||
("python3_bin", "python3", True),
|
||||
("ssh_run_pre_flight", True, True),
|
||||
("no_host_keys", True, True),
|
||||
("saltfile", "/tmp/test", True),
|
||||
("doesnotexist", None, False),
|
||||
],
|
||||
)
|
||||
def test_ssh_kwargs(test_opts):
|
||||
"""
|
||||
test all ssh kwargs are not excluded from kwargs
|
||||
when preparing the SSH opts
|
||||
"""
|
||||
opt_key = test_opts[0]
|
||||
opt_value = test_opts[1]
|
||||
# Is the kwarg in salt.utils.parsers?
|
||||
in_parser = test_opts[2]
|
||||
|
||||
opts = {
|
||||
"eauth": "auto",
|
||||
"username": "test",
|
||||
"password": "test",
|
||||
"client": "ssh",
|
||||
"tgt": "localhost",
|
||||
"fun": "test.ping",
|
||||
opt_key: opt_value,
|
||||
}
|
||||
client = salt.client.ssh.client.SSHClient(disable_custom_roster=True)
|
||||
if in_parser:
|
||||
ssh_kwargs = salt.utils.parsers.SaltSSHOptionParser().defaults
|
||||
assert opt_key in ssh_kwargs
|
||||
|
||||
with patch("salt.roster.get_roster_file", MagicMock(return_value="")):
|
||||
ssh_obj = client._prep_ssh(**opts)
|
||||
assert ssh_obj.opts.get(opt_key, None) == opt_value
|
||||
|
|
16
tests/pytests/unit/modules/test_nacl.py
Normal file
16
tests/pytests/unit/modules/test_nacl.py
Normal file
|
@ -0,0 +1,16 @@
|
|||
"""
|
||||
Unit tests for the salt.modules.nacl module
|
||||
"""
|
||||
|
||||
import salt.modules.nacl
|
||||
from tests.support.mock import patch
|
||||
|
||||
|
||||
def test_fips_mode():
|
||||
"""
|
||||
Nacl module does not load when fips_mode is True
|
||||
"""
|
||||
opts = {"fips_mode": True}
|
||||
with patch("salt.modules.nacl.__opts__", opts, create=True):
|
||||
ret = salt.modules.nacl.__virtual__()
|
||||
assert ret == (False, "nacl module not available in FIPS mode")
|
21
tests/pytests/unit/modules/test_state.py
Normal file
21
tests/pytests/unit/modules/test_state.py
Normal file
|
@ -0,0 +1,21 @@
|
|||
"""
|
||||
Unit tests for the salt.modules.state module
|
||||
"""
|
||||
|
||||
import salt.loader_context
|
||||
import salt.modules.state
|
||||
from tests.support.mock import patch
|
||||
|
||||
|
||||
def test_get_initial_pillar():
|
||||
"""
|
||||
_get_initial_pillar returns pillar data not named context
|
||||
"""
|
||||
ctx = salt.loader_context.LoaderContext()
|
||||
pillar_data = {"foo": "bar"}
|
||||
named_ctx = ctx.named_context("__pillar__", pillar_data)
|
||||
opts = {"__cli": "salt-call", "pillarenv": "base"}
|
||||
with patch("salt.modules.state.__pillar__", named_ctx, create=True):
|
||||
with patch("salt.modules.state.__opts__", opts, create=True):
|
||||
pillar = salt.modules.state._get_initial_pillar(opts)
|
||||
assert pillar == pillar_data
|
0
tests/pytests/unit/pillar/__init__.py
Normal file
0
tests/pytests/unit/pillar/__init__.py
Normal file
16
tests/pytests/unit/pillar/test_nacl.py
Normal file
16
tests/pytests/unit/pillar/test_nacl.py
Normal file
|
@ -0,0 +1,16 @@
|
|||
"""
|
||||
Unit tests for the salt.pillar.nacl module
|
||||
"""
|
||||
|
||||
import salt.pillar.nacl
|
||||
from tests.support.mock import patch
|
||||
|
||||
|
||||
def test_fips_mode():
|
||||
"""
|
||||
Nacl pillar doesn't load when fips_mode is True
|
||||
"""
|
||||
opts = {"fips_mode": True}
|
||||
with patch("salt.pillar.nacl.__opts__", opts, create=True):
|
||||
ret = salt.pillar.nacl.__virtual__()
|
||||
assert ret == (False, "nacl pillar data not available in FIPS mode")
|
0
tests/pytests/unit/runners/__init__.py
Normal file
0
tests/pytests/unit/runners/__init__.py
Normal file
16
tests/pytests/unit/runners/test_nacl.py
Normal file
16
tests/pytests/unit/runners/test_nacl.py
Normal file
|
@ -0,0 +1,16 @@
|
|||
"""
|
||||
Unit tests for the salt.runners.nacl module
|
||||
"""
|
||||
|
||||
import salt.runners.nacl
|
||||
from tests.support.mock import patch
|
||||
|
||||
|
||||
def test_fips_mode():
|
||||
"""
|
||||
Nacl runner doesn't load when fips_mode is True
|
||||
"""
|
||||
opts = {"fips_mode": True}
|
||||
with patch("salt.runners.nacl.__opts__", opts, create=True):
|
||||
ret = salt.runners.nacl.__virtual__()
|
||||
assert ret == (False, "nacl runner not available in FIPS mode")
|
|
@ -93,3 +93,24 @@ def test_loaders_create_named_loader_contexts(loader_dir):
|
|||
module_name = func.func.__module__
|
||||
module = sys.modules[module_name]
|
||||
assert isinstance(module.__context__, salt.loader_context.NamedLoaderContext)
|
||||
|
||||
|
||||
def test_loaders_convert_context_to_values(loader_dir):
|
||||
"""
|
||||
LazyLoaders convert NamedLoaderContexts to values when instantiated.
|
||||
"""
|
||||
loader_context = salt.loader_context.LoaderContext()
|
||||
grains_default = {
|
||||
"os": "linux",
|
||||
}
|
||||
grains = salt.loader_context.NamedLoaderContext(
|
||||
"grains", loader_context, grains_default
|
||||
)
|
||||
opts = {
|
||||
"optimization_order": [0, 1, 2],
|
||||
"grains": grains,
|
||||
}
|
||||
loader_1 = salt.loader.LazyLoader([loader_dir], opts,)
|
||||
assert loader_1.opts["grains"] == grains_default
|
||||
# The loader's opts is a copy
|
||||
assert opts["grains"] == grains
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
"""
|
||||
Tests for salt.loader_context
|
||||
"""
|
||||
import copy
|
||||
|
||||
import salt.loader
|
||||
import salt.loader_context
|
||||
|
||||
|
@ -31,3 +33,15 @@ def test_named_loader_default():
|
|||
# The loader's value is the same object as default
|
||||
assert named_context.value() is default
|
||||
assert named_context["foo"] == "bar"
|
||||
|
||||
|
||||
def test_named_loader_context_deepcopy():
|
||||
loader_context = salt.loader_context.LoaderContext()
|
||||
default_data = {"foo": "bar"}
|
||||
named_context = salt.loader_context.NamedLoaderContext(
|
||||
"__test__", loader_context, default_data
|
||||
)
|
||||
coppied = copy.deepcopy(named_context)
|
||||
assert coppied.name == named_context.name
|
||||
assert id(coppied.loader_context) == id(named_context.loader_context)
|
||||
assert id(coppied.default) != id(named_context.default)
|
||||
|
|
16
tests/pytests/unit/utils/test_nacl.py
Normal file
16
tests/pytests/unit/utils/test_nacl.py
Normal file
|
@ -0,0 +1,16 @@
|
|||
"""
|
||||
Unit tests for the salt.utils.nacl module
|
||||
"""
|
||||
|
||||
import salt.utils.nacl
|
||||
from tests.support.mock import patch
|
||||
|
||||
|
||||
def test_fips_mode():
|
||||
"""
|
||||
Nacl pillar doesn't load when fips_mode is True
|
||||
"""
|
||||
opts = {"fips_mode": True}
|
||||
with patch("salt.utils.nacl.__opts__", opts, create=True):
|
||||
ret = salt.utils.nacl.__virtual__()
|
||||
assert ret == (False, "nacl utils not available in FIPS mode")
|
|
@ -381,3 +381,50 @@ class RestartcheckTestCase(TestCase, LoaderModuleMockMixin):
|
|||
"Found 1 processes using old versions of upgraded files", ret
|
||||
)
|
||||
self.assertFalse(os.path.exists(create_file))
|
||||
|
||||
def test_valid_command_b(self):
|
||||
"""
|
||||
test for CVE-2020-28243
|
||||
"""
|
||||
create_file = os.path.join(RUNTIME_VARS.TMP, "created_file")
|
||||
|
||||
patch_kernel = patch(
|
||||
"salt.modules.restartcheck._kernel_versions_redhat",
|
||||
return_value=["3.10.0-1127.el7.x86_64"],
|
||||
)
|
||||
services = {
|
||||
"NetworkManager": {"ExecMainPID": 123},
|
||||
"auditd": {"ExecMainPID": 456},
|
||||
"crond": {"ExecMainPID": 789},
|
||||
}
|
||||
|
||||
patch_salt = patch.dict(
|
||||
restartcheck.__salt__,
|
||||
{
|
||||
"cmd.run": MagicMock(
|
||||
return_value="Linux localhost.localdomain 3.10.0-1127.el7.x86_64"
|
||||
),
|
||||
"service.get_running": MagicMock(return_value=list(services.keys())),
|
||||
"service.show": MagicMock(side_effect=list(services.values())),
|
||||
"pkg.owner": MagicMock(return_value=""),
|
||||
"service.available": MagicMock(return_value=True),
|
||||
},
|
||||
)
|
||||
|
||||
patch_deleted = patch(
|
||||
"salt.modules.restartcheck._deleted_files",
|
||||
MagicMock(return_value=[("--admindir tmp dpkg", 123, "/root/ (deleted)")]),
|
||||
)
|
||||
|
||||
patch_readlink = patch("os.readlink", return_value="--admindir tmp dpkg")
|
||||
|
||||
popen_mock = MagicMock()
|
||||
popen_mock.return_value.stdout.readline.side_effect = ["/usr/bin\n", ""]
|
||||
patch_popen = patch("subprocess.Popen", popen_mock)
|
||||
|
||||
patch_grains = patch.dict(restartcheck.__grains__, {"os_family": "RedHat"})
|
||||
with patch_kernel, patch_salt, patch_deleted, patch_readlink, patch_grains, patch_popen:
|
||||
ret = restartcheck.restartcheck()
|
||||
self.assertIn("Found 1 processes using old versions of upgraded files", ret)
|
||||
args, kwargs = popen_mock.call_args
|
||||
assert args[0] == ["repoquery", "-l", "--admindir tmp dpkg"]
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Author: Bo Maryniuk <bo@suse.de>
|
||||
#
|
||||
|
@ -15,8 +14,6 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# Import Salt Testing Libs
|
||||
from __future__ import absolute_import, print_function, unicode_literals
|
||||
|
||||
import datetime
|
||||
import os
|
||||
|
@ -25,16 +22,11 @@ import tempfile
|
|||
import salt.utils.files
|
||||
import salt.utils.stringutils
|
||||
from salt.modules import x509
|
||||
from tests.support.helpers import dedent
|
||||
from tests.support.mixins import LoaderModuleMockMixin
|
||||
from tests.support.mock import MagicMock, patch
|
||||
from tests.support.unit import TestCase, skipIf
|
||||
|
||||
try:
|
||||
import pytest
|
||||
except ImportError as import_error:
|
||||
pytest = None
|
||||
|
||||
|
||||
try:
|
||||
import M2Crypto # pylint: disable=unused-import
|
||||
|
||||
|
@ -99,10 +91,9 @@ c9bcgp7D7xD+TxWWNj4CSXEccJgGr91StV+gFg4ARQ==
|
|||
}
|
||||
|
||||
|
||||
@skipIf(not bool(pytest), False)
|
||||
class X509TestCase(TestCase, LoaderModuleMockMixin):
|
||||
def setup_loader_modules(self):
|
||||
return {x509: {}}
|
||||
return {x509: {"__opts__": {"fips_mode": False}}}
|
||||
|
||||
@patch("salt.modules.x509.log", MagicMock())
|
||||
def test_private_func__parse_subject(self):
|
||||
|
@ -111,7 +102,7 @@ class X509TestCase(TestCase, LoaderModuleMockMixin):
|
|||
:return:
|
||||
"""
|
||||
|
||||
class FakeSubject(object):
|
||||
class FakeSubject:
|
||||
"""
|
||||
Class for faking x509'th subject.
|
||||
"""
|
||||
|
@ -436,3 +427,64 @@ class X509TestCase(TestCase, LoaderModuleMockMixin):
|
|||
# Ensure that the correct server cert serial is amongst
|
||||
# the revoked certificates
|
||||
self.assertIn(serial_number, crl)
|
||||
|
||||
@skipIf(not HAS_M2CRYPTO, "Skipping, M2Crypto is unavailable")
|
||||
def test_read_certificate(self):
|
||||
"""
|
||||
:return:
|
||||
"""
|
||||
cet = dedent(
|
||||
"""
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICdDCCAd2gAwIBAgIUH6g+PC0bGKSY4LMq7PISP09M5B4wDQYJKoZIhvcNAQEL
|
||||
BQAwTDELMAkGA1UEBhMCVVMxEDAOBgNVBAgMB0FyaXpvbmExEzARBgNVBAcMClNj
|
||||
b3R0c2RhbGUxFjAUBgNVBAoMDVN1cGVyIFdpZGdpdHMwHhcNMjEwMzIzMDExNDE2
|
||||
WhcNMjIwMzIzMDExNDE2WjBMMQswCQYDVQQGEwJVUzEQMA4GA1UECAwHQXJpem9u
|
||||
YTETMBEGA1UEBwwKU2NvdHRzZGFsZTEWMBQGA1UECgwNU3VwZXIgV2lkZ2l0czCB
|
||||
nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAvtFFZP47UkzyAmVWtBnVHuXwe7iK
|
||||
yu19c3qx59KPVAMHkMKgCew4S2KBMDHySBVnspiEz1peP1ywozcP1tIeWHG6aY/7
|
||||
j2ewzl5bJ4HZPDBnEOYzGsC/NM8YY3qFlrteda/awvwoF99MkpVlrcLBMJzjt/c8
|
||||
HjuBb0zTlnm4r7ECAwEAAaNTMFEwHQYDVR0OBBYEFJwdb0PKsvu3dU0j3kx3uP4B
|
||||
NGpfMB8GA1UdIwQYMBaAFJwdb0PKsvu3dU0j3kx3uP4BNGpfMA8GA1UdEwEB/wQF
|
||||
MAMBAf8wDQYJKoZIhvcNAQELBQADgYEAZblVv70rSk6+7ti3mYxVo48VLf3hG5R/
|
||||
rMd434WYTeDOWlvl5GSklrBc4ToBW5GsJe/+JaFbUFo9YB+a0K0xjyNZ5CWWiaxg
|
||||
3lwqTx6vwK1ucS18B+nt2qqyq9hL0UvpSB7gH4KeCwCMDIfRMsrPi32jg1RyKftD
|
||||
B+O0S5LeuJw=
|
||||
-----END CERTIFICATE-----
|
||||
"""
|
||||
)
|
||||
ret = x509.read_certificate(cet)
|
||||
assert "MD5 Finger Print" in ret
|
||||
|
||||
|
||||
class X509FipsTestCase(TestCase, LoaderModuleMockMixin):
|
||||
def setup_loader_modules(self):
|
||||
return {x509: {"__opts__": {"fips_mode": True}}}
|
||||
|
||||
@skipIf(not HAS_M2CRYPTO, "Skipping, M2Crypto is unavailable")
|
||||
def test_read_certificate(self):
|
||||
"""
|
||||
:return:
|
||||
"""
|
||||
cet = dedent(
|
||||
"""
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICdDCCAd2gAwIBAgIUH6g+PC0bGKSY4LMq7PISP09M5B4wDQYJKoZIhvcNAQEL
|
||||
BQAwTDELMAkGA1UEBhMCVVMxEDAOBgNVBAgMB0FyaXpvbmExEzARBgNVBAcMClNj
|
||||
b3R0c2RhbGUxFjAUBgNVBAoMDVN1cGVyIFdpZGdpdHMwHhcNMjEwMzIzMDExNDE2
|
||||
WhcNMjIwMzIzMDExNDE2WjBMMQswCQYDVQQGEwJVUzEQMA4GA1UECAwHQXJpem9u
|
||||
YTETMBEGA1UEBwwKU2NvdHRzZGFsZTEWMBQGA1UECgwNU3VwZXIgV2lkZ2l0czCB
|
||||
nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAvtFFZP47UkzyAmVWtBnVHuXwe7iK
|
||||
yu19c3qx59KPVAMHkMKgCew4S2KBMDHySBVnspiEz1peP1ywozcP1tIeWHG6aY/7
|
||||
j2ewzl5bJ4HZPDBnEOYzGsC/NM8YY3qFlrteda/awvwoF99MkpVlrcLBMJzjt/c8
|
||||
HjuBb0zTlnm4r7ECAwEAAaNTMFEwHQYDVR0OBBYEFJwdb0PKsvu3dU0j3kx3uP4B
|
||||
NGpfMB8GA1UdIwQYMBaAFJwdb0PKsvu3dU0j3kx3uP4BNGpfMA8GA1UdEwEB/wQF
|
||||
MAMBAf8wDQYJKoZIhvcNAQELBQADgYEAZblVv70rSk6+7ti3mYxVo48VLf3hG5R/
|
||||
rMd434WYTeDOWlvl5GSklrBc4ToBW5GsJe/+JaFbUFo9YB+a0K0xjyNZ5CWWiaxg
|
||||
3lwqTx6vwK1ucS18B+nt2qqyq9hL0UvpSB7gH4KeCwCMDIfRMsrPi32jg1RyKftD
|
||||
B+O0S5LeuJw=
|
||||
-----END CERTIFICATE-----
|
||||
"""
|
||||
)
|
||||
ret = x509.read_certificate(cet)
|
||||
assert "MD5 Finger Print" not in ret
|
||||
|
|
122
tests/unit/states/test_x509.py
Normal file
122
tests/unit/states/test_x509.py
Normal file
|
@ -0,0 +1,122 @@
|
|||
import tempfile
|
||||
|
||||
import salt.utils.files
|
||||
from salt.modules import x509 as x509_mod
|
||||
from salt.states import x509
|
||||
from tests.support.helpers import dedent
|
||||
from tests.support.mixins import LoaderModuleMockMixin
|
||||
from tests.support.mock import MagicMock
|
||||
from tests.support.unit import TestCase, skipIf
|
||||
|
||||
try:
|
||||
import M2Crypto # pylint: disable=unused-import
|
||||
|
||||
HAS_M2CRYPTO = True
|
||||
except ImportError:
|
||||
HAS_M2CRYPTO = False
|
||||
|
||||
|
||||
class X509TestCase(TestCase, LoaderModuleMockMixin):
|
||||
def setup_loader_modules(self):
|
||||
return {x509: {"__opts__": {"fips_mode": False}}}
|
||||
|
||||
def test_certificate_info_matches(self):
|
||||
cert_info = {"MD5 Finger Print": ""}
|
||||
required_info = {"MD5 Finger Print": ""}
|
||||
ret = x509._certificate_info_matches(cert_info, required_info)
|
||||
assert ret == (True, [])
|
||||
|
||||
|
||||
class X509FipsTestCase(TestCase, LoaderModuleMockMixin):
|
||||
def setup_loader_modules(self):
|
||||
self.file_managed_mock = MagicMock()
|
||||
self.file_managed_mock.return_value = {"changes": True}
|
||||
|
||||
return {
|
||||
x509: {
|
||||
"__opts__": {"fips_mode": True},
|
||||
"__salt__": {
|
||||
"x509.get_pem_entry": x509_mod.get_pem_entry,
|
||||
"x509.get_private_key_size": x509_mod.get_private_key_size,
|
||||
},
|
||||
"__states__": {"file.managed": self.file_managed_mock},
|
||||
}
|
||||
}
|
||||
|
||||
@skipIf(not HAS_M2CRYPTO, "Skipping, M2Crypto is unavailable")
|
||||
def test_private_key_fips_mode(self):
|
||||
"""
|
||||
:return:
|
||||
"""
|
||||
test_key = dedent(
|
||||
"""
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDx7UUt0cPi5G51
|
||||
FmRBhAZtZb5x6P0PFn7GwnLmSvLNhCsOcD/vq/yBUU62pknzmOjM5pgWTACZj66O
|
||||
GOFmWBg06v8+sqUbaF9PZ/CxQD5MogmQhYNgfyuopHWWgLXMub2hlP+15qGohkzg
|
||||
Tr/mXp2ohVAb6ihjqb7XV9MiZaLNVX+XWauM8SlhqXMiJyDUopEGbg2pLsHhIMcX
|
||||
1twLlyDja+uDbCMZ4jDNB+wsWxTaPRH8KizfEabB1Cl+fdyD10pSAYcodOAnlkW+
|
||||
G/DX2hwb/ZAM9B1SXTfZ3gzaIIbqXBEHcZQNXxHL7szBTVcOmfx/RPfOeRncytb9
|
||||
Mit7RIBxAgMBAAECggEAD4Pi+uRIBsYVm2a7OURpURzEUPPbPtt3d/HCgqht1+ZR
|
||||
CJUEVK+X+wcm4Cnb9kZpL7LeMBfhtfdz/2LzGagurT4g7nlwg0h3TFVjJ0ryc+G0
|
||||
cVNOsKKXPzKE5AkPH7kNw04V9Cl9Vpx+U6hZQEHzJHqgP5oNyw540cCtJriT700b
|
||||
fG1q3PYKWSkDwTiUnJTnVLybFIKQC6urxTeT2UWeiBadfDY7DjI4USfrQsqCfGMO
|
||||
uWPpOOJk5RIvw5r0Of2xvxV76xCgzVTkgtWjBRMTEkfeYx3019xKlQtAKoGbZd1T
|
||||
tF8DH0cDlnri4nG7YT8yYvx/LWVDg12E6IZij1X60QKBgQD7062JuQGEmTd99a7o
|
||||
5TcgWYqDrmE9AEgJZjN+gnEPcsxc50HJaTQgrkV0oKrS8CMbStIymbzMKWifOj7o
|
||||
gvQBVecydq1AaXePt3gRe8vBFiP4cHjFcSegs9FDvdfJR36iHOBIgEp4DWvV1vgs
|
||||
+z82LT6Qy5kxUQvnlQ4dEaGdrQKBgQD175f0H4enRJ3BoWTrqt2mTAwtJcPsKmGD
|
||||
9YfFB3H4+O2rEKP4FpBO5PFXZ0dqm54hDtxqyC/lSXorFCUjVUBero1ECGt6Gnn2
|
||||
TSnhgk0VMxvhnc0GReIt4K9WrXGd0CMUDwIhFHj8kbb1X1yqt2hwyw7b10xFVStl
|
||||
sGv8CQB+VQKBgAF9q1VZZwzl61Ivli2CzeS/IvbMnX7C9ao4lK13EDxLLbKPG/CZ
|
||||
UtmurnKWUOyWx15t/viVuGxtAlWO/rhZriAj5g6CbVwoQ7DyIR/ZX8dw3h2mbNCe
|
||||
buGgruh7wz9J0RIcoadMOySiz7SgZS++/QzRD8HDstB77loco8zAQfixAoGBALDO
|
||||
FbTocfKbjrpkmBQg24YxR9OxQb/n3AEtI/VO2+38r4h6xxaUyhwd1S9bzWjkBXOI
|
||||
poeR8XTqNQ0BR422PTeUT3SohPPcUu/yG3jG3zmta47wjjPDS85lqEgtGvA0cPN7
|
||||
srErcatJ6nlOnGUSw9/K65y6lFeH2lIZ2hfwNM2dAoGBAMVCc7i3AIhLp6UrGzjP
|
||||
0ioCHCakpxfl8s1VQp55lhHlP6Y4RfqT72Zq7ScteTrisIAQyI9ot0gsuct2miQM
|
||||
nyDdyKGki/MPduGTzzWlBA7GZEHnxbAILH8kWJ7eE/Nh7zdF1CRts8utEO9L9S+0
|
||||
lVz1j/xGOseQk4cVos681Wpw
|
||||
-----END PRIVATE KEY-----"""
|
||||
)
|
||||
test_cert = dedent(
|
||||
"""
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDazCCAlOgAwIBAgIUAfATs1aodKw11Varh55msmU0LoowDQYJKoZIhvcNAQEL
|
||||
BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM
|
||||
GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMTAzMjMwMTM4MzdaFw0yMjAz
|
||||
MjMwMTM4MzdaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw
|
||||
HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggEiMA0GCSqGSIb3DQEB
|
||||
AQUAA4IBDwAwggEKAoIBAQDx7UUt0cPi5G51FmRBhAZtZb5x6P0PFn7GwnLmSvLN
|
||||
hCsOcD/vq/yBUU62pknzmOjM5pgWTACZj66OGOFmWBg06v8+sqUbaF9PZ/CxQD5M
|
||||
ogmQhYNgfyuopHWWgLXMub2hlP+15qGohkzgTr/mXp2ohVAb6ihjqb7XV9MiZaLN
|
||||
VX+XWauM8SlhqXMiJyDUopEGbg2pLsHhIMcX1twLlyDja+uDbCMZ4jDNB+wsWxTa
|
||||
PRH8KizfEabB1Cl+fdyD10pSAYcodOAnlkW+G/DX2hwb/ZAM9B1SXTfZ3gzaIIbq
|
||||
XBEHcZQNXxHL7szBTVcOmfx/RPfOeRncytb9Mit7RIBxAgMBAAGjUzBRMB0GA1Ud
|
||||
DgQWBBT0qx4KLhozvuWAI9peT/utYV9FITAfBgNVHSMEGDAWgBT0qx4KLhozvuWA
|
||||
I9peT/utYV9FITAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQDx
|
||||
tWvUyGfEwJJg1ViBa10nVhg5sEc6KfqcPzc2GvatIGJlAbc3b1AYu6677X04SQNA
|
||||
dYRA2jcZcKudy6eolPJow6SDpkt66IqciZYdbQE5h9elnwpZxmXlJTQTB9cEwyIk
|
||||
2em5DKpdIwa9rRDlbAjAVJb3015MtpKRu2gsQ7gl5X2U3K+DFsWtBPf+0xiJqUiq
|
||||
rd7tiHF/zylubSyH/LVONJZ6+/oT/qzJfxfpvygtQWcu4b2zzME/FPenMA8W6Rau
|
||||
ZYycQfpMVc7KwqF5/wfjnkmfxoFKnkD7WQ3qFCJ/xULk/Yn1hrvNeIr+khX3qKQi
|
||||
Y3BMA5m+J+PZrNy7EQSa
|
||||
-----END CERTIFICATE-----
|
||||
"""
|
||||
)
|
||||
fp, name = tempfile.mkstemp()
|
||||
with salt.utils.files.fopen(name, "w") as fd:
|
||||
fd.write(test_key)
|
||||
fd.write(test_cert)
|
||||
ret = x509.private_key_managed(name)
|
||||
self.file_managed_mock.assert_called_once()
|
||||
assert (
|
||||
self.file_managed_mock.call_args.kwargs["contents"].strip()
|
||||
== test_key.strip()
|
||||
)
|
||||
|
||||
def test_certificate_info_matches(self):
|
||||
cert_info = {"MD5 Finger Print": ""}
|
||||
required_info = {"MD5 Finger Print": ""}
|
||||
ret = x509._certificate_info_matches(cert_info, required_info)
|
||||
assert ret == (False, ["MD5 Finger Print"])
|
|
@ -200,6 +200,7 @@ class BadTestModuleNamesTestCase(TestCase):
|
|||
"unit.utils.scheduler.test_run_job",
|
||||
"unit.utils.scheduler.test_schedule",
|
||||
"unit.utils.scheduler.test_skip",
|
||||
"unit.auth.test_auth",
|
||||
)
|
||||
errors = []
|
||||
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
# coding: utf-8
|
||||
"""
|
||||
Test the RSA ANSI X9.31 signer and verifier
|
||||
"""
|
||||
|
||||
# python libs
|
||||
from __future__ import absolute_import, print_function, unicode_literals
|
||||
|
||||
import ctypes
|
||||
import ctypes.util
|
||||
import fnmatch
|
||||
|
@ -174,49 +170,89 @@ class RSAX931Test(TestCase):
|
|||
fnmatch.fnmatch(lib_path, "/opt/freeware/lib/libcrypto.so*")
|
||||
)
|
||||
|
||||
@skipIf(not salt.utils.platform.is_darwin(), "Host OS is not Darwin-like or macOS.")
|
||||
@patch.object(salt.utils.platform, "is_darwin", lambda: True)
|
||||
@patch.object(platform, "mac_ver", lambda: ("10.14.2", (), ""))
|
||||
@patch.object(glob, "glob", lambda _: [])
|
||||
def test_find_libcrypto_with_system_and_not_catalina(self):
|
||||
@patch.object(sys, "platform", "macosx")
|
||||
def test_find_libcrypto_with_system_before_catalina(self):
|
||||
"""
|
||||
Test _find_libcrypto on a Catalina-like macOS host, simulate
|
||||
not finding any other libcryptos and just defaulting to system.
|
||||
Test _find_libcrypto on a pre-Catalina macOS host by simulating not
|
||||
finding any other libcryptos and verifying that it defaults to system.
|
||||
"""
|
||||
lib_path = _find_libcrypto()
|
||||
passed = False
|
||||
for i in (
|
||||
"/opt/salt/lib/libcrypto.dylib",
|
||||
"/usr/local/opt/openssl/lib/libcrypto.dylib",
|
||||
"/usr/local/opt/openssl@*/lib/libcrypto.dylib",
|
||||
"/opt/local/lib/libcrypto.dylib",
|
||||
"/usr/lib/libcrypto.*.dylib",
|
||||
):
|
||||
if fnmatch.fnmatch(lib_path, i):
|
||||
passed = True
|
||||
break
|
||||
self.assertFalse(passed)
|
||||
self.assertEqual(lib_path, "/usr/lib/libcrypto.dylib")
|
||||
|
||||
@skipIf(not salt.utils.platform.is_darwin(), "Host OS is not Darwin-like or macOS.")
|
||||
@patch.object(salt.utils.platform, "is_darwin", lambda: True)
|
||||
@patch.object(platform, "mac_ver", lambda: ("10.15.2", (), ""))
|
||||
@patch.object(sys, "platform", "macosx")
|
||||
def test_find_libcrypto_darwin_catalina(self):
|
||||
"""
|
||||
Test _find_libcrypto on a Darwin-like macOS host where there isn't a
|
||||
lacation returned by ctypes.util.find_library()
|
||||
Test _find_libcrypto on a macOS Catalina host where there are no custom
|
||||
libcryptos and defaulting to the versioned system libraries.
|
||||
"""
|
||||
lib_path = _find_libcrypto()
|
||||
passed = False
|
||||
for i in (
|
||||
"/opt/salt/lib/libcrypto.dylib",
|
||||
"/usr/local/opt/openssl/lib/libcrypto.dylib",
|
||||
"/usr/local/opt/openssl@*/lib/libcrypto.dylib",
|
||||
"/opt/local/lib/libcrypto.dylib",
|
||||
"/usr/lib/libcrypto.*.dylib",
|
||||
):
|
||||
if fnmatch.fnmatch(lib_path, i):
|
||||
passed = True
|
||||
break
|
||||
self.assertTrue(passed)
|
||||
available = [
|
||||
"/usr/lib/libcrypto.0.9.7.dylib",
|
||||
"/usr/lib/libcrypto.0.9.8.dylib",
|
||||
"/usr/lib/libcrypto.35.dylib",
|
||||
"/usr/lib/libcrypto.41.dylib",
|
||||
"/usr/lib/libcrypto.42.dylib",
|
||||
"/usr/lib/libcrypto.44.dylib",
|
||||
"/usr/lib/libcrypto.dylib",
|
||||
]
|
||||
|
||||
def test_glob(pattern):
|
||||
return [lib for lib in available if fnmatch.fnmatch(lib, pattern)]
|
||||
|
||||
with patch.object(glob, "glob", test_glob):
|
||||
lib_path = _find_libcrypto()
|
||||
self.assertEqual("/usr/lib/libcrypto.44.dylib", lib_path)
|
||||
|
||||
@patch.object(salt.utils.platform, "is_darwin", lambda: True)
|
||||
@patch.object(platform, "mac_ver", lambda: ("11.2.2", (), ""))
|
||||
@patch.object(sys, "platform", "macosx")
|
||||
def test_find_libcrypto_darwin_bigsur_packaged(self):
|
||||
"""
|
||||
Test _find_libcrypto on a Darwin-like macOS host where there isn't a
|
||||
lacation returned by ctypes.util.find_library() and the libcrypto
|
||||
installation comes from a package manager (ports, brew, salt).
|
||||
"""
|
||||
managed_paths = {
|
||||
"salt": "/opt/salt/lib/libcrypto.dylib",
|
||||
"brew": "/test/homebrew/prefix/opt/openssl/lib/libcrypto.dylib",
|
||||
"port": "/opt/local/lib/libcrypto.dylib",
|
||||
}
|
||||
|
||||
saved_getenv = os.getenv
|
||||
|
||||
def mock_getenv(env):
|
||||
def test_getenv(var, default=None):
|
||||
return env.get(var, saved_getenv(var, default))
|
||||
|
||||
return test_getenv
|
||||
|
||||
def mock_glob(expected_lib):
|
||||
def test_glob(pattern):
|
||||
if fnmatch.fnmatch(expected_lib, pattern):
|
||||
return [expected_lib]
|
||||
return []
|
||||
|
||||
return test_glob
|
||||
|
||||
for package_manager, expected_lib in managed_paths.items():
|
||||
if package_manager == "brew":
|
||||
env = {"HOMEBREW_PREFIX": "/test/homebrew/prefix"}
|
||||
else:
|
||||
env = {"HOMEBREW_PREFIX": ""}
|
||||
with patch.object(os, "getenv", mock_getenv(env)):
|
||||
with patch.object(glob, "glob", mock_glob(expected_lib)):
|
||||
lib_path = _find_libcrypto()
|
||||
|
||||
self.assertEqual(expected_lib, lib_path)
|
||||
|
||||
# On Big Sur, there's nothing else to fall back on.
|
||||
with patch.object(glob, "glob", lambda _: []):
|
||||
with self.assertRaises(OSError):
|
||||
lib_path = _find_libcrypto()
|
||||
|
||||
@patch.object(ctypes.util, "find_library", lambda a: None)
|
||||
@patch.object(glob, "glob", lambda a: [])
|
||||
|
|
Loading…
Add table
Reference in a new issue