Compare commits
15 Commits
main
...
feat/dns-z
Author | SHA1 | Date | |
---|---|---|---|
ab996acb36 | |||
2df6309bf1 | |||
83d275f313 | |||
b7e65abd3d | |||
9ed53d92a4 | |||
8bcc020346 | |||
a0e45be691 | |||
29675007db | |||
74c9f8b2f8 | |||
883140deea | |||
194d5ed1f0 | |||
84989cfbee | |||
452a1cd252 | |||
f5fc5bb845 | |||
cd14bbc629 |
67
.gitea/workflows/pull-request-open.yml
Normal file
67
.gitea/workflows/pull-request-open.yml
Normal file
@ -0,0 +1,67 @@
|
||||
---
|
||||
name: pull-requests-open
|
||||
on:
|
||||
pull_request:
|
||||
types:
|
||||
- opened
|
||||
- edited
|
||||
- synchronize
|
||||
branches:
|
||||
- main
|
||||
- develop
|
||||
|
||||
jobs:
|
||||
commit-history-check:
|
||||
name: Check commit compliance
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Install commitizen
|
||||
run: pip3 install commitizen
|
||||
shell: bash
|
||||
working-directory: ${{ gitea.workspace }}
|
||||
|
||||
- name: Verify commit message compliance
|
||||
run: |
|
||||
echo "cz check --rev-range origin/${{ gitea.event.pull_request.base.ref }}.."
|
||||
cz check --rev-range origin/${{ gitea.event.pull_request.base.ref }}..
|
||||
shell: bash
|
||||
working-directory: ${{ gitea.workspace }}
|
||||
|
||||
run-tests:
|
||||
name: Run tests
|
||||
runs-on: ubuntu-latest
|
||||
needs: commit-history-check
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.10"
|
||||
|
||||
- name: Install requirements
|
||||
run: pip3 install -r tests/requirements.txt
|
||||
shell: bash
|
||||
working-directory: ${{ gitea.workspace }}
|
||||
|
||||
- name: Setup testing environment
|
||||
run: ansible-galaxy collection install ${{ gitea.workspace }}
|
||||
shell: bash
|
||||
working-directory: ${{ gitea.workspace }}
|
||||
|
||||
- name: Run ansible unit tests
|
||||
run: ansible-test units --coverage
|
||||
shell: bash
|
||||
working-directory: /root/.ansible/collections/ansible_collections/ednz_cloud/infomaniak
|
||||
|
||||
- name: Print coverage informations
|
||||
run: ansible-test coverage report
|
||||
shell: bash
|
||||
working-directory: /root/.ansible/collections/ansible_collections/ednz_cloud/infomaniak
|
54
.gitea/workflows/release.yml
Normal file
54
.gitea/workflows/release.yml
Normal file
@ -0,0 +1,54 @@
|
||||
---
|
||||
name: release
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
do-release:
|
||||
if: "!startsWith(github.event.head_commit.message, 'bump:')"
|
||||
runs-on: ubuntu-latest
|
||||
name: Bump version and create changelog with commitizen
|
||||
steps:
|
||||
- name: Get secrets from vault
|
||||
id: import-secrets
|
||||
uses: hashicorp/vault-action@v3
|
||||
with:
|
||||
url: "https://vault.ednz.fr"
|
||||
method: approle
|
||||
roleId: ${{ secrets.VAULT_APPROLE_ID }}
|
||||
secretId: ${{ secrets.VAULT_APPROLE_SECRET_ID }}
|
||||
secrets: |
|
||||
kv/data/applications/gitea/users/actions username | GITEA_ACTIONS_USERNAME ;
|
||||
kv/data/applications/gitea/users/actions token_write | GITEA_ACTIONS_TOKEN ;
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
token: ${{ steps.import-secrets.outputs.GITEA_ACTIONS_TOKEN }}
|
||||
|
||||
- name: Install commitizen
|
||||
run: pip3 install commitizen
|
||||
shell: bash
|
||||
working-directory: ${{ gitea.workspace }}
|
||||
|
||||
- name: Configure git credentials
|
||||
uses: oleksiyrudenko/gha-git-credentials@v2
|
||||
with:
|
||||
global: true
|
||||
name: "Gitea-Actions Bot"
|
||||
email: "gitea-actions@ednz.fr"
|
||||
actor: ${{ steps.import-secrets.outputs.GITEA_ACTIONS_USERNAME }}
|
||||
token: ${{ steps.import-secrets.outputs.GITEA_ACTIONS_TOKEN }}
|
||||
|
||||
- name: Do release
|
||||
run: cz -nr 21 bump --yes
|
||||
shell: bash
|
||||
working-directory: ${{ gitea.workspace }}
|
||||
|
||||
- name: Push release
|
||||
run: git push && git push --tags
|
||||
shell: bash
|
||||
working-directory: ${{ gitea.workspace }}
|
19
.gitignore
vendored
19
.gitignore
vendored
@ -1,11 +1,14 @@
|
||||
# ignore molecule/testinfra pycache
|
||||
**/__pycache__
|
||||
|
||||
# ignore vscode files
|
||||
.vscode
|
||||
roles/ednz_cloud.*
|
||||
vault_config.yml
|
||||
consul_config.yml
|
||||
**/certificates/**
|
||||
**/secrets/credentials.yml
|
||||
**/secrets/credentials.decrypt.yml
|
||||
**/secrets/vault.yml
|
||||
**/.ansible-vault
|
||||
|
||||
# ignore test output (auto-generated)
|
||||
tests/output/**
|
||||
|
||||
# ignore virtual environments
|
||||
.env
|
||||
.venv
|
||||
env
|
||||
venv
|
||||
|
@ -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
|
||||
|
14
molecule/public_cloud_config_info/converge.yml
Normal file
14
molecule/public_cloud_config_info/converge.yml
Normal 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 }}"
|
37
molecule/public_cloud_config_info/molecule.yml
Normal file
37
molecule/public_cloud_config_info/molecule.yml
Normal 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
|
9
molecule/public_cloud_config_info/prepare.yml
Normal file
9
molecule/public_cloud_config_info/prepare.yml
Normal file
@ -0,0 +1,9 @@
|
||||
---
|
||||
- name: Converge
|
||||
hosts: all
|
||||
become: true
|
||||
tasks:
|
||||
- name: "Install python requirements"
|
||||
ansible.builtin.pip:
|
||||
name: requests
|
||||
executable: pip3
|
4
molecule/public_cloud_config_info/requirements.yml
Normal file
4
molecule/public_cloud_config_info/requirements.yml
Normal file
@ -0,0 +1,4 @@
|
||||
---
|
||||
# requirements file for molecule
|
||||
collections:
|
||||
- name: ednz_cloud.infomaniak
|
31
plugins/README.md
Normal file
31
plugins/README.md
Normal 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).
|
52
plugins/module_utils/infomaniak_api_client.py
Normal file
52
plugins/module_utils/infomaniak_api_client.py
Normal 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)
|
110
plugins/modules/public_cloud_config_info.py
Normal file
110
plugins/modules/public_cloud_config_info.py
Normal 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, 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()
|
5
tests/requirements.txt
Normal file
5
tests/requirements.txt
Normal file
@ -0,0 +1,5 @@
|
||||
ansible==10.3.0
|
||||
requests==2.32.3
|
||||
pytest==8.3.3
|
||||
pytest-xdist==3.6.1
|
||||
coverage==7.3.2
|
194
tests/unit/plugins/modules/test_public_cloud_config_info.py
Normal file
194
tests/unit/plugins/modules/test_public_cloud_config_info.py
Normal file
@ -0,0 +1,194 @@
|
||||
import unittest
|
||||
import pytest
|
||||
import json
|
||||
from unittest.mock import patch, MagicMock, Mock
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils import basic
|
||||
from ansible.module_utils.common.text.converters import to_bytes
|
||||
from ansible_collections.ednz_cloud.infomaniak.plugins.modules import (
|
||||
public_cloud_config_info,
|
||||
)
|
||||
|
||||
|
||||
def set_module_args(args):
|
||||
if "_ansible_remote_tmp" not in args:
|
||||
args["_ansible_remote_tmp"] = "/tmp"
|
||||
if "_ansible_keep_remote_files" not in args:
|
||||
args["_ansible_keep_remote_files"] = False
|
||||
|
||||
args = json.dumps({"ANSIBLE_MODULE_ARGS": args})
|
||||
basic._ANSIBLE_ARGS = to_bytes(args)
|
||||
|
||||
|
||||
class AnsibleExitJson(Exception):
|
||||
def __init__(self, kwargs):
|
||||
self.kwargs = kwargs
|
||||
|
||||
|
||||
def exit_json(*args, **kwargs):
|
||||
if "changed" not in kwargs:
|
||||
kwargs["changed"] = False
|
||||
raise AnsibleExitJson(kwargs)
|
||||
|
||||
|
||||
def fail_json(*args, **kwargs):
|
||||
raise SystemExit(json.dumps(kwargs))
|
||||
|
||||
|
||||
class TestPublicCloudConfigInfoModule(unittest.TestCase):
|
||||
"""
|
||||
Unit tests for the public_cloud_config_info Ansible module.
|
||||
"""
|
||||
|
||||
@patch(
|
||||
"ansible_collections.ednz_cloud.infomaniak.plugins.modules.public_cloud_config_info.AnsibleModule"
|
||||
)
|
||||
@patch(
|
||||
"ansible_collections.ednz_cloud.infomaniak.plugins.modules.public_cloud_config_info.InfomaniakAPIClient"
|
||||
)
|
||||
def test_successful_retrieval(self, mock_client_class, mock_ansible_module):
|
||||
"""
|
||||
Test a successful retrieval of public cloud configuration.
|
||||
"""
|
||||
api_response_data = {
|
||||
"result": "success",
|
||||
"data": {
|
||||
"free_tier": 300,
|
||||
"free_tier_used": 24.34,
|
||||
"account_resource_level": 2,
|
||||
"valid_from": 1707584356,
|
||||
"valid_to": 1717192799,
|
||||
"project_count": 2,
|
||||
},
|
||||
}
|
||||
|
||||
mock_client_instance = MagicMock()
|
||||
mock_client_instance.get.return_value = api_response_data
|
||||
mock_client_class.return_value = mock_client_instance
|
||||
|
||||
mock_module_instance = MagicMock()
|
||||
mock_module_instance.params = {
|
||||
"api_token": "mock_api_token",
|
||||
"account_id": "mock_account_id",
|
||||
}
|
||||
mock_module_instance.check_mode = False
|
||||
mock_ansible_module.return_value = mock_module_instance
|
||||
|
||||
mock_module_instance.exit_json = MagicMock()
|
||||
|
||||
public_cloud_config_info.run_module()
|
||||
|
||||
mock_client_class.assert_called_with(
|
||||
api_version="1", api_token="mock_api_token"
|
||||
)
|
||||
|
||||
mock_client_instance.get.assert_called_once_with(
|
||||
"/public_clouds/config", params={"account_id": "mock_account_id"}
|
||||
)
|
||||
|
||||
mock_module_instance.exit_json.assert_called_once_with(
|
||||
changed=False, config=api_response_data["data"]
|
||||
)
|
||||
|
||||
def test_missing_required_params(self):
|
||||
"""
|
||||
Test behavior when required parameters are missing.
|
||||
"""
|
||||
set_module_args(
|
||||
{
|
||||
"api_token": "mock_api_token",
|
||||
# 'account_id' is missing
|
||||
}
|
||||
)
|
||||
|
||||
with patch.object(AnsibleModule, "fail_json", side_effect=fail_json):
|
||||
with pytest.raises(SystemExit) as e:
|
||||
public_cloud_config_info.main()
|
||||
|
||||
captured_output = json.loads(e.value.args[0])
|
||||
|
||||
assert "msg" in captured_output
|
||||
assert "missing required arguments: account_id" in captured_output["msg"]
|
||||
|
||||
def test_check_mode(self):
|
||||
"""
|
||||
Test the behavior in check mode, where no changes should be made.
|
||||
"""
|
||||
set_module_args(
|
||||
{
|
||||
"api_token": "mock_api_token",
|
||||
"account_id": "mock_account_id",
|
||||
"_ansible_check_mode": True,
|
||||
}
|
||||
)
|
||||
|
||||
with patch.object(
|
||||
AnsibleModule, "exit_json", side_effect=exit_json
|
||||
) as mock_exit_json:
|
||||
with pytest.raises(AnsibleExitJson) as e:
|
||||
public_cloud_config_info.main()
|
||||
|
||||
mock_exit_json.assert_called_once_with(
|
||||
changed=False,
|
||||
msg="Check mode: No changes made, would retrieve public cloud config.",
|
||||
)
|
||||
|
||||
@patch(
|
||||
"ansible_collections.ednz_cloud.infomaniak.plugins.modules.public_cloud_config_info.InfomaniakAPIClient"
|
||||
)
|
||||
def test_network_timeout(self, mock_client_class):
|
||||
"""
|
||||
Test behavior when a network timeout occurs.
|
||||
"""
|
||||
# Simulate a network timeout error
|
||||
mock_client_instance = MagicMock()
|
||||
mock_client_instance.get.side_effect = Exception("Request timeout")
|
||||
mock_client_class.return_value = mock_client_instance
|
||||
|
||||
set_module_args(
|
||||
{
|
||||
"api_token": "mock_api_token",
|
||||
"account_id": "mock_account_id",
|
||||
}
|
||||
)
|
||||
|
||||
with patch.object(
|
||||
AnsibleModule, "fail_json", side_effect=fail_json
|
||||
) as mock_fail_json:
|
||||
with pytest.raises(SystemExit) as e:
|
||||
public_cloud_config_info.main()
|
||||
|
||||
captured_output = json.loads(e.value.args[0])
|
||||
assert "msg" in captured_output
|
||||
assert captured_output["msg"] == "Request timeout"
|
||||
mock_fail_json.assert_called_once()
|
||||
|
||||
@patch(
|
||||
"ansible_collections.ednz_cloud.infomaniak.plugins.modules.public_cloud_config_info.InfomaniakAPIClient"
|
||||
)
|
||||
def test_invalid_json_response(self, mock_client_class):
|
||||
"""
|
||||
Test behavior when the API returns an invalid JSON response.
|
||||
"""
|
||||
mock_client_instance = MagicMock()
|
||||
mock_client_instance.get.side_effect = Exception("Invalid JSON response")
|
||||
mock_client_class.return_value = mock_client_instance
|
||||
|
||||
# Set module args with the required parameters
|
||||
set_module_args(
|
||||
{
|
||||
"api_token": "mock_api_token",
|
||||
"account_id": "mock_account_id",
|
||||
}
|
||||
)
|
||||
|
||||
with patch.object(
|
||||
AnsibleModule, "fail_json", side_effect=fail_json
|
||||
) as mock_fail_json:
|
||||
with pytest.raises(SystemExit) as e:
|
||||
public_cloud_config_info.main()
|
||||
|
||||
captured_output = json.loads(e.value.args[0])
|
||||
assert "msg" in captured_output
|
||||
assert captured_output["msg"] == "Invalid JSON response"
|
||||
mock_fail_json.assert_called_once()
|
Loading…
Reference in New Issue
Block a user