Hello community, here is the log from the commit of package salt for openSUSE:Factory checked in at 2018-09-26 14:53:15 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/salt (Old) and /work/SRC/openSUSE:Factory/.salt.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "salt" Wed Sep 26 14:53:15 2018 rev:80 rq:636408 version:2018.3.2 Changes: -------- --- /work/SRC/openSUSE:Factory/salt/salt.changes 2018-08-02 14:55:43.928034731 +0200 +++ /work/SRC/openSUSE:Factory/.salt.new/salt.changes 2018-09-26 14:53:17.955118391 +0200 @@ -1,0 +2,53 @@ +Tue Sep 18 14:28:13 UTC 2018 - mihai.di...@suse.com + +- Decode file contents for python2 (bsc#1103530) +- Check dmidecoder executable on each "smbios" call to avoid race condition (bsc#1101880) +- Fix pkg.upgrade reports when dealing with multiversion packages (bsc#1102265) +- Accounting for when files in an archive contain non-ascii characters (bsc#1099460) +- Fix deprecation warning (bsc#1095507) +- Fix (bsc#1065792) +- Fix (bsc#108758) +- Handle packages with multiple version properly with zypper (bsc#1096514) +- Fix file.get_diff regression in 2018.3 (bsc#1098394) +- Provide python version mismatch solutions (bsc#1072599) +- Fix file.managed binary file utf8 error (bsc#1098394) +- Prevent zypper from parsing repo configuration from not .repo files (bsc#1094055) +- Add environment variable to know if yum is invoked from Salt (bsc#1057635) +- Prevent deprecation warning with salt-ssh (bsc#1095507) +- Align SUSE salt-master.service 'LimitNOFILES' limit with upstream Salt +- Add 'other' attribute to GECOS fields to avoid inconsistencies with chfn +- Collect all versions of installed packages on SUSE and RHEL systems (bsc#1089526) + +------------------------------------------------------------------- +Mon Sep 17 13:47:09 UTC 2018 - b...@suse.de + +- Prepend current directory when path is just filename (bsc#1095942) +- Integration of MSI authentication for azurearm +- Adds fix for SUSE Expanded Support os grain detection +- Fixes 509x remote signing +- Fix for StringIO import in Python2 +- Use Adler32 algorithm to compute string checksums (bsc#1102819) +- Only do reverse DNS lookup on IPs for salt-ssh (bsc#1104154) +- Add support for Python 3.7 +- Fix license macro to build on SLE12SP2 +- Decode file contents for python2 (bsc#1102013) +- Fix for sorting of multi-version packages (bsc#1097174 and bsc#1097413) +- Fix mine.get not returning data - workaround for #48020 (bsc#1100142) + +- Added: + * change-stringio-import-in-python2-to-import-the-clas.patch + * integration-of-msi-authentication-with-azurearm-clou.patch + * x509-fixes-for-remote-signing-106.patch + * fix-for-suse-expanded-support-detection.patch + * only-do-reverse-dns-lookup-on-ips-for-salt-ssh.patch + * prepend-current-directory-when-path-is-just-filename.patch + * add-support-for-python-3.7.patch + * decode-file-contents-for-python2-bsc-1102013.patch + * fix-mine.get-not-returning-data-workaround-for-48020.patch + * x509-fixes-111.patch + * use-adler32-algorithm-to-compute-string-checksums.patch + +- Modified: + * fix-for-sorting-of-multi-version-packages-bsc-109717.patch + +------------------------------------------------------------------- @@ -57 +110 @@ -Thu May 17 15:14:01 UTC 2018 - Jochen Breuer <jbre...@suse.de> +Thu May 17 15:14:01 UTC 2018 - jbre...@suse.de @@ -63 +116 @@ -Wed May 16 10:57:17 UTC 2018 - Jochen Breuer <jbre...@suse.de> +Wed May 16 10:57:17 UTC 2018 - jbre...@suse.de @@ -73 +126 @@ -Thu May 10 09:12:24 UTC 2018 - Pablo Suárez Hernández <psuarezhernan...@suse.com> +Thu May 10 09:12:24 UTC 2018 - psuarezhernan...@suse.com @@ -89 +142 @@ -Fri May 4 12:17:07 UTC 2018 - Jochen Breuer <jbre...@suse.de> +Fri May 4 12:17:07 UTC 2018 - jbre...@suse.de @@ -97 +150 @@ -Wed Apr 25 14:50:36 UTC 2018 - Pablo Suárez Hernández <psuarezhernan...@suse.com> +Wed Apr 25 14:50:36 UTC 2018 - psuarezhernan...@suse.com @@ -110 +163 @@ -Wed Apr 18 17:09:41 UTC 2018 - Pablo Suárez Hernández <psuarezhernan...@suse.com> +Wed Apr 18 17:09:41 UTC 2018 - psuarezhernan...@suse.com @@ -118 +171 @@ -Wed Apr 18 16:55:28 UTC 2018 - Pablo Suárez Hernández <psuarezhernan...@suse.com> +Wed Apr 18 16:55:28 UTC 2018 - psuarezhernan...@suse.com @@ -138 +191 @@ -Fri Apr 6 16:58:59 UTC 2018 - Mihai Dinca <mdi...@suse.de> +Fri Apr 6 16:58:59 UTC 2018 - mdi...@suse.de @@ -160 +213 @@ -Thu Apr 5 15:58:22 UTC 2018 - Mihai Dinca <mdi...@suse.de> +Thu Apr 5 15:58:22 UTC 2018 - mdi...@suse.de @@ -168 +221 @@ -Wed Apr 4 16:32:10 UTC 2018 - Mihai Dinca <mdi...@suse.de> +Wed Apr 4 16:32:10 UTC 2018 - mdi...@suse.de @@ -179 +232 @@ -Wed Mar 28 12:18:08 UTC 2018 - Mihai Dinca <mdi...@suse.de> +Wed Mar 28 12:18:08 UTC 2018 - mdi...@suse.de @@ -185 +238 @@ -Wed Mar 28 11:57:30 UTC 2018 - Michael Calmer <m...@suse.de> +Wed Mar 28 11:57:30 UTC 2018 - m...@suse.de @@ -209 +262 @@ -Tue Mar 27 16:29:08 UTC 2018 - Mihai Dinca <mdi...@suse.de> +Tue Mar 27 16:29:08 UTC 2018 - mdi...@suse.de @@ -217 +270 @@ -Fri Mar 23 18:12:09 UTC 2018 - Mihai Dinca <mdi...@suse.de> +Fri Mar 23 18:12:09 UTC 2018 - mdi...@suse.de @@ -231 +284 @@ -Fri Mar 23 16:19:42 UTC 2018 - Mihai Dinca <mdi...@suse.de> +Fri Mar 23 16:19:42 UTC 2018 - mdi...@suse.de @@ -244 +297 @@ -Thu Mar 22 14:40:50 UTC 2018 - Pablo Suárez Hernández <psuarezhernan...@suse.com> +Thu Mar 22 14:40:50 UTC 2018 - psuarezhernan...@suse.com @@ -252 +305 @@ -Thu Mar 22 09:10:33 UTC 2018 - Michael Calmer <m...@suse.de> +Thu Mar 22 09:10:33 UTC 2018 - m...@suse.de @@ -267 +320 @@ -Wed Mar 14 09:37:07 UTC 2018 - Mihai Dinca <mdi...@suse.de> +Wed Mar 14 09:37:07 UTC 2018 - mdi...@suse.de @@ -287 +340 @@ -Tue Mar 13 18:28:03 UTC 2018 - Mihai Dinca <mdi...@suse.de> +Tue Mar 13 18:28:03 UTC 2018 - mdi...@suse.de @@ -295 +348 @@ -Mon Mar 12 17:47:34 UTC 2018 - Michael Calmer <m...@suse.de> +Mon Mar 12 17:47:34 UTC 2018 - m...@suse.de @@ -300 +353 @@ -Sat Mar 10 12:00:17 UTC 2018 - Michael Calmer <m...@suse.de> +Sat Mar 10 12:00:17 UTC 2018 - m...@suse.de @@ -314 +367 @@ -Fri Mar 9 15:56:00 UTC 2018 - Mihai Dinca <mdi...@suse.de> +Fri Mar 9 15:56:00 UTC 2018 - mdi...@suse.de @@ -323 +375,0 @@ - @@ -325 +376,0 @@ - @@ -327 +377,0 @@ - @@ -329 +378,0 @@ - @@ -331 +379,0 @@ - @@ -333 +380,0 @@ - @@ -335 +381,0 @@ - @@ -337 +382,0 @@ - @@ -339 +383,0 @@ - @@ -342 +385,0 @@ - @@ -344 +387 @@ -Thu Mar 8 11:20:01 UTC 2018 - Mihai Dinca <mdi...@suse.de> +Thu Mar 8 11:20:01 UTC 2018 - mdi...@suse.de @@ -364 +407 @@ -Fri Mar 2 13:15:46 UTC 2018 - Mihai Dinca <mdi...@suse.de> +Fri Mar 2 13:15:46 UTC 2018 - mdi...@suse.de @@ -375 +418 @@ -Fri Mar 2 13:15:46 UTC 2018 - Mihai Dinca <mdi...@suse.de> +Fri Mar 2 13:15:46 UTC 2018 - mdi...@suse.de @@ -383 +426 @@ -Tue Feb 20 10:47:34 UTC 2018 - Mihai Dinca <mdi...@suse.de> +Tue Feb 20 10:47:34 UTC 2018 - mdi...@suse.de @@ -388 +431 @@ -Tue Feb 13 15:17:11 UTC 2018 - Mihai Dinca <mdi...@suse.de> +Tue Feb 13 15:17:11 UTC 2018 - mdi...@suse.de @@ -396 +439 @@ -Fri Feb 09 15:39:08 UTC 2018 - Mihai Dinca <mdi...@suse.de> +Fri Feb 09 15:39:08 UTC 2018 - mdi...@suse.de @@ -428 +471 @@ -Fri Feb 09 15:39:08 UTC 2018 - Jochen Breuer <jbre...@suse.de> +Fri Feb 09 15:39:08 UTC 2018 - jbre...@suse.de @@ -438 +481 @@ -Fri Feb 09 15:39:08 UTC 2018 - Jochen Breuer <jbre...@suse.de> +Fri Feb 09 15:39:08 UTC 2018 - jbre...@suse.de @@ -445 +488 @@ -Wed Feb 07 13:23:51 UTC 2018 - Mihai Dinca <mdi...@suse.de> +Wed Feb 07 13:23:51 UTC 2018 - mdi...@suse.de New: ---- add-support-for-python-3.7.patch change-stringio-import-in-python2-to-import-the-clas.patch decode-file-contents-for-python2-bsc-1102013.patch fix-for-sorting-of-multi-version-packages-bsc-109717.patch fix-for-suse-expanded-support-detection.patch fix-mine.get-not-returning-data-workaround-for-48020.patch integration-of-msi-authentication-with-azurearm-clou.patch only-do-reverse-dns-lookup-on-ips-for-salt-ssh.patch prepend-current-directory-when-path-is-just-filename.patch use-adler32-algorithm-to-compute-string-checksums.patch x509-fixes-111.patch x509-fixes-for-remote-signing-106.patch ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ salt.spec ++++++ --- /var/tmp/diff_new_pack.6bpAjw/_old 2018-09-26 14:53:19.811115544 +0200 +++ /var/tmp/diff_new_pack.6bpAjw/_new 2018-09-26 14:53:19.815115539 +0200 @@ -126,6 +126,30 @@ Patch30: add-engine-relaying-libvirt-events.patch # PATCH-FIX_UPSTREAM https://github.com/saltstack/salt/pull/48781 Patch31: avoid-incomprehensive-message-if-crashes.patch +# PATCH-FIX_UPSTREAM https://github.com/saltstack/salt/pull/48765 +Patch32: fix-mine.get-not-returning-data-workaround-for-48020.patch +# PATCH-FIX_OPENSUSE bsc#1097174 and bsc#1097413 +Patch33: fix-for-sorting-of-multi-version-packages-bsc-109717.patch +# PATCH-FIX_UPSTREAM https://github.com/saltstack/salt/pull/48863 +Patch34: decode-file-contents-for-python2-bsc-1102013.patch +# PATCH-FIX_UPSTREAM https://github.com/saltstack/salt/pull/49052 +Patch35: add-support-for-python-3.7.patch +# PATCH-FIX_UPSTREAM https://github.com/saltstack/salt/pull/48771 +Patch36: only-do-reverse-dns-lookup-on-ips-for-salt-ssh.patch +# PATCH-FIX_UPSTREAM https://github.com/saltstack/salt/pull/49277 +Patch37: prepend-current-directory-when-path-is-just-filename.patch +# PATCH-FIX_UPSTREAM https://github.com/saltstack/salt/pull/49063 +Patch38: integration-of-msi-authentication-with-azurearm-clou.patch +# PATCH-FIX_UPSTREAM https://github.com/saltstack/salt/pull/49538 +Patch39: fix-for-suse-expanded-support-detection.patch +# PATCH-FIX_UPSTREAM https://github.com/saltstack/salt/pull/49508 +Patch40: x509-fixes-for-remote-signing-106.patch +# PATCH-FIX_UPSTREAM https://github.com/saltstack/salt/pull/49555 +Patch41: change-stringio-import-in-python2-to-import-the-clas.patch +# PATCH-FIX_UPSTREAM https://github.com/saltstack/salt/pull/48812 +Patch42: use-adler32-algorithm-to-compute-string-checksums.patch +# PATCH-FIX_UPSTREAM https://github.com/saltstack/salt/pull/49497 +Patch43: x509-fixes-111.patch # BuildRoot: %{_tmppath}/%{name}-%{version}-build BuildRoot: %{_tmppath}/%{name}-%{version}-build @@ -615,6 +639,18 @@ %patch29 -p1 %patch30 -p1 %patch31 -p1 +%patch32 -p1 +%patch33 -p1 +%patch34 -p1 +%patch35 -p1 +%patch36 -p1 +%patch37 -p1 +%patch38 -p1 +%patch39 -p1 +%patch40 -p1 +%patch41 -p1 +%patch42 -p1 +%patch43 -p1 %build %if 0%{?build_py2} @@ -1256,8 +1292,12 @@ %{_mandir}/man1/salt-call.1.gz %{_mandir}/man1/spm.1.gz %config(noreplace) %{_sysconfdir}/logrotate.d/salt +%if 0%{?suse_version} < 1500 +%doc LICENSE AUTHORS README.rst HACKING.rst README.SUSE +%else %license LICENSE %doc AUTHORS README.rst HACKING.rst README.SUSE +%endif # %dir %attr(0750, root, salt) %{_sysconfdir}/salt %dir %attr(0750, root, salt) %{_sysconfdir}/salt/pki ++++++ _lastrevision ++++++ --- /var/tmp/diff_new_pack.6bpAjw/_old 2018-09-26 14:53:19.883115434 +0200 +++ /var/tmp/diff_new_pack.6bpAjw/_new 2018-09-26 14:53:19.887115428 +0200 @@ -1 +1 @@ -eb0ca38e07c96eb021ac7490ac1f61a54dc9d904 +ebc77d067d9fa300bdc5bb5dcccaa09e1787f688 \ No newline at end of file ++++++ add-support-for-python-3.7.patch ++++++ ++++ 1171 lines (skipped) ++++++ change-stringio-import-in-python2-to-import-the-clas.patch ++++++ >From a0d5af98c8d2a22c5eb56943ff320ca287fa79ea Mon Sep 17 00:00:00 2001 From: Florian Bergmann <bergma...@users.noreply.github.com> Date: Tue, 11 Sep 2018 14:03:33 +0200 Subject: [PATCH] Change StringIO import in python2 to import the class. (#107) Instead of using StringIO in python3, use the correct BytesIO class instead. --- salt/modules/hashutil.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/salt/modules/hashutil.py b/salt/modules/hashutil.py index 721957973d..5123cc7cd7 100644 --- a/salt/modules/hashutil.py +++ b/salt/modules/hashutil.py @@ -17,9 +17,10 @@ import salt.utils.hashutils import salt.utils.stringutils if six.PY2: - import StringIO + from StringIO import StringIO + BytesIO = StringIO elif six.PY3: - from io import StringIO + from io import BytesIO, StringIO def digest(instr, checksum='md5'): @@ -155,13 +156,13 @@ def base64_encodefile(fname): salt '*' hashutil.base64_encodefile /path/to/binary_file ''' - encoded_f = StringIO.StringIO() + encoded_f = BytesIO() with salt.utils.files.fopen(fname, 'rb') as f: base64.encode(f, encoded_f) encoded_f.seek(0) - return encoded_f.read() + return salt.utils.stringutils.to_str(encoded_f.read()) def base64_decodestring(instr): @@ -192,7 +193,7 @@ def base64_decodefile(instr, outfile): salt '*' hashutil.base64_decodefile instr='Z2V0IHNhbHRlZAo=' outfile='/path/to/binary_file' ''' - encoded_f = StringIO.StringIO(instr) + encoded_f = StringIO(instr) with salt.utils.files.fopen(outfile, 'wb') as f: base64.decode(encoded_f, f) -- 2.19.0 ++++++ decode-file-contents-for-python2-bsc-1102013.patch ++++++ >From 58913b6801b92bd59374cd53fa48fa74171abb73 Mon Sep 17 00:00:00 2001 From: Abid Mehmood <amehm...@suse.de> Date: Wed, 1 Aug 2018 17:19:11 +0200 Subject: [PATCH] Decode file contents for python2(bsc#1102013) --- salt/states/file.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/salt/states/file.py b/salt/states/file.py index e1d247ae4f..db82098a33 100644 --- a/salt/states/file.py +++ b/salt/states/file.py @@ -1105,8 +1105,7 @@ def _get_template_texts(source_list=None, tmplines = None with salt.utils.files.fopen(rndrd_templ_fn, 'rb') as fp_: tmplines = fp_.read() - if six.PY3: - tmplines = tmplines.decode(__salt_system_encoding__) + tmplines = tmplines.decode(__salt_system_encoding__) tmplines = tmplines.splitlines(True) if not tmplines: msg = 'Failed to read rendered template file {0} ({1})' -- 2.17.1 ++++++ fix-for-sorting-of-multi-version-packages-bsc-109717.patch ++++++ >From f0f63dc8dd5979b51db71cf759d4350da1078383 Mon Sep 17 00:00:00 2001 From: Jochen Breuer <jbre...@suse.de> Date: Wed, 13 Jun 2018 17:51:13 +0200 Subject: [PATCH] Fix for sorting of multi-version packages (bsc#1097174 and bsc#1097413) --- salt/modules/rpm.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/salt/modules/rpm.py b/salt/modules/rpm.py index 3683234f59..8e71992f81 100644 --- a/salt/modules/rpm.py +++ b/salt/modules/rpm.py @@ -9,6 +9,7 @@ import logging import os import re import datetime +from distutils.version import LooseVersion # Import Salt libs import salt.utils.decorators.path @@ -609,7 +610,7 @@ def info(*packages, **kwargs): # pick only latest versions # (in case multiple packages installed, e.g. kernel) ret = dict() - for pkg_data in reversed(sorted(_ret, key=lambda x: x['edition'])): + for pkg_data in reversed(sorted(_ret, key=lambda x: LooseVersion(x['edition']))): pkg_name = pkg_data.pop('name') # Filter out GPG public keys packages if pkg_name.startswith('gpg-pubkey'): -- 2.17.1 ++++++ fix-for-suse-expanded-support-detection.patch ++++++ >From 1c9cba3a397d53e399b82320507fb5141234c67f Mon Sep 17 00:00:00 2001 From: Jochen Breuer <jbre...@suse.de> Date: Thu, 6 Sep 2018 17:15:18 +0200 Subject: [PATCH] Fix for SUSE Expanded Support detection A SUSE ES installation has both, the centos-release and redhat-release file. Since os_data only used the centos-release file to detect a CentOS installation, this lead to SUSE ES being detected as CentOS. This change also adds a check for redhat-release and then marks the 'lsb_distrib_id' as RedHat. --- salt/grains/core.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/salt/grains/core.py b/salt/grains/core.py index dc472a6c0a..a5c3a6a8cf 100644 --- a/salt/grains/core.py +++ b/salt/grains/core.py @@ -1593,8 +1593,17 @@ def os_data(): grains['lsb_distrib_codename'] = \ comps[3].replace('(', '').replace(')', '') elif os.path.isfile('/etc/centos-release'): - # CentOS Linux - grains['lsb_distrib_id'] = 'CentOS' + log.trace('Parsing distrib info from /etc/centos-release') + # Maybe CentOS Linux; could also be SUSE Expanded Support. + # SUSE ES has both, centos-release and redhat-release. + if os.path.isfile('/etc/redhat-release'): + with salt.utils.files.fopen('/etc/redhat-release') as ifile: + for line in ifile: + if "red hat enterprise linux server" in line.lower(): + # This is a SUSE Expanded Support Rhel installation + grains['lsb_distrib_id'] = 'RedHat' + break + grains.setdefault('lsb_distrib_id', 'CentOS') with salt.utils.files.fopen('/etc/centos-release') as ifile: for line in ifile: # Need to pull out the version and codename -- 2.19.0 ++++++ fix-mine.get-not-returning-data-workaround-for-48020.patch ++++++ >From f8c0811c3a05ef334eef1943a906fe01b13c1afc Mon Sep 17 00:00:00 2001 From: Federico Ceratto <federico.cera...@suse.com> Date: Wed, 25 Jul 2018 10:33:09 +0000 Subject: [PATCH] Fix mine.get not returning data (Workaround for #48020) --- salt/utils/minions.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/salt/utils/minions.py b/salt/utils/minions.py index c3acc6ba90..bb0cbaa589 100644 --- a/salt/utils/minions.py +++ b/salt/utils/minions.py @@ -239,12 +239,12 @@ class CkMinions(object): Retreive complete minion list from PKI dir. Respects cache if configured ''' - if self.opts.get('__role') == 'master' and self.opts.get('__cli') == 'salt-run': - # Compiling pillar directly on the master, just return the master's - # ID as that is the only one that is available. - return [self.opts['id']] minions = [] pki_cache_fn = os.path.join(self.opts['pki_dir'], self.acc, '.key_cache') + try: + os.makedirs(os.path.dirname(pki_cache_fn)) + except OSError: + pass try: if self.opts['key_cache'] and os.path.exists(pki_cache_fn): log.debug('Returning cached minion list') -- 2.17.1 ++++++ integration-of-msi-authentication-with-azurearm-clou.patch ++++++ >From 06aff97c83342cf9635fa750222f774ab1664a0d Mon Sep 17 00:00:00 2001 From: ed lane <ed.lan...@gmail.com> Date: Thu, 30 Aug 2018 06:07:08 -0600 Subject: [PATCH] Integration of MSI authentication with azurearm cloud driver (#105) --- salt/cloud/clouds/azurearm.py | 47 +++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/salt/cloud/clouds/azurearm.py b/salt/cloud/clouds/azurearm.py index bd9a25a7e2..8b9a9e8903 100644 --- a/salt/cloud/clouds/azurearm.py +++ b/salt/cloud/clouds/azurearm.py @@ -25,6 +25,9 @@ The Azure cloud module is used to control access to Microsoft Azure * ``client_id`` * ``secret`` + if using MSI-style authentication: + * ``subscription_id`` + Example ``/etc/salt/cloud.providers`` or ``/etc/salt/cloud.providers.d/azure.conf`` configuration: @@ -48,6 +51,10 @@ Example ``/etc/salt/cloud.providers`` or For example, this creates a service principal with 'owner' role for the whole subscription: az ad sp create-for-rbac -n "http://mysaltapp" --role owner --scopes /subscriptions/3287abc8-f98a-c678-3bde-326766fd3617 *Note: review the details of Service Principals. Owner role is more than you normally need, and you can restrict scope to a resource group or individual resources. + + Or my-azure-config with MSI-style authentication: + driver: azure + subscription_id: 3287abc8-f98a-c678-3bde-326766fd3617 ''' # pylint: disable=E0102 @@ -86,6 +93,7 @@ try: UserPassCredentials, ServicePrincipalCredentials, ) + from msrestazure.azure_active_directory import MSIAuthentication from azure.mgmt.compute import ComputeManagementClient from azure.mgmt.compute.models import ( CachingTypes, @@ -166,19 +174,30 @@ def get_configured_provider(): ''' Return the first configured instance. ''' + # check if using Service Principle style authentication... provider = config.is_provider_configured( __opts__, __active_provider_name__ or __virtualname__, - ('subscription_id', 'tenant', 'client_id', 'secret') + required_keys=('subscription_id', 'tenant', 'client_id', 'secret'), + log_message=False #... allowed to fail so no need to log warnings ) if provider is False: - return config.is_provider_configured( + # check if using username/password style authentication... + provider = config.is_provider_configured( __opts__, __active_provider_name__ or __virtualname__, - ('subscription_id', 'username', 'password') + required_keys=('subscription_id', 'username', 'password'), + log_message=False ) - else: - return provider + if provider is False: + # check if using MSI style credentials... + provider = config.is_provider_configured( + __opts__, + __active_provider_name__ or __virtualname__, + required_keys=('subscription_id',), + log_message=False + ) + return provider def get_dependencies(): @@ -210,6 +229,7 @@ def get_conn(Client=None): get_configured_provider(), __opts__, search_global=False ) if tenant is not None: + # using Service Principle style authentication... client_id = config.get_cloud_config_value( 'client_id', get_configured_provider(), __opts__, search_global=False @@ -224,15 +244,20 @@ def get_conn(Client=None): 'username', get_configured_provider(), __opts__, search_global=False ) - password = config.get_cloud_config_value( - 'password', - get_configured_provider(), __opts__, search_global=False - ) - credentials = UserPassCredentials(username, password) + if username is not None: + # using username/password style authentication... + password = config.get_cloud_config_value( + 'password', + get_configured_provider(), __opts__, search_global=False + ) + credentials = UserPassCredentials(username, password) + else: + # using MSI style authentication ... + credentials = MSIAuthentication() client = Client( credentials=credentials, - subscription_id=subscription_id, + subscription_id=str(subscription_id), ) client.config.add_user_agent('SaltCloud/{0}'.format(salt.version.__version__)) return client -- 2.19.0 ++++++ only-do-reverse-dns-lookup-on-ips-for-salt-ssh.patch ++++++ >From f346e83f6d4651a1cdcaad8c995642b55f66ddbc Mon Sep 17 00:00:00 2001 From: Daniel Wallace <danielwall...@gtmanfred.com> Date: Wed, 25 Jul 2018 09:48:29 -0500 Subject: [PATCH] only do reverse dns lookup on ips for salt-ssh Fixes #48676 --- salt/client/ssh/__init__.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/salt/client/ssh/__init__.py b/salt/client/ssh/__init__.py index 8a85cc2480..d6ff0c3479 100644 --- a/salt/client/ssh/__init__.py +++ b/salt/client/ssh/__init__.py @@ -349,7 +349,9 @@ class SSH(object): return hostname = self.opts['tgt'].split('@')[-1] - needs_expansion = '*' not in hostname and salt.utils.network.is_reachable_host(hostname) + needs_expansion = '*' not in hostname and \ + salt.utils.network.is_reachable_host(hostname) and \ + salt.utils.network.is_ip(hostname) if needs_expansion: hostname = salt.utils.network.ip_to_host(hostname) if hostname is None: -- 2.17.1 ++++++ prepend-current-directory-when-path-is-just-filename.patch ++++++ >From 341ee0c44cabf2f34bdd2f4b54e4b83053a3133e Mon Sep 17 00:00:00 2001 From: Mihai Dinca <mdi...@suse.de> Date: Thu, 23 Aug 2018 16:14:36 +0200 Subject: [PATCH] Prepend current directory when path is just filename (bsc#1095942) --- salt/utils/parsers.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/salt/utils/parsers.py b/salt/utils/parsers.py index 5a415ab576..9a7f27ac11 100644 --- a/salt/utils/parsers.py +++ b/salt/utils/parsers.py @@ -591,10 +591,19 @@ class LogLevelMixIn(six.with_metaclass(MixInMeta, object)): ) ) + def _logfile_callback(option, opt, value, parser, *args, **kwargs): + if not os.path.dirname(value): + # if the path is only a file name (no parent directory), assume current directory + value = os.path.join(os.path.curdir, value) + setattr(parser.values, self._logfile_config_setting_name_, value) + group.add_option( '--log-file', dest=self._logfile_config_setting_name_, default=None, + action='callback', + type='string', + callback=_logfile_callback, help='Log file path. Default: \'{0}\'.'.format( self._default_logging_logfile_ ) -- 2.19.0 ++++++ use-adler32-algorithm-to-compute-string-checksums.patch ++++++ >From 1cb2d2bc6c1cf1a39e735120c184d6ade9e64c34 Mon Sep 17 00:00:00 2001 From: Bo Maryniuk <b...@suse.de> Date: Sat, 28 Jul 2018 22:59:04 +0200 Subject: [PATCH] Use Adler32 algorithm to compute string checksums Generate the same numeric value across all Python versions and platforms Re-add getting hash by Python shell-out method Add an option to choose between default hashing, Adler32 or CRC32 algorithms Set default config option for server_id hashing to False on minion Choose CRC method, default to faster but less reliable "adler32", if crc is in use Add warning for Sodium. --- salt/config/__init__.py | 13 +++++++++- salt/grains/core.py | 54 +++++++++++++++++++++++++++-------------- 2 files changed, 48 insertions(+), 19 deletions(-) diff --git a/salt/config/__init__.py b/salt/config/__init__.py index feda0abac1..59df7e1cba 100644 --- a/salt/config/__init__.py +++ b/salt/config/__init__.py @@ -1186,6 +1186,16 @@ VALID_OPTS = { # Enable calling ssh minions from the salt master 'enable_ssh_minions': bool, + + # Thorium saltenv + 'thoriumenv': (type(None), six.string_types), + + # Thorium top file location + 'thorium_top': six.string_types, + + # Use Adler32 hashing algorithm for server_id (default False until Sodium, "adler32" after) + # Possible values are: False, adler32, crc32 + 'server_id_use_crc': (bool, six.string_types), } # default configurations @@ -1486,7 +1496,8 @@ DEFAULT_MINION_OPTS = { }, 'discovery': False, 'schedule': {}, - 'ssh_merge_pillar': True + 'ssh_merge_pillar': True, + 'server_id_use_crc': False, } DEFAULT_MASTER_OPTS = { diff --git a/salt/grains/core.py b/salt/grains/core.py index a5c3a6a8cf..6aaf38096d 100644 --- a/salt/grains/core.py +++ b/salt/grains/core.py @@ -20,6 +20,7 @@ import platform import logging import locale import uuid +import zlib from errno import EACCES, EPERM import datetime @@ -46,6 +47,8 @@ import salt.utils.files import salt.utils.network import salt.utils.path import salt.utils.platform +import salt.utils.stringutils +import salt.utils.versions from salt.ext import six from salt.ext.six.moves import range @@ -2420,40 +2423,55 @@ def _hw_data(osdata): return grains -def get_server_id(): +def _get_hash_by_shell(): ''' - Provides an integer based on the FQDN of a machine. - Useful as server-id in MySQL replication or anywhere else you'll need an ID - like this. + Shell-out Python 3 for compute reliable hash + :return: ''' - # Provides: - # server_id - - if salt.utils.platform.is_proxy(): - return {} id_ = __opts__.get('id', '') id_hash = None py_ver = sys.version_info[:2] if py_ver >= (3, 3): # Python 3.3 enabled hash randomization, so we need to shell out to get # a reliable hash. - id_hash = __salt__['cmd.run']( - [sys.executable, '-c', 'print(hash("{0}"))'.format(id_)], - env={'PYTHONHASHSEED': '0'} - ) + id_hash = __salt__['cmd.run']([sys.executable, '-c', 'print(hash("{0}"))'.format(id_)], + env={'PYTHONHASHSEED': '0'}) try: id_hash = int(id_hash) except (TypeError, ValueError): - log.debug( - 'Failed to hash the ID to get the server_id grain. Result of ' - 'hash command: %s', id_hash - ) + log.debug('Failed to hash the ID to get the server_id grain. Result of hash command: %s', id_hash) id_hash = None if id_hash is None: # Python < 3.3 or error encountered above id_hash = hash(id_) - return {'server_id': abs(id_hash % (2 ** 31))} + return abs(id_hash % (2 ** 31)) + + +def get_server_id(): + ''' + Provides an integer based on the FQDN of a machine. + Useful as server-id in MySQL replication or anywhere else you'll need an ID + like this. + ''' + # Provides: + # server_id + + if salt.utils.platform.is_proxy(): + server_id = {} + else: + use_crc = __opts__.get('server_id_use_crc') + if bool(use_crc): + id_hash = getattr(zlib, use_crc, zlib.adler32)(__opts__.get('id', '').encode()) & 0xffffffff + else: + salt.utils.versions.warn_until('Sodium', 'This server_id is computed nor by Adler32 neither by CRC32. ' + 'Please use "server_id_use_crc" option and define algorithm you' + 'prefer (default "Adler32"). The server_id will be computed with' + 'Adler32 by default.') + id_hash = _get_hash_by_shell() + server_id = {'server_id': id_hash} + + return server_id def get_master(): -- 2.19.0 ++++++ x509-fixes-111.patch ++++++ >From 053d97afcc7486f7300e339bc56cb3c850cc523b Mon Sep 17 00:00:00 2001 From: Florian Bergmann <bergma...@users.noreply.github.com> Date: Fri, 14 Sep 2018 10:30:39 +0200 Subject: [PATCH] X509 fixes (#111) * Return proper content type for the x509 certificate * Remove parenthesis * Remove extra-variables during the import * Comment fix * Remove double returns * Change log level from trace to debug * Remove 'pass' and add logging instead * Remove unnecessary wrapping Remove wrapping * PEP 8: line too long PEP8: line too long * PEP8: Redefine RSAError variable in except clause * Do not return None if name was not found * Do not return None if no matched minions found * Fix unit tests --- salt/modules/publish.py | 8 +- salt/modules/x509.py | 132 ++++++++++++-------------------- salt/states/x509.py | 22 ++++-- tests/unit/modules/test_x509.py | 9 ++- 4 files changed, 74 insertions(+), 97 deletions(-) diff --git a/salt/modules/publish.py b/salt/modules/publish.py index 2de99583f4..ac31b4b65f 100644 --- a/salt/modules/publish.py +++ b/salt/modules/publish.py @@ -83,10 +83,8 @@ def _publish( in minion configuration but `via_master` was specified.') else: # Find the master in the list of master_uris generated by the minion base class - matching_master_uris = [master for master - in __opts__['master_uri_list'] - if '//{0}:'.format(via_master) - in master] + matching_master_uris = [master for master in __opts__['master_uri_list'] + if '//{0}:'.format(via_master) in master] if not matching_master_uris: raise SaltInvocationError('Could not find match for {0} in \ @@ -176,6 +174,8 @@ def _publish( else: return ret + return {} + def publish(tgt, fun, diff --git a/salt/modules/x509.py b/salt/modules/x509.py index 9901bc5bd9..45afcccd99 100644 --- a/salt/modules/x509.py +++ b/salt/modules/x509.py @@ -36,14 +36,13 @@ from salt.state import STATE_INTERNAL_KEYWORDS as _STATE_INTERNAL_KEYWORDS # Import 3rd Party Libs try: import M2Crypto - HAS_M2 = True except ImportError: - HAS_M2 = False + M2Crypto = None + try: import OpenSSL - HAS_OPENSSL = True except ImportError: - HAS_OPENSSL = False + OpenSSL = None __virtualname__ = 'x509' @@ -81,10 +80,7 @@ def __virtual__(): ''' only load this module if m2crypto is available ''' - if HAS_M2: - return __virtualname__ - else: - return (False, 'Could not load x509 module, m2crypto unavailable') + return __virtualname__ if M2Crypto is not None else False, 'Could not load x509 module, m2crypto unavailable' class _Ctx(ctypes.Structure): @@ -127,10 +123,8 @@ def _new_extension(name, value, critical=0, issuer=None, _pyfree=1): doesn't support getting the publickeyidentifier from the issuer to create the authoritykeyidentifier extension. ''' - if name == 'subjectKeyIdentifier' and \ - value.strip('0123456789abcdefABCDEF:') is not '': - raise salt.exceptions.SaltInvocationError( - 'value must be precomputed hash') + if name == 'subjectKeyIdentifier' and value.strip('0123456789abcdefABCDEF:') is not '': + raise salt.exceptions.SaltInvocationError('value must be precomputed hash') # ensure name and value are bytes name = salt.utils.stringutils.to_str(name) @@ -145,7 +139,7 @@ def _new_extension(name, value, critical=0, issuer=None, _pyfree=1): x509_ext_ptr = M2Crypto.m2.x509v3_ext_conf(None, ctx, name, value) lhash = None except AttributeError: - lhash = M2Crypto.m2.x509v3_lhash() # pylint: disable=no-member + lhash = M2Crypto.m2.x509v3_lhash() # pylint: disable=no-member ctx = M2Crypto.m2.x509v3_set_conf_lhash( lhash) # pylint: disable=no-member # ctx not zeroed @@ -196,10 +190,8 @@ def _get_csr_extensions(csr): csrtempfile.flush() csryaml = _parse_openssl_req(csrtempfile.name) csrtempfile.close() - if csryaml and 'Requested Extensions' in \ - csryaml['Certificate Request']['Data']: - csrexts = \ - csryaml['Certificate Request']['Data']['Requested Extensions'] + if csryaml and 'Requested Extensions' in csryaml['Certificate Request']['Data']: + csrexts = csryaml['Certificate Request']['Data']['Requested Extensions'] if not csrexts: return ret @@ -294,7 +286,7 @@ def _get_signing_policy(name): signing_policy = policies.get(name) if signing_policy: return signing_policy - return __salt__['config.get']('x509_signing_policies', {}).get(name) + return __salt__['config.get']('x509_signing_policies', {}).get(name) or {} def _pretty_hex(hex_str): @@ -321,9 +313,11 @@ def _text_or_file(input_): ''' if os.path.isfile(input_): with salt.utils.files.fopen(input_) as fp_: - return salt.utils.stringutils.to_str(fp_.read()) + out = salt.utils.stringutils.to_str(fp_.read()) else: - return salt.utils.stringutils.to_str(input_) + out = salt.utils.stringutils.to_str(input_) + + return out def _parse_subject(subject): @@ -341,7 +335,7 @@ def _parse_subject(subject): ret[nid_name] = val nids.append(nid_num) except TypeError as err: - log.trace("Missing attribute '%s'. Error: %s", nid_name, err) + log.debug("Missing attribute '%s'. Error: %s", nid_name, err) return ret @@ -520,8 +514,8 @@ def get_pem_entries(glob_path): if os.path.isfile(path): try: ret[path] = get_pem_entry(text=path) - except ValueError: - pass + except ValueError as err: + log.debug('Unable to get PEM entries from %s: %s', path, err) return ret @@ -599,8 +593,8 @@ def read_certificates(glob_path): if os.path.isfile(path): try: ret[path] = read_certificate(certificate=path) - except ValueError: - pass + except ValueError as err: + log.debug('Unable to read certificate %s: %s', path, err) return ret @@ -629,12 +623,10 @@ def read_csr(csr): # Get size returns in bytes. The world thinks of key sizes in bits. 'Subject': _parse_subject(csr.get_subject()), 'Subject Hash': _dec2hex(csr.get_subject().as_hash()), - 'Public Key Hash': hashlib.sha1(csr.get_pubkey().get_modulus())\ - .hexdigest() + 'Public Key Hash': hashlib.sha1(csr.get_pubkey().get_modulus()).hexdigest(), + 'X509v3 Extensions': _get_csr_extensions(csr), } - ret['X509v3 Extensions'] = _get_csr_extensions(csr) - return ret @@ -937,7 +929,7 @@ def create_crl( # pylint: disable=too-many-arguments,too-many-locals # pyOpenSSL Note due to current limitations in pyOpenSSL it is impossible # to specify a digest For signing the CRL. This will hopefully be fixed # soon: https://github.com/pyca/pyopenssl/pull/161 - if not HAS_OPENSSL: + if OpenSSL is None: raise salt.exceptions.SaltInvocationError( 'Could not load OpenSSL module, OpenSSL unavailable' ) @@ -962,8 +954,7 @@ def create_crl( # pylint: disable=too-many-arguments,too-many-locals continue if 'revocation_date' not in rev_item: - rev_item['revocation_date'] = datetime.datetime\ - .now().strftime('%Y-%m-%d %H:%M:%S') + rev_item['revocation_date'] = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') rev_date = datetime.datetime.strptime( rev_item['revocation_date'], '%Y-%m-%d %H:%M:%S') @@ -1002,8 +993,9 @@ def create_crl( # pylint: disable=too-many-arguments,too-many-locals try: crltext = crl.export(**export_kwargs) except (TypeError, ValueError): - log.warning( - 'Error signing crl with specified digest. Are you using pyopenssl 0.15 or newer? The default md5 digest will be used.') + log.warning('Error signing crl with specified digest. ' + 'Are you using pyopenssl 0.15 or newer? ' + 'The default md5 digest will be used.') export_kwargs.pop('digest', None) crltext = crl.export(**export_kwargs) @@ -1042,8 +1034,7 @@ def sign_remote_certificate(argdic, **kwargs): if 'signing_policy' in argdic: signing_policy = _get_signing_policy(argdic['signing_policy']) if not signing_policy: - return 'Signing policy {0} does not exist.'.format( - argdic['signing_policy']) + return 'Signing policy {0} does not exist.'.format(argdic['signing_policy']) if isinstance(signing_policy, list): dict_ = {} @@ -1080,6 +1071,7 @@ def get_signing_policy(signing_policy_name): signing_policy = _get_signing_policy(signing_policy_name) if not signing_policy: return 'Signing policy {0} does not exist.'.format(signing_policy_name) + if isinstance(signing_policy, list): dict_ = {} for item in signing_policy: @@ -1092,10 +1084,9 @@ def get_signing_policy(signing_policy_name): pass try: - signing_policy['signing_cert'] = get_pem_entry( - signing_policy['signing_cert'], 'CERTIFICATE') + signing_policy['signing_cert'] = get_pem_entry(signing_policy['signing_cert'], 'CERTIFICATE') except KeyError: - pass + log.debug('Unable to get "certificate" PEM entry') return signing_policy @@ -1346,8 +1337,7 @@ def create_certificate( signing_private_key='/etc/pki/myca.key' csr='/etc/pki/myca.csr'} ''' - if not path and not text and \ - ('testrun' not in kwargs or kwargs['testrun'] is False): + if not path and not text and ('testrun' not in kwargs or kwargs['testrun'] is False): raise salt.exceptions.SaltInvocationError( 'Either path or text must be specified.') if path and text: @@ -1376,8 +1366,7 @@ def create_certificate( # Including listen_in and preqreuired because they are not included # in STATE_INTERNAL_KEYWORDS # for salt 2014.7.2 - for ignore in list(_STATE_INTERNAL_KEYWORDS) + \ - ['listen_in', 'preqrequired', '__prerequired__']: + for ignore in list(_STATE_INTERNAL_KEYWORDS) + ['listen_in', 'preqrequired', '__prerequired__']: kwargs.pop(ignore, None) certs = __salt__['publish.publish']( @@ -1484,8 +1473,7 @@ def create_certificate( continue # Use explicitly set values first, fall back to CSR values. - extval = kwargs.get(extname) or kwargs.get(extlongname) or \ - csrexts.get(extname) or csrexts.get(extlongname) + extval = kwargs.get(extname) or kwargs.get(extlongname) or csrexts.get(extname) or csrexts.get(extlongname) critical = False if extval.startswith('critical '): @@ -1608,8 +1596,8 @@ def create_csr(path=None, text=False, **kwargs): if 'private_key' not in kwargs and 'public_key' in kwargs: kwargs['private_key'] = kwargs['public_key'] - log.warning( - "OpenSSL no longer allows working with non-signed CSRs. A private_key must be specified. Attempting to use public_key as private_key") + log.warning("OpenSSL no longer allows working with non-signed CSRs. " + "A private_key must be specified. Attempting to use public_key as private_key") if 'private_key' not in kwargs: raise salt.exceptions.SaltInvocationError('private_key is required') @@ -1621,11 +1609,9 @@ def create_csr(path=None, text=False, **kwargs): kwargs['private_key_passphrase'] = None if 'public_key_passphrase' not in kwargs: kwargs['public_key_passphrase'] = None - if kwargs['public_key_passphrase'] and not kwargs[ - 'private_key_passphrase']: + if kwargs['public_key_passphrase'] and not kwargs['private_key_passphrase']: kwargs['private_key_passphrase'] = kwargs['public_key_passphrase'] - if kwargs['private_key_passphrase'] and not kwargs[ - 'public_key_passphrase']: + if kwargs['private_key_passphrase'] and not kwargs['public_key_passphrase']: kwargs['public_key_passphrase'] = kwargs['private_key_passphrase'] csr.set_pubkey(get_public_key(kwargs['public_key'], @@ -1669,18 +1655,10 @@ def create_csr(path=None, text=False, **kwargs): extstack.push(ext) csr.add_extensions(extstack) - csr.sign(_get_private_key_obj(kwargs['private_key'], passphrase=kwargs['private_key_passphrase']), kwargs['algorithm']) - if path: - return write_pem( - text=csr.as_pem(), - path=path, - pem_type='CERTIFICATE REQUEST' - ) - else: - return csr.as_pem() + return write_pem(text=csr.as_pem(), path=path, pem_type='CERTIFICATE REQUEST') if path else csr.as_pem() def verify_private_key(private_key, public_key, passphrase=None): @@ -1705,8 +1683,7 @@ def verify_private_key(private_key, public_key, passphrase=None): salt '*' x509.verify_private_key private_key=/etc/pki/myca.key \\ public_key=/etc/pki/myca.crt ''' - return bool(get_public_key(private_key, passphrase) - == get_public_key(public_key)) + return get_public_key(private_key, passphrase) == get_public_key(public_key) def verify_signature(certificate, signing_pub_key=None, @@ -1760,9 +1737,8 @@ def verify_crl(crl, cert): salt '*' x509.verify_crl crl=/etc/pki/myca.crl cert=/etc/pki/myca.crt ''' if not salt.utils.path.which('openssl'): - raise salt.exceptions.SaltInvocationError( - 'openssl binary not found in path' - ) + raise salt.exceptions.SaltInvocationError('External command "openssl" not found') + crltext = _text_or_file(crl) crltext = get_pem_entry(crltext, pem_type='X509 CRL') crltempfile = tempfile.NamedTemporaryFile() @@ -1783,10 +1759,7 @@ def verify_crl(crl, cert): crltempfile.close() certtempfile.close() - if 'verify OK' in output: - return True - else: - return False + return 'verify OK' in output def expired(certificate): @@ -1823,8 +1796,9 @@ def expired(certificate): ret['expired'] = True else: ret['expired'] = False - except ValueError: - pass + except ValueError as err: + log.debug('Failed to get data of expired certificate: %s', err) + log.trace(err, exc_info=True) return ret @@ -1847,6 +1821,7 @@ def will_expire(certificate, days): salt '*' x509.will_expire "/etc/pki/mycert.crt" days=30 ''' + ts_pt = "%Y-%m-%d %H:%M:%S" ret = {} if os.path.isfile(certificate): @@ -1856,18 +1831,13 @@ def will_expire(certificate, days): cert = _get_certificate_obj(certificate) - _check_time = datetime.datetime.utcnow() + \ - datetime.timedelta(days=days) + _check_time = datetime.datetime.utcnow() + datetime.timedelta(days=days) _expiration_date = cert.get_not_after().get_datetime() ret['cn'] = _parse_subject(cert.get_subject())['CN'] - - if _expiration_date.strftime("%Y-%m-%d %H:%M:%S") <= \ - _check_time.strftime("%Y-%m-%d %H:%M:%S"): - ret['will_expire'] = True - else: - ret['will_expire'] = False - except ValueError: - pass + ret['will_expire'] = _expiration_date.strftime(ts_pt) <= _check_time.strftime(ts_pt) + except ValueError as err: + log.debug('Unable to return details of a sertificate expiration: %s', err) + log.trace(err, exc_info=True) return ret diff --git a/salt/states/x509.py b/salt/states/x509.py index 7bb941f393..3ba4f79c79 100644 --- a/salt/states/x509.py +++ b/salt/states/x509.py @@ -163,6 +163,7 @@ import copy # Import Salt Libs import salt.exceptions +import salt.utils.stringutils # Import 3rd-party libs from salt.ext import six @@ -170,7 +171,7 @@ from salt.ext import six try: from M2Crypto.RSA import RSAError except ImportError: - pass + RSAError = Exception('RSA Error') def __virtual__(): @@ -180,7 +181,7 @@ def __virtual__(): if 'x509.get_pem_entry' in __salt__: return 'x509' else: - return (False, 'Could not load x509 state: m2crypto unavailable') + return False, 'Could not load x509 state: the x509 is not available' def _revoked_to_list(revs): @@ -267,7 +268,8 @@ def private_key_managed(name, new: Always create a new key. Defaults to False. - Combining new with :mod:`prereq <salt.states.requsities.preqreq>`, or when used as part of a `managed_private_key` can allow key rotation whenever a new certificiate is generated. + Combining new with :mod:`prereq <salt.states.requsities.preqreq>`, or when used as part of a + `managed_private_key` can allow key rotation whenever a new certificiate is generated. overwrite: Overwrite an existing private key if the provided passphrase cannot decrypt it. @@ -453,8 +455,10 @@ def certificate_managed(name, private_key_args['name'], pem_type='RSA PRIVATE KEY') else: new_private_key = True - private_key = __salt__['x509.create_private_key'](text=True, bits=private_key_args['bits'], passphrase=private_key_args[ - 'passphrase'], cipher=private_key_args['cipher'], verbose=private_key_args['verbose']) + private_key = __salt__['x509.create_private_key'](text=True, bits=private_key_args['bits'], + passphrase=private_key_args['passphrase'], + cipher=private_key_args['cipher'], + verbose=private_key_args['verbose']) kwargs['public_key'] = private_key @@ -664,8 +668,10 @@ def crl_managed(name, else: current = '{0} does not exist.'.format(name) - new_crl = __salt__['x509.create_crl'](text=True, signing_private_key=signing_private_key, signing_private_key_passphrase=signing_private_key_passphrase, - signing_cert=signing_cert, revoked=revoked, days_valid=days_valid, digest=digest, include_expired=include_expired) + new_crl = __salt__['x509.create_crl'](text=True, signing_private_key=signing_private_key, + signing_private_key_passphrase=signing_private_key_passphrase, + signing_cert=signing_cert, revoked=revoked, days_valid=days_valid, + digest=digest, include_expired=include_expired) new = __salt__['x509.read_crl'](crl=new_crl) new_comp = new.copy() @@ -707,6 +713,6 @@ def pem_managed(name, Any arguments supported by :state:`file.managed <salt.states.file.managed>` are supported. ''' file_args, kwargs = _get_file_args(name, **kwargs) - file_args['contents'] = __salt__['x509.get_pem_entry'](text=text) + file_args['contents'] = salt.utils.stringutils.to_str(__salt__['x509.get_pem_entry'](text=text)) return __states__['file.managed'](**file_args) diff --git a/tests/unit/modules/test_x509.py b/tests/unit/modules/test_x509.py index c300a56d64..7e00c97140 100644 --- a/tests/unit/modules/test_x509.py +++ b/tests/unit/modules/test_x509.py @@ -67,10 +67,11 @@ class X509TestCase(TestCase, LoaderModuleMockMixin): subj = FakeSubject() x509._parse_subject(subj) - x509.log.trace.assert_called_once() - assert x509.log.trace.call_args[0][0] == "Missing attribute '%s'. Error: %s" - assert x509.log.trace.call_args[0][1] == list(subj.nid.keys())[0] - assert isinstance(x509.log.trace.call_args[0][2], TypeError) + x509.log.debug.assert_called_once() + + assert x509.log.debug.call_args[0][0] == "Missing attribute '%s'. Error: %s" + assert x509.log.debug.call_args[0][1] == list(subj.nid.keys())[0] + assert isinstance(x509.log.debug.call_args[0][2], TypeError) @skipIf(not HAS_M2CRYPTO, 'Skipping, M2Crypt is unavailble') def test_get_pem_entry(self): -- 2.19.0 ++++++ x509-fixes-for-remote-signing-106.patch ++++++ >From 6276eb2cd3f2b396c13118a111998230477cc65a Mon Sep 17 00:00:00 2001 From: Florian Bergmann <bergma...@users.noreply.github.com> Date: Tue, 11 Sep 2018 14:02:55 +0200 Subject: [PATCH] X509 fixes for remote signing (#106) * Use to_str salt.utils when writing to a file. * Assign the certificate as a string. * Convert to string before sending via 'publish'. Otherwise the publish call with receive a "b''" string, which can not be used in the functions. * Do not silently ignore errors. At least log the occurring errors to debug and trace. --- salt/modules/x509.py | 10 +++++----- salt/states/x509.py | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/salt/modules/x509.py b/salt/modules/x509.py index 15de06e200..9901bc5bd9 100644 --- a/salt/modules/x509.py +++ b/salt/modules/x509.py @@ -658,7 +658,7 @@ def read_crl(crl): text = get_pem_entry(text, pem_type='X509 CRL') crltempfile = tempfile.NamedTemporaryFile() - crltempfile.write(text) + crltempfile.write(salt.utils.stringutils.to_str(text)) crltempfile.flush() crlparsed = _parse_openssl_crl(crltempfile.name) crltempfile.close() @@ -1368,9 +1368,9 @@ def create_certificate( pem_type='CERTIFICATE REQUEST').replace('\n', '') if 'public_key' in kwargs: # Strip newlines to make passing through as cli functions easier - kwargs['public_key'] = get_public_key( + kwargs['public_key'] = salt.utils.stringutils.to_str(get_public_key( kwargs['public_key'], - passphrase=kwargs['public_key_passphrase']).replace('\n', '') + passphrase=kwargs['public_key_passphrase'])).replace('\n', '') # Remove system entries in kwargs # Including listen_in and preqreuired because they are not included @@ -1766,13 +1766,13 @@ def verify_crl(crl, cert): crltext = _text_or_file(crl) crltext = get_pem_entry(crltext, pem_type='X509 CRL') crltempfile = tempfile.NamedTemporaryFile() - crltempfile.write(crltext) + crltempfile.write(salt.utils.stringutils.to_str(crltext)) crltempfile.flush() certtext = _text_or_file(cert) certtext = get_pem_entry(certtext, pem_type='CERTIFICATE') certtempfile = tempfile.NamedTemporaryFile() - certtempfile.write(certtext) + certtempfile.write(salt.utils.stringutils.to_str(certtext)) certtempfile.flush() cmd = ('openssl crl -noout -in {0} -CAfile {1}'.format( diff --git a/salt/states/x509.py b/salt/states/x509.py index 832f74168c..7bb941f393 100644 --- a/salt/states/x509.py +++ b/salt/states/x509.py @@ -545,7 +545,7 @@ def certificate_managed(name, if not private_ret['result']: return private_ret - file_args['contents'] += certificate + file_args['contents'] += salt.utils.stringutils.to_str(certificate) if not append_certs: append_certs = [] -- 2.19.0