summaryrefslogtreecommitdiffstats
path: root/test/integration/targets/prepare_http_tests
diff options
context:
space:
mode:
Diffstat (limited to 'test/integration/targets/prepare_http_tests')
-rw-r--r--test/integration/targets/prepare_http_tests/defaults/main.yml5
-rw-r--r--test/integration/targets/prepare_http_tests/handlers/main.yml4
-rw-r--r--test/integration/targets/prepare_http_tests/library/httptester_kinit.py138
-rw-r--r--test/integration/targets/prepare_http_tests/meta/main.yml3
-rw-r--r--test/integration/targets/prepare_http_tests/tasks/default.yml55
-rw-r--r--test/integration/targets/prepare_http_tests/tasks/kerberos.yml65
-rw-r--r--test/integration/targets/prepare_http_tests/tasks/main.yml35
-rw-r--r--test/integration/targets/prepare_http_tests/tasks/windows.yml33
-rw-r--r--test/integration/targets/prepare_http_tests/templates/krb5.conf.j225
-rw-r--r--test/integration/targets/prepare_http_tests/vars/Alpine.yml3
-rw-r--r--test/integration/targets/prepare_http_tests/vars/Debian.yml3
-rw-r--r--test/integration/targets/prepare_http_tests/vars/FreeBSD.yml2
-rw-r--r--test/integration/targets/prepare_http_tests/vars/RedHat-9.yml4
-rw-r--r--test/integration/targets/prepare_http_tests/vars/Suse.yml3
-rw-r--r--test/integration/targets/prepare_http_tests/vars/default.yml3
-rw-r--r--test/integration/targets/prepare_http_tests/vars/httptester.yml6
16 files changed, 387 insertions, 0 deletions
diff --git a/test/integration/targets/prepare_http_tests/defaults/main.yml b/test/integration/targets/prepare_http_tests/defaults/main.yml
new file mode 100644
index 0000000..217b3db
--- /dev/null
+++ b/test/integration/targets/prepare_http_tests/defaults/main.yml
@@ -0,0 +1,5 @@
+badssl_host: wrong.host.badssl.com
+self_signed_host: self-signed.ansible.http.tests
+httpbin_host: httpbin.org
+sni_host: ci-files.testing.ansible.com
+badssl_host_substring: wrong.host.badssl.com
diff --git a/test/integration/targets/prepare_http_tests/handlers/main.yml b/test/integration/targets/prepare_http_tests/handlers/main.yml
new file mode 100644
index 0000000..172cab7
--- /dev/null
+++ b/test/integration/targets/prepare_http_tests/handlers/main.yml
@@ -0,0 +1,4 @@
+- name: Remove python gssapi
+ pip:
+ name: gssapi
+ state: absent
diff --git a/test/integration/targets/prepare_http_tests/library/httptester_kinit.py b/test/integration/targets/prepare_http_tests/library/httptester_kinit.py
new file mode 100644
index 0000000..4f7b7ad
--- /dev/null
+++ b/test/integration/targets/prepare_http_tests/library/httptester_kinit.py
@@ -0,0 +1,138 @@
+#!/usr/bin/python
+
+# Copyright: (c) 2020, Ansible Project
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+DOCUMENTATION = r'''
+---
+module: httptester_kinit
+short_description: Get Kerberos ticket
+description: Get Kerberos ticket using kinit non-interactively.
+options:
+ username:
+ description: The username to get the ticket for.
+ required: true
+ type: str
+ password:
+ description: The password for I(username).
+ required; true
+ type: str
+author:
+- Ansible Project
+'''
+
+EXAMPLES = r'''
+#
+'''
+
+RETURN = r'''
+#
+'''
+
+import contextlib
+import errno
+import os
+import subprocess
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils.common.text.converters import to_bytes, to_text
+
+try:
+ import configparser
+except ImportError:
+ import ConfigParser as configparser
+
+
+@contextlib.contextmanager
+def env_path(name, value, default_value):
+ """ Adds a value to a PATH-like env var and preserve the existing value if present. """
+ orig_value = os.environ.get(name, None)
+ os.environ[name] = '%s:%s' % (value, orig_value or default_value)
+ try:
+ yield
+
+ finally:
+ if orig_value:
+ os.environ[name] = orig_value
+
+ else:
+ del os.environ[name]
+
+
+@contextlib.contextmanager
+def krb5_conf(module, config):
+ """ Runs with a custom krb5.conf file that extends the existing config if present. """
+ if config:
+ ini_config = configparser.ConfigParser()
+ for section, entries in config.items():
+ ini_config.add_section(section)
+ for key, value in entries.items():
+ ini_config.set(section, key, value)
+
+ config_path = os.path.join(module.tmpdir, 'krb5.conf')
+ with open(config_path, mode='wt') as config_fd:
+ ini_config.write(config_fd)
+
+ with env_path('KRB5_CONFIG', config_path, '/etc/krb5.conf'):
+ yield
+
+ else:
+ yield
+
+
+def main():
+ module_args = dict(
+ username=dict(type='str', required=True),
+ password=dict(type='str', required=True, no_log=True),
+ )
+ module = AnsibleModule(
+ argument_spec=module_args,
+ required_together=[('username', 'password')],
+ )
+
+ # Heimdal has a few quirks that we want to paper over in this module
+ # 1. KRB5_TRACE does not work in any released version (<=7.7), we need to use a custom krb5.config to enable it
+ # 2. When reading the password it reads from the pty not stdin by default causing an issue with subprocess. We
+ # can control that behaviour with '--password-file=STDIN'
+ # Also need to set the custom path to krb5-config and kinit as FreeBSD relies on the newer Heimdal version in the
+ # port package.
+ sysname = os.uname()[0]
+ prefix = '/usr/local/bin/' if sysname == 'FreeBSD' else ''
+ is_heimdal = sysname in ['Darwin', 'FreeBSD']
+
+ # Debugging purposes, get the Kerberos version. On platforms like OpenSUSE this may not be on the PATH.
+ try:
+ process = subprocess.Popen(['%skrb5-config' % prefix, '--version'], stdout=subprocess.PIPE)
+ stdout, stderr = process.communicate()
+ version = to_text(stdout)
+ except OSError as e:
+ if e.errno != errno.ENOENT:
+ raise
+ version = 'Unknown (no krb5-config)'
+
+ kinit_args = ['%skinit' % prefix]
+ config = {}
+ if is_heimdal:
+ kinit_args.append('--password-file=STDIN')
+ config['logging'] = {'krb5': 'FILE:/dev/stdout'}
+ kinit_args.append(to_text(module.params['username'], errors='surrogate_or_strict'))
+
+ with krb5_conf(module, config):
+ # Weirdly setting KRB5_CONFIG in the modules environment block does not work unless we pass it in explicitly.
+ # Take a copy of the existing environment to make sure the process has the same env vars as ours. Also set
+ # KRB5_TRACE to output and debug logs helping to identify problems when calling kinit with MIT.
+ kinit_env = os.environ.copy()
+ kinit_env['KRB5_TRACE'] = '/dev/stdout'
+
+ process = subprocess.Popen(kinit_args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
+ env=kinit_env)
+ stdout, stderr = process.communicate(to_bytes(module.params['password'], errors='surrogate_or_strict') + b'\n')
+ rc = process.returncode
+
+ module.exit_json(changed=True, stdout=to_text(stdout), stderr=to_text(stderr), rc=rc, version=version)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/test/integration/targets/prepare_http_tests/meta/main.yml b/test/integration/targets/prepare_http_tests/meta/main.yml
new file mode 100644
index 0000000..c2c543a
--- /dev/null
+++ b/test/integration/targets/prepare_http_tests/meta/main.yml
@@ -0,0 +1,3 @@
+dependencies:
+ - setup_remote_tmp_dir
+ - setup_remote_constraints
diff --git a/test/integration/targets/prepare_http_tests/tasks/default.yml b/test/integration/targets/prepare_http_tests/tasks/default.yml
new file mode 100644
index 0000000..2fb26a1
--- /dev/null
+++ b/test/integration/targets/prepare_http_tests/tasks/default.yml
@@ -0,0 +1,55 @@
+- name: RedHat - Enable the dynamic CA configuration feature
+ command: update-ca-trust force-enable
+ when: ansible_os_family == 'RedHat'
+
+- name: RedHat - Retrieve test cacert
+ get_url:
+ url: "http://ansible.http.tests/cacert.pem"
+ dest: "/etc/pki/ca-trust/source/anchors/ansible.pem"
+ when: ansible_os_family == 'RedHat'
+
+- name: Get client cert/key
+ get_url:
+ url: "http://ansible.http.tests/{{ item }}"
+ dest: "{{ remote_tmp_dir }}/{{ item }}"
+ with_items:
+ - client.pem
+ - client.key
+
+- name: Suse - Retrieve test cacert
+ get_url:
+ url: "http://ansible.http.tests/cacert.pem"
+ dest: "/etc/pki/trust/anchors/ansible.pem"
+ when: ansible_os_family == 'Suse'
+
+- name: Debian/Alpine - Retrieve test cacert
+ get_url:
+ url: "http://ansible.http.tests/cacert.pem"
+ dest: "/usr/local/share/ca-certificates/ansible.crt"
+ when: ansible_os_family in ['Debian', 'Alpine']
+
+- name: Redhat - Update ca trust
+ command: update-ca-trust extract
+ when: ansible_os_family == 'RedHat'
+
+- name: Debian/Alpine/Suse - Update ca certificates
+ command: update-ca-certificates
+ when: ansible_os_family in ['Debian', 'Alpine', 'Suse']
+
+- name: Update cacert
+ when: ansible_os_family in ['FreeBSD', 'Darwin']
+ block:
+ - name: Retrieve test cacert
+ uri:
+ url: "http://ansible.http.tests/cacert.pem"
+ return_content: true
+ register: cacert_pem
+
+ - name: Locate cacert
+ command: '{{ ansible_python_interpreter }} -c "import ssl; print(ssl.get_default_verify_paths().cafile)"'
+ register: cafile_path
+
+ - name: Update cacert
+ blockinfile:
+ path: "{{ cafile_path.stdout_lines|first }}"
+ block: "{{ cacert_pem.content }}"
diff --git a/test/integration/targets/prepare_http_tests/tasks/kerberos.yml b/test/integration/targets/prepare_http_tests/tasks/kerberos.yml
new file mode 100644
index 0000000..2678b46
--- /dev/null
+++ b/test/integration/targets/prepare_http_tests/tasks/kerberos.yml
@@ -0,0 +1,65 @@
+- set_fact:
+ krb5_config: '{{ remote_tmp_dir }}/krb5.conf'
+ krb5_realm: '{{ httpbin_host.split(".")[1:] | join(".") | upper }}'
+ krb5_provider: '{{ (ansible_facts.os_family == "FreeBSD" or ansible_facts.distribution == "MacOSX") | ternary("Heimdal", "MIT") }}'
+
+- set_fact:
+ krb5_username: admin@{{ krb5_realm }}
+
+- name: Create krb5.conf file
+ template:
+ src: krb5.conf.j2
+ dest: '{{ krb5_config }}'
+
+- name: Include distribution specific variables
+ include_vars: '{{ lookup("first_found", params) }}'
+ vars:
+ params:
+ files:
+ - '{{ ansible_facts.distribution }}-{{ ansible_facts.distribution_major_version }}.yml'
+ - '{{ ansible_facts.os_family }}-{{ ansible_facts.distribution_major_version }}.yml'
+ - '{{ ansible_facts.distribution }}.yml'
+ - '{{ ansible_facts.os_family }}.yml'
+ - default.yml
+ paths:
+ - '{{ role_path }}/vars'
+
+- name: Install Kerberos sytem packages
+ package:
+ name: '{{ krb5_packages }}'
+ state: present
+ when: ansible_facts.distribution not in ['Alpine', 'MacOSX']
+
+# apk isn't available on ansible-core so just call command
+- name: Alpine - Install Kerberos system packages
+ command: apk add {{ krb5_packages | join(' ') }}
+ when: ansible_facts.distribution == 'Alpine'
+
+- name: Install python gssapi
+ pip:
+ name:
+ - decorator < 5.0.0 ; python_version < '3.5' # decorator 5.0.5 and later require python 3.5 or later
+ - gssapi < 1.6.0 ; python_version <= '2.7' # gssapi 1.6.0 and later require python 3 or later
+ - gssapi ; python_version > '2.7'
+ - importlib ; python_version < '2.7'
+ state: present
+ extra_args: '-c {{ remote_constraints }}'
+ environment:
+ # Put /usr/local/bin for FreeBSD as we need to use the heimdal port over the builtin version
+ # https://github.com/pythongssapi/python-gssapi/issues/228
+ # Need the /usr/lib/mit/bin custom path for OpenSUSE as krb5-config is placed there
+ PATH: '/usr/local/bin:{{ ansible_facts.env.PATH }}:/usr/lib/mit/bin'
+ notify: Remove python gssapi
+
+- name: test the environment to make sure Kerberos is working properly
+ httptester_kinit:
+ username: '{{ krb5_username }}'
+ password: '{{ krb5_password }}'
+ environment:
+ KRB5_CONFIG: '{{ krb5_config }}'
+ KRB5CCNAME: FILE:{{ remote_tmp_dir }}/krb5.cc
+
+- name: remove test credential cache
+ file:
+ path: '{{ remote_tmp_dir }}/krb5.cc'
+ state: absent
diff --git a/test/integration/targets/prepare_http_tests/tasks/main.yml b/test/integration/targets/prepare_http_tests/tasks/main.yml
new file mode 100644
index 0000000..8d34a3c
--- /dev/null
+++ b/test/integration/targets/prepare_http_tests/tasks/main.yml
@@ -0,0 +1,35 @@
+# The docker --link functionality gives us an ENV var we can key off of to see if we have access to
+# the httptester container
+- set_fact:
+ has_httptester: "{{ lookup('env', 'HTTPTESTER') != '' }}"
+
+- name: make sure we have the ansible_os_family and ansible_distribution_version facts
+ setup:
+ gather_subset: distribution
+ when: ansible_facts == {}
+
+# If we are running with access to a httptester container, grab it's cacert and install it
+- block:
+ # Override hostname defaults with httptester linked names
+ - include_vars: httptester.yml
+
+ - include_tasks: "{{ lookup('first_found', files)}}"
+ vars:
+ files:
+ - "{{ ansible_os_family | lower }}-{{ ansible_distribution_major_version }}.yml"
+ - "{{ ansible_os_family | lower }}.yml"
+ - "default.yml"
+ when:
+ - has_httptester|bool
+ # skip the setup if running on Windows Server 2008 as httptester is not available
+ - ansible_os_family != 'Windows' or (ansible_os_family == 'Windows' and not ansible_distribution_version.startswith("6.0."))
+
+- set_fact:
+ krb5_password: "{{ lookup('env', 'KRB5_PASSWORD') }}"
+
+- name: setup Kerberos client
+ include_tasks: kerberos.yml
+ when:
+ - has_httptester|bool
+ - ansible_os_family != 'Windows'
+ - krb5_password != ''
diff --git a/test/integration/targets/prepare_http_tests/tasks/windows.yml b/test/integration/targets/prepare_http_tests/tasks/windows.yml
new file mode 100644
index 0000000..da8b0eb
--- /dev/null
+++ b/test/integration/targets/prepare_http_tests/tasks/windows.yml
@@ -0,0 +1,33 @@
+# Server 2008 R2 uses a 3rd party program to foward the ports and it may
+# not be ready straight away, we give it at least 5 minutes before
+# conceding defeat
+- name: Windows - make sure the port forwarder is active
+ win_wait_for:
+ host: ansible.http.tests
+ port: 80
+ state: started
+ timeout: 300
+
+- name: Windows - Get client cert/key
+ win_get_url:
+ url: http://ansible.http.tests/{{ item }}
+ dest: '{{ remote_tmp_dir }}\{{ item }}'
+ register: win_download
+ # Server 2008 R2 is slightly slower, we attempt 5 retries
+ retries: 5
+ until: win_download is successful
+ with_items:
+ - client.pem
+ - client.key
+
+- name: Windows - Retrieve test cacert
+ win_get_url:
+ url: http://ansible.http.tests/cacert.pem
+ dest: '{{ remote_tmp_dir }}\cacert.pem'
+
+- name: Windows - Update ca trust
+ win_certificate_store:
+ path: '{{ remote_tmp_dir }}\cacert.pem'
+ state: present
+ store_location: LocalMachine
+ store_name: Root
diff --git a/test/integration/targets/prepare_http_tests/templates/krb5.conf.j2 b/test/integration/targets/prepare_http_tests/templates/krb5.conf.j2
new file mode 100644
index 0000000..3ddfe5e
--- /dev/null
+++ b/test/integration/targets/prepare_http_tests/templates/krb5.conf.j2
@@ -0,0 +1,25 @@
+[libdefaults]
+ default_realm = {{ krb5_realm | upper }}
+ dns_lookup_realm = false
+ dns_lookup_kdc = false
+ rdns = false
+
+[realms]
+ {{ krb5_realm | upper }} = {
+{% if krb5_provider == 'Heimdal' %}
+{# Heimdal seems to only use UDP unless TCP is explicitly set and we must use TCP as the SSH tunnel only supports TCP. #}
+{# The hostname doesn't seem to work when using the alias, just use localhost as that works. #}
+ kdc = tcp/127.0.0.1
+ admin_server = tcp/127.0.0.1
+{% else %}
+ kdc = {{ httpbin_host }}
+ admin_server = {{ httpbin_host }}
+{% endif %}
+ }
+
+[domain_realm]
+ .{{ krb5_realm | lower }} = {{ krb5_realm | upper }}
+ {{ krb5_realm | lower }} = {{ krb5_realm | upper }}
+
+[logging]
+ krb5 = FILE:/dev/stdout
diff --git a/test/integration/targets/prepare_http_tests/vars/Alpine.yml b/test/integration/targets/prepare_http_tests/vars/Alpine.yml
new file mode 100644
index 0000000..2ac6a38
--- /dev/null
+++ b/test/integration/targets/prepare_http_tests/vars/Alpine.yml
@@ -0,0 +1,3 @@
+krb5_packages:
+- krb5
+- krb5-dev
diff --git a/test/integration/targets/prepare_http_tests/vars/Debian.yml b/test/integration/targets/prepare_http_tests/vars/Debian.yml
new file mode 100644
index 0000000..2b6f9b8
--- /dev/null
+++ b/test/integration/targets/prepare_http_tests/vars/Debian.yml
@@ -0,0 +1,3 @@
+krb5_packages:
+- krb5-user
+- libkrb5-dev
diff --git a/test/integration/targets/prepare_http_tests/vars/FreeBSD.yml b/test/integration/targets/prepare_http_tests/vars/FreeBSD.yml
new file mode 100644
index 0000000..752b536
--- /dev/null
+++ b/test/integration/targets/prepare_http_tests/vars/FreeBSD.yml
@@ -0,0 +1,2 @@
+krb5_packages:
+- heimdal
diff --git a/test/integration/targets/prepare_http_tests/vars/RedHat-9.yml b/test/integration/targets/prepare_http_tests/vars/RedHat-9.yml
new file mode 100644
index 0000000..2618233
--- /dev/null
+++ b/test/integration/targets/prepare_http_tests/vars/RedHat-9.yml
@@ -0,0 +1,4 @@
+krb5_packages:
+- krb5-devel
+- krb5-workstation
+- redhat-rpm-config # needed for gssapi install
diff --git a/test/integration/targets/prepare_http_tests/vars/Suse.yml b/test/integration/targets/prepare_http_tests/vars/Suse.yml
new file mode 100644
index 0000000..0e159c4
--- /dev/null
+++ b/test/integration/targets/prepare_http_tests/vars/Suse.yml
@@ -0,0 +1,3 @@
+krb5_packages:
+- krb5-client
+- krb5-devel
diff --git a/test/integration/targets/prepare_http_tests/vars/default.yml b/test/integration/targets/prepare_http_tests/vars/default.yml
new file mode 100644
index 0000000..5bc07d5
--- /dev/null
+++ b/test/integration/targets/prepare_http_tests/vars/default.yml
@@ -0,0 +1,3 @@
+krb5_packages:
+- krb5-devel
+- krb5-workstation
diff --git a/test/integration/targets/prepare_http_tests/vars/httptester.yml b/test/integration/targets/prepare_http_tests/vars/httptester.yml
new file mode 100644
index 0000000..26acf11
--- /dev/null
+++ b/test/integration/targets/prepare_http_tests/vars/httptester.yml
@@ -0,0 +1,6 @@
+# these are fake hostnames provided by docker link for the httptester container
+badssl_host: fail.ansible.http.tests
+httpbin_host: ansible.http.tests
+sni_host: sni1.ansible.http.tests
+badssl_host_substring: HTTP Client Testing Service
+self_signed_host: self-signed.ansible.http.tests