uri - add ca_path parameter (#71979)
* add changelog fragment for #71979 (ca_path for uri) * add integration tests for ca_path in the uri module * return path of ca cert instead of its content * connect to port 444 on self_signed_host and use quay.io/ansible/http-test-container:1.3.0 * state that the certificate in ca_path is used for validation
This commit is contained in:
parent
82cdd7e735
commit
8d6136eab9
4 changed files with 55 additions and 7 deletions
2
changelogs/fragments/71979_ca_path_for_uri.yaml
Normal file
2
changelogs/fragments/71979_ca_path_for_uri.yaml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
minor_changes:
|
||||||
|
- uri - add ``ca_path`` argument to allow specification of a CA certificate (https://github.com/ansible/ansible/pull/71979).
|
|
@ -923,9 +923,7 @@ class SSLValidationHandler(urllib_request.BaseHandler):
|
||||||
to_native(f.read(), errors='surrogate_or_strict')
|
to_native(f.read(), errors='surrogate_or_strict')
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
else:
|
return self.ca_path, cadata, paths_checked
|
||||||
ca_certs.append(f.read())
|
|
||||||
return ca_certs, cadata, paths_checked
|
|
||||||
|
|
||||||
if not HAS_SSLCONTEXT:
|
if not HAS_SSLCONTEXT:
|
||||||
paths_checked.append('/etc/ssl/certs')
|
paths_checked.append('/etc/ssl/certs')
|
||||||
|
|
|
@ -141,6 +141,11 @@ options:
|
||||||
- If I(client_cert) contains both the certificate and key, this option is not required.
|
- If I(client_cert) contains both the certificate and key, this option is not required.
|
||||||
type: path
|
type: path
|
||||||
version_added: '2.4'
|
version_added: '2.4'
|
||||||
|
ca_path:
|
||||||
|
description:
|
||||||
|
- PEM formatted file that contains a CA certificate to be used for validation
|
||||||
|
type: path
|
||||||
|
version_added: '2.11'
|
||||||
src:
|
src:
|
||||||
description:
|
description:
|
||||||
- Path to file to be submitted to the remote server.
|
- Path to file to be submitted to the remote server.
|
||||||
|
@ -548,13 +553,12 @@ def form_urlencoded(body):
|
||||||
return body
|
return body
|
||||||
|
|
||||||
|
|
||||||
def uri(module, url, dest, body, body_format, method, headers, socket_timeout):
|
def uri(module, url, dest, body, body_format, method, headers, socket_timeout, ca_path):
|
||||||
# is dest is set and is a directory, let's check if we get redirected and
|
# is dest is set and is a directory, let's check if we get redirected and
|
||||||
# set the filename from that url
|
# set the filename from that url
|
||||||
redirected = False
|
redirected = False
|
||||||
redir_info = {}
|
redir_info = {}
|
||||||
r = {}
|
r = {}
|
||||||
|
|
||||||
src = module.params['src']
|
src = module.params['src']
|
||||||
if src:
|
if src:
|
||||||
try:
|
try:
|
||||||
|
@ -594,6 +598,7 @@ def uri(module, url, dest, body, body_format, method, headers, socket_timeout):
|
||||||
|
|
||||||
resp, info = fetch_url(module, url, data=data, headers=headers,
|
resp, info = fetch_url(module, url, data=data, headers=headers,
|
||||||
method=method, timeout=socket_timeout, unix_socket=module.params['unix_socket'],
|
method=method, timeout=socket_timeout, unix_socket=module.params['unix_socket'],
|
||||||
|
ca_path=ca_path,
|
||||||
**kwargs)
|
**kwargs)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -636,6 +641,7 @@ def main():
|
||||||
headers=dict(type='dict', default={}),
|
headers=dict(type='dict', default={}),
|
||||||
unix_socket=dict(type='path'),
|
unix_socket=dict(type='path'),
|
||||||
remote_src=dict(type='bool', default=False),
|
remote_src=dict(type='bool', default=False),
|
||||||
|
ca_path=dict(type='path', default=None),
|
||||||
)
|
)
|
||||||
|
|
||||||
module = AnsibleModule(
|
module = AnsibleModule(
|
||||||
|
@ -658,7 +664,7 @@ def main():
|
||||||
removes = module.params['removes']
|
removes = module.params['removes']
|
||||||
status_code = [int(x) for x in list(module.params['status_code'])]
|
status_code = [int(x) for x in list(module.params['status_code'])]
|
||||||
socket_timeout = module.params['timeout']
|
socket_timeout = module.params['timeout']
|
||||||
|
ca_path = module.params['ca_path']
|
||||||
dict_headers = module.params['headers']
|
dict_headers = module.params['headers']
|
||||||
|
|
||||||
if not re.match('^[A-Z]+$', method):
|
if not re.match('^[A-Z]+$', method):
|
||||||
|
@ -702,7 +708,7 @@ def main():
|
||||||
# Make the request
|
# Make the request
|
||||||
start = datetime.datetime.utcnow()
|
start = datetime.datetime.utcnow()
|
||||||
resp, content, dest = uri(module, url, dest, body, body_format, method,
|
resp, content, dest = uri(module, url, dest, body, body_format, method,
|
||||||
dict_headers, socket_timeout)
|
dict_headers, socket_timeout, ca_path)
|
||||||
resp['elapsed'] = (datetime.datetime.utcnow() - start).seconds
|
resp['elapsed'] = (datetime.datetime.utcnow() - start).seconds
|
||||||
resp['status'] = int(resp['status'])
|
resp['status'] = int(resp['status'])
|
||||||
resp['changed'] = False
|
resp['changed'] = False
|
||||||
|
|
|
@ -131,6 +131,48 @@
|
||||||
- "stat_result.stat.exists == true"
|
- "stat_result.stat.exists == true"
|
||||||
- "result.changed == true"
|
- "result.changed == true"
|
||||||
|
|
||||||
|
- name: "get ca certificate {{ self_signed_host }}"
|
||||||
|
get_url:
|
||||||
|
url: "http://{{ httpbin_host }}/ca2cert.pem"
|
||||||
|
dest: "{{ remote_tmp_dir }}/ca2cert.pem"
|
||||||
|
|
||||||
|
- name: test https fetch to a site with self signed certificate using ca_path
|
||||||
|
uri:
|
||||||
|
url: "https://{{ self_signed_host }}:444/"
|
||||||
|
dest: "{{ output_dir }}/self-signed_using_ca_path.html"
|
||||||
|
ca_path: "{{ remote_tmp_dir }}/ca2cert.pem"
|
||||||
|
validate_certs: yes
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- stat:
|
||||||
|
path: "{{ output_dir }}/self-signed_using_ca_path.html"
|
||||||
|
register: stat_result
|
||||||
|
|
||||||
|
- name: Assert that the file was downloaded
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- "stat_result.stat.exists == true"
|
||||||
|
- "result.changed == true"
|
||||||
|
|
||||||
|
- name: test https fetch to a site with self signed certificate without using ca_path
|
||||||
|
uri:
|
||||||
|
url: "https://{{ self_signed_host }}:444/"
|
||||||
|
dest: "{{ output_dir }}/self-signed-without_using_ca_path.html"
|
||||||
|
validate_certs: yes
|
||||||
|
register: result
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- stat:
|
||||||
|
path: "{{ output_dir }}/self-signed-without_using_ca_path.html"
|
||||||
|
register: stat_result
|
||||||
|
|
||||||
|
- name: Assure that https access to a host with self-signed certificate without providing ca_path fails
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- "stat_result.stat.exists == false"
|
||||||
|
- result is failed
|
||||||
|
- "'certificate verify failed' in result.msg"
|
||||||
|
|
||||||
- name: test redirect without follow_redirects
|
- name: test redirect without follow_redirects
|
||||||
uri:
|
uri:
|
||||||
url: 'https://{{ httpbin_host }}/redirect/2'
|
url: 'https://{{ httpbin_host }}/redirect/2'
|
||||||
|
|
Loading…
Reference in a new issue