Files

178 lines
4.9 KiB
Python

#!/usr/bin/python
# -*- coding: utf-8 -*-
from subprocess import call
import os
TMPL_GEN_TS = "keytool -import -noprompt -alias {0} -file {1} -keystore {2} -storepass:file {3}.storepass"
DEV_NULL = open('/dev/null', 'w')
class Keytool:
def __init__(self, cadir, hostname, store_password, hosts_to_trust):
self.cadir = cadir
self.hostname = hostname
self.store_password = store_password
self.hosts_to_trust = hosts_to_trust
def execute_command(self, cmd):
call(cmd, shell=True, stdout=DEV_NULL, stderr=DEV_NULL)
def validate(self):
if not os.path.exists(self.cadir):
return dict(success=False, msg="CA directory '{0}' does not exist.".format(self.cadir))
elif len(self.hosts_to_trust) == 0:
return dict(success=False, msg="No hosts specified for the truststore.")
else:
return dict(success=True)
def ensure_directory_exists(self, dir):
if not os.path.exists(dir):
os.mkdir(dir)
def get_truststore_path(self):
return "truststores" + os.sep + self.hostname + ".trust.jks"
def get_storepass_path(self):
return self.hostname + ".storepass"
def resolve_certificate(self, host):
server = "./server/{0}.cert.pem".format(host)
client = "./client/{0}.cert.pem".format(host)
if os.path.exists(server):
return server
elif os.path.exists(client):
return client
else:
return None
def build_trust_store(self):
changed = False
success = True
errors = []
changes = []
CURDIR = os.getcwd()
os.chdir(self.cadir)
errors.append("CURDIR: {0}".format(os.getcwd()))
self.ensure_directory_exists("truststores")
truststore_path = self.get_truststore_path()
storepass_path = self.get_storepass_path()
if not os.path.exists(truststore_path):
# Write the password out to file.
with open(storepass_path, "w") as storepass:
storepass.write(self.store_password)
try:
cmd = TMPL_GEN_TS.format("CA", "cacert.pem", truststore_path, self.hostname)
self.execute_command(cmd)
changed = True
changes.append("Added the CA Certificate to the truststore.")
for host in self.hosts_to_trust:
hostcert = self.resolve_certificate(host)
errors.append("HOSTCERT: {0}".format(hostcert))
if not hostcert is None:
cmd = TMPL_GEN_TS.format(host, hostcert, truststore_path, self.hostname)
changes.append("Executing: '{0}'".format(cmd))
self.execute_command(cmd)
changed = True
changes.append("Added '{0}' to the truststore.".format(host))
else:
success=False
errors.append("Could not find cert for host: {0}".format(host))
except Exception as e:
success = False
errors.append(e.message)
finally:
# Remove the password
os.remove(storepass_path)
if success == False:
os.remove(truststore_path)
os.chdir(CURDIR)
return dict(success=success, changed=changed, changes=changes, path=truststore_path, errors=errors, msg=", ".join(errors))
def remove_trust_store(self):
changed = False
changes = []
CURDIR = os.getcwd()
os.chdir(self.cadir)
truststore_path = self.get_truststore_path()
if os.path.exists(truststore_path):
os.remove(truststore_path)
changed=True
changes.append("Successfully removed truststore.")
os.chdir(CURDIR)
return dict(success=True, changed=changed, changes=changes, msg="")
def main():
BASE_MODULE_ARGS = dict(
cadir = dict(default="/etc/certs"),
hostname = dict(required=True),
store_password = dict(required=True),
hosts_to_trust = dict(required=True, type="list"),
state = dict(default="present", choices=["present", "absent"])
)
module = AnsibleModule(
argument_spec= BASE_MODULE_ARGS,
supports_check_mode=True
)
keytool = Keytool(
module.params["cadir"],
module.params["hostname"],
module.params["store_password"],
module.params["hosts_to_trust"]
)
isValid = keytool.validate()
if isValid["success"]:
if module.params["state"] == "present":
isValid = keytool.build_trust_store()
else:
isValid = keytool.remove_trust_store()
if not isValid["success"]:
module.fail_json(msg=isValid["msg"])
else:
module.exit_json(**isValid)
# this is magic, see lib/ansible/module_common.py
#<<INCLUDE_ANSIBLE_MODULE_COMMON>>
main()