1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2024-09-14 20:13:21 +02:00

Update java_cert module (#2008) (#2199)

* porting https://github.com/ansible/ansible/pull/56778 as requested in https://github.com/ansible-collections/community.general/issues/821

* fix imports, add back trust_cacerts option

* try to fix import, ansible-lint fixes

* modify import to use ansible.module_utils.six instead

* cleanup indentation for tests/integration/targets/java_cert/tasks/main.yml file

* remove external crypto dependency - switch to openssl, work on password obfuscation, using files compare to reduce logic

* java_cert - remove latest run_command using password in arguments

* fix sanity check

* rename changelog fragment file - wrong extension

* add openssl dependency

* fix openssl_bin parameter missing on _get_digest_from_x509_file function call

* remove useless close files, fix paragraph, fix changelog, clean import re

* fix missing dots at end-of-line in changelogs fragments

* fix reminder case

* fix changelog

* restore .gitignore

* fix indentation on integration test files, delete useless json file

* fix typo importing tasks in tests/integration/targets/java_cert/tasks/main.yml

* Update changelogs/fragments/2008-update-java-cert-replace-cert-when-changed.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update tests/integration/targets/java_cert/tasks/state_change.yml

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/modules/system/java_cert.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/modules/system/java_cert.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/modules/system/java_cert.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/modules/system/java_cert.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/modules/system/java_cert.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/modules/system/java_cert.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/modules/system/java_cert.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* fix hardcoded executable keytool, use re.sub instead of import, add required cert_url or cert_alias parameter when absent, fix python script and cert_url test

* fix pylint issue with setupSSLServeR.py

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 40ce0f995b)

Co-authored-by: absynth76 <58172580+absynth76@users.noreply.github.com>
This commit is contained in:
patchback[bot] 2021-04-07 20:41:58 +02:00 committed by GitHub
parent 809cdda9ef
commit 19a87874f7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 496 additions and 111 deletions

View file

@ -0,0 +1,7 @@
minor_changes:
- "java_cert - change ``state: present`` to check certificates by hash, not just alias name (https://github.com/ansible/ansible/issues/43249)."
bugfixes:
- "java_cert - allow setting ``state: absent`` by providing just the ``cert_alias`` (https://github.com/ansible/ansible/issues/27982)."
- "java_cert - properly handle proxy arguments when the scheme is provided (https://github.com/ansible/ansible/issues/54481)."
security_fixes:
- "java_cert - remove password from ``run_command`` arguments (https://github.com/ansible-collections/community.general/pull/2008)."

View file

