Mini Shell
"""
State management of a java keystore
"""
import logging
import os
__virtualname__ = "keystore"
# Init logger
log = logging.getLogger(__name__)
def __virtual__():
"""
Only load this module if the keystore execution module is available
"""
if "keystore.list" in __salt__:
return __virtualname__
return (
False,
"Cannot load the {} state module: keystore execution module not found".format(
__virtualname__
),
)
def managed(name, passphrase, entries, force_remove=False):
"""
Create or manage a java keystore.
:param name: The path to the keystore file
:param passphrase: The password to the keystore
:param entries: A list containing an alias, certificate, and optional private_key.
The certificate and private_key can be a file or a string
.. code-block:: yaml
- entries:
- alias: hostname2
certificate: /path/to/cert.crt
private_key: /path/to/key.key
- alias: stringhost
certificate: |
-----BEGIN CERTIFICATE-----
MIICEjCCAXsCAg36MA0GCSqGSIb3DQEBBQUAMIGbMQswCQYDVQQGEwJKUDEOMAwG
2VguKv4SWjRFoRkIfIlHX0qVviMhSlNy2ioFLy7JcPZb+v3ftDGywUqcBiVDoea0
-----END CERTIFICATE-----
:param force_remove: If True will cause the state to remove any entries found in the keystore
which are not defined in the state. The default is False. Example:
.. code-block:: yaml
define_keystore:
keystore.managed:
- name: /path/to/keystore
- passphrase: changeit
- force_remove: True
- entries:
- alias: hostname1
certificate: /path/to/cert.crt
- alias: remotehost
certificate: /path/to/cert2.crt
private_key: /path/to/key2.key
- alias: pillarhost
certificate: {{ salt.pillar.get('path:to:cert') }}
"""
ret = {"changes": {}, "comment": "", "name": name, "result": True}
keep_list = []
old_aliases = []
if force_remove:
if os.path.exists(name):
existing_entries = __salt__["keystore.list"](name, passphrase)
for entry in existing_entries:
old_aliases.append(entry.get("alias"))
log.debug("Existing aliases list: %s", old_aliases)
for entry in entries:
update_entry = True
existing_entry = None
if os.path.exists(name):
if force_remove:
keep_list.append(entry["alias"])
existing_entry = __salt__["keystore.list"](name, passphrase, entry["alias"])
if existing_entry:
existing_sha1 = existing_entry[0]["sha1"]
try:
new_sha1 = __salt__["x509.read_certificate"](entry["certificate"])[
"SHA1 Finger Print"
]
except (KeyError, TypeError) as err:
log.debug(
"Unable to obtain SHA1 finger print from entry's certificate"
)
new_sha1 = __salt__["keystore.get_sha1"](entry["certificate"])
if existing_sha1.decode(__salt_system_encoding__) == new_sha1.decode(
__salt_system_encoding__
):
update_entry = False
if update_entry:
if __opts__["test"]:
ret["result"] = None
if existing_entry:
ret["comment"] += "Alias {} would have been updated\n".format(
entry["alias"]
)
else:
ret["comment"] += "Alias {} would have been added\n".format(
entry["alias"]
)
else:
if existing_entry:
result = __salt__["keystore.remove"](
entry["alias"], name, passphrase
)
result = __salt__["keystore.add"](
entry["alias"],
name,
passphrase,
entry["certificate"],
private_key=entry.get("private_key", None),
)
if result:
ret["changes"][entry["alias"]] = "Updated"
ret["comment"] += "Alias {} updated.\n".format(entry["alias"])
else:
result = __salt__["keystore.add"](
entry["alias"],
name,
passphrase,
entry["certificate"],
private_key=entry.get("private_key", None),
)
if result:
ret["changes"][entry["alias"]] = "Added"
ret["comment"] += "Alias {} added.\n".format(entry["alias"])
if force_remove:
# Determine which aliases need to be removed
remove_list = list(set(old_aliases) - set(keep_list))
log.debug("Will remove: %s", remove_list)
for alias_name in remove_list:
if __opts__["test"]:
ret["comment"] += f"Alias {alias_name} would have been removed"
ret["result"] = None
else:
__salt__["keystore.remove"](alias_name, name, passphrase)
ret["changes"][alias_name] = "Removed"
ret["comment"] += f"Alias {alias_name} removed.\n"
if not ret["changes"] and not ret["comment"]:
ret["comment"] = "No changes made.\n"
return ret
Zerion Mini Shell 1.0