feat: add public_cloud_config_info module

This commit is contained in:
Bertrand Lanson 2024-09-12 23:17:36 +02:00
parent 191b4f5bd1
commit cd14bbc629
Signed by: lanson
SSH Key Fingerprint: SHA256:/nqc6HGqld/PS208F6FUOvZlUzTS0rGpNNwR5O2bQBw
8 changed files with 261 additions and 5 deletions

View File

@ -1,7 +1,7 @@
---
namespace: ednz_cloud
name: hashistack
version: 0.7.0
name: infomaniak
version: 0.0.0
readme: README.md
authors:
- Bertrand Lanson <bertrand.lanson@protonmail.com>
@ -11,9 +11,9 @@ license_file: "LICENSE"
# A list of tags you want to associate with the collection for indexing/searching. A tag name has the same character
# requirements as 'namespace' and 'name'
tags: ["tools"]
tags: ["infomaniak", "cloud"]
dependencies: {}
repository: https://git.ednz.fr/ansible-collections/hashistack
repository: https://git.ednz.fr/ansible-collections/infomaniak
documentation: http://docs.example.com
homepage: http://example.com
issues: http://example.com/issue/tracker
@ -22,7 +22,6 @@ issues: http://example.com/issue/tracker
# uses 'fnmatch' to match the files or directories. Some directories and files like 'galaxy.yml', '*.pyc', '*.retry',
# and '.git' are always filtered. Mutually exclusive with 'manifest'
build_ignore:
- assets**
- .gitea**
# A dict controlling use of manifest directives used in building the collection artifact. The key 'directives' is a
# list of MANIFEST.in style

View File

@ -0,0 +1,14 @@
---
- name: Converge
hosts: all
become: true
tasks:
- name: "Run module"
ednz_cloud.infomaniak.public_cloud_config_info:
api_token: "{{ lookup('ansible.builtin.env', 'IK_API_TOKEN') }}"
account_id: "{{ lookup('ansible.builtin.env', 'IK_ACCOUNT_ID') }}"
register: _result
- name: "Print result"
ansible.builtin.debug:
msg: "{{ _result }}"

View File

@ -0,0 +1,37 @@
---
dependency:
name: galaxy
options:
requirements-file: ./requirements.yml
driver:
name: docker
platforms:
- name: instance
image: geerlingguy/docker-${MOLECULE_TEST_OS}-ansible
command: ""
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup
cgroupns_mode: host
privileged: true
pre_build_image: true
provisioner:
name: ansible
config_options:
defaults:
remote_tmp: /tmp/.ansible
verifier:
name: ansible
scenario:
name: public_cloud_config_info
test_sequence:
- dependency
- cleanup
- destroy
- syntax
- create
- prepare
- converge
- idempotence
- verify
- cleanup
- destroy

View File

@ -0,0 +1,9 @@
---
- name: Converge
hosts: all
become: true
tasks:
- name: "Install python requirements"
ansible.builtin.pip:
name: requests
executable: pip3

View File

@ -0,0 +1,4 @@
---
# requirements file for molecule
collections:
- name: ednz_cloud.infomaniak

31
plugins/README.md Normal file
View File

