Skip to content

Commit

Permalink
tests: get traefik ip from lb
Browse files Browse the repository at this point in the history
  • Loading branch information
natalian98 committed Sep 5, 2024
1 parent b4e144a commit 54c8299
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 29 deletions.
34 changes: 26 additions & 8 deletions oauth_tools/oauth_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
from os.path import join
from typing import Dict, List, Optional

from lightkube import ApiError, Client
from lightkube.resources.core_v1 import Service
from playwright.async_api import expect
from playwright.async_api._generated import BrowserContext, Page
from pytest_operator.plugin import OpsTest
Expand All @@ -17,19 +19,31 @@
logger = logging.getLogger(__name__)


async def get_k8s_service_address(ops_test: OpsTest, service_name: str, client: Client) -> Optional[str]:
"""Get the address of a LoadBalancer Kubernetes service using kubectl."""
try:
result = client.get(Service, name=service_name, namespace=ops_test.model.name)
return result.status.loadBalancer.ingress[0].ip
except ApiError as e:
logger.error(f"Error retrieving service address: {e}")
return None


async def get_reverse_proxy_app_url(
ops_test: OpsTest, ingress_app_name: str, app_name: str
ops_test: OpsTest, ingress_app_name: str, app_name: str, client: Client
) -> str:
"""Get the address of a proxied application.
Args:
ops_test (OpsTest): The ops_test fixture.
ingress_app_name (str): The ingress app's name.
app_name (str): The app's name.
client: The lightkube client.
"""
status = await ops_test.model.get_status() # noqa: F821
address = status["applications"][ingress_app_name]["public-address"]
return f"https://{address}/{ops_test.model.name}-{app_name}/"
address = await get_k8s_service_address(ops_test, f"{ingress_app_name}-lb", client)
proxy_app_url = f"https://{address}/{ops_test.model.name}-{app_name}/"
logger.debug(f"Retrieved IP address: {proxy_app_url}")
return proxy_app_url


