vars/password-store: implement upload and hashing

This commit is contained in:
DavHau
2024-09-09 22:13:10 +02:00
parent 33f98aba05
commit 54cb6862b1

View File

@@ -1,5 +1,6 @@
import os import os
import subprocess import subprocess
from itertools import chain
from pathlib import Path from pathlib import Path
from typing import override from typing import override
@@ -12,6 +13,7 @@ from . import SecretStoreBase
class SecretStore(SecretStoreBase): class SecretStore(SecretStoreBase):
def __init__(self, machine: Machine) -> None: def __init__(self, machine: Machine) -> None:
self.machine = machine self.machine = machine
self.entry_prefix = "clan-vars"
@property @property
def store_name(self) -> str: def store_name(self) -> str:
@@ -23,6 +25,9 @@ class SecretStore(SecretStoreBase):
"PASSWORD_STORE_DIR", f"{os.environ['HOME']}/.password-store" "PASSWORD_STORE_DIR", f"{os.environ['HOME']}/.password-store"
) )
def entry_dir(self, generator_name: str, name: str, shared: bool) -> Path:
return Path(self.entry_prefix) / self.rel_dir(generator_name, name, shared)
def _set( def _set(
self, self,
generator_name: str, generator_name: str,
@@ -38,7 +43,7 @@ class SecretStore(SecretStoreBase):
"pass", "pass",
"insert", "insert",
"-m", "-m",
str(self.rel_dir(generator_name, name, shared)), str(self.entry_dir(generator_name, name, shared)),
], ],
), ),
input=value, input=value,
@@ -53,7 +58,7 @@ class SecretStore(SecretStoreBase):
[ [
"pass", "pass",
"show", "show",
str(self.rel_dir(generator_name, name, shared)), str(self.entry_dir(generator_name, name, shared)),
], ],
), ),
check=True, check=True,
@@ -65,11 +70,10 @@ class SecretStore(SecretStoreBase):
return False return False
return ( return (
Path(self._password_store_dir) Path(self._password_store_dir)
/ f"{self.rel_dir(generator_name, name, shared)}.gpg" / f"{self.entry_dir(generator_name, name, shared)}.gpg"
).exists() ).exists()
def generate_hash(self) -> bytes: def generate_hash(self) -> bytes:
password_store = self._password_store_dir
hashes = [] hashes = []
hashes.append( hashes.append(
subprocess.run( subprocess.run(
@@ -78,17 +82,24 @@ class SecretStore(SecretStoreBase):
[ [
"git", "git",
"-C", "-C",
password_store, self._password_store_dir,
"log", "log",
"-1", "-1",
"--format=%H", "--format=%H",
f"machines/{self.machine.name}", self.entry_prefix,
], ],
), ),
stdout=subprocess.PIPE, stdout=subprocess.PIPE,
).stdout.strip() ).stdout.strip()
) )
for symlink in Path(password_store).glob(f"machines/{self.machine.name}/**/*"): shared_dir = Path(self._password_store_dir) / self.entry_prefix / "shared"
machine_dir = (
Path(self._password_store_dir)
/ self.entry_prefix
/ "per-machine"
/ self.machine.name
)
for symlink in chain(shared_dir.glob("**/*"), machine_dir.glob("**/*")):
if symlink.is_symlink(): if symlink.is_symlink():
hashes.append( hashes.append(
subprocess.run( subprocess.run(
@@ -97,7 +108,7 @@ class SecretStore(SecretStoreBase):
[ [
"git", "git",
"-C", "-C",
password_store, self._password_store_dir,
"log", "log",
"-1", "-1",
"--format=%H", "--format=%H",
@@ -128,17 +139,15 @@ class SecretStore(SecretStoreBase):
return local_hash.decode() == remote_hash return local_hash.decode() == remote_hash
# TODO: fixme
def upload(self, output_dir: Path) -> None: def upload(self, output_dir: Path) -> None:
pass for secret_var in self.get_all():
# for service in self.machine.facts_data: if not secret_var.deployed:
# for secret in self.machine.facts_data[service]["secret"]: continue
# if isinstance(secret, dict): rel_dir = self.rel_dir(
# secret_name = secret["name"] secret_var.generator, secret_var.name, secret_var.shared
# else: )
# # TODO: drop old format soon with (output_dir / rel_dir).open("wb") as f:
# secret_name = secret f.write(
# with (output_dir / secret_name).open("wb") as f: self.get(secret_var.generator, secret_var.name, secret_var.shared)
# f.chmod(0o600) )
# f.write(self.get(service, secret_name)) (output_dir / ".pass_info").write_bytes(self.generate_hash())
# (output_dir / ".pass_info").write_bytes(self.generate_hash())