...

Text file src/github.com/datawire/ambassador/v2/python/tests/unit/test_shadow.py

Documentation: github.com/datawire/ambassador/v2/python/tests/unit

     1import logging
     2from typing import TYPE_CHECKING, Optional
     3
     4import pytest
     5
     6from tests.selfsigned import TLSCerts
     7from tests.utils import assert_valid_envoy_config
     8
     9logging.basicConfig(
    10    level=logging.INFO,
    11    format="%(asctime)s test %(levelname)s: %(message)s",
    12    datefmt="%Y-%m-%d %H:%M:%S",
    13)
    14
    15logger = logging.getLogger("ambassador")
    16
    17from ambassador import IR, Config
    18from ambassador.envoy import EnvoyConfig
    19from ambassador.fetch import ResourceFetcher
    20from ambassador.utils import SecretHandler, SecretInfo
    21
    22if TYPE_CHECKING:
    23    from ambassador.ir.irresource import IRResource  # pragma: no cover
    24
    25
    26class MockSecretHandler(SecretHandler):
    27    def load_secret(
    28        self, resource: "IRResource", secret_name: str, namespace: str
    29    ) -> Optional[SecretInfo]:
    30        return SecretInfo(
    31            "fallback-self-signed-cert",
    32            "ambassador",
    33            "mocked-fallback-secret",
    34            TLSCerts["acook"].pubcert,
    35            TLSCerts["acook"].privkey,
    36            decode_b64=False,
    37        )
    38
    39
    40def get_mirrored_config(ads_config):
    41    for l in ads_config.get("static_resources", {}).get("listeners"):
    42        for fc in l.get("filter_chains"):
    43            for f in fc.get("filters"):
    44                for vh in f["typed_config"]["route_config"]["virtual_hosts"]:
    45                    for r in vh.get("routes"):
    46                        if r["match"]["prefix"] == "/httpbin/":
    47                            return r
    48    return None
    49
    50
    51@pytest.mark.compilertest
    52def test_shadow_v3():
    53    aconf = Config()
    54
    55    yaml = """
    56---
    57apiVersion: getambassador.io/v3alpha1
    58kind: Listener
    59metadata:
    60  name: ambassador-listener-8080
    61  namespace: default
    62spec:
    63  port: 8080
    64  protocol: HTTPS
    65  securityModel: XFP
    66  hostBinding:
    67    namespace:
    68      from: ALL
    69---
    70apiVersion: getambassador.io/v3alpha1
    71kind: Mapping
    72metadata:
    73  name: httpbin-mapping
    74  namespace: default
    75spec:
    76  service: httpbin
    77  hostname: "*"
    78  prefix: /httpbin/
    79---
    80apiVersion: getambassador.io/v3alpha1
    81kind: Mapping
    82metadata:
    83  name: httpbin-mapping-shadow
    84  namespace: default
    85spec:
    86  service: httpbin-shadow
    87  hostname: "*"
    88  prefix: /httpbin/
    89  shadow: true
    90  weight: 10
    91"""
    92    fetcher = ResourceFetcher(logger, aconf)
    93    fetcher.parse_yaml(yaml, k8s=True)
    94
    95    aconf.load_all(fetcher.sorted())
    96
    97    secret_handler = MockSecretHandler(logger, "mockery", "/tmp/ambassador/snapshots", "v1")
    98    ir = IR(aconf, file_checker=lambda path: True, secret_handler=secret_handler)
    99
   100    assert ir
   101
   102    econf = EnvoyConfig.generate(ir, "V3")
   103
   104    bootstrap_config, ads_config, _ = econf.split_config()
   105    ads_config.pop("@type", None)
   106
   107    mirrored_config = get_mirrored_config(ads_config)
   108    assert "request_mirror_policies" in mirrored_config["route"]
   109    assert len(mirrored_config["route"]["request_mirror_policies"]) == 1
   110    mirror_policy = mirrored_config["route"]["request_mirror_policies"][0]
   111    assert mirror_policy["cluster"] == "cluster_shadow_httpbin_shadow_default"
   112    assert mirror_policy["runtime_fraction"]["default_value"]["numerator"] == 10
   113    assert mirror_policy["runtime_fraction"]["default_value"]["denominator"] == "HUNDRED"
   114    assert_valid_envoy_config(ads_config)
   115    assert_valid_envoy_config(bootstrap_config)
   116
   117
   118@pytest.mark.compilertest
   119def test_shadow_v2():
   120    aconf = Config()
   121
   122    yaml = """
   123---
   124apiVersion: getambassador.io/v3alpha1
   125kind: Listener
   126metadata:
   127  name: ambassador-listener-8080
   128  namespace: default
   129spec:
   130  port: 8080
   131  protocol: HTTPS
   132  securityModel: XFP
   133  hostBinding:
   134    namespace:
   135      from: ALL
   136---
   137apiVersion: getambassador.io/v3alpha1
   138kind: Mapping
   139metadata:
   140  name: httpbin-mapping
   141  namespace: default
   142spec:
   143  service: httpbin
   144  hostname: "*"
   145  prefix: /httpbin/
   146---
   147apiVersion: getambassador.io/v3alpha1
   148kind: Mapping
   149metadata:
   150  name: httpbin-mapping-shadow
   151  namespace: default
   152spec:
   153  service: httpbin-shadow
   154  hostname: "*"
   155  prefix: /httpbin/
   156  shadow: true
   157  weight: 10
   158"""
   159    fetcher = ResourceFetcher(logger, aconf)
   160    fetcher.parse_yaml(yaml, k8s=True)
   161
   162    aconf.load_all(fetcher.sorted())
   163
   164    secret_handler = MockSecretHandler(logger, "mockery", "/tmp/ambassador/snapshots", "v1")
   165    ir = IR(aconf, file_checker=lambda path: True, secret_handler=secret_handler)
   166
   167    assert ir
   168
   169    econf = EnvoyConfig.generate(ir, "V2")
   170
   171    bootstrap_config, ads_config, _ = econf.split_config()
   172    ads_config.pop("@type", None)
   173
   174    mirrored_config = get_mirrored_config(ads_config)
   175    assert "request_mirror_policy" in mirrored_config["route"]
   176    mirror_policy = mirrored_config["route"]["request_mirror_policy"]
   177    assert mirror_policy["cluster"] == "cluster_shadow_httpbin_shadow_default"
   178    assert mirror_policy["runtime_fraction"]["default_value"]["numerator"] == 10
   179    assert mirror_policy["runtime_fraction"]["default_value"]["denominator"] == "HUNDRED"
   180    assert_valid_envoy_config(ads_config, v2=True)
   181    assert_valid_envoy_config(bootstrap_config, v2=True)

View as plain text