2024-01-26 23:54:13 +00:00
|
|
|
#!/usr/bin/python
|
|
|
|
|
|
|
|
from __future__ import absolute_import, division, print_function
|
2024-01-28 00:07:55 +00:00
|
|
|
from typing import Tuple
|
2024-01-26 23:54:13 +00:00
|
|
|
|
|
|
|
__metaclass__ = type
|
|
|
|
|
|
|
|
DOCUMENTATION = r"""
|
2024-01-28 15:21:38 +00:00
|
|
|
---
|
2024-02-07 20:49:00 +00:00
|
|
|
module: ednz_cloud.hashistack.consul_acl_bootstrap
|
2024-01-28 15:21:38 +00:00
|
|
|
|
|
|
|
short_description: Bootstraps ACL for a Consul cluster.
|
|
|
|
|
2024-09-02 20:09:57 +00:00
|
|
|
version_added: "0.1.0"
|
2024-01-28 15:21:38 +00:00
|
|
|
|
|
|
|
description:
|
|
|
|
- This module bootstraps ACL (Access Control List) for a Consul cluster. It performs the ACL bootstrap operation,
|
2024-09-02 20:09:57 +00:00
|
|
|
creating the initial tokens needed for secure communication within the cluster.
|
2024-01-28 15:21:38 +00:00
|
|
|
|
|
|
|
options:
|
|
|
|
api_addr:
|
|
|
|
description: The address of the Consul API.
|
|
|
|
required: true
|
|
|
|
type: str
|
|
|
|
scheme:
|
|
|
|
description: The URL scheme to use (http or https).
|
|
|
|
required: false
|
|
|
|
type: str
|
|
|
|
default: http
|
|
|
|
port:
|
|
|
|
description: The port on which the Consul API is running.
|
|
|
|
required: false
|
|
|
|
type: int
|
|
|
|
default: 8500
|
|
|
|
|
|
|
|
author:
|
2024-02-07 20:49:00 +00:00
|
|
|
- Bertrand Lanson (@ednz_cloud)
|
2024-01-26 23:54:13 +00:00
|
|
|
"""
|
|
|
|
|
|
|
|
EXAMPLES = r"""
|
2024-01-28 15:21:38 +00:00
|
|
|
# Example: Bootstrap ACL for a Consul cluster
|
|
|
|
- name: Bootstrap ACL for Consul cluster
|
2024-09-02 20:09:57 +00:00
|
|
|
ednz_cloud.hashistack.consul_acl_bootstrap:
|
|
|
|
api_addr: 127.0.0.1
|
|
|
|
scheme: http
|
|
|
|
port: 8500
|
2024-01-26 23:54:13 +00:00
|
|
|
"""
|
|
|
|
|
|
|
|
RETURN = r"""
|
2024-01-28 15:21:38 +00:00
|
|
|
state:
|
|
|
|
description: Information about the state of ACL bootstrap for the Consul cluster.
|
|
|
|
type: dict
|
|
|
|
returned: always
|
|
|
|
sample:
|
|
|
|
accessor_id: "uuuuuuuu-uuuu-iiii-dddd-111111111111",
|
|
|
|
secret_id: "uuuuuuuu-uuuu-iiii-dddd-222222222222"
|
2024-01-26 23:54:13 +00:00
|
|
|
"""
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
2024-01-28 00:07:55 +00:00
|
|
|
def bootstrap_acl(scheme: str, api_addr: str, port: int) -> Tuple[bool, dict]:
|
|
|
|
url = f"{scheme}://" + f"{api_addr}:{port}" + "/v1/acl/bootstrap"
|
2024-01-27 20:11:36 +00:00
|
|
|
|
2024-01-28 00:07:55 +00:00
|
|
|
# Make a PUT request to bootstrap the cluster
|
|
|
|
response = requests.put(url)
|
|
|
|
|
|
|
|
# Check the HTTP status code and handle the response
|
|
|
|
if response.status_code == 200:
|
|
|
|
return True, {
|
|
|
|
"accessor_id": response.json()["AccessorID"],
|
|
|
|
"secret_id": response.json()["SecretID"],
|
|
|
|
}
|
|
|
|
elif response.status_code == 403:
|
2024-01-28 15:21:38 +00:00
|
|
|
return False, {"message": "Cluster has already been bootstrapped"}
|
2024-01-28 00:07:55 +00:00
|
|
|
else:
|
|
|
|
response.raise_for_status() # Raise an exception for other status codes
|
2024-01-27 20:11:36 +00:00
|
|
|
|
|
|
|
|
2024-01-26 23:54:13 +00:00
|
|
|
def run_module():
|
|
|
|
module_args = dict(
|
2024-01-28 00:07:55 +00:00
|
|
|
api_addr=dict(type="str", required=True),
|
|
|
|
scheme=dict(type="str", required=False, default="http"),
|
|
|
|
port=dict(type="int", required=False, default=8500),
|
2024-01-26 23:54:13 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
result = dict(changed=False, state="")
|
|
|
|
|
2024-01-28 15:21:38 +00:00
|
|
|
module = AnsibleModule(argument_spec=module_args, supports_check_mode=False)
|
2024-01-27 20:11:36 +00:00
|
|
|
|
|
|
|
try:
|
|
|
|
if not HAS_REQUESTS:
|
|
|
|
module.fail_json(
|
|
|
|
msg="Requests library is required but not installed. {}".format(
|
|
|
|
REQUESTS_IMPORT_ERROR
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
2024-01-28 00:07:55 +00:00
|
|
|
acl_bootstrap_result, response_data = bootstrap_acl(
|
2024-01-28 15:21:38 +00:00
|
|
|
scheme=module.params["scheme"],
|
|
|
|
api_addr=module.params["api_addr"],
|
|
|
|
port=module.params["port"],
|
2024-01-28 00:07:55 +00:00
|
|
|
)
|
2024-01-27 20:11:36 +00:00
|
|
|
|
2024-01-28 00:07:55 +00:00
|
|
|
result["changed"] = acl_bootstrap_result
|
|
|
|
result["state"] = response_data
|
2024-01-27 20:11:36 +00:00
|
|
|
|
|
|
|
module.exit_json(**result)
|
|
|
|
|
2024-01-28 00:07:55 +00:00
|
|
|
except requests.exceptions.RequestException as e:
|
|
|
|
module.fail_json(msg="Error during ACL Bootstrap: {}".format(str(e)))
|
2024-01-27 20:11:36 +00:00
|
|
|
|
2024-01-26 23:54:13 +00:00
|
|
|
|
|
|
|
def main():
|
|
|
|
run_module()
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
main()
|