@ -0,0 +1,31 @@
# Collections Plugins Directory
This directory can be used to ship various plugins inside an Ansible collection. Each plugin is placed in a folder that
is named after the type of plugin it is in. It can also include the `module_utils` and `modules` directory that
would contain module utils and modules respectively.
Here is an example directory of the majority of plugins currently supported by Ansible:
```
└── plugins
├── action
├── become
├── cache
├── callback
├── cliconf
├── connection
├── filter
├── httpapi
├── inventory
├── lookup
├── module_utils
├── modules
├── netconf
├── shell
├── strategy
├── terminal
├── test
└── vars
```
A full list of plugin types can be found at [Working With Plugins](https://docs.ansible.com/ansible-core/2.15/plugins/plugins.html).

View File

@ -0,0 +1,52 @@
import requests
import json
INFOMANIAK_API_URL = "https://api.infomaniak.com"
class InfomaniakAPIClient:
def __init__(self, api_version, api_token):
self.base_url = f"{INFOMANIAK_API_URL}/{api_version}"
self.headers = {
"Authorization": f"Bearer {api_token}",
"Content-Type": "application/json",
"Accept": "application/json",
}
def _request(self, method, endpoint, data=None, params=None):
url = f"{self.base_url}{endpoint}"
try:
response = requests.request(
method=method,
url=url,
headers=self.headers,
json=data,
params=params,
timeout=10,
)
response.raise_for_status()
try:
return response.json()
except json.JSONDecodeError:
raise Exception(f"Invalid JSON response: {response.text}")
except requests.exceptions.HTTPError as http_err:
error_content = response.content if response else "No response"
raise Exception(
f"HTTP error occurred: {http_err}, Response content: {error_content}"
)
except requests.exceptions.RequestException as req_err:
raise Exception(f"Request error occurred: {req_err}")
except Exception as err:
raise Exception(f"An error occurred: {err}")
def get(self, endpoint, params=None):
return self._request("GET", endpoint, params=params)
def post(self, endpoint, data=None):
return self._request("POST", endpoint, data=data)
def put(self, endpoint, data=None):
return self._request("PUT", endpoint, data=data)
def delete(self, endpoint):
return self._request("DELETE", endpoint)

View File

@ -0,0 +1,110 @@
#!/usr/bin/python
from __future__ import absolute_import, division, print_function
__metaclass__ = type
DOCUMENTATION = r"""
---
module: ednz_cloud.infomaniak.public_cloud_config_info
short_description: Retrieves the public cloud configuration from the Infomaniak API.
version_added: "0.1.0"
description:
- This module queries the Infomaniak API to retrieve the public cloud configuration for a given account.
- It uses the provided API token for authentication and the account ID as a query parameter.
requirements:
- C(requests)
options:
api_token:
description: The API token used to authenticate with the Infomaniak API.
required: true
type: str
account_id:
description: The account ID for which to query the public cloud configuration.
required: true
type: str
author:
- Bertrand Lanson (@ednxzu)
"""
EXAMPLES = r"""
# Example: Retrieve public cloud configuration for account ID 965060
- name: Get public cloud configuration
public_cloud_config_info:
api_token: "your_api_token"
account_id: "123456"
"""
RETURN = r"""
config:
description:
- The public cloud configuration for the specified account.
type: dict
returned: always
sample:
free_tier: 300
free_tier_used: 24.34
account_resource_level: 2
valid_from: 1707584356
valid_to: 1717192799
project_count: 2
"""
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.ednz_cloud.infomaniak.plugins.module_utils.infomaniak_api_client import (
InfomaniakAPIClient,
)
def get_public_cloud_config(client: InfomaniakAPIClient, account_id: str):
endpoint = "/public_clouds/config"
params = {"account_id": account_id}
response = client.get(endpoint, params=params)
if response.get("result") != "success":
raise Exception(f"API request failed with result: {response.get('result')}")
return response.get("data", {})
def run_module():
module_args = dict(
api_token=dict(type="str", required=True, no_log=True),
account_id=dict(type="str", required=True),
)
result = dict(changed=False, public_cloud_config={})
module = AnsibleModule(argument_spec=module_args, supports_check_mode=True)
api_token = module.params["api_token"]
account_id = module.params["account_id"]
if module.check_mode:
module.exit_json(
changed=False,
msg="Check mode: No changes made, would retrieve public cloud config.",
)
client = InfomaniakAPIClient(api_version="1", api_token=api_token)
try:
config_data = get_public_cloud_config(client, account_id)
result["config"] = config_data
module.exit_json(**result)
except Exception as e:
module.fail_json(msg=str(e))
def main():
run_module()
if __name__ == "__main__":
main()