async def deploy_identity_bundle(
Expand Down Expand Up @@ -156,14 +170,15 @@ async def click_on_sign_in_button_by_alt_text(page: Page, alt_text: str):


async def complete_auth_code_login(
page: Page, ops_test: OpsTest, ext_idp_service: ExternalIdpService
page: Page, ops_test: OpsTest, ext_idp_service: ExternalIdpService, client: Client
) -> None:
"""Take a page that is in the identity-platform's login page and login the user.
Args:
page (page): The page fixture.
ops_test (OpsTest): The ops_test fixture.
ext_idp_service (ExternalIdpService): The ExternalIdpService.
client: The lightkube client.
"""
if not isinstance(ext_idp_service, ExternalIdpService):
raise ValueError(
Expand All @@ -172,7 +187,7 @@ async def complete_auth_code_login(

expected_url = join(
await get_reverse_proxy_app_url(
ops_test, APPS.TRAEFIK_PUBLIC, APPS.IDENTITY_PLATFORM_LOGIN_UI_OPERATOR
ops_test, APPS.TRAEFIK_PUBLIC, APPS.IDENTITY_PLATFORM_LOGIN_UI_OPERATOR, client
),
"ui/login",
)
Expand All @@ -190,6 +205,7 @@ async def complete_device_login(
ops_test: OpsTest,
verification_uri_complete: str,
ext_idp_service: ExternalIdpService,
client: Client,
) -> None:
"""Perform the device code login flow.
Expand All @@ -198,11 +214,12 @@ async def complete_device_login(
ops_test (OpsTest): The ops_test fixture.
verification_uri_complete (str): The `verification_uri_complete` the user is shown.
ext_idp_service (ExternalIdpService): The ExternalIdpService.
client: The lightkube client.
"""
await page.goto(verification_uri_complete)
expected_url = join(
await get_reverse_proxy_app_url(
ops_test, APPS.TRAEFIK_PUBLIC, "identity-platform-login-ui-operator"
ops_test, APPS.TRAEFIK_PUBLIC, "identity-platform-login-ui-operator", client
),
"ui/device_code",
)
Expand All @@ -217,7 +234,7 @@ async def complete_device_login(
logger.info("Device login flow is complete")
expected_url = join(
await get_reverse_proxy_app_url(
ops_test, APPS.TRAEFIK_PUBLIC, "identity-platform-login-ui-operator"
ops_test, APPS.TRAEFIK_PUBLIC, "identity-platform-login-ui-operator", client
),
"ui/device_complete",
)
Expand Down Expand Up @@ -264,6 +281,7 @@ async def get_cookies_from_browser_by_url(browser_context: BrowserContext, url:


__all__ = [
"get_k8s_service_address",
"get_reverse_proxy_app_url",
"deploy_identity_bundle",
"clean_up_identity_bundle",
Expand Down
48 changes: 27 additions & 21 deletions tests/integration/test_bundle.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import os
from os.path import join
from pathlib import Path
from typing import Optional
from urllib.parse import parse_qs, urlparse

import pytest
Expand All @@ -19,6 +20,8 @@
get_authorization_url,
userinfo_request,
)
from lightkube import ApiError, Client
from lightkube.resources.core_v1 import Service
from playwright.async_api._generated import Page
from pytest_operator.plugin import OpsTest

Expand All @@ -42,23 +45,23 @@ def get_bundle_template() -> Path:
return get_this_script_dir() / ".." / ".." / "bundle.yaml.j2"


async def get_unit_address(ops_test: OpsTest, app_name: str, unit_num: int) -> str:
"""Get private address of a unit."""
status = await ops_test.model.get_status() # noqa: F821
return status["applications"][app_name]["units"][f"{app_name}/{unit_num}"]["address"]


async def get_app_address(ops_test: OpsTest, app_name: str) -> str:
"""Get address of an app."""
status = await ops_test.model.get_status() # noqa: F821
return status["applications"][app_name]["public-address"]
async def get_k8s_service_address(ops_test: OpsTest, service_name: str, client: Client) -> Optional[str]:
"""Get the address of a LoadBalancer Kubernetes service using kubectl."""
try:
result = client.get(Service, name=service_name, namespace=ops_test.model.name)
return result.status.loadBalancer.ingress[0].ip
except ApiError as e:
logger.error(f"Error retrieving service address: {e}")
return None


async def get_reverse_proxy_app_url(
ops_test: OpsTest, ingress_app_name: str, app_name: str
ops_test: OpsTest, ingress_app_name: str, app_name: str, client: Client
) -> str:
address = await get_app_address(ops_test, ingress_app_name)
return f"https://{address}/{ops_test.model.name}-{app_name}/"
address = await get_k8s_service_address(ops_test, f"{ingress_app_name}-lb", client)
proxy_app_url = f"https://{address}/{ops_test.model.name}-{app_name}/"
logger.debug(f"Retrieved IP address: {proxy_app_url}")
return proxy_app_url


@pytest.mark.skip_if_deployed
Expand Down Expand Up @@ -87,10 +90,10 @@ async def test_render_and_deploy_bundle(

@pytest.mark.abort_on_fail
async def test_hydra_is_up(
ops_test: OpsTest, admin_traefik_app_name: str, hydra_app_name: str
ops_test: OpsTest, admin_traefik_app_name: str, hydra_app_name: str, client: Client
) -> None:
"""Check that hydra and its environment dependencies (e.g. the database) are responsive."""
hydra_url = await get_reverse_proxy_app_url(ops_test, admin_traefik_app_name, hydra_app_name)
hydra_url = await get_reverse_proxy_app_url(ops_test, admin_traefik_app_name, hydra_app_name, client)

health_check_url = join(hydra_url, "health/ready")

Expand All @@ -100,10 +103,10 @@ async def test_hydra_is_up(

@pytest.mark.abort_on_fail
async def test_kratos_is_up(
ops_test: OpsTest, admin_traefik_app_name: str, kratos_app_name: str
ops_test: OpsTest, admin_traefik_app_name: str, kratos_app_name: str, client: Client
) -> None:
"""Check that kratos and its environment dependencies (e.g. the database) are responsive."""
kratos_url = await get_reverse_proxy_app_url(ops_test, admin_traefik_app_name, kratos_app_name)
kratos_url = await get_reverse_proxy_app_url(ops_test, admin_traefik_app_name, kratos_app_name, client)

health_check_url = join(kratos_url, "admin/health/ready")

Expand Down Expand Up @@ -246,11 +249,12 @@ async def test_authorization_code_flow(
user_email: str,
hydra_app_name: str,
public_traefik_app_name: str,
client: Client,
) -> None:
# This is a hack, we just need a server to be running on the redirect_uri
# so that when we get redirected there we don't get a connection_refused
# error.
redirect_uri = await get_reverse_proxy_app_url(ops_test, public_traefik_app_name, "dummy")
redirect_uri = await get_reverse_proxy_app_url(ops_test, public_traefik_app_name, "dummy", client)
app = ops_test.model.applications[hydra_app_name]
action = await app.units[0].run_action(
"create-oauth-client",
Expand All @@ -263,7 +267,7 @@ async def test_authorization_code_flow(
client_id = res["client-id"]
client_secret = res["client-secret"]

hydra_url = await get_reverse_proxy_app_url(ops_test, public_traefik_app_name, hydra_app_name)
hydra_url = await get_reverse_proxy_app_url(ops_test, public_traefik_app_name, hydra_app_name, client)

# Go to hydra authorization endpoint
await page.goto(get_authorization_url(hydra_url, client_id, redirect_uri))
Expand Down Expand Up @@ -298,6 +302,7 @@ async def test_client_credentials_flow(
ops_test: OpsTest,
hydra_app_name: str,
public_traefik_app_name: str,
client: Client,
) -> None:
app = ops_test.model.applications[hydra_app_name]
action = await app.units[0].run_action(
Expand All @@ -310,7 +315,7 @@ async def test_client_credentials_flow(
client_id = res["client-id"]
client_secret = res["client-secret"]

hydra_url = await get_reverse_proxy_app_url(ops_test, public_traefik_app_name, hydra_app_name)
hydra_url = await get_reverse_proxy_app_url(ops_test, public_traefik_app_name, hydra_app_name, client)

resp = client_credentials_grant_request(hydra_url, client_id, client_secret)

Expand All @@ -324,6 +329,7 @@ async def test_device_flow(
user_email: str,
hydra_app_name: str,
public_traefik_app_name: str,
client: Client,
) -> None:
scopes = ["openid", "profile", "email", "offline_access"]
app = ops_test.model.applications[hydra_app_name]
Expand All @@ -338,7 +344,7 @@ async def test_device_flow(
client_id = res["client-id"]
client_secret = res["client-secret"]

hydra_url = await get_reverse_proxy_app_url(ops_test, public_traefik_app_name, hydra_app_name)
hydra_url = await get_reverse_proxy_app_url(ops_test, public_traefik_app_name, hydra_app_name, client)

# Make the device auth request
auth_resp = device_auth_request(hydra_url, client_id, client_secret, scope=" ".join(scopes))
Expand Down

0 comments on commit 54c8299

Please sign in to comment.