Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions tests/test_volume_mount_audit.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import sys
import tempfile
import unittest
from pathlib import Path

sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "tools"))

from volume_mount_audit import build


class VolumeMountAuditTest(unittest.TestCase):
def test_detects_missing_mounts(self):
with tempfile.TemporaryDirectory() as tmpdir:
root = Path(tmpdir)
static = root / "deployment" / "mx-exporter"
helm = static / "helm" / "mx-exporter" / "templates"
helm.mkdir(parents=True)
static.joinpath("mx-exporter-daemonset.yaml").write_text(
'- name: "config-vol"\n mountPath: "/etc/config"\n- name: "var-log"\n mountPath: "/host/var/log"\n',
encoding="utf-8",
)
helm.joinpath("daemonset.yaml").write_text(
'- name: "config-vol"\n mountPath: "/etc/config"\n',
encoding="utf-8",
)

report = build(root)

self.assertEqual(report["only_in_static"], ["var-log"])


if __name__ == "__main__":
unittest.main()
55 changes: 55 additions & 0 deletions tools/volume_mount_audit.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#!/usr/bin/env python3
"""Compare static and Helm volume mounts for mx-exporter."""

from __future__ import annotations

import argparse
import json
from pathlib import Path


def extract_mounts(text: str) -> list[dict[str, str]]:
mounts = []
current_name = None
for raw_line in text.splitlines():
line = raw_line.strip()
if line.startswith('- name: "') and line.endswith('"'):
current_name = line.split('"')[1]
continue
if current_name and line.startswith('mountPath: "') and line.endswith('"'):
mounts.append({"name": current_name, "path": line.split('"')[1]})
current_name = None
return mounts


def build(repo_root: Path) -> dict[str, object]:
static_text = (repo_root / "deployment" / "mx-exporter" / "mx-exporter-daemonset.yaml").read_text(encoding="utf-8")
helm_text = (repo_root / "deployment" / "mx-exporter" / "helm" / "mx-exporter" / "templates" / "daemonset.yaml").read_text(encoding="utf-8")
static_mounts = extract_mounts(static_text)
helm_mounts = extract_mounts(helm_text)
static_names = {mount["name"] for mount in static_mounts}
helm_names = {mount["name"] for mount in helm_mounts}
return {
"static_mount_count": len(static_mounts),
"helm_mount_count": len(helm_mounts),
"only_in_static": sorted(static_names - helm_names),
"only_in_helm": sorted(helm_names - static_names),
}


def main() -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--repo-root", type=Path, default=Path("."))
parser.add_argument("--output", type=Path)
args = parser.parse_args()

text = json.dumps(build(args.repo_root), indent=2, ensure_ascii=False)
if args.output:
args.output.write_text(text + "\n", encoding="utf-8")
else:
print(text)
return 0


if __name__ == "__main__":
raise SystemExit(main())