From 70d76e06c0bc23c709ba4bc08e6c282af353f631 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20F=C3=A9ron?= Date: Mon, 10 Jan 2022 12:46:35 +0100 Subject: [PATCH] Fix matching a Mapping with host_redirect a Host MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Gabriel Féron fix redirect mappings thanks to @gferon Signed-off-by: AliceProxy update gold-test snapshot Signed-off-by: AliceProxy update changelog Signed-off-by: AliceProxy --- CHANGELOG.md | 5 + docs/releaseNotes.yml | 10 + python/ambassador/ir/irhost.py | 7 +- python/tests/gold/plain/snapshots/econf.json | 856 +++++++++++++++++++ python/tests/kat/t_mappingtests_plain.py | 3 - 5 files changed, 877 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c5b5bc57b8..1471eee800 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -88,6 +88,11 @@ Please see the [Envoy documentation](https://www.envoyproxy.io/docs/envoy/latest - Change: Docker BuildKit is enabled for all Emissary builds. Additionally, the Go build cache is fully enabled when building images, speeding up repeated builds. +- Bugfix: Any `Mapping` that uses the `host_redirect` field is now properly discovered and used. + Thanks to Gabriel Féron for contributing this bugfix! ([3709]) + +[3709]: https://github.com/emissary-ingress/emissary/issues/3709 + ## 2.1.1 not issued *Emissary-ingress 2.1.1 was not issued; Ambassador Edge Stack 2.1.1 uses Emissary-ingress 2.1.0.* diff --git a/docs/releaseNotes.yml b/docs/releaseNotes.yml index ad6ae74fa3..662265df79 100644 --- a/docs/releaseNotes.yml +++ b/docs/releaseNotes.yml @@ -42,6 +42,16 @@ items: build cache is fully enabled when building images, speeding up repeated builds. docs: https://github.com/moby/buildkit/blob/master/frontend/dockerfile/docs/syntax.md + - title: Correctly use Mappings with host redirects + type: bugfix + body: >- + Any Mapping that uses the host_redirect field is now properly discovered and used. Thanks + to Gabriel Féron for contributing this bugfix! + github: + - title: 3709 + link: https://github.com/emissary-ingress/emissary/issues/3709 + docs: https://github.com/emissary-ingress/emissary/issues/3709 + - version: 2.1.1 date: 'N/A' notes: diff --git a/python/ambassador/ir/irhost.py b/python/ambassador/ir/irhost.py index afd8a066b1..24c80dec99 100644 --- a/python/ambassador/ir/irhost.py +++ b/python/ambassador/ir/irhost.py @@ -383,7 +383,12 @@ def matches_httpgroup(self, group: 'IRHTTPMappingGroup') -> bool: else: # It is NOT A TYPO that we use group.get("host") here -- whether the Mapping supplies # "hostname" or "host", the Mapping code normalizes to "host" internally. - group_glob = group.get('host') or None # NOT A TYPO: see above. + + # It's possible for group.host_redirect to be None instead of missing, and it's also + # conceivably possible for group.host_redirect.host to be "", which we'd rather be + # None. Hence we do this two-line dance to massage the various cases. + host_redirecct = (group.get('host_redirect') or {}).get('host') + group_glob = group.get('host') or host_redirecct # NOT A TYPO: see above. if group_glob: host_match = hostglob_matches(self.hostname, group_glob) diff --git a/python/tests/gold/plain/snapshots/econf.json b/python/tests/gold/plain/snapshots/econf.json index edada77c54..ddbf908bbd 100644 --- a/python/tests/gold/plain/snapshots/econf.json +++ b/python/tests/gold/plain/snapshots/econf.json @@ -2587,6 +2587,68 @@ ], "name": "listener-8080-plain-*", "routes": [ + { + "match": { + "case_sensitive": true, + "headers": [ + { + "exact_match": "https", + "name": "x-forwarded-proto" + } + ], + "runtime_fraction": { + "default_value": { + "denominator": "HUNDRED", + "numerator": 100 + } + }, + "safe_regex": { + "google_re2": { + "max_program_size": 200 + }, + "regex": "/HostRedirectMapping-5/assets/([a-f0-9]{12})/images" + } + }, + "redirect": { + "host_redirect": "foobar.com", + "regex_rewrite": { + "pattern": { + "google_re2": {}, + "regex": "/HostRedirectMapping-5/assets/([a-f0-9]{12})/images" + }, + "substitution": "/images/\\1" + }, + "response_code": 4 + } + }, + { + "match": { + "case_sensitive": true, + "runtime_fraction": { + "default_value": { + "denominator": "HUNDRED", + "numerator": 100 + } + }, + "safe_regex": { + "google_re2": { + "max_program_size": 200 + }, + "regex": "/HostRedirectMapping-5/assets/([a-f0-9]{12})/images" + } + }, + "redirect": { + "host_redirect": "foobar.com", + "regex_rewrite": { + "pattern": { + "google_re2": {}, + "regex": "/HostRedirectMapping-5/assets/([a-f0-9]{12})/images" + }, + "substitution": "/images/\\1" + }, + "response_code": 4 + } + }, { "match": { "case_sensitive": true, @@ -4283,6 +4345,46 @@ "timeout": "3.000s" } }, + { + "match": { + "case_sensitive": true, + "headers": [ + { + "exact_match": "https", + "name": "x-forwarded-proto" + } + ], + "prefix": "/HostRedirectMapping-4/foo/bar/baz", + "runtime_fraction": { + "default_value": { + "denominator": "HUNDRED", + "numerator": 100 + } + } + }, + "redirect": { + "host_redirect": "foobar.com", + "prefix_rewrite": "/foobar/baz", + "response_code": 3 + } + }, + { + "match": { + "case_sensitive": true, + "prefix": "/HostRedirectMapping-4/foo/bar/baz", + "runtime_fraction": { + "default_value": { + "denominator": "HUNDRED", + "numerator": 100 + } + } + }, + "redirect": { + "host_redirect": "foobar.com", + "prefix_rewrite": "/foobar/baz", + "response_code": 3 + } + }, { "match": { "case_sensitive": true, @@ -5151,6 +5253,46 @@ "timeout": "3.000s" } }, + { + "match": { + "case_sensitive": true, + "headers": [ + { + "exact_match": "https", + "name": "x-forwarded-proto" + } + ], + "prefix": "/HostRedirectMapping-3/foo/", + "runtime_fraction": { + "default_value": { + "denominator": "HUNDRED", + "numerator": 100 + } + } + }, + "redirect": { + "host_redirect": "foobar.com", + "path_redirect": "/redirect/", + "response_code": 1 + } + }, + { + "match": { + "case_sensitive": true, + "prefix": "/HostRedirectMapping-3/foo/", + "runtime_fraction": { + "default_value": { + "denominator": "HUNDRED", + "numerator": 100 + } + } + }, + "redirect": { + "host_redirect": "foobar.com", + "path_redirect": "/redirect/", + "response_code": 1 + } + }, { "match": { "case_sensitive": true, @@ -7071,6 +7213,42 @@ ] } }, + { + "match": { + "case_sensitive": false, + "headers": [ + { + "exact_match": "https", + "name": "x-forwarded-proto" + } + ], + "prefix": "/HostRedirectMapping-2/", + "runtime_fraction": { + "default_value": { + "denominator": "HUNDRED", + "numerator": 100 + } + } + }, + "redirect": { + "host_redirect": "foobar.com" + } + }, + { + "match": { + "case_sensitive": false, + "prefix": "/HostRedirectMapping-2/", + "runtime_fraction": { + "default_value": { + "denominator": "HUNDRED", + "numerator": 100 + } + } + }, + "redirect": { + "host_redirect": "foobar.com" + } + }, { "match": { "case_sensitive": true, @@ -7599,6 +7777,42 @@ "timeout": "3.000s" } }, + { + "match": { + "case_sensitive": true, + "headers": [ + { + "exact_match": "https", + "name": "x-forwarded-proto" + } + ], + "prefix": "/HostRedirectMapping/", + "runtime_fraction": { + "default_value": { + "denominator": "HUNDRED", + "numerator": 100 + } + } + }, + "redirect": { + "host_redirect": "foobar.com" + } + }, + { + "match": { + "case_sensitive": true, + "prefix": "/HostRedirectMapping/", + "runtime_fraction": { + "default_value": { + "denominator": "HUNDRED", + "numerator": 100 + } + } + }, + "redirect": { + "host_redirect": "foobar.com" + } + }, { "match": { "case_sensitive": true, @@ -7784,6 +7998,68 @@ ], "name": "listener-8080-plain-*", "routes": [ + { + "match": { + "case_sensitive": true, + "headers": [ + { + "exact_match": "https", + "name": "x-forwarded-proto" + } + ], + "runtime_fraction": { + "default_value": { + "denominator": "HUNDRED", + "numerator": 100 + } + }, + "safe_regex": { + "google_re2": { + "max_program_size": 200 + }, + "regex": "/HostRedirectMapping-5/assets/([a-f0-9]{12})/images" + } + }, + "redirect": { + "host_redirect": "foobar.com", + "regex_rewrite": { + "pattern": { + "google_re2": {}, + "regex": "/HostRedirectMapping-5/assets/([a-f0-9]{12})/images" + }, + "substitution": "/images/\\1" + }, + "response_code": 4 + } + }, + { + "match": { + "case_sensitive": true, + "runtime_fraction": { + "default_value": { + "denominator": "HUNDRED", + "numerator": 100 + } + }, + "safe_regex": { + "google_re2": { + "max_program_size": 200 + }, + "regex": "/HostRedirectMapping-5/assets/([a-f0-9]{12})/images" + } + }, + "redirect": { + "host_redirect": "foobar.com", + "regex_rewrite": { + "pattern": { + "google_re2": {}, + "regex": "/HostRedirectMapping-5/assets/([a-f0-9]{12})/images" + }, + "substitution": "/images/\\1" + }, + "response_code": 4 + } + }, { "match": { "case_sensitive": true, @@ -9480,6 +9756,46 @@ "timeout": "3.000s" } }, + { + "match": { + "case_sensitive": true, + "headers": [ + { + "exact_match": "https", + "name": "x-forwarded-proto" + } + ], + "prefix": "/HostRedirectMapping-4/foo/bar/baz", + "runtime_fraction": { + "default_value": { + "denominator": "HUNDRED", + "numerator": 100 + } + } + }, + "redirect": { + "host_redirect": "foobar.com", + "prefix_rewrite": "/foobar/baz", + "response_code": 3 + } + }, + { + "match": { + "case_sensitive": true, + "prefix": "/HostRedirectMapping-4/foo/bar/baz", + "runtime_fraction": { + "default_value": { + "denominator": "HUNDRED", + "numerator": 100 + } + } + }, + "redirect": { + "host_redirect": "foobar.com", + "prefix_rewrite": "/foobar/baz", + "response_code": 3 + } + }, { "match": { "case_sensitive": true, @@ -10348,6 +10664,46 @@ "timeout": "3.000s" } }, + { + "match": { + "case_sensitive": true, + "headers": [ + { + "exact_match": "https", + "name": "x-forwarded-proto" + } + ], + "prefix": "/HostRedirectMapping-3/foo/", + "runtime_fraction": { + "default_value": { + "denominator": "HUNDRED", + "numerator": 100 + } + } + }, + "redirect": { + "host_redirect": "foobar.com", + "path_redirect": "/redirect/", + "response_code": 1 + } + }, + { + "match": { + "case_sensitive": true, + "prefix": "/HostRedirectMapping-3/foo/", + "runtime_fraction": { + "default_value": { + "denominator": "HUNDRED", + "numerator": 100 + } + } + }, + "redirect": { + "host_redirect": "foobar.com", + "path_redirect": "/redirect/", + "response_code": 1 + } + }, { "match": { "case_sensitive": true, @@ -12268,6 +12624,42 @@ ] } }, + { + "match": { + "case_sensitive": false, + "headers": [ + { + "exact_match": "https", + "name": "x-forwarded-proto" + } + ], + "prefix": "/HostRedirectMapping-2/", + "runtime_fraction": { + "default_value": { + "denominator": "HUNDRED", + "numerator": 100 + } + } + }, + "redirect": { + "host_redirect": "foobar.com" + } + }, + { + "match": { + "case_sensitive": false, + "prefix": "/HostRedirectMapping-2/", + "runtime_fraction": { + "default_value": { + "denominator": "HUNDRED", + "numerator": 100 + } + } + }, + "redirect": { + "host_redirect": "foobar.com" + } + }, { "match": { "case_sensitive": true, @@ -12796,6 +13188,42 @@ "timeout": "3.000s" } }, + { + "match": { + "case_sensitive": true, + "headers": [ + { + "exact_match": "https", + "name": "x-forwarded-proto" + } + ], + "prefix": "/HostRedirectMapping/", + "runtime_fraction": { + "default_value": { + "denominator": "HUNDRED", + "numerator": 100 + } + } + }, + "redirect": { + "host_redirect": "foobar.com" + } + }, + { + "match": { + "case_sensitive": true, + "prefix": "/HostRedirectMapping/", + "runtime_fraction": { + "default_value": { + "denominator": "HUNDRED", + "numerator": 100 + } + } + }, + "redirect": { + "host_redirect": "foobar.com" + } + }, { "match": { "case_sensitive": true, @@ -13001,6 +13429,68 @@ ], "name": "listener-8443-plain-*", "routes": [ + { + "match": { + "case_sensitive": true, + "headers": [ + { + "exact_match": "https", + "name": "x-forwarded-proto" + } + ], + "runtime_fraction": { + "default_value": { + "denominator": "HUNDRED", + "numerator": 100 + } + }, + "safe_regex": { + "google_re2": { + "max_program_size": 200 + }, + "regex": "/HostRedirectMapping-5/assets/([a-f0-9]{12})/images" + } + }, + "redirect": { + "host_redirect": "foobar.com", + "regex_rewrite": { + "pattern": { + "google_re2": {}, + "regex": "/HostRedirectMapping-5/assets/([a-f0-9]{12})/images" + }, + "substitution": "/images/\\1" + }, + "response_code": 4 + } + }, + { + "match": { + "case_sensitive": true, + "runtime_fraction": { + "default_value": { + "denominator": "HUNDRED", + "numerator": 100 + } + }, + "safe_regex": { + "google_re2": { + "max_program_size": 200 + }, + "regex": "/HostRedirectMapping-5/assets/([a-f0-9]{12})/images" + } + }, + "redirect": { + "host_redirect": "foobar.com", + "regex_rewrite": { + "pattern": { + "google_re2": {}, + "regex": "/HostRedirectMapping-5/assets/([a-f0-9]{12})/images" + }, + "substitution": "/images/\\1" + }, + "response_code": 4 + } + }, { "match": { "case_sensitive": true, @@ -14697,6 +15187,46 @@ "timeout": "3.000s" } }, + { + "match": { + "case_sensitive": true, + "headers": [ + { + "exact_match": "https", + "name": "x-forwarded-proto" + } + ], + "prefix": "/HostRedirectMapping-4/foo/bar/baz", + "runtime_fraction": { + "default_value": { + "denominator": "HUNDRED", + "numerator": 100 + } + } + }, + "redirect": { + "host_redirect": "foobar.com", + "prefix_rewrite": "/foobar/baz", + "response_code": 3 + } + }, + { + "match": { + "case_sensitive": true, + "prefix": "/HostRedirectMapping-4/foo/bar/baz", + "runtime_fraction": { + "default_value": { + "denominator": "HUNDRED", + "numerator": 100 + } + } + }, + "redirect": { + "host_redirect": "foobar.com", + "prefix_rewrite": "/foobar/baz", + "response_code": 3 + } + }, { "match": { "case_sensitive": true, @@ -15565,6 +16095,46 @@ "timeout": "3.000s" } }, + { + "match": { + "case_sensitive": true, + "headers": [ + { + "exact_match": "https", + "name": "x-forwarded-proto" + } + ], + "prefix": "/HostRedirectMapping-3/foo/", + "runtime_fraction": { + "default_value": { + "denominator": "HUNDRED", + "numerator": 100 + } + } + }, + "redirect": { + "host_redirect": "foobar.com", + "path_redirect": "/redirect/", + "response_code": 1 + } + }, + { + "match": { + "case_sensitive": true, + "prefix": "/HostRedirectMapping-3/foo/", + "runtime_fraction": { + "default_value": { + "denominator": "HUNDRED", + "numerator": 100 + } + } + }, + "redirect": { + "host_redirect": "foobar.com", + "path_redirect": "/redirect/", + "response_code": 1 + } + }, { "match": { "case_sensitive": true, @@ -17485,6 +18055,42 @@ ] } }, + { + "match": { + "case_sensitive": false, + "headers": [ + { + "exact_match": "https", + "name": "x-forwarded-proto" + } + ], + "prefix": "/HostRedirectMapping-2/", + "runtime_fraction": { + "default_value": { + "denominator": "HUNDRED", + "numerator": 100 + } + } + }, + "redirect": { + "host_redirect": "foobar.com" + } + }, + { + "match": { + "case_sensitive": false, + "prefix": "/HostRedirectMapping-2/", + "runtime_fraction": { + "default_value": { + "denominator": "HUNDRED", + "numerator": 100 + } + } + }, + "redirect": { + "host_redirect": "foobar.com" + } + }, { "match": { "case_sensitive": true, @@ -18013,6 +18619,42 @@ "timeout": "3.000s" } }, + { + "match": { + "case_sensitive": true, + "headers": [ + { + "exact_match": "https", + "name": "x-forwarded-proto" + } + ], + "prefix": "/HostRedirectMapping/", + "runtime_fraction": { + "default_value": { + "denominator": "HUNDRED", + "numerator": 100 + } + } + }, + "redirect": { + "host_redirect": "foobar.com" + } + }, + { + "match": { + "case_sensitive": true, + "prefix": "/HostRedirectMapping/", + "runtime_fraction": { + "default_value": { + "denominator": "HUNDRED", + "numerator": 100 + } + } + }, + "redirect": { + "host_redirect": "foobar.com" + } + }, { "match": { "case_sensitive": true, @@ -18198,6 +18840,68 @@ ], "name": "listener-8443-plain-*", "routes": [ + { + "match": { + "case_sensitive": true, + "headers": [ + { + "exact_match": "https", + "name": "x-forwarded-proto" + } + ], + "runtime_fraction": { + "default_value": { + "denominator": "HUNDRED", + "numerator": 100 + } + }, + "safe_regex": { + "google_re2": { + "max_program_size": 200 + }, + "regex": "/HostRedirectMapping-5/assets/([a-f0-9]{12})/images" + } + }, + "redirect": { + "host_redirect": "foobar.com", + "regex_rewrite": { + "pattern": { + "google_re2": {}, + "regex": "/HostRedirectMapping-5/assets/([a-f0-9]{12})/images" + }, + "substitution": "/images/\\1" + }, + "response_code": 4 + } + }, + { + "match": { + "case_sensitive": true, + "runtime_fraction": { + "default_value": { + "denominator": "HUNDRED", + "numerator": 100 + } + }, + "safe_regex": { + "google_re2": { + "max_program_size": 200 + }, + "regex": "/HostRedirectMapping-5/assets/([a-f0-9]{12})/images" + } + }, + "redirect": { + "host_redirect": "foobar.com", + "regex_rewrite": { + "pattern": { + "google_re2": {}, + "regex": "/HostRedirectMapping-5/assets/([a-f0-9]{12})/images" + }, + "substitution": "/images/\\1" + }, + "response_code": 4 + } + }, { "match": { "case_sensitive": true, @@ -19894,6 +20598,46 @@ "timeout": "3.000s" } }, + { + "match": { + "case_sensitive": true, + "headers": [ + { + "exact_match": "https", + "name": "x-forwarded-proto" + } + ], + "prefix": "/HostRedirectMapping-4/foo/bar/baz", + "runtime_fraction": { + "default_value": { + "denominator": "HUNDRED", + "numerator": 100 + } + } + }, + "redirect": { + "host_redirect": "foobar.com", + "prefix_rewrite": "/foobar/baz", + "response_code": 3 + } + }, + { + "match": { + "case_sensitive": true, + "prefix": "/HostRedirectMapping-4/foo/bar/baz", + "runtime_fraction": { + "default_value": { + "denominator": "HUNDRED", + "numerator": 100 + } + } + }, + "redirect": { + "host_redirect": "foobar.com", + "prefix_rewrite": "/foobar/baz", + "response_code": 3 + } + }, { "match": { "case_sensitive": true, @@ -20762,6 +21506,46 @@ "timeout": "3.000s" } }, + { + "match": { + "case_sensitive": true, + "headers": [ + { + "exact_match": "https", + "name": "x-forwarded-proto" + } + ], + "prefix": "/HostRedirectMapping-3/foo/", + "runtime_fraction": { + "default_value": { + "denominator": "HUNDRED", + "numerator": 100 + } + } + }, + "redirect": { + "host_redirect": "foobar.com", + "path_redirect": "/redirect/", + "response_code": 1 + } + }, + { + "match": { + "case_sensitive": true, + "prefix": "/HostRedirectMapping-3/foo/", + "runtime_fraction": { + "default_value": { + "denominator": "HUNDRED", + "numerator": 100 + } + } + }, + "redirect": { + "host_redirect": "foobar.com", + "path_redirect": "/redirect/", + "response_code": 1 + } + }, { "match": { "case_sensitive": true, @@ -22682,6 +23466,42 @@ ] } }, + { + "match": { + "case_sensitive": false, + "headers": [ + { + "exact_match": "https", + "name": "x-forwarded-proto" + } + ], + "prefix": "/HostRedirectMapping-2/", + "runtime_fraction": { + "default_value": { + "denominator": "HUNDRED", + "numerator": 100 + } + } + }, + "redirect": { + "host_redirect": "foobar.com" + } + }, + { + "match": { + "case_sensitive": false, + "prefix": "/HostRedirectMapping-2/", + "runtime_fraction": { + "default_value": { + "denominator": "HUNDRED", + "numerator": 100 + } + } + }, + "redirect": { + "host_redirect": "foobar.com" + } + }, { "match": { "case_sensitive": true, @@ -23210,6 +24030,42 @@ "timeout": "3.000s" } }, + { + "match": { + "case_sensitive": true, + "headers": [ + { + "exact_match": "https", + "name": "x-forwarded-proto" + } + ], + "prefix": "/HostRedirectMapping/", + "runtime_fraction": { + "default_value": { + "denominator": "HUNDRED", + "numerator": 100 + } + } + }, + "redirect": { + "host_redirect": "foobar.com" + } + }, + { + "match": { + "case_sensitive": true, + "prefix": "/HostRedirectMapping/", + "runtime_fraction": { + "default_value": { + "denominator": "HUNDRED", + "numerator": 100 + } + } + }, + "redirect": { + "host_redirect": "foobar.com" + } + }, { "match": { "case_sensitive": true, diff --git a/python/tests/kat/t_mappingtests_plain.py b/python/tests/kat/t_mappingtests_plain.py index b586fd8092..4c5f964f70 100644 --- a/python/tests/kat/t_mappingtests_plain.py +++ b/python/tests/kat/t_mappingtests_plain.py @@ -373,9 +373,6 @@ class HostRedirectMapping(MappingTest): target: ServiceType def init(self): - # Skip until fixing the hostglob thing. - self.skip_node = True - MappingTest.init(self, HTTP()) def config(self) -> Generator[Union[str, Tuple[Node, str]], None, None]: