vars: implement secret generation

This commit is contained in:
DavHau
2024-07-10 17:26:47 +07:00
parent b066c3633a
commit d21926db47
5 changed files with 204 additions and 127 deletions

View File

@@ -14,13 +14,16 @@ class SecretStore(SecretStoreBase):
self.machine = machine
# no need to generate keys if we don't manage secrets
if not hasattr(self.machine, "vars_data") or not self.machine.vars_generators:
if not self.machine.vars_generators:
return
has_secrets = False
for generator in self.machine.vars_generators.values():
if "files" in generator:
for file in generator["files"].values():
if file["secret"]:
return
has_secrets = True
if not has_secrets:
return
if has_machine(self.machine.flake_dir, self.machine.name):
return
@@ -38,7 +41,7 @@ class SecretStore(SecretStoreBase):
) -> Path | None:
path = (
sops_secrets_folder(self.machine.flake_dir)
/ f"{self.machine.name}-{generator_name}-{name}"
/ f"vars-{self.machine.name}-{generator_name}-{name}"
)
encrypt_secret(
self.machine.flake_dir,
@@ -49,15 +52,15 @@ class SecretStore(SecretStoreBase):
)
return path
def get(self, service: str, name: str) -> bytes:
def get(self, generator_name: str, name: str) -> bytes:
return decrypt_secret(
self.machine.flake_dir, f"{self.machine.name}-{name}"
self.machine.flake_dir, f"vars-{self.machine.name}-{generator_name}-{name}"
).encode("utf-8")
def exists(self, service: str, name: str) -> bool:
def exists(self, generator_name: str, name: str) -> bool:
return has_secret(
self.machine.flake_dir,
f"{self.machine.name}-{name}",
f"vars-{self.machine.name}-{generator_name}-{name}",
)
def upload(self, output_dir: Path) -> None:

View File

@@ -7,6 +7,11 @@ class KeyPair:
self.privkey = privkey
class SopsSetup:
def __init__(self, keys: list[KeyPair]) -> None:
self.keys = keys
KEYS = [
KeyPair(
"age1dhwqzkah943xzc34tc3dlmfayyevcmdmxzjezdgdy33euxwf59vsp3vk3c",
@@ -29,3 +34,14 @@ def age_keys() -> list[KeyPair]:
Root directory of the tests
"""
return KEYS
@pytest.fixture
def sops_setup(
monkeypatch: pytest.MonkeyPatch,
) -> SopsSetup:
"""
Root directory of the tests
"""
monkeypatch.setenv("SOPS_AGE_KEY", KEYS[0].privkey)
return SopsSetup(KEYS)

View File

@@ -1,17 +1,15 @@
import os
from pathlib import Path
from typing import TYPE_CHECKING
import pytest
from age_keys import SopsSetup
from fixtures_flakes import generate_flake
from helpers import cli
from root import CLAN_CORE
if TYPE_CHECKING:
pass
@pytest.mark.impure
def test_generate_secret(
def test_generate_public_var(
monkeypatch: pytest.MonkeyPatch,
temporary_home: Path,
# age_keys: list["KeyPair"],
@@ -41,8 +39,58 @@ def test_generate_secret(
),
)
monkeypatch.chdir(flake.path)
cmd = ["vars", "generate", "--flake", str(flake.path), "my_machine"]
cli.run(cmd)
cli.run(["vars", "generate", "--flake", str(flake.path), "my_machine"])
assert (
flake.path / "machines" / "my_machine" / "vars" / "my_generator" / "my_secret"
).is_file()
@pytest.mark.impure
def test_generate_secret_var(
monkeypatch: pytest.MonkeyPatch,
temporary_home: Path,
sops_setup: SopsSetup,
) -> None:
flake = generate_flake(
temporary_home,
flake_template=CLAN_CORE / "templates" / "minimal",
machine_configs=dict(
my_machine=dict(
clan=dict(
core=dict(
vars=dict(
generators=dict(
my_generator=dict(
files=dict(
my_secret=dict(
secret=True,
)
),
script="echo hello > $out/my_secret",
)
)
)
)
)
)
),
)
monkeypatch.chdir(flake.path)
cli.run(
[
"secrets",
"users",
"add",
"--flake",
str(flake.path),
os.environ.get("USER", "user"),
sops_setup.keys[0].pubkey,
]
)
cli.run(["vars", "generate", "--flake", str(flake.path), "my_machine"])
assert not (
flake.path / "machines" / "my_machine" / "vars" / "my_generator" / "my_secret"
).is_file()
assert (
flake.path / "sops" / "secrets" / "vars-my_machine-my_generator-my_secret"
).is_dir()