Skip to content

Commit f81bc93

Browse files
committed
Introduce mirrored reads [RHELDST-28332]
This commit modifies exodus-cdn's lookup behavior to enable mirrored reads. This means, that when exodus-cdn looks up content to be served for a path with a $releasever alias in effect, exodus-cdn attempts to look up content on both sides of the alias. (Previously, exodus-cdn only performed a content lookup on the destination side.) The mirrored reads are enabled by default, but they can be disabled by setting the new config option "disable_mirrored_reads" to true (1, '1', or 'True', where 'True' is not case sensitive.)
1 parent 1403d5c commit f81bc93

File tree

7 files changed

+449
-5
lines changed

7 files changed

+449
-5
lines changed

configuration/lambda_config.template

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
"headers": {
1818
"max_age": $EXODUS_HEADERS_MAX_AGE
1919
},
20+
"disable_mirrored_reads": "$EXODUS_LAMBDA_DISABLE_MIRRORED_READS",
2021
"lambda_version": "$EXODUS_LAMBDA_VERSION",
2122
"index_filename": "$EXODUS_INDEX_FILENAME",
2223
"logging": {

exodus_lambda/functions/base.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@ def lambda_version(self):
5959
def index(self):
6060
return self.conf["index_filename"]
6161

62+
@property
63+
def disable_mirrored_reads(self):
64+
if str(self.conf.get("disable_mirrored_reads", "false")).lower() in ('1', 'true'):
65+
return True
66+
return False
67+
6268
def set_lambda_version(self, response):
6369
response.setdefault("headers", {})["x-exodus-version"] = [
6470
{"key": "X-Exodus-Version", "value": self.lambda_version}

exodus_lambda/functions/origin_request.py

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -126,12 +126,14 @@ def uri_alias(self, uri, aliases, ignore_exclusions=False):
126126

127127
return uri
128128

129-
def resolve_aliases(self, uri, ignore_exclusions=False):
129+
def resolve_aliases(
130+
self, uri, ignore_exclusions=False, ignore_releasever=False
131+
):
130132
# aliases relating to origin, e.g. content/origin <=> origin
131-
132133
uri = self.uri_alias(
133134
uri, self.definitions.get("origin_alias"), ignore_exclusions
134135
)
136+
135137
# aliases relating to rhui; listing files are a special exemption
136138
# because they must be allowed to differ for rhui vs non-rhui.
137139
if not uri.endswith("/listing"):
@@ -140,9 +142,12 @@ def resolve_aliases(self, uri, ignore_exclusions=False):
140142
)
141143

142144
# aliases relating to releasever; e.g. /content/dist/rhel8/8 <=> /content/dist/rhel8/8.5
143-
uri = self.uri_alias(
144-
uri, self.definitions.get("releasever_alias"), ignore_exclusions
145-
)
145+
if not ignore_releasever:
146+
uri = self.uri_alias(
147+
uri,
148+
self.definitions.get("releasever_alias"),
149+
ignore_exclusions,
150+
)
146151

147152
self.logger.debug("Resolved request URI: %s", uri)
148153

@@ -393,6 +398,22 @@ def handler(self, event, context):
393398
if preferred_uri != fallback_uri:
394399
uris.append(fallback_uri)
395400

401+
# When exodus-cdn is looking up content to be served for a path having a
402+
# $releasever alias in effect, it should attempt to look up content on
403+
# both sides of the alias.
404+
if not self.disable_mirrored_reads:
405+
# Attempt to look up the original path.
406+
# Note: Only the releasever alias is left unresolved. Other alias types
407+
# (rhui and origin aliases) are resolved.
408+
for ignore_exclusions in (False, True):
409+
mirrored_uri = self.resolve_aliases(
410+
request["uri"],
411+
ignore_exclusions=ignore_exclusions,
412+
ignore_releasever=True,
413+
)
414+
if mirrored_uri not in uris:
415+
uris.append(mirrored_uri)
416+
396417
for uri in uris:
397418
if listing_response := self.handle_listing_request(uri):
398419
self.set_cache_control(uri, listing_response)

scripts/mk-config

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export ENV_TYPE=${ENV_TYPE:-dev}
1212
export EXODUS_TABLE=${EXODUS_TABLE:-$PROJECT-cdn-$ENV_TYPE}
1313
export EXODUS_CONFIG_TABLE=${EXODUS_CONFIG_TABLE:-$PROJECT-config-$ENV_TYPE}
1414
export EXODUS_INDEX_FILENAME=${EXODUS_INDEX_FILENAME:-.__exodus_autoindex}
15+
export EXODUS_DISABLE_MIRRORED_READS=${EXODUS_DISABLE_MIRRORED_READS:-false}
1516

1617
REVISION="${CODEBUILD_RESOLVED_SOURCE_VERSION:-$(git rev-parse HEAD)}"
1718
export EXODUS_LAMBDA_VERSION="${EXODUS_LAMBDA_VERSION:-$(date -u --iso=s) ${REVISION}}"

tests/conftest.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ def mock_conf_file():
8686
test_env["ORIGIN_REQUEST_LOGGER_LEVEL"] = "DEBUG"
8787
test_env["EXODUS_LAMBDA_VERSION"] = "fake version"
8888
test_env["EXODUS_INDEX_FILENAME"] = ".__exodus_autoindex"
89+
test_env["EXODUS_DISABLE_MIRRORED_READS"] = "false"
8990

9091
subprocess.run(
9192
["envsubst"],

tests/functions/test_base.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,3 +133,30 @@ def test_json_logger_configurable_datefmt(caplog):
133133
"response": None,
134134
},
135135
]
136+
137+
138+
@pytest.mark.parametrize(
139+
"config_value,disabled",
140+
[
141+
("True", True),
142+
("true", True),
143+
(1, True),
144+
("1", True),
145+
("", False),
146+
("false", False),
147+
],
148+
ids=[
149+
"mixed case true",
150+
"lowercase true",
151+
"int 1",
152+
"string 1",
153+
"empty string",
154+
"false string",
155+
],
156+
)
157+
def test_disable_reads(config_value, disabled):
158+
"""Verify that the disable_mirrored_reads config value produces the expected
159+
disable_mirrored_reads property."""
160+
conf = copy.deepcopy(TEST_CONF)
161+
conf["disable_mirrored_reads"] = config_value
162+
assert LambdaBase(conf_file=conf).disable_mirrored_reads == disabled

0 commit comments

Comments
 (0)