From be4be926c4c89d208dd7ca4b01778967e6e017ff Mon Sep 17 00:00:00 2001 From: Rick Elrod Date: Mon, 27 Jul 2020 13:18:54 -0500 Subject: [PATCH] subversion Give subversion module a validate_certs option (#70890) * Give subversion module a validate_certs option Change: - Add `validate_certs` option to subversion module. Defaults to off for backwards compatibility. Tickets: - Fixes #22599 Signed-off-by: Rick Elrod * Update changelogs/fragments/22599_svn_validate_certs.yml Co-authored-by: Abhijeet Kasurde * test verify_certs codepaths Signed-off-by: Rick Elrod Co-authored-by: Abhijeet Kasurde --- .../fragments/22599_svn_validate_certs.yml | 2 ++ lib/ansible/modules/subversion.py | 17 ++++++++++++++--- .../roles/subversion/defaults/main.yml | 1 + .../subversion/roles/subversion/tasks/tests.yml | 12 ++++++++++++ 4 files changed, 29 insertions(+), 3 deletions(-) create mode 100644 changelogs/fragments/22599_svn_validate_certs.yml diff --git a/changelogs/fragments/22599_svn_validate_certs.yml b/changelogs/fragments/22599_svn_validate_certs.yml new file mode 100644 index 00000000000..fc4bf8400b0 --- /dev/null +++ b/changelogs/fragments/22599_svn_validate_certs.yml @@ -0,0 +1,2 @@ +minor_changes: + - subversion - ``validate_certs`` option, which, when true, will avoid passing ``--trust-server-cert`` to ``svn`` commands (https://github.com/ansible/ansible/issues/22599). diff --git a/lib/ansible/modules/subversion.py b/lib/ansible/modules/subversion.py index 730d26f0571..34218705bd1 100644 --- a/lib/ansible/modules/subversion.py +++ b/lib/ansible/modules/subversion.py @@ -85,6 +85,13 @@ options: default: "yes" version_added: "2.0" type: bool + validate_certs: + description: + - If C(no), passes the C(--trust-server-cert) flag to svn. + - If C(yes), does not pass the flag. + default: "no" + version_added: "2.11" + type: bool requirements: - subversion (the command line tool with C(svn) entrypoint) @@ -119,7 +126,7 @@ from ansible.module_utils.basic import AnsibleModule class Subversion(object): - def __init__(self, module, dest, repo, revision, username, password, svn_path): + def __init__(self, module, dest, repo, revision, username, password, svn_path, validate_certs): self.module = module self.dest = dest self.repo = repo @@ -127,6 +134,7 @@ class Subversion(object): self.username = username self.password = password self.svn_path = svn_path + self.validate_certs = validate_certs def has_option_password_from_stdin(self): rc, version, err = self.module.run_command([self.svn_path, '--version', '--quiet'], check_rc=True) @@ -137,9 +145,10 @@ class Subversion(object): bits = [ self.svn_path, '--non-interactive', - '--trust-server-cert', '--no-auth-cache', ] + if not self.validate_certs: + bits.append('--trust-server-cert') stdin_data = None if self.username: bits.extend(["--username", self.username]) @@ -257,6 +266,7 @@ def main(): update=dict(type='bool', default=True), switch=dict(type='bool', default=True), in_place=dict(type='bool', default=False), + validate_certs=dict(type='bool', default=False), ), supports_check_mode=True, ) @@ -273,6 +283,7 @@ def main(): checkout = module.params['checkout'] update = module.params['update'] in_place = module.params['in_place'] + validate_certs = module.params['validate_certs'] # We screenscrape a huge amount of svn commands so use C locale anytime we # call run_command() @@ -281,7 +292,7 @@ def main(): if not dest and (checkout or update or export): module.fail_json(msg="the destination directory must be specified unless checkout=no, update=no, and export=no") - svn = Subversion(module, dest, repo, revision, username, password, svn_path) + svn = Subversion(module, dest, repo, revision, username, password, svn_path, validate_certs) if not export and not update and not checkout: module.exit_json(changed=False, after=svn.get_remote_revision()) diff --git a/test/integration/targets/subversion/roles/subversion/defaults/main.yml b/test/integration/targets/subversion/roles/subversion/defaults/main.yml index af5ea0263ca..f989345a662 100644 --- a/test/integration/targets/subversion/roles/subversion/defaults/main.yml +++ b/test/integration/targets/subversion/roles/subversion/defaults/main.yml @@ -8,3 +8,4 @@ subversion_repo_url: http://127.0.0.1:{{ apache_port }}/svn/{{ subversion_repo_n subversion_repo_auth_url: http://127.0.0.1:{{ apache_port }}/svnauth/{{ subversion_repo_name }} subversion_username: subsvn_user''' subversion_password: Password123! +subversion_external_repo_url: https://github.com/ansible/ansible-base-test-container # GitHub serves SVN diff --git a/test/integration/targets/subversion/roles/subversion/tasks/tests.yml b/test/integration/targets/subversion/roles/subversion/tasks/tests.yml index 8421f9deca8..b8f85d95c7e 100644 --- a/test/integration/targets/subversion/roles/subversion/tasks/tests.yml +++ b/test/integration/targets/subversion/roles/subversion/tasks/tests.yml @@ -130,4 +130,16 @@ - "export_branches.stat.isdir" - "subverted4.changed" +- name: clone a small external repo with validate_certs=true + subversion: + repo: "{{ subversion_external_repo_url }}" + dest: "{{ subversion_test_dir }}/svn-external1" + validate_certs: yes + +- name: clone a small external repo with validate_certs=false + subversion: + repo: "{{ subversion_external_repo_url }}" + dest: "{{ subversion_test_dir }}/svn-external2" + validate_certs: no + # TBA: test for additional options or URL variants welcome