1
0
mirror of https://github.com/ansible/awx.git synced 2024-10-30 22:21:13 +03:00

Merge pull request #4458 from ryanpetrello/fifo-cred-plugin-hang-372

[3.7.2] remove the usage of create_temporary_fifo from credential plugins
This commit is contained in:
Ryan Petrello 2020-07-14 17:21:35 -04:00 committed by GitHub
commit c410f1f344
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 69 additions and 49 deletions

View File

@ -1,15 +1,10 @@
from .plugin import CredentialPlugin
from .plugin import CredentialPlugin, CertFiles
from urllib.parse import quote, urlencode, urljoin
from django.utils.translation import ugettext_lazy as _
import requests
# AWX
from awx.main.utils import (
create_temporary_fifo,
)
aim_inputs = {
'fields': [{
'id': 'url',
@ -81,22 +76,14 @@ def aim_backend(**kwargs):
request_qs = '?' + urlencode(query_params, quote_via=quote)
request_url = urljoin(url, '/'.join(['AIMWebService', 'api', 'Accounts']))
cert = None
if client_cert and client_key:
cert = (
create_temporary_fifo(client_cert.encode()),
create_temporary_fifo(client_key.encode())
with CertFiles(client_cert, client_key) as cert:
res = requests.get(
request_url + request_qs,
timeout=30,
cert=cert,
verify=verify,
allow_redirects=False,
)
elif client_cert:
cert = create_temporary_fifo(client_cert.encode())
res = requests.get(
request_url + request_qs,
timeout=30,
cert=cert,
verify=verify,
allow_redirects=False,
)
res.raise_for_status()
return res.json()['Content']

View File

@ -1,4 +1,4 @@
from .plugin import CredentialPlugin
from .plugin import CredentialPlugin, CertFiles
import base64
from urllib.parse import urljoin, quote_plus
@ -6,11 +6,6 @@ from urllib.parse import urljoin, quote_plus
from django.utils.translation import ugettext_lazy as _
import requests
# AWX
from awx.main.utils import (
create_temporary_fifo,
)
conjur_inputs = {
'fields': [{
@ -66,14 +61,14 @@ def conjur_backend(**kwargs):
'data': api_key,
'allow_redirects': False,
}
if cacert:
auth_kwargs['verify'] = create_temporary_fifo(cacert.encode())
# https://www.conjur.org/api.html#authentication-authenticate-post
resp = requests.post(
urljoin(url, '/'.join(['authn', account, username, 'authenticate'])),
**auth_kwargs
)
with CertFiles(cacert) as cert:
# https://www.conjur.org/api.html#authentication-authenticate-post
auth_kwargs['verify'] = cert
resp = requests.post(
urljoin(url, '/'.join(['authn', account, username, 'authenticate'])),
**auth_kwargs
)
resp.raise_for_status()
token = base64.b64encode(resp.content).decode('utf-8')
@ -81,8 +76,6 @@ def conjur_backend(**kwargs):
'headers': {'Authorization': 'Token token="{}"'.format(token)},
'allow_redirects': False,
}
if cacert:
lookup_kwargs['verify'] = create_temporary_fifo(cacert.encode())
# https://www.conjur.org/api.html#secrets-retrieve-a-secret-get
path = urljoin(url, '/'.join([
@ -94,7 +87,9 @@ def conjur_backend(**kwargs):
if version:
path = '?'.join([path, version])
resp = requests.get(path, timeout=30, **lookup_kwargs)
with CertFiles(cacert) as cert:
lookup_kwargs['verify'] = cert
resp = requests.get(path, timeout=30, **lookup_kwargs)
resp.raise_for_status()
return resp.text

View File

@ -3,16 +3,11 @@ import os
import pathlib
from urllib.parse import urljoin
from .plugin import CredentialPlugin
from .plugin import CredentialPlugin, CertFiles
import requests
from django.utils.translation import ugettext_lazy as _
# AWX
from awx.main.utils import (
create_temporary_fifo,
)
base_inputs = {
'fields': [{
'id': 'url',
@ -101,8 +96,6 @@ def kv_backend(**kwargs):
'timeout': 30,
'allow_redirects': False,
}
if cacert:
request_kwargs['verify'] = create_temporary_fifo(cacert.encode())
sess = requests.Session()
sess.headers['Authorization'] = 'Bearer {}'.format(token)
@ -129,7 +122,9 @@ def kv_backend(**kwargs):
path_segments = [secret_path]
request_url = urljoin(url, '/'.join(['v1'] + path_segments)).rstrip('/')
response = sess.get(request_url, **request_kwargs)
with CertFiles(cacert) as cert:
request_kwargs['verify'] = cert
response = sess.get(request_url, **request_kwargs)
response.raise_for_status()
json = response.json()
@ -157,8 +152,6 @@ def ssh_backend(**kwargs):
'timeout': 30,
'allow_redirects': False,
}
if cacert:
request_kwargs['verify'] = create_temporary_fifo(cacert.encode())
request_kwargs['json'] = {'public_key': kwargs['public_key']}
if kwargs.get('valid_principals'):
@ -170,7 +163,10 @@ def ssh_backend(**kwargs):
sess.headers['X-Vault-Token'] = token
# https://www.vaultproject.io/api/secret/ssh/index.html#sign-ssh-key
request_url = '/'.join([url, secret_path, 'sign', role]).rstrip('/')
resp = sess.post(request_url, **request_kwargs)
with CertFiles(cacert) as cert:
request_kwargs['verify'] = cert
resp = sess.post(request_url, **request_kwargs)
resp.raise_for_status()
return resp.json()['data']['signed_key']

View File

@ -1,3 +1,45 @@
import os
import tempfile
from collections import namedtuple
CredentialPlugin = namedtuple('CredentialPlugin', ['name', 'inputs', 'backend'])
class CertFiles():
"""
A context manager used for writing a certificate and (optional) key
to $TMPDIR, and cleaning up afterwards.
This is particularly useful as a shared resource for credential plugins
that want to pull cert/key data out of the database and persist it
temporarily to the file system so that it can loaded into the openssl
certificate chain (generally, for HTTPS requests plugins make via the
Python requests library)
with CertFiles(cert_data, key_data) as cert:
# cert is string representing a path to the cert or pemfile
# temporarily written to disk
requests.post(..., cert=cert)
"""
certfile = None
def __init__(self, cert, key=None):
self.cert = cert
self.key = key
def __enter__(self):
if not self.cert:
return None
self.certfile = tempfile.NamedTemporaryFile('wb', delete=False)
self.certfile.write(self.cert.encode())
if self.key:
self.certfile.write(b'\n')
self.certfile.write(self.key.encode())
self.certfile.flush()
return str(self.certfile.name)
def __exit__(self, *args):
if self.certfile and os.path.exists(self.certfile.name):
os.remove(self.certfile.name)