secret.py 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. import subprocess
  2. from pathlib import Path
  3. from dataclasses import dataclass
  4. from pc_backup.keepass import KeePass
  5. from pc_backup.podman import Podman
  6. @dataclass
  7. class Secret:
  8. name: str
  9. mode: int
  10. def create(self, keepass: KeePass): ...
  11. @classmethod
  12. def from_line(cls, line: str):
  13. name, type_, *args = line.split(",")
  14. match type_:
  15. case "file":
  16. sub_class = SecretFile
  17. case "keepass-attribute":
  18. sub_class = SecretKeepassAttribute
  19. case "keepass-attachment":
  20. sub_class = SecretKeepassAttachment
  21. case _:
  22. raise ValueError(f"Cannot read `{line}` as a secret spec")
  23. return sub_class.from_line(name, *args)
  24. @classmethod
  25. def read_sources(cls, file: Path) -> list["Secret"]:
  26. with open(file) as f:
  27. lines = f.readlines()
  28. return [cls.from_line(l.strip()) for l in lines]
  29. @dataclass
  30. class SecretKeepassAttachment(Secret):
  31. key: str
  32. attachment: str
  33. def create(self, keepass: KeePass):
  34. value = keepass.read_entry_attachment(self.key, self.attachment)
  35. Podman.secret_create(self.name, value=value.encode())
  36. @classmethod
  37. def from_line(cls, name: str, key: str, attachment: str):
  38. return cls(name=name, key=key, mode=0o0400, attachment=attachment)
  39. @dataclass
  40. class SecretKeepassAttribute(Secret):
  41. key: str
  42. attribute: str
  43. def create(self, keepass: KeePass):
  44. value = keepass.read_entry_attribute(self.key, self.attribute)
  45. Podman.secret_create(self.name, value=value.encode())
  46. @classmethod
  47. def from_line(cls, name: str, key: str, attribute: str):
  48. return cls(name=name, key=key, mode=0o0400, attribute=attribute)
  49. @dataclass
  50. class SecretFile(Secret):
  51. host_path: Path
  52. def create(self, keepass: KeePass):
  53. args = ["--replace", self.name, self.host_path]
  54. Podman.secret_create(self.name, host_path=self.host_path)
  55. @classmethod
  56. def from_line(cls, name: str, path: str):
  57. path = Path(path).expanduser()
  58. return cls(host_path=path, name=name, mode=0o0400)