@ -10,6 +10,7 @@ __metaclass__ = type
DOCUMENTATION = r''' DOCUMENTATION = r'''
--- ---
module: java_cert module: java_cert
short_description: Uses keytool to import/remove key from java keystore (cacerts) short_description: Uses keytool to import/remove key from java keystore (cacerts)
description: description:
- This is a wrapper module around keytool, which can be used to import/remove - This is a wrapper module around keytool, which can be used to import/remove
@ -81,9 +82,12 @@ options:
state: state:
description: description:
- Defines action which can be either certificate import or removal. - Defines action which can be either certificate import or removal.
- When state is present, the certificate will always idempotently be inserted
into the keystore, even if there already exists a cert alias that is different.
type: str type: str
choices: [ absent, present ] choices: [ absent, present ]
default: present default: present
requirements: [openssl, keytool]
author: author:
- Adam Hamsik (@haad) - Adam Hamsik (@haad)
''' '''
@ -166,41 +170,143 @@ cmd:
''' '''
import os import os
import tempfile
import random
import string
import re import re
# import module snippets # import module snippets
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.six.moves.urllib.parse import urlparse
from ansible.module_utils.six.moves.urllib.request import getproxies
def get_keystore_type(keystore_type): def _get_keystore_type_keytool_parameters(keystore_type):
''' Check that custom keystore is presented in parameters ''' ''' Check that custom keystore is presented in parameters '''
if keystore_type: if keystore_type:
return " -storetype '%s'" % keystore_type return ["-storetype", keystore_type]
return '' return []
def check_cert_present(module, executable, keystore_path, keystore_pass, alias, keystore_type): def _check_cert_present(module, executable, keystore_path, keystore_pass, alias, keystore_type):
''' Check if certificate with alias is present in keystore ''' Check if certificate with alias is present in keystore
located at keystore_path ''' located at keystore_path '''
test_cmd = ("%s -noprompt -list -keystore '%s' -storepass '%s' " test_cmd = [
"-alias '%s' %s") % (executable, keystore_path, keystore_pass, alias, get_keystore_type(keystore_type)) executable,
"-list",
"-keystore",
keystore_path,
"-alias",
alias,
"-rfc"
]
test_cmd += _get_keystore_type_keytool_parameters(keystore_type)
check_rc, dummy, dummy = module.run_command(test_cmd) (check_rc, stdout, dummy) = module.run_command(test_cmd, data=keystore_pass, check_rc=False)
if check_rc == 0: if check_rc == 0:
return True return (True, stdout)
return False return (False, '')
def import_cert_url(module, executable, url, port, keystore_path, keystore_pass, alias, keystore_type, trust_cacert): def _get_certificate_from_url(module, executable, url, port, pem_certificate_output):
''' Import certificate from URL into keystore located at keystore_path ''' remote_cert_pem_chain = _download_cert_url(module, executable, url, port)
with open(pem_certificate_output, 'w') as f:
f.write(remote_cert_pem_chain)
https_proxy = os.getenv("https_proxy")
def _get_first_certificate_from_x509_file(module, pem_certificate_file, pem_certificate_output, openssl_bin):
""" Read a X509 certificate chain file and output the first certificate in the list """
extract_cmd = [
openssl_bin,
"x509",
"-in",
pem_certificate_file,
"-out",
pem_certificate_output
]
(extract_rc, dummy, extract_stderr) = module.run_command(extract_cmd, check_rc=False)
if extract_rc != 0:
# trying der encoded file
extract_cmd += ["-inform", "der"]
(extract_rc, dummy, extract_stderr) = module.run_command(extract_cmd, check_rc=False)
if extract_rc != 0:
# this time it's a real failure
module.fail_json(msg="Internal module failure, cannot extract certificate, error: %s" % extract_stderr,
rc=extract_rc, cmd=extract_cmd)
return extract_rc
def _get_digest_from_x509_file(module, pem_certificate_file, openssl_bin):
""" Read a X509 certificate file and output sha256 digest using openssl """
# cleanup file before to compare
(dummy, tmp_certificate) = tempfile.mkstemp()
module.add_cleanup_file(tmp_certificate)
_get_first_certificate_from_x509_file(module, pem_certificate_file, tmp_certificate, openssl_bin)
dgst_cmd = [
openssl_bin,
"dgst",
"-r",
"-sha256",
tmp_certificate
]
(dgst_rc, dgst_stdout, dgst_stderr) = module.run_command(dgst_cmd, check_rc=False)
if dgst_rc != 0:
module.fail_json(msg="Internal module failure, cannot compute digest for certificate, error: %s" % dgst_stderr,
rc=dgst_rc, cmd=dgst_cmd)
return dgst_stdout.split(' ')[0]
def _export_public_cert_from_pkcs12(module, executable, pkcs_file, alias, password, dest):
""" Runs keytools to extract the public cert from a PKCS12 archive and write it to a file. """
export_cmd = [
executable,
"-list",
"-keystore",
pkcs_file,
"-alias",
alias,
"-storetype",
"pkcs12",
"-rfc"
]
(export_rc, export_stdout, export_err) = module.run_command(export_cmd, data=password, check_rc=False)
if export_rc != 0:
module.fail_json(msg="Internal module failure, cannot extract public certificate from pkcs12, error: %s" % export_err,
rc=export_rc)
with open(dest, 'w') as f:
f.write(export_stdout)
def get_proxy_settings(scheme='https'):
""" Returns a tuple containing (proxy_host, proxy_port). (False, False) if no proxy is found """
proxy_url = getproxies().get(scheme, '')
if not proxy_url:
return (False, False)
else:
parsed_url = urlparse(proxy_url)
if parsed_url.scheme:
(proxy_host, proxy_port) = parsed_url.netloc.split(':')
else:
(proxy_host, proxy_port) = parsed_url.path.split(':')
return (proxy_host, proxy_port)
def build_proxy_options():
""" Returns list of valid proxy options for keytool """
(proxy_host, proxy_port) = get_proxy_settings()
no_proxy = os.getenv("no_proxy") no_proxy = os.getenv("no_proxy")
proxy_opts = '' proxy_opts = []
if https_proxy is not None: if proxy_host:
(proxy_host, proxy_port) = https_proxy.split(':') proxy_opts.extend(["-J-Dhttps.proxyHost=%s" % proxy_host, "-J-Dhttps.proxyPort=%s" % proxy_port])
proxy_opts = "-J-Dhttps.proxyHost=%s -J-Dhttps.proxyPort=%s" % (proxy_host, proxy_port)
if no_proxy is not None: if no_proxy is not None:
# For Java's nonProxyHosts property, items are separated by '|', # For Java's nonProxyHosts property, items are separated by '|',
@ -210,46 +316,48 @@ def import_cert_url(module, executable, url, port, keystore_path, keystore_pass,
# The property name is http.nonProxyHosts, there is no # The property name is http.nonProxyHosts, there is no
# separate setting for HTTPS. # separate setting for HTTPS.
proxy_opts += " -J-Dhttp.nonProxyHosts='%s'" % non_proxy_hosts proxy_opts.extend(["-J-Dhttp.nonProxyHosts=%s" % non_proxy_hosts])
return proxy_opts
fetch_cmd = "%s -printcert -rfc -sslserver %s %s:%d" % (executable, proxy_opts, url, port)
import_cmd = ("%s -importcert -noprompt -keystore '%s' " def _download_cert_url(module, executable, url, port):
"-storepass '%s' -alias '%s' %s") % (executable, keystore_path, """ Fetches the certificate from the remote URL using `keytool -printcert...`
keystore_pass, alias, The PEM formatted string is returned """
get_keystore_type(keystore_type)) proxy_opts = build_proxy_options()
if trust_cacert: fetch_cmd = [executable, "-printcert", "-rfc", "-sslserver"] + proxy_opts + ["%s:%d" % (url, port)]
import_cmd = import_cmd + " -trustcacerts"
# Fetch SSL certificate from remote host. # Fetch SSL certificate from remote host.
dummy, fetch_out, dummy = module.run_command(fetch_cmd, check_rc=True) (fetch_rc, fetch_out, fetch_err) = module.run_command(fetch_cmd, check_rc=False)
# Use remote certificate from remote host and import it to a java keystore if fetch_rc != 0:
(import_rc, import_out, import_err) = module.run_command(import_cmd, module.fail_json(msg="Internal module failure, cannot download certificate, error: %s" % fetch_err,
data=fetch_out, rc=fetch_rc, cmd=fetch_cmd)
check_rc=False)
diff = {'before': '\n', 'after': '%s\n' % alias} return fetch_out
if import_rc == 0:
module.exit_json(changed=True, msg=import_out,
rc=import_rc, cmd=import_cmd, stdout=import_out,
diff=diff)
else:
module.fail_json(msg=import_out, rc=import_rc, cmd=import_cmd,
error=import_err)
def import_cert_path(module, executable, path, keystore_path, keystore_pass, alias, keystore_type, trust_cacert): def import_cert_path(module, executable, path, keystore_path, keystore_pass, alias, keystore_type, trust_cacert):
''' Import certificate from path into keystore located on ''' Import certificate from path into keystore located on
keystore_path as alias ''' keystore_path as alias '''
import_cmd = ("%s -importcert -noprompt -keystore '%s' " import_cmd = [
"-storepass '%s' -file '%s' -alias '%s' %s") % (executable, keystore_path, executable,
keystore_pass, path, alias, "-importcert",
get_keystore_type(keystore_type)) "-noprompt",
"-keystore",
keystore_path,
"-file",
path,
"-alias",
alias
]
import_cmd += _get_keystore_type_keytool_parameters(keystore_type)
if trust_cacert: if trust_cacert:
import_cmd = import_cmd + " -trustcacerts" import_cmd.extend(["-trustcacerts"])
# Use local certificate from local path and import it to a java keystore # Use local certificate from local path and import it to a java keystore
(import_rc, import_out, import_err) = module.run_command(import_cmd, (import_rc, import_out, import_err) = module.run_command(import_cmd,
data="%s\n%s" % (keystore_pass, keystore_pass),
check_rc=False) check_rc=False)
diff = {'before': '\n', 'after': '%s\n' % alias} diff = {'before': '\n', 'after': '%s\n' % alias}
@ -261,41 +369,29 @@ def import_cert_path(module, executable, path, keystore_path, keystore_pass, ali
module.fail_json(msg=import_out, rc=import_rc, cmd=import_cmd) module.fail_json(msg=import_out, rc=import_rc, cmd=import_cmd)
def import_pkcs12_path(module, executable, path, keystore_path, keystore_pass, pkcs12_pass, pkcs12_alias, alias, keystore_type): def delete_cert(module, executable, keystore_path, keystore_pass, alias, keystore_type, exit_after=True):
''' Import pkcs12 from path into keystore located on
keystore_path as alias '''
import_cmd = ("%s -importkeystore -noprompt -destkeystore '%s' -srcstoretype PKCS12 "
"-deststorepass '%s' -destkeypass '%s' -srckeystore '%s' -srcstorepass '%s' "
"-srcalias '%s' -destalias '%s' %s") % (executable, keystore_path, keystore_pass,
keystore_pass, path, pkcs12_pass, pkcs12_alias,
alias, get_keystore_type(keystore_type))
# Use local certificate from local path and import it to a java keystore
(import_rc, import_out, import_err) = module.run_command(import_cmd,
check_rc=False)
diff = {'before': '\n', 'after': '%s\n' % alias}
if import_rc == 0:
module.exit_json(changed=True, msg=import_out,
rc=import_rc, cmd=import_cmd, stdout=import_out,
error=import_err, diff=diff)
else:
module.fail_json(msg=import_out, rc=import_rc, cmd=import_cmd)
def delete_cert(module, executable, keystore_path, keystore_pass, alias, keystore_type):
''' Delete certificate identified with alias from keystore on keystore_path ''' ''' Delete certificate identified with alias from keystore on keystore_path '''
del_cmd = ("%s -delete -keystore '%s' -storepass '%s' " del_cmd = [
"-alias '%s' %s") % (executable, keystore_path, keystore_pass, alias, get_keystore_type(keystore_type)) executable,
"-delete",
"-noprompt",
"-keystore",
keystore_path,
"-alias",
alias
]
del_cmd += _get_keystore_type_keytool_parameters(keystore_type)
# Delete SSL certificate from keystore # Delete SSL certificate from keystore
(del_rc, del_out, del_err) = module.run_command(del_cmd, check_rc=True) (del_rc, del_out, del_err) = module.run_command(del_cmd, data=keystore_pass, check_rc=True)
diff = {'before': '%s\n' % alias, 'after': None} if exit_after:
diff = {'before': '%s\n' % alias, 'after': None}
module.exit_json(changed=True, msg=del_out, module.exit_json(changed=True, msg=del_out,
rc=del_rc, cmd=del_cmd, stdout=del_out, rc=del_rc, cmd=del_cmd, stdout=del_out,
error=del_err, diff=diff) error=del_err, diff=diff)
def test_keytool(module, executable): def test_keytool(module, executable):
@ -333,7 +429,8 @@ def main():
module = AnsibleModule( module = AnsibleModule(
argument_spec=argument_spec, argument_spec=argument_spec,
required_one_of=[['cert_path', 'cert_url', 'pkcs12_path']], required_if=[['state', 'present', ('cert_path', 'cert_url', 'pkcs12_path'), True],
['state', 'absent', ('cert_url', 'cert_alias'), True]],
required_together=[['keystore_path', 'keystore_pass']], required_together=[['keystore_path', 'keystore_pass']],
mutually_exclusive=[ mutually_exclusive=[
['cert_url', 'cert_path', 'pkcs12_path'] ['cert_url', 'cert_path', 'pkcs12_path']
@ -359,6 +456,9 @@ def main():
executable = module.params.get('executable') executable = module.params.get('executable')
state = module.params.get('state') state = module.params.get('state')
# openssl dependency resolution
openssl_bin = module.get_bin_path('openssl', True)
if path and not cert_alias: if path and not cert_alias:
module.fail_json(changed=False, module.fail_json(changed=False,
msg="Using local path import from %s requires alias argument." msg="Using local path import from %s requires alias argument."
@ -369,31 +469,62 @@ def main():
if not keystore_create: if not keystore_create:
test_keystore(module, keystore_path) test_keystore(module, keystore_path)
cert_present = check_cert_present(module, executable, keystore_path, alias_exists, alias_exists_output = _check_cert_present(
keystore_pass, cert_alias, keystore_type) module, executable, keystore_path, keystore_pass, cert_alias, keystore_type)
if state == 'absent' and cert_present: (dummy, new_certificate) = tempfile.mkstemp()
(dummy, old_certificate) = tempfile.mkstemp()
module.add_cleanup_file(new_certificate)
module.add_cleanup_file(old_certificate)
if state == 'absent' and alias_exists:
if module.check_mode: if module.check_mode:
module.exit_json(changed=True) module.exit_json(changed=True)
# delete and exit
delete_cert(module, executable, keystore_path, keystore_pass, cert_alias, keystore_type) delete_cert(module, executable, keystore_path, keystore_pass, cert_alias, keystore_type)
elif state == 'present' and not cert_present: # dump certificate to enroll in the keystore on disk and compute digest
if module.check_mode: if state == 'present':
module.exit_json(changed=True) # The alias exists in the keystore so we must now compare the SHA256 hash of the
# public certificate already in the keystore, and the certificate we are wanting to add
if alias_exists:
with open(old_certificate, "w") as f:
f.write(alias_exists_output)
keystore_cert_digest = _get_digest_from_x509_file(module, old_certificate, openssl_bin)
else:
keystore_cert_digest = ''
if pkcs12_path: if pkcs12_path:
import_pkcs12_path(module, executable, pkcs12_path, keystore_path, # Extracting certificate with openssl
keystore_pass, pkcs12_pass, pkcs12_alias, cert_alias, keystore_type) _export_public_cert_from_pkcs12(module, executable, pkcs12_path, cert_alias, pkcs12_pass, new_certificate)
if path: elif path:
import_cert_path(module, executable, path, keystore_path, # Extracting the X509 digest is a bit easier. Keytool will print the PEM
# certificate to stdout so we don't need to do any transformations.
new_certificate = path
elif url:
# Getting the X509 digest from a URL is the same as from a path, we just have
# to download the cert first
_get_certificate_from_url(module, executable, url, port, new_certificate)
new_cert_digest = _get_digest_from_x509_file(module, new_certificate, openssl_bin)
if keystore_cert_digest != new_cert_digest:
if module.check_mode:
module.exit_json(changed=True)
if alias_exists:
# The certificate in the keystore does not match with the one we want to be present
# The existing certificate must first be deleted before we insert the correct one
delete_cert(module, executable, keystore_path, keystore_pass, cert_alias, keystore_type, exit_after=False)
import_cert_path(module, executable, new_certificate, keystore_path,
keystore_pass, cert_alias, keystore_type, trust_cacert) keystore_pass, cert_alias, keystore_type, trust_cacert)
if url:
import_cert_url(module, executable, url, port, keystore_path,
keystore_pass, cert_alias, keystore_type, trust_cacert)
module.exit_json(changed=False) module.exit_json(changed=False)

View file

@ -1,3 +1,13 @@
--- ---
test_pkcs12_path: testpkcs.p12 test_pkcs12_path: testpkcs.p12
test_keystore_path: keystore.jks test_keystore_path: keystore.jks
test_keystore2_path: "{{ output_dir }}/keystore2.jks"
test_keystore2_password: changeit
test_cert_path: "{{ output_dir }}/cert.pem"
test_key_path: "{{ output_dir }}/key.pem"
test_cert2_path: "{{ output_dir }}/cert2.pem"
test_key2_path: "{{ output_dir }}/key2.pem"
test_pkcs_path: "{{ output_dir }}/cert.p12"
test_pkcs2_path: "{{ output_dir }}/cert2.p12"
test_ssl: setupSSLServer.py
test_ssl_port: 21500

View file

@ -0,0 +1,20 @@
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import ssl
import os
import sys
root_dir = sys.argv[1]
port = int(sys.argv[2])
try:
from BaseHTTPServer import HTTPServer
from SimpleHTTPServer import SimpleHTTPRequestHandler
except ModuleNotFoundError:
from http.server import HTTPServer, SimpleHTTPRequestHandler
httpd = HTTPServer(('localhost', port), SimpleHTTPRequestHandler)
httpd.socket = ssl.wrap_socket(httpd.socket, server_side=True,
certfile=os.path.join(root_dir, 'cert.pem'),
keyfile=os.path.join(root_dir, 'key.pem'))
httpd.handle_request()

View file

@ -1,2 +1,3 @@
dependencies: dependencies:
- setup_java_keytool - setup_java_keytool
- setup_openssl

View file

@ -11,15 +11,16 @@
- name: import pkcs12 - name: import pkcs12
java_cert: java_cert:
pkcs12_path: "{{output_dir}}/{{ test_pkcs12_path }}" pkcs12_path: "{{output_dir}}/{{ test_pkcs12_path }}"
pkcs12_password: changeit pkcs12_password: changeit
pkcs12_alias: default pkcs12_alias: default
cert_alias: default cert_alias: default
keystore_path: "{{output_dir}}/{{ test_keystore_path }}" keystore_path: "{{output_dir}}/{{ test_keystore_path }}"
keystore_pass: changeme_keystore keystore_pass: changeme_keystore
keystore_create: yes keystore_create: yes
state: present state: present
register: result_success register: result_success
- name: verify success - name: verify success
assert: assert:
that: that:
@ -27,14 +28,14 @@
- name: import pkcs12 with wrong password - name: import pkcs12 with wrong password
java_cert: java_cert:
pkcs12_path: "{{output_dir}}/{{ test_pkcs12_path }}" pkcs12_path: "{{output_dir}}/{{ test_pkcs12_path }}"
pkcs12_password: wrong_pass pkcs12_password: wrong_pass
pkcs12_alias: default pkcs12_alias: default
cert_alias: default_new cert_alias: default_new
keystore_path: "{{output_dir}}/{{ test_keystore_path }}" keystore_path: "{{output_dir}}/{{ test_keystore_path }}"
keystore_pass: changeme_keystore keystore_pass: changeme_keystore
keystore_create: yes keystore_create: yes
state: present state: present
ignore_errors: true ignore_errors: true
register: result_wrong_pass register: result_wrong_pass
@ -45,16 +46,62 @@
- name: test fail on mutually exclusive params - name: test fail on mutually exclusive params
java_cert: java_cert:
cert_path: ca.crt cert_path: ca.crt
pkcs12_path: "{{output_dir}}/{{ test_pkcs12_path }}" pkcs12_path: "{{output_dir}}/{{ test_pkcs12_path }}"
cert_alias: default cert_alias: default
keystore_path: "{{output_dir}}/{{ test_keystore_path }}" keystore_path: "{{output_dir}}/{{ test_keystore_path }}"
keystore_pass: changeme_keystore keystore_pass: changeme_keystore
keystore_create: yes keystore_create: yes
state: present state: present
ignore_errors: true ignore_errors: true
register: result_excl_params register: result_excl_params
- name: verify failed exclusive params - name: verify failed exclusive params
assert: assert:
that: that:
- result_excl_params is failed - result_excl_params is failed
- name: test fail on missing required params
java_cert:
keystore_path: "{{output_dir}}/{{ test_keystore_path }}"
keystore_pass: changeme_keystore
state: absent
ignore_errors: true
register: result_missing_required_param
- name: verify failed missing required params
assert:
that:
- result_missing_required_param is failed
- name: delete object based on cert_alias parameter
java_cert:
keystore_path: "{{output_dir}}/{{ test_keystore_path }}"
keystore_pass: changeme_keystore
cert_alias: default
state: absent
ignore_errors: true
register: result_alias_deleted
- name: verify object successfully deleted
assert:
that:
- result_alias_deleted is successful
- name: include extended test suite
import_tasks: state_change.yml
- name: cleanup environment
file:
path: "{{ item }}"
state: absent
loop:
- "{{ output_dir }}/{{ test_pkcs12_path }}"
- "{{ output_dir }}/{{ test_keystore_path }}"
- "{{ test_keystore2_path }}"
- "{{ test_cert_path }}"
- "{{ test_key_path }}"
- "{{ test_cert2_path }}"
- "{{ test_key2_path }}"
- "{{ test_pkcs_path }}"
- "{{ test_pkcs2_path }}"

View file

@ -0,0 +1,169 @@
---
- name: Generate the self signed cert used as a place holder to create the java keystore
command: openssl req -x509 -newkey rsa:4096 -keyout {{ test_key_path }} -out {{ test_cert_path }} -days 365 -nodes -subj '/CN=localhost'
args:
creates: "{{ test_key_path }}"
- name: Create the test keystore
java_keystore:
name: placeholder
dest: "{{ test_keystore2_path }}"
password: "{{ test_keystore2_password }}"
private_key: "{{ lookup('file', '{{ test_key_path }}') }}"
certificate: "{{ lookup('file', '{{ test_cert_path }}') }}"
- name: Generate the self signed cert we will use for testing
command: openssl req -x509 -newkey rsa:4096 -keyout '{{ test_key2_path }}' -out '{{ test_cert2_path }}' -days 365 -nodes -subj '/CN=localhost'
args:
creates: "{{ test_key2_path }}"
- name: |
Import the newly created certificate. This is our main test.
If the java_cert has been updated properly, then this task will report changed each time
since the module will be comparing the hash of the certificate instead of validating that the alias
simply exists
java_cert:
cert_alias: test_cert
cert_path: "{{ test_cert2_path }}"
keystore_path: "{{ test_keystore2_path }}"
keystore_pass: "{{ test_keystore2_password }}"
state: present
register: result_x509_changed
- name: Verify the x509 status has changed
assert:
that:
- result_x509_changed is changed
- name: |
We also want to make sure that the status doesnt change if we import the same cert
java_cert:
cert_alias: test_cert
cert_path: "{{ test_cert2_path }}"
keystore_path: "{{ test_keystore2_path }}"
keystore_pass: "{{ test_keystore2_password }}"
state: present
register: result_x509_succeeded
- name: Verify the x509 status is ok
assert:
that:
- result_x509_succeeded is succeeded
- name: Create the pkcs12 archive from the test x509 cert
command: >
openssl pkcs12
-in {{ test_cert_path }}
-inkey {{ test_key_path }}
-export
-name test_pkcs12_cert
-out {{ test_pkcs_path }}
-passout pass:"{{ test_keystore2_password }}"
- name: Create the pkcs12 archive from the certificate we will be trying to add to the keystore
command: >
openssl pkcs12
-in {{ test_cert2_path }}
-inkey {{ test_key2_path }}
-export
-name test_pkcs12_cert
-out {{ test_pkcs2_path }}
-passout pass:"{{ test_keystore2_password }}"
- name: >
Ensure the original pkcs12 cert is in the keystore
java_cert:
cert_alias: test_pkcs12_cert
pkcs12_alias: test_pkcs12_cert
pkcs12_path: "{{ test_pkcs_path }}"
pkcs12_password: "{{ test_keystore2_password }}"
keystore_path: "{{ test_keystore2_path }}"
keystore_pass: "{{ test_keystore2_password }}"
state: present
- name: |
Perform the same test, but we will now be testing the pkcs12 functionality
If we add a different pkcs12 cert with the same alias, we should have a chnaged result, NOT the same
java_cert:
cert_alias: test_pkcs12_cert
pkcs12_alias: test_pkcs12_cert
pkcs12_path: "{{ test_pkcs2_path }}"
pkcs12_password: "{{ test_keystore2_password }}"
keystore_path: "{{ test_keystore2_path }}"
keystore_pass: "{{ test_keystore2_password }}"
state: present
register: result_pkcs12_changed
- name: Verify the pkcs12 status has changed
assert:
that:
- result_pkcs12_changed is changed
- name: |
We are requesting the same cert now, so the status should show OK
java_cert:
cert_alias: test_pkcs12_cert
pkcs12_alias: test_pkcs12_cert
pkcs12_path: "{{ test_pkcs2_path }}"
pkcs12_password: "{{ test_keystore2_password }}"
keystore_path: "{{ test_keystore2_path }}"
keystore_pass: "{{ test_keystore2_password }}"
register: result_pkcs12_succeeded
- name: Verify the pkcs12 status is ok
assert:
that:
- result_pkcs12_succeeded is succeeded
- name: Copy the ssl server script
copy:
src: "setupSSLServer.py"
dest: "{{ output_dir }}"
- name: Create an SSL server that we will use for testing URL imports
command: python {{ output_dir }}/setupSSLServer.py {{ output_dir }} {{ test_ssl_port }}
async: 10
poll: 0
- name: |
Download the original cert.pem from our temporary server. The current cert should contain
cert2.pem. Importing this cert should return a status of changed
java_cert:
cert_alias: test_cert_localhost
cert_url: localhost
cert_port: "{{ test_ssl_port }}"
keystore_path: "{{ test_keystore2_path }}"
keystore_pass: "{{ test_keystore2_password }}"
state: present
register: result_url_changed
- name: Verify that the url status is changed
assert:
that:
- result_url_changed is changed
- name: Ensure we can remove the x509 cert
java_cert:
cert_alias: test_cert
keystore_path: "{{ test_keystore2_path }}"
keystore_pass: "{{ test_keystore2_password }}"
state: absent
register: result_x509_absent
- name: Verify the x509 cert is absent
assert:
that:
- result_x509_absent is changed
- name: Ensure we can remove the pkcs12 archive
java_cert:
cert_alias: test_pkcs12_cert
keystore_path: "{{ test_keystore2_path }}"
keystore_pass: "{{ test_keystore2_password }}"
state: absent
register: result_pkcs12_absent
- name: Verify the pkcs12 archive is absent
assert:
that:
- result_pkcs12_absent is changed