Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a02669-87ee-7a31-b111-edc95a16e0fa
133 lines
3.7 KiB
Python
133 lines
3.7 KiB
Python
from __future__ import annotations
|
|
|
|
import sys
|
|
import tempfile
|
|
import unittest
|
|
from pathlib import Path
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
sys.path.insert(0, str(ROOT / "tools"))
|
|
|
|
from exposure import ExposureError, validate_rendered_exposure # noqa: E402
|
|
|
|
|
|
PRIVATE = """apiVersion: v1
|
|
kind: Service
|
|
metadata: {name: example}
|
|
spec: {type: ClusterIP}
|
|
"""
|
|
|
|
PUBLIC = """apiVersion: networking.k8s.io/v1
|
|
kind: Ingress
|
|
metadata: {name: example}
|
|
spec:
|
|
rules:
|
|
- host: app.example.test
|
|
"""
|
|
|
|
|
|
class ExposureTests(unittest.TestCase):
|
|
def declarations(self, rapp: str, reef: str):
|
|
temp = tempfile.TemporaryDirectory()
|
|
root = Path(temp.name)
|
|
rapp_path = root / "rapp.yaml"
|
|
reef_path = root / "reef.yaml"
|
|
rapp_path.write_text(rapp, encoding="utf-8")
|
|
reef_path.write_text(reef, encoding="utf-8")
|
|
return rapp_path, reef_path, temp
|
|
|
|
def test_private_manifest_needs_no_declarations(self) -> None:
|
|
result = validate_rendered_exposure(PRIVATE)
|
|
self.assertEqual("private", result["posture"])
|
|
|
|
def test_public_manifest_fails_without_declarations(self) -> None:
|
|
with self.assertRaisesRegex(ExposureError, "rapp-declaration"):
|
|
validate_rendered_exposure(PUBLIC)
|
|
|
|
def test_matching_grants_pass(self) -> None:
|
|
rapp, reef, temp = self.declarations(
|
|
"""exposure:
|
|
posture: public
|
|
binding_admission: production-approved
|
|
grant:
|
|
hostname: app.example.test
|
|
reason: test
|
|
approved_on: '2026-08-22'
|
|
residual_risk_owner: test
|
|
""",
|
|
"""exposure:
|
|
posture: public
|
|
grants:
|
|
- port: 443
|
|
reason: test
|
|
approved_on: '2026-08-22'
|
|
residual_risk_owner: test
|
|
""",
|
|
)
|
|
self.addCleanup(temp.cleanup)
|
|
result = validate_rendered_exposure(PUBLIC, rapp_declaration=rapp, reef_declaration=reef)
|
|
self.assertEqual(["app.example.test"], result["public_hosts"])
|
|
|
|
def test_unapproved_binding_fails(self) -> None:
|
|
rapp, reef, temp = self.declarations(
|
|
"""exposure:
|
|
posture: public
|
|
binding_admission: verified
|
|
grant: {hostname: app.example.test}
|
|
""",
|
|
"""exposure:
|
|
posture: public
|
|
grants: [{port: 443}]
|
|
""",
|
|
)
|
|
self.addCleanup(temp.cleanup)
|
|
with self.assertRaisesRegex(ExposureError, "production-approved"):
|
|
validate_rendered_exposure(PUBLIC, rapp_declaration=rapp, reef_declaration=reef)
|
|
|
|
def test_mismatched_hostname_fails(self) -> None:
|
|
rapp, reef, temp = self.declarations(
|
|
"""exposure:
|
|
posture: public
|
|
binding_admission: production-approved
|
|
grant:
|
|
hostname: other.example.test
|
|
reason: test
|
|
approved_on: '2026-08-22'
|
|
residual_risk_owner: test
|
|
""",
|
|
"""exposure:
|
|
posture: public
|
|
grants:
|
|
- port: 443
|
|
reason: test
|
|
approved_on: '2026-08-22'
|
|
residual_risk_owner: test
|
|
""",
|
|
)
|
|
self.addCleanup(temp.cleanup)
|
|
with self.assertRaisesRegex(ExposureError, "does not name"):
|
|
validate_rendered_exposure(PUBLIC, rapp_declaration=rapp, reef_declaration=reef)
|
|
|
|
def test_incomplete_grant_fails(self) -> None:
|
|
rapp, reef, temp = self.declarations(
|
|
"""exposure:
|
|
posture: public
|
|
binding_admission: production-approved
|
|
grant: {hostname: app.example.test}
|
|
""",
|
|
"""exposure:
|
|
posture: public
|
|
grants:
|
|
- port: 443
|
|
reason: test
|
|
approved_on: '2026-08-22'
|
|
residual_risk_owner: test
|
|
""",
|
|
)
|
|
self.addCleanup(temp.cleanup)
|
|
with self.assertRaisesRegex(ExposureError, "rapp grant is missing"):
|
|
validate_rendered_exposure(PUBLIC, rapp_declaration=rapp, reef_declaration=reef)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|