|
4 | 4 |
|
5 | 5 | from backup_automation.playbook import Playbook |
6 | 6 | from backup_automation.playbook_parser import PlaybookParser, PlaybookParserSettings |
| 7 | +from backup_automation.prompt_credential_provider import PromptCredentialProvider |
7 | 8 | from backup_automation.restic.restic_backend import ResticBackend |
8 | 9 | from backup_automation.restic.restic_playbook import ResticPlaybook |
9 | 10 | from backup_automation.restic.restic_playbook_exception import ResticPlaybookException |
@@ -31,6 +32,7 @@ def __init__(self, |
31 | 32 | self.__repositories: dict[str, ResticRepository] = {} |
32 | 33 | self.__steps: list[ResticPlaybookStep] = [] |
33 | 34 | self.__format = ResticPlaybookFormat() |
| 35 | + self.__prompt_credential_provider = PromptCredentialProvider() |
34 | 36 |
|
35 | 37 | def parse(self, playbook_path: pathlib.Path) -> Playbook: |
36 | 38 | """ |
@@ -115,19 +117,30 @@ def __parse_repositories_json(self, repositories_json: JsonList) -> None: |
115 | 117 | self.__repositories[repository_id] = repository |
116 | 118 |
|
117 | 119 | def __resolve_repository_password(self, repository_id: str, password_value: str | None) -> str: |
| 120 | + # No password provided in the playbook |
118 | 121 | if not password_value: |
119 | 122 | if self.__no_interaction: |
120 | 123 | raise ResticPlaybookException(f"No password was provided for repository \"{repository_id}\"") |
121 | 124 | return getpass.getpass(f"Enter password for restic repository \"{repository_id}\": ") |
122 | 125 |
|
123 | | - if not password_value.lower().startswith(self.__format.REPOSITORIES_PASSWORD_VALUE_ENV_PREFIX): |
124 | | - return password_value |
| 126 | + # Environment password provided in the playbook |
| 127 | + if password_value.lower().startswith(self.__format.REPOSITORIES_PASSWORD_VALUE_ENV_PREFIX): |
| 128 | + password_environment_variable = password_value[len(self.__format.REPOSITORIES_PASSWORD_VALUE_ENV_PREFIX):] |
| 129 | + if password_environment_variable not in os.environ: |
| 130 | + raise ResticPlaybookException(f"Environment variable \"{password_environment_variable}\"" |
| 131 | + f" for repository \"{repository_id}\" is not defined!") |
| 132 | + return os.environ[password_environment_variable] |
125 | 133 |
|
126 | | - password_environment_variable = password_value[len(self.__format.REPOSITORIES_PASSWORD_VALUE_ENV_PREFIX):] |
127 | | - if password_environment_variable not in os.environ: |
128 | | - raise ResticPlaybookException(f"Environment variable \"{password_environment_variable}\"" |
129 | | - f" for repository \"{repository_id}\" is not defined!") |
130 | | - return os.environ[password_environment_variable] |
| 134 | + # Prompt password provided in the playbook |
| 135 | + if password_value.lower().startswith(self.__format.REPOSITORIES_PASSWORD_VALUE_PROMPT_PREFIX): |
| 136 | + if self.__no_interaction: |
| 137 | + raise ResticPlaybookException(f"Repository \"{repository_id}\" requested the prompt credential provider," |
| 138 | + f" which cannot be used in the no-interaction mode.") |
| 139 | + credential_name = password_value[len(self.__format.REPOSITORIES_PASSWORD_VALUE_PROMPT_PREFIX):] |
| 140 | + return self.__prompt_credential_provider.get_credential(credential_name) |
| 141 | + |
| 142 | + # Plain text password provided in the playbook |
| 143 | + return password_value |
131 | 144 |
|
132 | 145 | def __parse_steps_json(self, steps_json: JsonList) -> None: |
133 | 146 | step_parser = ResticPlaybookStepParser(self.__backend, self.__repository_lookup) |
|
0 commit comments