openshift-update-proxy 1.2.0__tar.gz → 1.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (22) hide show
  1. {openshift_update_proxy-1.2.0 → openshift_update_proxy-1.3.0}/PKG-INFO +4 -2
  2. {openshift_update_proxy-1.2.0 → openshift_update_proxy-1.3.0}/README.md +3 -1
  3. {openshift_update_proxy-1.2.0 → openshift_update_proxy-1.3.0}/pyproject.toml +1 -1
  4. {openshift_update_proxy-1.2.0 → openshift_update_proxy-1.3.0}/src/openshift_update_proxy/__init__.py +1 -1
  5. {openshift_update_proxy-1.2.0 → openshift_update_proxy-1.3.0}/src/openshift_update_proxy/app.py +29 -4
  6. {openshift_update_proxy-1.2.0 → openshift_update_proxy-1.3.0}/src/openshift_update_proxy.egg-info/PKG-INFO +4 -2
  7. {openshift_update_proxy-1.2.0 → openshift_update_proxy-1.3.0}/tests/test_app.py +41 -1
  8. {openshift_update_proxy-1.2.0 → openshift_update_proxy-1.3.0}/LICENSE +0 -0
  9. {openshift_update_proxy-1.2.0 → openshift_update_proxy-1.3.0}/setup.cfg +0 -0
  10. {openshift_update_proxy-1.2.0 → openshift_update_proxy-1.3.0}/src/openshift_update_proxy/__main__.py +0 -0
  11. {openshift_update_proxy-1.2.0 → openshift_update_proxy-1.3.0}/src/openshift_update_proxy/cache.py +0 -0
  12. {openshift_update_proxy-1.2.0 → openshift_update_proxy-1.3.0}/src/openshift_update_proxy/catalog.py +0 -0
  13. {openshift_update_proxy-1.2.0 → openshift_update_proxy-1.3.0}/src/openshift_update_proxy/config.py +0 -0
  14. {openshift_update_proxy-1.2.0 → openshift_update_proxy-1.3.0}/src/openshift_update_proxy/graph.py +0 -0
  15. {openshift_update_proxy-1.2.0 → openshift_update_proxy-1.3.0}/src/openshift_update_proxy/lifecycle.py +0 -0
  16. {openshift_update_proxy-1.2.0 → openshift_update_proxy-1.3.0}/src/openshift_update_proxy.egg-info/SOURCES.txt +0 -0
  17. {openshift_update_proxy-1.2.0 → openshift_update_proxy-1.3.0}/src/openshift_update_proxy.egg-info/dependency_links.txt +0 -0
  18. {openshift_update_proxy-1.2.0 → openshift_update_proxy-1.3.0}/src/openshift_update_proxy.egg-info/entry_points.txt +0 -0
  19. {openshift_update_proxy-1.2.0 → openshift_update_proxy-1.3.0}/src/openshift_update_proxy.egg-info/requires.txt +0 -0
  20. {openshift_update_proxy-1.2.0 → openshift_update_proxy-1.3.0}/src/openshift_update_proxy.egg-info/top_level.txt +0 -0
  21. {openshift_update_proxy-1.2.0 → openshift_update_proxy-1.3.0}/tests/test_catalog.py +0 -0
  22. {openshift_update_proxy-1.2.0 → openshift_update_proxy-1.3.0}/tests/test_lifecycle.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: openshift-update-proxy
3
- Version: 1.2.0
3
+ Version: 1.3.0
4
4
  Summary: Forwarding proxy for OpenShift update resources (Cincinnati API, mirror, release signatures)
5
5
  Author-email: Simon Lauger <simon@lauger.de>
6
6
  License-Expression: Apache-2.0
@@ -189,7 +189,9 @@ curl -s "http://update-proxy.example.com:5000/configmaps/4.16.8" | oc apply -f -
189
189
 
190
190
  The optional `arch` (default `amd64`) and `channel_prefix` (default `stable`) query
191
191
  parameters select the architecture and the update channel used for the lookup, e.g.
192
- `/configmaps/4.16.8?arch=arm64`.
192
+ `/configmaps/4.16.8?arch=arm64`. Version lookups name the ConfigMap
193
+ `release-image-<version>`; digest lookups use `signature-sha256-<digest>` as the
194
+ version is not known there.
193
195
 
