mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
* python3 support for letsencrypt module (fixes #30690) * initialize result to a dict in some methods to prevent 'NoneType is not iterable' TypeError * use dict.get() to retrieve values from info dict to prevent KeyError * convert to/from text/bytes using _text methods for PY3 support
This commit is contained in:
parent
551847beea
commit
3a634058f3
1 changed files with 25 additions and 13 deletions
|
@ -166,8 +166,22 @@ import traceback
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible.module_utils._text import to_native
|
from ansible.module_utils._text import to_native, to_text, to_bytes
|
||||||
from ansible.module_utils.urls import fetch_url
|
from ansible.module_utils.urls import fetch_url as _fetch_url
|
||||||
|
|
||||||
|
|
||||||
|
def _lowercase_fetch_url(*args, **kwargs):
|
||||||
|
'''
|
||||||
|
Add lowercase representations of the header names as dict keys
|
||||||
|
|
||||||
|
'''
|
||||||
|
response, info = _fetch_url(*args, **kwargs)
|
||||||
|
|
||||||
|
info.update(dict((header.lower(), value) for (header, value) in info.items()))
|
||||||
|
return response, info
|
||||||
|
|
||||||
|
|
||||||
|
fetch_url = _lowercase_fetch_url
|
||||||
|
|
||||||
|
|
||||||
def nopad_b64(data):
|
def nopad_b64(data):
|
||||||
|
@ -177,12 +191,11 @@ def nopad_b64(data):
|
||||||
def simple_get(module, url):
|
def simple_get(module, url):
|
||||||
resp, info = fetch_url(module, url, method='GET')
|
resp, info = fetch_url(module, url, method='GET')
|
||||||
|
|
||||||
result = None
|
result = {}
|
||||||
try:
|
try:
|
||||||
content = resp.read()
|
content = resp.read()
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
if info['body']:
|
content = info.get('body')
|
||||||
content = info['body']
|
|
||||||
|
|
||||||
if content:
|
if content:
|
||||||
if info['content-type'].startswith('application/json'):
|
if info['content-type'].startswith('application/json'):
|
||||||
|
@ -355,7 +368,7 @@ class ACMEAccount(object):
|
||||||
|
|
||||||
pub_hex, pub_exp = re.search(
|
pub_hex, pub_exp = re.search(
|
||||||
r"modulus:\n\s+00:([a-f0-9\:\s]+?)\npublicExponent: ([0-9]+)",
|
r"modulus:\n\s+00:([a-f0-9\:\s]+?)\npublicExponent: ([0-9]+)",
|
||||||
out.decode('utf8'), re.MULTILINE | re.DOTALL).groups()
|
to_text(out, errors='surrogate_or_strict'), re.MULTILINE | re.DOTALL).groups()
|
||||||
pub_exp = "{0:x}".format(int(pub_exp))
|
pub_exp = "{0:x}".format(int(pub_exp))
|
||||||
if len(pub_exp) % 2:
|
if len(pub_exp) % 2:
|
||||||
pub_exp = "0{0}".format(pub_exp)
|
pub_exp = "0{0}".format(pub_exp)
|
||||||
|
@ -385,16 +398,15 @@ class ACMEAccount(object):
|
||||||
"header": self.jws_header,
|
"header": self.jws_header,
|
||||||
"protected": protected64,
|
"protected": protected64,
|
||||||
"payload": payload64,
|
"payload": payload64,
|
||||||
"signature": nopad_b64(out),
|
"signature": nopad_b64(to_bytes(out)),
|
||||||
})
|
})
|
||||||
|
|
||||||
resp, info = fetch_url(self.module, url, data=data, method='POST')
|
resp, info = fetch_url(self.module, url, data=data, method='POST')
|
||||||
result = None
|
result = {}
|
||||||
try:
|
try:
|
||||||
content = resp.read()
|
content = resp.read()
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
if info['body']:
|
content = info.get('body')
|
||||||
content = info['body']
|
|
||||||
|
|
||||||
if content:
|
if content:
|
||||||
if info['content-type'].startswith('application/json'):
|
if info['content-type'].startswith('application/json'):
|
||||||
|
@ -541,10 +553,10 @@ class ACMEClient(object):
|
||||||
_, out, _ = self.module.run_command(openssl_csr_cmd, check_rc=True)
|
_, out, _ = self.module.run_command(openssl_csr_cmd, check_rc=True)
|
||||||
|
|
||||||
domains = set([])
|
domains = set([])
|
||||||
common_name = re.search(r"Subject:.*? CN\s?=\s?([^\s,;/]+)", out.decode('utf8'))
|
common_name = re.search(r"Subject:.*? CN\s?=\s?([^\s,;/]+)", to_text(out, errors='surrogate_or_strict'))
|
||||||
if common_name is not None:
|
if common_name is not None:
|
||||||
domains.add(common_name.group(1))
|
domains.add(common_name.group(1))
|
||||||
subject_alt_names = re.search(r"X509v3 Subject Alternative Name: \n +([^\n]+)\n", out.decode('utf8'), re.MULTILINE | re.DOTALL)
|
subject_alt_names = re.search(r"X509v3 Subject Alternative Name: \n +([^\n]+)\n", to_text(out, errors='surrogate_or_strict'), re.MULTILINE | re.DOTALL)
|
||||||
if subject_alt_names is not None:
|
if subject_alt_names is not None:
|
||||||
for san in subject_alt_names.group(1).split(", "):
|
for san in subject_alt_names.group(1).split(", "):
|
||||||
if san.startswith("DNS:"):
|
if san.startswith("DNS:"):
|
||||||
|
@ -641,7 +653,7 @@ class ACMEClient(object):
|
||||||
elif type == 'dns-01':
|
elif type == 'dns-01':
|
||||||
# https://tools.ietf.org/html/draft-ietf-acme-acme-02#section-7.4
|
# https://tools.ietf.org/html/draft-ietf-acme-acme-02#section-7.4
|
||||||
resource = '_acme-challenge'
|
resource = '_acme-challenge'
|
||||||
value = nopad_b64(hashlib.sha256(keyauthorization).digest()).encode('utf8')
|
value = nopad_b64(hashlib.sha256(to_bytes(keyauthorization)).digest())
|
||||||
else:
|
else:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue