diff --git a/src/gcore/resources/cloud/load_balancers/listeners_custom.py b/src/gcore/resources/cloud/load_balancers/listeners_custom.py index 60f4903f..9ff0bfa1 100644 --- a/src/gcore/resources/cloud/load_balancers/listeners_custom.py +++ b/src/gcore/resources/cloud/load_balancers/listeners_custom.py @@ -42,6 +42,7 @@ def create_and_poll( protocol_port: int, allowed_cidrs: Optional[SequenceNotStr[str]] | Omit = omit, connection_limit: int | Omit = omit, + default_pool_id: str | Omit = omit, insert_x_forwarded: bool | Omit = omit, secret_id: Literal[""] | Omit = omit, sni_secret_id: SequenceNotStr[str] | Omit = omit, @@ -67,6 +68,7 @@ def create_and_poll( protocol_port=protocol_port, allowed_cidrs=allowed_cidrs, connection_limit=connection_limit, + default_pool_id=default_pool_id, insert_x_forwarded=insert_x_forwarded, secret_id=secret_id, sni_secret_id=sni_secret_id, @@ -110,6 +112,7 @@ def delete_and_poll( *, project_id: int | None = None, region_id: int | None = None, + delete_default_pool: bool | Omit = omit, polling_interval_seconds: int | Omit = omit, polling_timeout_seconds: int | Omit = omit, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, @@ -126,6 +129,7 @@ def delete_and_poll( listener_id=listener_id, project_id=project_id, region_id=region_id, + delete_default_pool=delete_default_pool, extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, @@ -146,6 +150,7 @@ def update_and_poll( *, project_id: int | None = None, region_id: int | None = None, + admin_state_up: bool | Omit = omit, allowed_cidrs: Optional[SequenceNotStr[str]] | Omit = omit, connection_limit: int | Omit = omit, name: str | Omit = omit, @@ -171,6 +176,7 @@ def update_and_poll( listener_id=listener_id, project_id=project_id, region_id=region_id, + admin_state_up=admin_state_up, allowed_cidrs=allowed_cidrs, connection_limit=connection_limit, name=name, @@ -224,6 +230,7 @@ async def create_and_poll( protocol_port: int, allowed_cidrs: Optional[SequenceNotStr[str]] | Omit = omit, connection_limit: int | Omit = omit, + default_pool_id: str | Omit = omit, insert_x_forwarded: bool | Omit = omit, secret_id: Literal[""] | Omit = omit, sni_secret_id: SequenceNotStr[str] | Omit = omit, @@ -249,6 +256,7 @@ async def create_and_poll( protocol_port=protocol_port, allowed_cidrs=allowed_cidrs, connection_limit=connection_limit, + default_pool_id=default_pool_id, insert_x_forwarded=insert_x_forwarded, secret_id=secret_id, sni_secret_id=sni_secret_id, @@ -292,6 +300,7 @@ async def delete_and_poll( *, project_id: int | None = None, region_id: int | None = None, + delete_default_pool: bool | Omit = omit, polling_interval_seconds: int | Omit = omit, polling_timeout_seconds: int | Omit = omit, timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, @@ -308,6 +317,7 @@ async def delete_and_poll( listener_id=listener_id, project_id=project_id, region_id=region_id, + delete_default_pool=delete_default_pool, extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, @@ -328,6 +338,7 @@ async def update_and_poll( *, project_id: int | None = None, region_id: int | None = None, + admin_state_up: bool | Omit = omit, allowed_cidrs: Optional[SequenceNotStr[str]] | Omit = omit, connection_limit: int | Omit = omit, name: str | Omit = omit, @@ -353,6 +364,7 @@ async def update_and_poll( listener_id=listener_id, project_id=project_id, region_id=region_id, + admin_state_up=admin_state_up, allowed_cidrs=allowed_cidrs, connection_limit=connection_limit, name=name, diff --git a/src/gcore/resources/cloud/load_balancers/pools/pools_custom.py b/src/gcore/resources/cloud/load_balancers/pools/pools_custom.py index b3e788ee..2931dc32 100644 --- a/src/gcore/resources/cloud/load_balancers/pools/pools_custom.py +++ b/src/gcore/resources/cloud/load_balancers/pools/pools_custom.py @@ -141,6 +141,7 @@ def update_and_poll( *, project_id: int | None = None, region_id: int | None = None, + admin_state_up: bool | Omit = omit, ca_secret_id: Optional[str] | Omit = omit, crl_secret_id: Optional[str] | Omit = omit, healthmonitor: Optional[pool_update_params.Healthmonitor] | Omit = omit, @@ -169,6 +170,7 @@ def update_and_poll( pool_id=pool_id, project_id=project_id, region_id=region_id, + admin_state_up=admin_state_up, ca_secret_id=ca_secret_id, crl_secret_id=crl_secret_id, healthmonitor=healthmonitor, @@ -327,6 +329,7 @@ async def update_and_poll( *, project_id: int | None = None, region_id: int | None = None, + admin_state_up: bool | Omit = omit, ca_secret_id: Optional[str] | Omit = omit, crl_secret_id: Optional[str] | Omit = omit, healthmonitor: Optional[pool_update_params.Healthmonitor] | Omit = omit, @@ -355,6 +358,7 @@ async def update_and_poll( pool_id=pool_id, project_id=project_id, region_id=region_id, + admin_state_up=admin_state_up, ca_secret_id=ca_secret_id, crl_secret_id=crl_secret_id, healthmonitor=healthmonitor, diff --git a/tests/api_resources/cloud/test_and_poll_custom.py b/tests/api_resources/cloud/test_and_poll_custom.py index 8379adee..ce49b271 100644 --- a/tests/api_resources/cloud/test_and_poll_custom.py +++ b/tests/api_resources/cloud/test_and_poll_custom.py @@ -7,6 +7,7 @@ # `scripts/test`) without needing the Prism/Steady mock server. from __future__ import annotations +import json from typing import Any, Callable import httpx @@ -682,3 +683,113 @@ def test_tasks_poll_error() -> None: router.route(url__regex=r".+").mock(return_value=httpx.Response(200, json=errored)) with pytest.raises(ValueError, match="boom"): client.cloud.tasks.poll(task_id="task-1") + + +# Parameters that the generated load-balancer methods accept but that the hand-written +# *_and_poll helpers dropped, so callers could not reach them through the convenience +# methods. Each case passes the parameter and asserts that it reaches the API request. +# (case_id, invoke, param, where it has to show up, expected value) +_LB_SUPPORTED_PARAM_CASES: list[tuple[str, Callable[[Any], Any], str, str, object]] = [ + ( + "cloud.load_balancers.listeners.create_and_poll", + lambda c: c.cloud.load_balancers.listeners.create_and_poll( + project_id=1, + region_id=1, + load_balancer_id="lb-1", + name="listener-1", + protocol="HTTP", + protocol_port=80, + default_pool_id="pool-1", + ), + "default_pool_id", + "body", + "pool-1", + ), + ( + "cloud.load_balancers.listeners.update_and_poll", + lambda c: c.cloud.load_balancers.listeners.update_and_poll( + "listener-1", + project_id=1, + region_id=1, + admin_state_up=False, + ), + "admin_state_up", + "body", + False, + ), + ( + "cloud.load_balancers.listeners.delete_and_poll", + lambda c: c.cloud.load_balancers.listeners.delete_and_poll( + "listener-1", + project_id=1, + region_id=1, + delete_default_pool=True, + ), + "delete_default_pool", + "query", + "true", + ), + ( + "cloud.load_balancers.pools.update_and_poll", + lambda c: c.cloud.load_balancers.pools.update_and_poll( + "pool-1", + project_id=1, + region_id=1, + admin_state_up=False, + ), + "admin_state_up", + "body", + False, + ), +] + +_LB_SUPPORTED_PARAM_IDS = [c[0] for c in _LB_SUPPORTED_PARAM_CASES] + + +def _assert_param_sent(case_id: str, router: respx.Router, param: str, where: str, expected: object) -> None: + action = next(call.request for call in router.calls if call.request.method != "GET") + if where == "body": + body = json.loads(action.content) + assert param in body, f"{case_id} did not send `{param}` in the request body" + assert body[param] == expected + else: + assert param in action.url.params, f"{case_id} did not send `{param}` in the query string" + assert action.url.params[param] == expected + + +@pytest.mark.parametrize( + ("case_id", "invoke", "param", "where", "expected"), + _LB_SUPPORTED_PARAM_CASES, + ids=_LB_SUPPORTED_PARAM_IDS, +) +def test_and_poll_forwards_supported_params( + case_id: str, + invoke: Callable[[Any], Any], + param: str, + where: str, + expected: object, +) -> None: + client = Gcore(base_url=base_url, api_key="test", _strict_response_validation=False) + with respx.mock(base_url=base_url) as router: + router.route(url__regex=r".+").mock(side_effect=_handler) + invoke(client) # must not raise + _assert_param_sent(case_id, router, param, where, expected) + + +@pytest.mark.parametrize( + ("case_id", "invoke", "param", "where", "expected"), + _LB_SUPPORTED_PARAM_CASES, + ids=_LB_SUPPORTED_PARAM_IDS, +) +async def test_and_poll_forwards_supported_params_async( + case_id: str, + invoke: Callable[[Any], Any], + param: str, + where: str, + expected: object, +) -> None: + client = AsyncGcore(base_url=base_url, api_key="test", _strict_response_validation=False) + with respx.mock(base_url=base_url) as router: + router.route(url__regex=r".+").mock(side_effect=_handler) + await invoke(client) # must not raise + _assert_param_sent(case_id, router, param, where, expected)