Accepting request 636187 from home:mdinca:branches:systemsmanagement:saltstack
- 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 OBS-URL: https://build.opensuse.org/request/show/636187 OBS-URL: https://build.opensuse.org/package/show/systemsmanagement:saltstack/salt?expand=0&rev=129
This commit is contained in:
parent
7966fde1ef
commit
c0d7cc4bb8
@ -1 +1 @@
|
||||
eb0ca38e07c96eb021ac7490ac1f61a54dc9d904
|
||||
ebc77d067d9fa300bdc5bb5dcccaa09e1787f688
|
1171
add-support-for-python-3.7.patch
Normal file
1171
add-support-for-python-3.7.patch
Normal file
File diff suppressed because it is too large
Load Diff
57
change-stringio-import-in-python2-to-import-the-clas.patch
Normal file
57
change-stringio-import-in-python2-to-import-the-clas.patch
Normal file
@ -0,0 +1,57 @@
|
||||
From a0d5af98c8d2a22c5eb56943ff320ca287fa79ea Mon Sep 17 00:00:00 2001
|
||||
From: Florian Bergmann <bergmannf@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
|
||||
|
||||
|
27
decode-file-contents-for-python2-bsc-1102013.patch
Normal file
27
decode-file-contents-for-python2-bsc-1102013.patch
Normal file
@ -0,0 +1,27 @@
|
||||
From 58913b6801b92bd59374cd53fa48fa74171abb73 Mon Sep 17 00:00:00 2001
|
||||
From: Abid Mehmood <amehmood@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
|
||||
|
||||
|
35
fix-for-sorting-of-multi-version-packages-bsc-109717.patch
Normal file
35
fix-for-sorting-of-multi-version-packages-bsc-109717.patch
Normal file
@ -0,0 +1,35 @@
|
||||
From f0f63dc8dd5979b51db71cf759d4350da1078383 Mon Sep 17 00:00:00 2001
|
||||
From: Jochen Breuer <jbreuer@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
|
||||
|
||||
|
43
fix-for-suse-expanded-support-detection.patch
Normal file
43
fix-for-suse-expanded-support-detection.patch
Normal file
@ -0,0 +1,43 @@
|
||||
From 1c9cba3a397d53e399b82320507fb5141234c67f Mon Sep 17 00:00:00 2001
|
||||
From: Jochen Breuer <jbreuer@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
|
||||
|
||||
|
34
fix-mine.get-not-returning-data-workaround-for-48020.patch
Normal file
34
fix-mine.get-not-returning-data-workaround-for-48020.patch
Normal file
@ -0,0 +1,34 @@
|
||||
From f8c0811c3a05ef334eef1943a906fe01b13c1afc Mon Sep 17 00:00:00 2001
|
||||
From: Federico Ceratto <federico.ceratto@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
|
||||
|
||||
|
118
integration-of-msi-authentication-with-azurearm-clou.patch
Normal file
118
integration-of-msi-authentication-with-azurearm-clou.patch
Normal file
@ -0,0 +1,118 @@
|
||||
From 06aff97c83342cf9635fa750222f774ab1664a0d Mon Sep 17 00:00:00 2001
|
||||
From: ed lane <ed.lane.0@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
|
||||
|
||||
|
29
only-do-reverse-dns-lookup-on-ips-for-salt-ssh.patch
Normal file
29
only-do-reverse-dns-lookup-on-ips-for-salt-ssh.patch
Normal file
@ -0,0 +1,29 @@
|
||||
From f346e83f6d4651a1cdcaad8c995642b55f66ddbc Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Wallace <danielwallace@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
|
||||
|
||||
|
38
prepend-current-directory-when-path-is-just-filename.patch
Normal file
38
prepend-current-directory-when-path-is-just-filename.patch
Normal file
@ -0,0 +1,38 @@
|
||||
From 341ee0c44cabf2f34bdd2f4b54e4b83053a3133e Mon Sep 17 00:00:00 2001
|
||||
From: Mihai Dinca <mdinca@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
|
||||
|
||||
|
32
salt.changes
32
salt.changes
@ -1,3 +1,35 @@
|
||||
-------------------------------------------------------------------
|
||||
Mon Sep 17 13:47:09 UTC 2018 - bo@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
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Mon Jul 30 10:42:01 UTC 2018 - mihai.dinca@suse.com
|
||||
|
||||
|
40
salt.spec
40
salt.spec
@ -126,6 +126,30 @@ Patch29: remove-old-hack-when-reporting-multiversion-packages.patch
|
||||
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 @@ cp %{S:5} ./.travis.yml
|
||||
%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 @@ rm -f %{_localstatedir}/cache/salt/minion/thin/version
|
||||
%{_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
|
||||
|
151
use-adler32-algorithm-to-compute-string-checksums.patch
Normal file
151
use-adler32-algorithm-to-compute-string-checksums.patch
Normal file
@ -0,0 +1,151 @@
|
||||
From 1cb2d2bc6c1cf1a39e735120c184d6ade9e64c34 Mon Sep 17 00:00:00 2001
|
||||
From: Bo Maryniuk <bo@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
|
||||
|
||||
|
518
x509-fixes-111.patch
Normal file
518
x509-fixes-111.patch
Normal file
@ -0,0 +1,518 @@
|
||||
From 053d97afcc7486f7300e339bc56cb3c850cc523b Mon Sep 17 00:00:00 2001
|
||||
From: Florian Bergmann <bergmannf@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
|
||||
|
||||
|
80
x509-fixes-for-remote-signing-106.patch
Normal file
80
x509-fixes-for-remote-signing-106.patch
Normal file
@ -0,0 +1,80 @@
|
||||
From 6276eb2cd3f2b396c13118a111998230477cc65a Mon Sep 17 00:00:00 2001
|
||||
From: Florian Bergmann <bergmannf@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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user