hashistack/plugins/modules/nomad_acl_bootstrap.py

156 lines
4.3 KiB
Python

#!/usr/bin/python
from __future__ import absolute_import, division, print_function
from typing import Tuple
__metaclass__ = type
DOCUMENTATION = r"""
---
module: ednz_cloud.hashistack.nomad_acl_bootstrap
short_description: Manages the ACL bootstrap of HashiCorp Nomad.
version_added: "0.1.0"
description:
- This module bootstraps HashiCorp Nomad ACL, ensuring that it is securely set up for use.
requirements:
- C(requests) (L(Python library,https://requests.readthedocs.io/en/latest/))
options:
api_url:
description: The URL of the HashiCorp Nomad API.
required: true
type: str
bootstrap_secret:
description:
- The secret to use for the bootstrap operation.
required: false
type: str
tls_verify:
description:
- Whether to verify the TLS certificate of the Nomad API URL.
- Default is true.
required: false
type: bool
default: true
author:
- Bertrand Lanson (@ednz_cloud)
"""
EXAMPLES = r"""
# Example: Bootstrap HashiCorp Nomad ACL with default settings
- name: Bootstrap HashiCorp Nomad ACL
ednz_cloud.hashistack.nomad_acl_bootstrap:
api_url: https://nomad.example.com
# Example: Bootstrap HashiCorp Nomad ACL with a custom bootstrap secret
- name: Bootstrap HashiCorp Nomad ACL with custom settings
ednz_cloud.hashistack.nomad_acl_bootstrap:
api_url: https://nomad.example.com
bootstrap_secret: 2b778dd9-f5f1-6f29-b4b4-9a5fa948757a
"""
RETURN = r"""
state:
description:
- Information about the state of HashiCorp Nomad after ACL bootstrap.
- This is a complex dictionary with details of the bootstrap.
type: dict
returned: always
sample:
- AccessorID: "b780e702-98ce-521f-2e5f-c6b87de05b24",
- SecretID: "3f4a0fcd-7c42-773c-25db-2d31ba0c05fe",
- Name: "Bootstrap Token",
- Type: "management",
- Policies: null,
- Global: true,
- CreateTime: "2017-08-23T22:47:14.695408057Z",
- CreateIndex: 7,
- ModifyIndex: 7
"""
from ansible.module_utils.basic import AnsibleModule
import traceback
try:
import requests
except ImportError:
HAS_REQUESTS = False
REQUESTS_IMPORT_ERROR = traceback.format_exc()
else:
REQUESTS_IMPORT_ERROR = None
HAS_REQUESTS = True
def bootstrap_nomad_acl(
api_url: str, tls_verify: bool, bootstrap_secret: str
) -> Tuple[bool, dict]:
payload = {}
if bootstrap_secret:
payload["BootstrapSecret"] = bootstrap_secret
response = None
try:
response = requests.post(
f"{api_url}/v1/acl/bootstrap", json=payload, verify=tls_verify
)
response.raise_for_status()
return True, response.json()
except requests.exceptions.HTTPError as e:
if response is not None and response.status_code == 400:
try:
error_message = response.json().get(
"Errors", ["Nomad ACL bootstrap already done"]
)[0]
except ValueError:
error_message = response.text
return False, {"message": error_message}
raise ValueError(f"Nomad ACL bootstrap failed: {str(e)}")
except requests.exceptions.RequestException as e:
raise ValueError(f"Nomad ACL bootstrap failed: {str(e)}")
def run_module():
module_args = dict(
api_url=dict(type="str", required=True),
bootstrap_secret=dict(type="str", required=False, no_log=True),
tls_verify=dict(type="bool", required=False, default=True),
)
result = dict(changed=False, state="")
module = AnsibleModule(argument_spec=module_args, supports_check_mode=False)
if not HAS_REQUESTS:
module.fail_json(
msg="Missing required library: requests", exception=REQUESTS_IMPORT_ERROR
)
try:
changed, response_data = bootstrap_nomad_acl(
api_url=module.params["api_url"],
tls_verify=module.params["tls_verify"],
bootstrap_secret=module.params.get("bootstrap_secret"),
)
result["changed"] = changed
result["state"] = response_data
module.exit_json(**result)
except ValueError as e:
module.fail_json(msg=str(e))
def main():
run_module()
if __name__ == "__main__":
main()