-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: compute load balancer targets status using a filter (#550)
##### SUMMARY Allow to compute the status of a load balancer using a filter. Closes #467 ##### ISSUE TYPE - Feature Pull Request ##### COMPONENT NAME hetzner.hcloud.loab_balancer_status
- Loading branch information
Showing
10 changed files
with
199 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
minor_changes: | ||
- load_balancer_status - Add new filter to compute the status of a Load Balancer based on its targets. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
from __future__ import annotations | ||
|
||
from typing import Literal | ||
|
||
from ansible.errors import AnsibleFilterError | ||
from ansible.module_utils.common.text.converters import to_native | ||
|
||
|
||
# pylint: disable=unused-argument | ||
def load_balancer_status(load_balancer: dict, *args, **kwargs) -> Literal["unknown", "unhealthy", "healthy"]: | ||
""" | ||
Return the status of a Load Balancer based on its targets. | ||
""" | ||
try: | ||
result = "healthy" | ||
for target in load_balancer["targets"]: | ||
target_health_status = target.get("health_status") | ||
|
||
# Report missing health status as unknown | ||
if not target_health_status: | ||
result = "unknown" | ||
continue | ||
|
||
for health_status in target_health_status: | ||
status = health_status.get("status") | ||
if status == "healthy": | ||
continue | ||
|
||
if status in (None, "unknown"): | ||
result = "unknown" | ||
continue | ||
|
||
if status == "unhealthy": | ||
return "unhealthy" | ||
|
||
return result | ||
except Exception as exc: | ||
raise AnsibleFilterError(f"load_balancer_status - {to_native(exc)}", orig_exc=exc) from exc | ||
|
||
|
||
class FilterModule: | ||
""" | ||
Hetzner Cloud filters. | ||
""" | ||
|
||
def filters(self): | ||
return { | ||
"load_balancer_status": load_balancer_status, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
DOCUMENTATION: | ||
name: load_balancer_status | ||
version_added: 4.2.0 | ||
short_description: Compute the status of a Load Balancer | ||
description: | ||
- Compute the status of a Load Balancer based on its targets. | ||
options: | ||
_input: | ||
description: Load Balancer data. | ||
type: dict | ||
required: true | ||
EXAMPLES: | | ||
# Ensure a load balancer is healthy | ||
{{ result.hcloud_load_balancer_info[0] | hetzner.hcloud.load_balancer_status == "healthy" }} | ||
RETURN: | ||
_value: | ||
description: The status of the Load Balancer targets, can be one of C(unknown), C(unhealthy) or C(healthy). | ||
type: string |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
cloud/hcloud | ||
gather_facts/no | ||
azp/group2 |
29 changes: 29 additions & 0 deletions
29
tests/integration/targets/filter_all/defaults/main/common.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# | ||
# DO NOT EDIT THIS FILE! Please edit the files in tests/integration/common instead. | ||
# | ||
--- | ||
# Azure Pipelines will configure this value to something similar to | ||
# "azp-84824-1-hetzner-2-13-test-2-13-hcloud-3-9-1-default-i" | ||
hcloud_prefix: "tests" | ||
|
||
# Used to namespace resources created by concurrent test pipelines/targets | ||
hcloud_run_ns: "{{ hcloud_prefix | md5 }}" | ||
hcloud_role_ns: "{{ role_name | split('_') | map('batch', 2) | map('first') | flatten() | join() }}" | ||
hcloud_ns: "ansible-{{ hcloud_run_ns }}-{{ hcloud_role_ns }}" | ||
|
||
# Used to easily update the server types and images across all our tests. | ||
hcloud_server_type_name: cax11 | ||
hcloud_server_type_id: 45 | ||
|
||
hcloud_server_type_upgrade_name: cax21 | ||
hcloud_server_type_upgrade_id: 93 | ||
|
||
hcloud_image_name: debian-12 | ||
hcloud_image_id: 114690389 # architecture=arm | ||
|
||
hcloud_location_name: hel1 | ||
hcloud_location_id: 3 | ||
hcloud_datacenter_name: hel1-dc2 | ||
hcloud_datacenter_id: 3 | ||
|
||
hcloud_network_zone_name: eu-central |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
# | ||
# DO NOT EDIT THIS FILE! Please edit the files in tests/integration/common instead. | ||
# | ||
--- | ||
- name: Check if cleanup.yml exists | ||
ansible.builtin.stat: | ||
path: "{{ role_path }}/tasks/cleanup.yml" | ||
register: cleanup_file | ||
|
||
- name: Check if prepare.yml exists | ||
ansible.builtin.stat: | ||
path: "{{ role_path }}/tasks/prepare.yml" | ||
register: prepare_file | ||
|
||
- name: Include cleanup tasks | ||
ansible.builtin.include_tasks: "{{ role_path }}/tasks/cleanup.yml" | ||
when: cleanup_file.stat.exists | ||
|
||
- name: Include prepare tasks | ||
ansible.builtin.include_tasks: "{{ role_path }}/tasks/prepare.yml" | ||
when: prepare_file.stat.exists | ||
|
||
- name: Run tests | ||
block: | ||
- name: Include test tasks | ||
ansible.builtin.include_tasks: "{{ role_path }}/tasks/test.yml" | ||
|
||
always: | ||
- name: Include cleanup tasks | ||
ansible.builtin.include_tasks: "{{ role_path }}/tasks/cleanup.yml" | ||
when: cleanup_file.stat.exists |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
- name: Test filter load_balancer_status | ||
block: | ||
- name: Load data | ||
ansible.builtin.set_fact: | ||
load_balancer_status_healthy: >- | ||
{{ { "targets": [ | ||
{"health_status": [{"status": "healthy"}]}, | ||
{"health_status": [{"status": "healthy"}]}, | ||
]} | hetzner.hcloud.load_balancer_status }} | ||
load_balancer_status_healthy_and_unhealthy: >- | ||
{{ { "targets": [ | ||
{"health_status": [{"status": "healthy"}, {"status": "unhealthy"}]}, | ||
{"health_status": [{"status": "healthy"}, {"status": "healthy"}]}, | ||
]} | hetzner.hcloud.load_balancer_status }} | ||
- name: Verify filter load_balancer_status | ||
ansible.builtin.assert: | ||
that: | ||
- load_balancer_status_healthy == "healthy" | ||
- load_balancer_status_healthy_and_unhealthy == "unhealthy" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
from __future__ import annotations | ||
|
||
import pytest | ||
|
||
from plugins.filter.all import load_balancer_status | ||
|
||
LOAD_BALANCER_STATUS_TEST_CASES = ( | ||
({"targets": [{"health_status": []}]}, "unknown"), | ||
({"targets": [{"health_status": [{}]}]}, "unknown"), | ||
({"targets": [{"health_status": [{"status": "unknown"}]}]}, "unknown"), | ||
({"targets": [{"health_status": [{"status": "unhealthy"}]}]}, "unhealthy"), | ||
({"targets": [{"health_status": [{"status": "healthy"}]}]}, "healthy"), | ||
( | ||
{ | ||
"targets": [ | ||
{"health_status": [{"status": "healthy"}]}, | ||
{"health_status": [{"status": "healthy"}]}, | ||
] | ||
}, | ||
"healthy", | ||
), | ||
( | ||
{ | ||
"targets": [ | ||
{"health_status": [{"status": "healthy"}, {"status": "unhealthy"}]}, | ||
{"health_status": [{"status": "healthy"}, {"status": "unknown"}]}, | ||
] | ||
}, | ||
"unhealthy", | ||
), | ||
( | ||
{ | ||
"targets": [ | ||
{"health_status": [{"status": "healthy"}]}, | ||
{"health_status": [{"status": "unhealthy"}]}, | ||
] | ||
}, | ||
"unhealthy", | ||
), | ||
) | ||
|
||
|
||
@pytest.mark.parametrize(("value", "expected"), LOAD_BALANCER_STATUS_TEST_CASES) | ||
def test_load_balancer_status(value, expected): | ||
assert expected == load_balancer_status(value) |