# Test code for the get_url module # (c) 2014, Richard Isaacson # This file is part of Ansible # # Ansible is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Ansible is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Ansible. If not, see . - name: Determine if python looks like it will support modern ssl features like SNI command: "{{ ansible_python.executable }} -c 'from ssl import SSLContext'" ignore_errors: True register: python_test - name: Set python_has_sslcontext if we have it set_fact: python_has_ssl_context: True when: python_test.rc == 0 - name: Set python_has_sslcontext False if we don't have it set_fact: python_has_ssl_context: False when: python_test.rc != 0 - name: Define test files for file schema set_fact: geturl_srcfile: "{{ output_dir }}/aurlfile.txt" geturl_dstfile: "{{ output_dir }}/aurlfile_copy.txt" - name: Create source file copy: dest: "{{ geturl_srcfile }}" content: "foobar" register: source_file_copied - name: test file fetch get_url: url: "file://{{ source_file_copied.dest }}" dest: "{{ geturl_dstfile }}" register: result - name: assert success and change assert: that: - result is changed - '"OK" in result.msg' - name: test nonexisting file fetch get_url: url: "file://{{ source_file_copied.dest }}NOFILE" dest: "{{ geturl_dstfile }}NOFILE" register: result ignore_errors: True - name: assert success and change assert: that: - result is failed - name: test HTTP HEAD request for file in check mode get_url: url: "https://{{ httpbin_host }}/get" dest: "{{ output_dir }}/get_url_check.txt" force: yes check_mode: True register: result - name: assert that the HEAD request was successful in check mode assert: that: - result is changed - '"OK" in result.msg' - name: test HTTP HEAD for nonexistent URL in check mode get_url: url: "https://{{ httpbin_host }}/DOESNOTEXIST" dest: "{{ output_dir }}/shouldnotexist.html" force: yes check_mode: True register: result ignore_errors: True - name: assert that HEAD request for nonexistent URL failed assert: that: - result is failed - name: test https fetch get_url: url="https://{{ httpbin_host }}/get" dest={{output_dir}}/get_url.txt force=yes register: result - name: assert the get_url call was successful assert: that: - result is changed - '"OK" in result.msg' - name: test https fetch to a site with mismatched hostname and certificate get_url: url: "https://{{ badssl_host }}/" dest: "{{ output_dir }}/shouldnotexist.html" ignore_errors: True register: result - stat: path: "{{ output_dir }}/shouldnotexist.html" register: stat_result - name: Assert that the file was not downloaded assert: that: - "result is failed" - "'Failed to validate the SSL certificate' in result.msg or ( result.msg is match('hostname .* doesn.t match .*'))" - "stat_result.stat.exists == false" - name: test https fetch to a site with mismatched hostname and certificate and validate_certs=no get_url: url: "https://{{ badssl_host }}/" dest: "{{ output_dir }}/get_url_no_validate.html" validate_certs: no register: result - stat: path: "{{ output_dir }}/get_url_no_validate.html" register: stat_result - name: Assert that the file was downloaded assert: that: - result is changed - "stat_result.stat.exists == true" # SNI Tests # SNI is only built into the stdlib from python-2.7.9 onwards - name: Test that SNI works get_url: url: 'https://{{ sni_host }}/' dest: "{{ output_dir }}/sni.html" register: get_url_result ignore_errors: True - command: "grep '{{ sni_host }}' {{ output_dir}}/sni.html" register: data_result when: python_has_ssl_context - debug: var: get_url_result - name: Assert that SNI works with this python version assert: that: - 'data_result.rc == 0' when: python_has_ssl_context # If the client doesn't support SNI then get_url should have failed with a certificate mismatch - name: Assert that hostname verification failed because SNI is not supported on this version of python assert: that: - 'get_url_result is failed' when: not python_has_ssl_context # These tests are just side effects of how the site is hosted. It's not # specifically a test site. So the tests may break due to the hosting changing - name: Test that SNI works get_url: url: 'https://{{ sni_host }}/' dest: "{{ output_dir }}/sni.html" register: get_url_result ignore_errors: True - command: "grep '{{ sni_host }}' {{ output_dir}}/sni.html" register: data_result when: python_has_ssl_context - debug: var: get_url_result - name: Assert that SNI works with this python version assert: that: - 'data_result.rc == 0' - 'get_url_result is not failed' when: python_has_ssl_context # If the client doesn't support SNI then get_url should have failed with a certificate mismatch - name: Assert that hostname verification failed because SNI is not supported on this version of python assert: that: - 'get_url_result is failed' when: not python_has_ssl_context # End hacky SNI test section - name: Test get_url with redirect get_url: url: 'https://{{ httpbin_host }}/redirect/6' dest: "{{ output_dir }}/redirect.json" - name: Test that setting file modes work get_url: url: 'https://{{ httpbin_host }}/' dest: '{{ output_dir }}/test' mode: '0707' register: result - stat: path: "{{ output_dir }}/test" register: stat_result - name: Assert that the file has the right permissions assert: that: - result is changed - "stat_result.stat.mode == '0707'" - name: Test that setting file modes on an already downlaoded file work get_url: url: 'https://{{ httpbin_host }}/' dest: '{{ output_dir }}/test' mode: '0070' register: result - stat: path: "{{ output_dir }}/test" register: stat_result - name: Assert that the file has the right permissions assert: that: - result is changed - "stat_result.stat.mode == '0070'" # https://github.com/ansible/ansible/issues/29614 - name: Change mode on an already downloaded file and specify checksum get_url: url: 'https://{{ httpbin_host }}/' dest: '{{ output_dir }}/test' checksum: 'sha256:7036ede810fad2b5d2e7547ec703cae8da61edbba43c23f9d7203a0239b765c4.' mode: '0775' register: result - stat: path: "{{ output_dir }}/test" register: stat_result - name: Assert that file permissions on already downloaded file were changed assert: that: - result is changed - "stat_result.stat.mode == '0775'" #https://github.com/ansible/ansible/issues/16191 - name: Test url split with no filename get_url: url: https://{{ httpbin_host }} dest: "{{ output_dir }}" - name: Test headers string get_url: url: https://{{ httpbin_host }}/headers headers: Foo:bar,Baz:qux dest: "{{ output_dir }}/headers_string.json" - name: Test headers string assert: that: - (lookup('file', output_dir ~ '/headers_string.json')|from_json).headers.get('Foo') == 'bar' - (lookup('file', output_dir ~ '/headers_string.json')|from_json).headers.get('Baz') == 'qux' - name: Test headers string invalid format get_url: url: https://{{ httpbin_host }}/headers headers: Foo dest: "{{ output_dir }}/headers_string_invalid.json" register: invalid_string_headers failed_when: - invalid_string_headers is successful - invalid_string_headers.msg != "The string representation for the `headers` parameter requires a key:value,key:value syntax to be properly parsed." - name: Test headers dict get_url: url: https://{{ httpbin_host }}/headers headers: Foo: bar Baz: qux dest: "{{ output_dir }}/headers_dict.json" - name: Test headers dict assert: that: - (lookup('file', output_dir ~ '/headers_dict.json')|from_json).headers.get('Foo') == 'bar' - (lookup('file', output_dir ~ '/headers_dict.json')|from_json).headers.get('Baz') == 'qux' - name: Test client cert auth, with certs get_url: url: "https://ansible.http.tests/ssl_client_verify" client_cert: "{{ output_dir }}/client.pem" client_key: "{{ output_dir }}/client.key" dest: "{{ output_dir }}/ssl_client_verify" when: has_httptester - name: Assert that the ssl_client_verify file contains the correct content assert: that: - 'lookup("file", "{{ output_dir }}/ssl_client_verify") == "ansible.http.tests:SUCCESS"' when: has_httptester