2023-12-26 18:14:30 +00:00
|
|
|
#!/usr/bin/python
|
|
|
|
|
2023-12-29 22:40:34 +00:00
|
|
|
from __future__ import absolute_import, division, print_function
|
2024-01-28 15:21:38 +00:00
|
|
|
from typing import Tuple
|
2023-12-29 22:40:34 +00:00
|
|
|
|
2023-12-26 18:14:30 +00:00
|
|
|
__metaclass__ = type
|
|
|
|
|
2023-12-29 22:40:34 +00:00
|
|
|
DOCUMENTATION = r"""
|
2023-12-26 18:14:30 +00:00
|
|
|
---
|
2024-09-02 20:09:57 +00:00
|
|
|
module: ednz_cloud.hashistack.vault_unseal
|
2023-12-26 18:14:30 +00:00
|
|
|
|
2024-09-02 20:09:57 +00:00
|
|
|
short_description: Unseals a Vault cluster.
|
2023-12-26 18:14:30 +00:00
|
|
|
|
2024-09-02 20:09:57 +00:00
|
|
|
version_added: "0.1.0"
|
2023-12-26 18:14:30 +00:00
|
|
|
|
2024-09-02 20:09:57 +00:00
|
|
|
description:
|
|
|
|
- This module unseals a Vault cluster by submitting the necessary unseal keys. It checks whether the Vault is sealed and performs the unseal operation if needed. The response will reflect the state after the last unseal key is submitted.
|
|
|
|
|
|
|
|
requirements:
|
|
|
|
- C(hvac) (L(Python library,https://hvac.readthedocs.io/en/stable/overview.html))
|
2023-12-26 18:14:30 +00:00
|
|
|
|
|
|
|
options:
|
2024-09-02 20:09:57 +00:00
|
|
|
api_url:
|
|
|
|
description: The URL of the Vault API.
|
2023-12-26 18:14:30 +00:00
|
|
|
required: true
|
|
|
|
type: str
|
2024-09-02 20:09:57 +00:00
|
|
|
tls_verify:
|
|
|
|
description: Whether to verify TLS certificates.
|
2023-12-26 18:14:30 +00:00
|
|
|
required: false
|
|
|
|
type: bool
|
2024-09-02 20:09:57 +00:00
|
|
|
default: true
|
|
|
|
key_shares:
|
|
|
|
description: List of unseal keys required to unseal the Vault.
|
|
|
|
required: false
|
|
|
|
type: list
|
|
|
|
default: []
|
2023-12-26 18:14:30 +00:00
|
|
|
|
|
|
|
author:
|
2024-09-02 20:09:57 +00:00
|
|
|
- Bertrand Lanson (@ednz_cloud)
|
2023-12-29 22:40:34 +00:00
|
|
|
"""
|
2023-12-26 18:14:30 +00:00
|
|
|
|
2023-12-29 22:40:34 +00:00
|
|
|
EXAMPLES = r"""
|
2024-09-02 20:09:57 +00:00
|
|
|
# Example: Unseal a Vault cluster
|
|
|
|
- name: Unseal Vault cluster
|
|
|
|
ednz_cloud.hashistack.vault_unseal:
|
|
|
|
api_url: "https://127.0.0.1:8200"
|
|
|
|
tls_verify: true
|
|
|
|
key_shares:
|
|
|
|
- "key1"
|
|
|
|
- "key2"
|
|
|
|
- "key3"
|
2023-12-26 18:14:30 +00:00
|
|
|
|
2024-09-02 20:09:57 +00:00
|
|
|
# Example: Unseal Vault cluster with no TLS verification
|
|
|
|
- name: Unseal Vault cluster without TLS verification
|
|
|
|
ednz_cloud.hashistack.vault_unseal:
|
|
|
|
api_url: "https://127.0.0.1:8200"
|
|
|
|
tls_verify: false
|
|
|
|
key_shares:
|
|
|
|
- "key1"
|
|
|
|
- "key2"
|
2023-12-29 22:40:34 +00:00
|
|
|
"""
|
2023-12-26 18:14:30 +00:00
|
|
|
|
2023-12-29 22:40:34 +00:00
|
|
|
RETURN = r"""
|
2024-09-02 20:09:57 +00:00
|
|
|
state:
|
|
|
|
description: Information about the state of the Vault unseal operation.
|
|
|
|
type: dict
|
2023-12-26 18:14:30 +00:00
|
|
|
returned: always
|
2024-09-02 20:09:57 +00:00
|
|
|
sample:
|
|
|
|
sealed: true,
|
|
|
|
t: 3,
|
|
|
|
n: 5,
|
|
|
|
progress: 2,
|
|
|
|
version: "0.6.2"
|
2023-12-29 22:40:34 +00:00
|
|
|
"""
|
2023-12-26 18:14:30 +00:00
|
|
|
from ansible.module_utils.basic import AnsibleModule
|
2023-12-29 11:51:00 +00:00
|
|
|
import traceback
|
2023-12-26 18:14:30 +00:00
|
|
|
|
|
|
|
try:
|
|
|
|
import hvac
|
|
|
|
except ImportError:
|
|
|
|
HAS_HVAC = False
|
|
|
|
HVAC_IMPORT_ERROR = traceback.format_exc()
|
|
|
|
else:
|
|
|
|
HVAC_IMPORT_ERROR = None
|
|
|
|
HAS_HVAC = True
|
|
|
|
|
2023-12-29 22:40:34 +00:00
|
|
|
|
2024-04-06 21:47:35 +00:00
|
|
|
def unseal_vault(api_url: str, tls_verify: bool, key_shares: list) -> Tuple[bool, dict]:
|
|
|
|
client = hvac.Client(url=api_url, verify=tls_verify)
|
2024-01-28 15:21:38 +00:00
|
|
|
|
|
|
|
try:
|
|
|
|
if client.sys.is_sealed():
|
|
|
|
return True, client.sys.submit_unseal_keys(key_shares)
|
|
|
|
else:
|
|
|
|
return False, {"message": "Vault is already unsealed"}
|
|
|
|
except hvac.exceptions.VaultError as e:
|
|
|
|
raise hvac.exceptions.VaultError(f"Vault unsealing failed: {str(e)}")
|
|
|
|
|
|
|
|
|
2023-12-26 18:14:30 +00:00
|
|
|
def run_module():
|
|
|
|
module_args = dict(
|
2023-12-29 22:40:34 +00:00
|
|
|
api_url=dict(type="str", required=True),
|
2024-04-06 21:47:35 +00:00
|
|
|
tls_verify=dict(type="bool", required=False, default=True),
|
2023-12-29 22:40:34 +00:00
|
|
|
key_shares=dict(type="list", required=False, default=[]),
|
2023-12-26 18:14:30 +00:00
|
|
|
)
|
2024-01-24 22:54:58 +00:00
|
|
|
result = dict(changed=False, state="")
|
2023-12-26 18:14:30 +00:00
|
|
|
|
2024-01-28 15:21:38 +00:00
|
|
|
module = AnsibleModule(argument_spec=module_args, supports_check_mode=False)
|
2023-12-26 18:14:30 +00:00
|
|
|
|
2024-04-06 21:47:35 +00:00
|
|
|
client = hvac.Client(
|
|
|
|
url=module.params["api_url"], verify=module.params["tls_verify"]
|
|
|
|
)
|
2023-12-29 22:40:34 +00:00
|
|
|
|
|
|
|
if not client.sys.is_sealed():
|
|
|
|
module.exit_json(**result)
|
2023-12-26 18:14:30 +00:00
|
|
|
|
2023-12-29 11:51:00 +00:00
|
|
|
try:
|
2024-01-28 15:21:38 +00:00
|
|
|
if not HAS_HVAC:
|
|
|
|
module.fail_json(
|
|
|
|
msg="Missing required library: hvac", exception=HVAC_IMPORT_ERROR
|
|
|
|
)
|
|
|
|
vault_unseal_result, response_data = unseal_vault(
|
2024-04-06 21:47:35 +00:00
|
|
|
api_url=module.params["api_url"],
|
|
|
|
tls_verify=module.params["tls_verify"],
|
|
|
|
key_shares=module.params["key_shares"],
|
2024-01-28 15:21:38 +00:00
|
|
|
)
|
2024-01-25 21:40:44 +00:00
|
|
|
|
2024-04-06 21:47:35 +00:00
|
|
|
if hvac.Client(
|
|
|
|
url=module.params["api_url"], verify=module.params["tls_verify"]
|
|
|
|
).sys.is_sealed():
|
2024-01-28 15:21:38 +00:00
|
|
|
module.fail_json(
|
|
|
|
msg="Vault unsealing failed. The unseal operation worked, but the vault is still sealed, maybe you didn't pass enough keys ?"
|
|
|
|
)
|
2024-01-25 21:40:44 +00:00
|
|
|
|
2024-01-28 15:21:38 +00:00
|
|
|
result["changed"] = vault_unseal_result
|
|
|
|
result["state"] = response_data
|
2023-12-29 11:51:00 +00:00
|
|
|
except hvac.exceptions.VaultError as ve:
|
|
|
|
module.fail_json(msg=f"Vault unsealing failed: {ve}")
|
2023-12-26 18:14:30 +00:00
|
|
|
|
2023-12-29 11:51:00 +00:00
|
|
|
module.exit_json(**result)
|
2023-12-26 18:14:30 +00:00
|
|
|
|
2023-12-29 22:40:34 +00:00
|
|
|
|
2023-12-26 18:14:30 +00:00
|
|
|
def main():
|
|
|
|
run_module()
|
|
|
|
|
2023-12-29 22:40:34 +00:00
|
|
|
|
|
|
|
if __name__ == "__main__":
|
2023-12-26 18:14:30 +00:00
|
|
|
main()
|