194
196
  Alternatively, a release digest can be passed directly:
195
197
 
@@ -158,7 +158,9 @@ curl -s "http://update-proxy.example.com:5000/configmaps/4.16.8" | oc apply -f -
158
158
 
159
159
  The optional `arch` (default `amd64`) and `channel_prefix` (default `stable`) query
160
160
  parameters select the architecture and the update channel used for the lookup, e.g.
161
- `/configmaps/4.16.8?arch=arm64`.
161
+ `/configmaps/4.16.8?arch=arm64`. Version lookups name the ConfigMap
162
+ `release-image-<version>`; digest lookups use `signature-sha256-<digest>` as the
163
+ version is not known there.
162
164
 
163
165
  Alternatively, a release digest can be passed directly:
164
166
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "openshift-update-proxy"
7
- version = "1.2.0"
7
+ version = "1.3.0"
8
8
  description = "Forwarding proxy for OpenShift update resources (Cincinnati API, mirror, release signatures)"
9
9
  readme = "README.md"
10
10
  license = "Apache-2.0"
@@ -1,3 +1,3 @@
1
1
  """OpenShift update proxy for disconnected environments."""
2
2
 
3
- __version__ = "1.2.0"
3
+ __version__ = "1.3.0"
@@ -5,6 +5,7 @@ import logging
5
5
  import re
6
6
 
7
7
  import requests
8
+ import urllib3
8
9
  from flask import Flask, Response, jsonify, request
9
10
 
10
11
  from openshift_update_proxy import __version__, catalog, graph, lifecycle
