...

Text file src/github.com/emissary-ingress/emissary/v3/python/tests/integration/utils.py

Documentation: github.com/emissary-ingress/emissary/v3/python/tests/integration

     1import os
     2import socket
     3import time
     4from collections import namedtuple
     5
     6import requests
     7import yaml
     8
     9import tests.integration.manifests as integration_manifests
    10from tests.kubeutils import apply_kube_artifacts
    11from tests.manifests import cleartext_host_manifest
    12from tests.runutils import run_and_assert
    13
    14# Assume that both of these are on the PATH if not explicitly set
    15KUBESTATUS_PATH = os.environ.get("KUBESTATUS_PATH", "kubestatus")
    16
    17
    18def install_crds() -> None:
    19    apply_kube_artifacts(
    20        namespace="emissary-system", artifacts=integration_manifests.crd_manifests()
    21    )
    22
    23
    24def install_ambassador(namespace, single_namespace=True, envs=None, debug=None):
    25    """
    26    Install Ambassador into a given namespace. NOTE WELL that although there
    27    is a 'single_namespace' parameter, this function probably needs work to do
    28    the fully-correct thing with single_namespace False.
    29
    30    :param namespace: namespace to install Ambassador in
    31    :param single_namespace: should we set AMBASSADOR_SINGLE_NAMESPACE? SEE NOTE ABOVE!
    32    :param envs: [
    33      {
    34        'name': 'ENV_NAME',
    35        'value': 'ENV_VALUE'
    36      },
    37      ...
    38      ...
    39    ]
    40    """
    41
    42    if envs is None:
    43        envs = []
    44
    45    if single_namespace:
    46        update_envs(envs, "AMBASSADOR_SINGLE_NAMESPACE", "true")
    47
    48    if debug:
    49        update_envs(envs, "AMBASSADOR_DEBUG", debug)
    50
    51    # Create namespace to install Ambassador
    52    create_namespace(namespace)
    53
    54    # Create Ambassador CRDs
    55    install_crds()
    56
    57    print("Wait for apiext to be running...")
    58    run_and_assert(
    59        [
    60            "tools/bin/kubectl",
    61            "wait",
    62            "--timeout=90s",
    63            "--for=condition=available",
    64            "deploy",
    65            "emissary-apiext",
    66            "-n",
    67            "emissary-system",
    68        ]
    69    )
    70
    71    # Proceed to install Ambassador now
    72    final_yaml = []
    73
    74    rbac_manifest_name = "rbac_namespace_scope" if single_namespace else "rbac_cluster_scope"
    75
    76    # Hackish fakes of actual KAT structures -- it's _far_ too much work to synthesize
    77    # actual KAT Nodes and Paths.
    78    fakeNode = namedtuple("fakeNode", ["namespace", "path", "ambassador_id"])
    79    fakePath = namedtuple("fakePath", ["k8s"])
    80
    81    ambassador_yaml = list(
    82        yaml.safe_load_all(
    83            integration_manifests.format(
    84                "\n".join(
    85                    [
    86                        integration_manifests.load(rbac_manifest_name),
    87                        integration_manifests.load("ambassador"),
    88                        (cleartext_host_manifest % namespace),
    89                    ]
    90                ),
    91                capabilities_block="",
    92                envs="",
    93                extra_ports="",
    94                self=fakeNode(
    95                    namespace=namespace, ambassador_id="default", path=fakePath(k8s="ambassador")
    96                ),
    97            )
    98        )
    99    )
   100
   101    for manifest in ambassador_yaml:
   102        kind = manifest.get("kind", None)
   103        metadata = manifest.get("metadata", {})
   104        name = metadata.get("name", None)
   105
   106        if (kind == "Pod") and (name == "ambassador"):
   107            # Force AMBASSADOR_ID to match ours.
   108            #
   109            # XXX This is not likely to work without single_namespace=True.
   110            for envvar in manifest["spec"]["containers"][0]["env"]:
   111                if envvar.get("name", "") == "AMBASSADOR_ID":
   112                    envvar["value"] = "default"
   113
   114            # add new envs, if any
   115            manifest["spec"]["containers"][0]["env"].extend(envs)
   116
   117    # print("INSTALLING AMBASSADOR: manifests:")
   118    # print(yaml.safe_dump_all(ambassador_yaml))
   119
   120    apply_kube_artifacts(namespace=namespace, artifacts=yaml.safe_dump_all(ambassador_yaml))
   121
   122
   123def update_envs(envs, name, value):
   124    found = False
   125
   126    for e in envs:
   127        if e["name"] == name:
   128            e["value"] = value
   129            found = True
   130            break
   131
   132    if not found:
   133        envs.append({"name": name, "value": value})
   134
   135
   136def create_namespace(namespace):
   137    apply_kube_artifacts(
   138        namespace=namespace, artifacts=integration_manifests.namespace_manifest(namespace)
   139    )
   140
   141
   142def create_qotm_mapping(namespace):
   143    qotm_mapping = f"""
   144---
   145apiVersion: getambassador.io/v3alpha1
   146kind: Mapping
   147metadata:
   148  name:  qotm-mapping
   149  namespace: {namespace}
   150spec:
   151  hostname: "*"
   152  prefix: /qotm/
   153  service: qotm
   154"""
   155
   156    apply_kube_artifacts(namespace=namespace, artifacts=qotm_mapping)
   157
   158
   159def create_httpbin_mapping(namespace):
   160    httpbin_mapping = f"""
   161---
   162apiVersion: getambassador.io/v3alpha1
   163kind: Mapping
   164metadata:
   165  name:  httpbin-mapping
   166  namespace: {namespace}
   167spec:
   168  hostname: "*"
   169  prefix: /httpbin/
   170  rewrite: /
   171  service: httpbin
   172"""
   173
   174    apply_kube_artifacts(namespace=namespace, artifacts=httpbin_mapping)
   175
   176
   177def get_code_with_retry(req, headers={}):
   178    for attempts in range(10):
   179        try:
   180            resp = requests.get(req, headers=headers, timeout=10)
   181            if resp.status_code < 500:
   182                return resp.status_code
   183            print(f"get_code_with_retry: 5xx code {resp.status_code}, retrying...")
   184        except requests.exceptions.ConnectionError as e:
   185            print(f"get_code_with_retry: ConnectionError {e}, attempt {attempts+1}")
   186        except socket.timeout as e:
   187            print(f"get_code_with_retry: socket.timeout {e}, attempt {attempts+1}")
   188        except Exception as e:
   189            print(f"get_code_with_retry: generic exception {e}, attempt {attempts+1}")
   190        time.sleep(5)
   191    return 503

View as plain text