mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-07 03:15:56 +00:00
3529 invalid comments in 528 files, grandfathered in while the linter only saw the working-tree diff. Removal ran through the linter's own collectors, so detection and deletion cannot drift: a comment whose opener line is blank before it and whose closer line is blank after it loses all its lines, anything else loses only the comment region, and a line left holding a bare delimiter goes with it. Five files keep their comments behind a nocheck marker instead. Four are upstream configs whose inline docs are upstream's own (mautrix, systemd journald, nextcloud-oidc-login, MediaWiki). In littlejs the commented-out entries ARE the deactivation mechanism for an example tile, so deleting them would delete configuration. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
64 lines
2.1 KiB
Python
64 lines
2.1 KiB
Python
import subprocess
|
|
from typing import Any
|
|
|
|
import yaml
|
|
from yaml.dumper import SafeDumper
|
|
from yaml.loader import SafeLoader
|
|
|
|
|
|
class VaultScalar(str):
|
|
"""A subclass of str to represent vault-encrypted strings."""
|
|
|
|
__slots__ = ()
|
|
|
|
|
|
def _vault_constructor(loader, node):
|
|
"""Load a !vault block as a VaultScalar so the tag survives a round-trip."""
|
|
return VaultScalar(node.value)
|
|
|
|
|
|
def _vault_representer(dumper, data):
|
|
"""Custom representer to dump VaultScalar as literal blocks."""
|
|
return dumper.represent_scalar("!vault", data, style="|")
|
|
|
|
|
|
SafeLoader.add_constructor("!vault", _vault_constructor)
|
|
getattr(yaml, "CSafeLoader", SafeLoader).add_constructor("!vault", _vault_constructor)
|
|
SafeDumper.add_representer(VaultScalar, _vault_representer)
|
|
|
|
|
|
class VaultHandler:
|
|
def __init__(self, vault_password_file: str):
|
|
self.vault_password_file = vault_password_file
|
|
|
|
def encrypt_string(self, value: str, name: str) -> str:
|
|
"""Encrypt a string using ansible-vault."""
|
|
cmd = [
|
|
"ansible-vault",
|
|
"encrypt_string",
|
|
"--stdin-name",
|
|
name,
|
|
"--vault-password-file",
|
|
self.vault_password_file,
|
|
]
|
|
proc = subprocess.run(
|
|
cmd, input=value, capture_output=True, text=True, check=False
|
|
)
|
|
if proc.returncode != 0:
|
|
raise RuntimeError(f"ansible-vault encrypt_string failed:\n{proc.stderr}")
|
|
return proc.stdout
|
|
|
|
def encrypt_leaves(self, branch: dict[str, Any], vault_pw: str):
|
|
"""Recursively encrypt all leaves (plain text values) under the credentials section."""
|
|
for key, value in branch.items():
|
|
if isinstance(value, dict):
|
|
self.encrypt_leaves(value, vault_pw)
|
|
elif isinstance(value, str) and not value.lstrip().startswith(
|
|
"$ANSIBLE_VAULT"
|
|
):
|
|
snippet = self.encrypt_string(value, key)
|
|
lines = snippet.splitlines()
|
|
indent = len(lines[1]) - len(lines[1].lstrip())
|
|
body = "\n".join(line[indent:] for line in lines[1:])
|
|
branch[key] = VaultScalar(body)
|