diff --git a/src/warnet/dashboard.py b/src/warnet/dashboard.py index 199eb8ff4..6eb693911 100644 --- a/src/warnet/dashboard.py +++ b/src/warnet/dashboard.py @@ -1,6 +1,8 @@ +import sys + import click -from .k8s import get_ingress_ip_or_host, wait_for_ingress_controller +from .k8s import get_ingress_ip_or_host, wait_for_ingress_endpoint @click.command() @@ -8,19 +10,15 @@ def dashboard(): """Open the Warnet dashboard in default browser""" import webbrowser - wait_for_ingress_controller() + timeout = 300 + click.echo(f"Waiting {timeout} seconds for ingress endpoint ...") + try: + wait_for_ingress_endpoint(timeout=timeout) + except Exception as e: + click.echo(e) + sys.exit(1) ip = get_ingress_ip_or_host() - if not ip: - click.echo("Error: Could not get the IP address of the dashboard") - click.echo( - "If you are running Minikube please run 'minikube tunnel' in a separate terminal" - ) - click.echo( - "If you are running in the cloud, you may need to wait a short while while the load balancer is provisioned" - ) - return - url = f"http://{ip}" webbrowser.open(url) diff --git a/src/warnet/k8s.py b/src/warnet/k8s.py index 528dfe34f..9ae3ec42a 100644 --- a/src/warnet/k8s.py +++ b/src/warnet/k8s.py @@ -4,7 +4,7 @@ import tarfile import tempfile from pathlib import Path -from time import sleep +from time import time, sleep from typing import Optional import yaml @@ -334,6 +334,33 @@ def wait_for_ingress_controller(timeout=300): return wait_for_pod_ready(pod.metadata.name, INGRESS_NAMESPACE, timeout) +def wait_for_ingress_endpoint(timeout=300): + config.load_kube_config() + networking_v1 = client.NetworkingV1Api() + start = time() + while time() - start < timeout: + try: + ingress = networking_v1.read_namespaced_ingress(CADDY_INGRESS_NAME, LOGGING_NAMESPACE) + except ApiException as e: + msg = ( + f'Failed to read ingress with name "{CADDY_INGRESS_NAME}" from namespace "{LOGGING_NAMESPACE}"\n' + + str(e).rstrip() + ) + if e.status == 404: + msg += "\n\nDid you deploy a network with caddy enabled?" + raise Exception(msg) from e + lb_ingress = ingress.status.load_balancer.ingress + if lb_ingress and (lb_ingress[0].hostname or lb_ingress[0].ip): + return True + sleep(1) + msg = ( + f"Ingress endpoint not found within {timeout} seconds.\n" + + "If you are running Minikube please run 'minikube tunnel' in a separate terminal.\n" + + "If you are running in the cloud, you may need to wait a short while while the load balancer is provisioned" + ) + raise TimeoutError(msg) + + def get_ingress_ip_or_host(): config.load_kube_config() networking_v1 = client.NetworkingV1Api()