@@ -34,7 +35,7 @@ VERSION_PATTERN = re.compile(r"^(?P<major>\d+)\.(?P<minor>\d+)\.\d+[A-Za-z0-9.+-
34
35
  CONFIGMAP_TEMPLATE = """apiVersion: v1
35
36
  kind: ConfigMap
36
37
  metadata:
37
- name: signature-sha256-{short_digest}
38
+ name: {name}
38
39
  namespace: openshift-config-managed
39
40
  labels:
40
41
  release.openshift.io/verification-signatures: ""
@@ -46,6 +47,23 @@ def create_app(config: Config | None = None) -> Flask:
46
47
  app = Flask(__name__)
47
48
  app.config["proxy"] = config or Config()
48
49
 
50
+ # the insecure request warning would be emitted on every upstream call;
51
+ # skipping verification is an explicit opt-in, so silence it
52
+ if not app.config["proxy"].ssl_verify:
53
+ urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
54
+
55
+ @app.after_request
56
+ def log_request(response: Response) -> Response:
57
+ if request.path != "/healthz":
58
+ logger.info(
59
+ '%s "%s %s" %s',
60
+ request.remote_addr,
61
+ request.method,
62
+ request.full_path if request.query_string else request.path,
63
+ response.status_code,
64
+ )
65
+ return response
66
+
49
67
  @app.route("/")
50
68
  def index() -> Response:
51
69
  return jsonify(
@@ -190,9 +208,11 @@ def create_app(config: Config | None = None) -> Flask:
190
208
  digest_match = DIGEST_PATTERN.match(ref)
191
209
  version_match = VERSION_PATTERN.match(ref)
192
210
 
211
+ name = None
193
212
  if digest_match:
194
213
  digest = digest_match.group("digest")
195
214
  elif version_match:
215
+ name = f"release-image-{ref}"
196
216
  arch = request.args.get("arch", "amd64")
197
217
  channel_prefix = request.args.get("channel_prefix", "stable")
198
218
 
@@ -228,7 +248,9 @@ def create_app(config: Config | None = None) -> Flask:
228
248
  if not signatures:
229
249
  return Response("no signatures found for digest\n", status=404, mimetype="text/plain")
230
250
 
231
- return Response(_render_configmap(digest, signatures), mimetype="application/yaml")
251
+ return Response(
252
+ _render_configmap(digest, signatures, name=name), mimetype="application/yaml"
253
+ )
232
254
 
233
255
  return app
234
256
 
@@ -290,10 +312,13 @@ def _fetch_signatures(cfg: Config, digest: str, limit: int = 10) -> list[bytes]:
290
312
  return signatures
291
313
 
292
314
 
293
- def _render_configmap(digest: str, signatures: list[bytes]) -> str:
315
+ def _render_configmap(digest: str, signatures: list[bytes], name: str | None = None) -> str:
294
316
  binary_data = "\n".join(
295
317
  f" sha256-{digest}-{index}: {base64.b64encode(signature).decode('ascii')}"
296
318
  for index, signature in enumerate(signatures, start=1)
297
319
  )
298
320
 
299
- return CONFIGMAP_TEMPLATE.format(short_digest=digest[:16], binary_data=binary_data)
321
+ return CONFIGMAP_TEMPLATE.format(
322
+ name=name or f"signature-sha256-{digest[:16]}",
323
+ binary_data=binary_data,
324
+ )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: openshift-update-proxy
3
- Version: 1.2.0
3
+ Version: 1.3.0
4
4
  Summary: Forwarding proxy for OpenShift update resources (Cincinnati API, mirror, release signatures)
5
5
  Author-email: Simon Lauger <simon@lauger.de>
6
6
  License-Expression: Apache-2.0
@@ -189,7 +189,9 @@ curl -s "http://update-proxy.example.com:5000/configmaps/4.16.8" | oc apply -f -
189
189
 
190
190
  The optional `arch` (default `amd64`) and `channel_prefix` (default `stable`) query
191
191
  parameters select the architecture and the update channel used for the lookup, e.g.
192
- `/configmaps/4.16.8?arch=arm64`.
192
+ `/configmaps/4.16.8?arch=arm64`. Version lookups name the ConfigMap
193
+ `release-image-<version>`; digest lookups use `signature-sha256-<digest>` as the
194
+ version is not known there.
193
195
 
194
196
  Alternatively, a release digest can be passed directly:
195
197
 
@@ -168,7 +168,9 @@ def test_configmap_by_version_resolves_digest(client, monkeypatch):
168
168
  assert response.status_code == 200
169
169
  assert graph_calls["params"]["channel"] == "stable-4.16"
170
170
  assert graph_calls["params"]["arch"] == "arm64"
171
- assert f"sha256-{DIGEST}-1:" in response.data.decode()
171
+ body = response.data.decode()
172
+ assert "name: release-image-4.16.8" in body
173
+ assert f"sha256-{DIGEST}-1:" in body
172
174
 
173
175
 
174
176
  def test_configmap_by_version_returns_404_for_unknown_version(client, monkeypatch):
@@ -203,6 +205,44 @@ def test_configmap_by_version_rejects_invalid_arch(client):
203
205
  assert response.status_code == 400
204
206
 
205
207
 
208
+ def test_requests_are_logged(client, caplog, monkeypatch):
209
+ monkeypatch.setattr(app_module.requests, "get", lambda *a, **kw: FakeResponse(b"{}"))
210
+
211
+ with caplog.at_level("INFO", logger="openshift-update-proxy"):
212
+ client.get("/api/upgrades_info/v1/graph?channel=stable-4.16")
213
+
214
+ assert any(
215
+ '"GET /api/upgrades_info/v1/graph?channel=stable-4.16" 200' in record.message
216
+ for record in caplog.records
217
+ )
218
+
219
+
220
+ def test_healthz_is_not_logged(client, caplog):
221
+ with caplog.at_level("INFO", logger="openshift-update-proxy"):
222
+ client.get("/healthz")
223
+
224
+ assert not caplog.records
225
+
226
+
227
+ def test_insecure_warnings_disabled_when_verify_off(monkeypatch):
228
+ from openshift_update_proxy.app import create_app
229
+ from openshift_update_proxy.config import Config
230
+
231
+ calls = []
232
+ monkeypatch.setattr(
233
+ app_module.urllib3, "disable_warnings", lambda category: calls.append(category)
234
+ )
235
+
236
+ monkeypatch.setenv("INSECURE_SKIP_TLS_VERIFY", "true")
237
+ create_app(Config())
238
+ assert calls == [app_module.urllib3.exceptions.InsecureRequestWarning]
239
+
240
+ calls.clear()
241
+ monkeypatch.delenv("INSECURE_SKIP_TLS_VERIFY")
242
+ create_app(Config())
243
+ assert calls == []
244
+
245
+
206
246
  def test_ssl_verify_enabled_by_default(config):
207
247
  assert config.ssl_verify is True
208
248