Skip to content

Commit f06e86c

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 "mirrored_reads" to false (0, '0', or 'False', where 'False' is not case sensitive.)
1 parent 1403d5c commit f06e86c

File tree

7 files changed

+684
-5
lines changed

7 files changed

+684
-5
lines changed

configuration/lambda_config.template

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
"headers": {
1818
"max_age": $EXODUS_HEADERS_MAX_AGE
1919
},
20+
"mirror_reads": "$EXODUS_MIRROR_READS",
2021
"lambda_version": "$EXODUS_LAMBDA_VERSION",
2122
"index_filename": "$EXODUS_INDEX_FILENAME",
2223
"logging": {

exodus_lambda/functions/base.py

+9
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,15 @@ def lambda_version(self):
5959
def index(self):
6060
return self.conf["index_filename"]
6161

62+
@property
63+
def mirror_reads(self):
64+
if str(self.conf.get("mirror_reads", "true")).lower() in (
65+
"0",
66+
"false",
67+
):
68+
return False
69+
return True
70+
6271
def set_lambda_version(self, response):
6372
response.setdefault("headers", {})["x-exodus-version"] = [
6473
{"key": "X-Exodus-Version", "value": self.lambda_version}

exodus_lambda/functions/origin_request.py

+27-5
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,23 @@ 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 self.mirror_reads:
405+
# Attempt to look up content on the other side of the alias (the original
406+
# path.)
407+
# Note: Only the releasever alias is left unresolved. Other alias types
408+
# (rhui and origin aliases) are resolved.
409+
for ignore_exclusions in (False, True):
410+
mirrored_uri = self.resolve_aliases(
411+
request["uri"],
412+
ignore_exclusions=ignore_exclusions,
413+
ignore_releasever=True,
414+
)
415+
if mirrored_uri not in uris:
416+
uris.append(mirrored_uri)
417+
396418
for uri in uris:
397419
if listing_response := self.handle_listing_request(uri):
398420
self.set_cache_control(uri, listing_response)

scripts/mk-config

+1
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_MIRROR_READS=${EXODUS_MIRROR_READS:-true}
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

+1
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_MIRRORED_READS"] = ""
8990

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

tests/functions/test_base.py

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

0 commit comments

Comments
 (0)