diff --git a/cli/TODO.md b/cli/TODO.md index e0a0fff8..e32a258f 100644 --- a/cli/TODO.md +++ b/cli/TODO.md @@ -1,2 +1,3 @@ # Todo -- Test this script. It's just a draft. Checkout https://chatgpt.com/c/681d9e2b-7b28-800f-aef8-4f1427e9021d \ No newline at end of file +- Test this script. It's just a draft. Checkout https://chatgpt.com/c/681d9e2b-7b28-800f-aef8-4f1427e9021d +- Solve bugs in show_vault_variables.py \ No newline at end of file diff --git a/cli/show_vault_variables_draft.py b/cli/show_vault_variables_draft.py new file mode 100644 index 00000000..6053fc8d --- /dev/null +++ b/cli/show_vault_variables_draft.py @@ -0,0 +1,105 @@ +import argparse +import subprocess +from ansible.parsing.vault import VaultLib, VaultSecret +import sys +import yaml +import re +from utils.handler.vault import VaultScalar +from yaml.loader import SafeLoader +from yaml.dumper import SafeDumper + +# Register the custom constructor and representer for VaultScalar in PyYAML +SafeLoader.add_constructor('!vault', lambda loader, node: VaultScalar(node.value)) +SafeDumper.add_representer(VaultScalar, lambda dumper, data: dumper.represent_scalar('!vault', data)) + +def is_vault_encrypted_data(data: str) -> bool: + """Check if the given data is encrypted with Ansible Vault by looking for the vault header.""" + return data.lstrip().startswith('$ANSIBLE_VAULT') + +def decrypt_vault_data(encrypted_data: str, vault_secret: VaultSecret) -> str: + """ + Decrypt the given encrypted data using the provided vault_secret. + :param encrypted_data: Encrypted string to be decrypted + :param vault_secret: The VaultSecret instance used to decrypt the data + :return: Decrypted data as a string + """ + vault = VaultLib() + decrypted_data = vault.decrypt(encrypted_data, vault_secret) + return decrypted_data + +def decrypt_vault_file(vault_file: str, vault_password_file: str): + """ + Decrypt the Ansible Vault file and return its contents. + :param vault_file: Path to the encrypted Ansible Vault file + :param vault_password_file: Path to the file containing the Vault password + :return: Decrypted contents of the Vault file + """ + # Read the vault password + with open(vault_password_file, 'r') as f: + vault_password = f.read().strip() + + # Create a VaultSecret instance from the password + vault_secret = VaultSecret(vault_password.encode()) + + # Read the encrypted file + with open(vault_file, 'r') as f: + file_content = f.read() + + # If the file is partially encrypted, we'll decrypt only the encrypted values + decrypted_data = file_content # Start with the unmodified content + + # Find all vault-encrypted values (i.e., values starting with $ANSIBLE_VAULT) + encrypted_values = re.findall(r'^\s*([\w\.\-_]+):\s*["\']?\$ANSIBLE_VAULT[^\n]+', file_content, flags=re.MULTILINE) + + # If there are encrypted values, decrypt them + for value in encrypted_values: + # Extract the encrypted value and decrypt it + encrypted_value = re.search(r'(["\']?\$ANSIBLE_VAULT[^\n]+)', value) + if encrypted_value: + # Remove any newlines or extra spaces from the encrypted value + encrypted_value = encrypted_value.group(0).replace('\n', '').replace('\r', '') + decrypted_value = decrypt_vault_data(encrypted_value, vault_secret) + # Replace the encrypted value with the decrypted value in the content + decrypted_data = decrypted_data.replace(encrypted_value, decrypted_value.strip()) + + return decrypted_data + +def decrypt_and_display(vault_file: str, vault_password_file: str): + """ + Decrypts the Ansible Vault file and its values, then display the result. + Supports both full file and partial value encryption. + :param vault_file: Path to the encrypted Ansible Vault file + :param vault_password_file: Path to the file containing the Vault password + """ + decrypted_data = decrypt_vault_file(vault_file, vault_password_file) + + # Convert the decrypted data to a string format (YAML or JSON) + output_data = yaml.dump(yaml.safe_load(decrypted_data), default_flow_style=False) + + # Use subprocess to call `less` for paginated, scrollable output + subprocess.run(["less"], input=output_data, text=True) + +def main(): + # Set up the argument parser + parser = argparse.ArgumentParser(description="Decrypt and display variables from an Ansible Vault file.") + + # Add arguments for the vault file and vault password file + parser.add_argument( + 'vault_file', + type=str, + help="Path to the encrypted Ansible Vault file" + ) + parser.add_argument( + 'vault_password_file', + type=str, + help="Path to the file containing the Vault password" + ) + + # Parse the arguments + args = parser.parse_args() + + # Display vault variables in a scrollable manner + decrypt_and_display(args.vault_file, args.vault_password_file) + +if __name__ == "__main__": + main() diff --git a/roles/docker-akaunting/meta/schema.yml b/roles/docker-akaunting/meta/schema.yml index 069492a3..2baaa7ab 100644 --- a/roles/docker-akaunting/meta/schema.yml +++ b/roles/docker-akaunting/meta/schema.yml @@ -1,8 +1,4 @@ credentials: - database_password: - description: "Database password for MariaDB" - algorithm: "bcrypt" - validation: "^\\$2[aby]\\$.{56}$" setup_admin_password: description: "Initial admin user password for Akaunting" algorithm: "sha256" diff --git a/roles/docker-attendize/meta/schema.yml b/roles/docker-attendize/meta/schema.yml index cd880863..075c0f24 100644 --- a/roles/docker-attendize/meta/schema.yml +++ b/roles/docker-attendize/meta/schema.yml @@ -1,5 +1 @@ -credentials: - database_password: - description: "Database password for MariaDB used by Attendize" - algorithm: "bcrypt" - validation: "^\\$2[aby]\\$.{56}$" \ No newline at end of file +credentials: \ No newline at end of file diff --git a/roles/docker-baserow/meta/schema.yml b/roles/docker-baserow/meta/schema.yml index ec3ae3b6..e69de29b 100644 --- a/roles/docker-baserow/meta/schema.yml +++ b/roles/docker-baserow/meta/schema.yml @@ -1,5 +0,0 @@ -credentials: - database_password: - description: "Password for the PostgreSQL database used by Baserow" - algorithm: "bcrypt" - validation: "^\\$2[aby]\\$.{56}$" \ No newline at end of file diff --git a/roles/docker-discourse/meta/schema.yml b/roles/docker-discourse/meta/schema.yml index aaaa73bb..e69de29b 100644 --- a/roles/docker-discourse/meta/schema.yml +++ b/roles/docker-discourse/meta/schema.yml @@ -1,5 +0,0 @@ -credentials: - database_password: - description: "Password for the Discourse PostgreSQL database" - algorithm: "bcrypt" - validation: "^\\$2[aby]\\$.{56}$" \ No newline at end of file diff --git a/roles/docker-friendica/meta/schema.yml b/roles/docker-friendica/meta/schema.yml index bb3349b1..e69de29b 100644 --- a/roles/docker-friendica/meta/schema.yml +++ b/roles/docker-friendica/meta/schema.yml @@ -1,5 +0,0 @@ -credentials: - database_password: - description: "Password for the Friendica database user" - algorithm: "bcrypt" - validation: "^\\$2[aby]\\$.{56}$" \ No newline at end of file diff --git a/roles/docker-funkwhale/meta/schema.yml b/roles/docker-funkwhale/meta/schema.yml index cca1a977..75a0d5ef 100644 --- a/roles/docker-funkwhale/meta/schema.yml +++ b/roles/docker-funkwhale/meta/schema.yml @@ -1,8 +1,4 @@ credentials: - database_password: - description: "Password for the Funkwhale PostgreSQL database" - algorithm: "bcrypt" - validation: "^\\$2[aby]\\$.{56}$" django_secret: description: "Django SECRET_KEY used for cryptographic signing" algorithm: "sha256" diff --git a/roles/docker-gitea/meta/schema.yml b/roles/docker-gitea/meta/schema.yml index 6646ac89..8b137891 100644 --- a/roles/docker-gitea/meta/schema.yml +++ b/roles/docker-gitea/meta/schema.yml @@ -1,5 +1 @@ -credentials: - database_password: - description: "Password for the Gitea database user" - algorithm: "bcrypt" - validation: "^\\$2[aby]\\$.{56}$" + diff --git a/roles/docker-gitlab/meta/schema.yml b/roles/docker-gitlab/meta/schema.yml index 5f164570..9990d543 100644 --- a/roles/docker-gitlab/meta/schema.yml +++ b/roles/docker-gitlab/meta/schema.yml @@ -1,9 +1,4 @@ credentials: - database_password: - description: "Password for the GitLab PostgreSQL database" - algorithm: "bcrypt" - validation: "^\\$2[aby]\\$.{56}$" - initial_root_password: description: "Initial password for the GitLab root user" algorithm: "sha256" diff --git a/roles/docker-joomla/meta/schema.yml b/roles/docker-joomla/meta/schema.yml index 6f59e72b..e69de29b 100644 --- a/roles/docker-joomla/meta/schema.yml +++ b/roles/docker-joomla/meta/schema.yml @@ -1,5 +0,0 @@ -credentials: - database_password: - description: "Password for the Joomla database user" - algorithm: "bcrypt" - validation: "^\\$2[aby]\\$.{56}$" \ No newline at end of file diff --git a/roles/docker-keycloak/meta/schema.yml b/roles/docker-keycloak/meta/schema.yml index 1355466e..6d25881b 100644 --- a/roles/docker-keycloak/meta/schema.yml +++ b/roles/docker-keycloak/meta/schema.yml @@ -1,9 +1,4 @@ credentials: - database_password: - description: "Password for the Keycloak PostgreSQL database" - algorithm: "bcrypt" - validation: "^\\$2[aby]\\$.{56}$" - administrator_password: description: "Password for the Keycloak administrator user (used in bootstrap and CLI access)" algorithm: "sha256" diff --git a/roles/docker-listmonk/meta/schema.yml b/roles/docker-listmonk/meta/schema.yml index 149f98f7..a4a7269d 100644 --- a/roles/docker-listmonk/meta/schema.yml +++ b/roles/docker-listmonk/meta/schema.yml @@ -1,9 +1,4 @@ credentials: - database_password: - description: "Password for the Listmonk PostgreSQL database user" - algorithm: "bcrypt" - validation: "^\\$2[aby]\\$.{56}$" - administrator_password: description: "Initial password for the Listmonk administrator account" algorithm: "sha256" diff --git a/roles/docker-mastodon/meta/schema.yml b/roles/docker-mastodon/meta/schema.yml index 6102f030..f55b9de6 100644 --- a/roles/docker-mastodon/meta/schema.yml +++ b/roles/docker-mastodon/meta/schema.yml @@ -1,9 +1,4 @@ credentials: - database_password: - description: "Password for the Mastodon PostgreSQL database user" - algorithm: "bcrypt" - validation: "^\\$2[aby]\\$.{56}$" - secret_key_base: description: "Main secret key used to verify the integrity of signed cookies and tokens" algorithm: "sha256" diff --git a/roles/docker-matomo/meta/schema.yml b/roles/docker-matomo/meta/schema.yml index 2b5e6fd0..9d23684e 100644 --- a/roles/docker-matomo/meta/schema.yml +++ b/roles/docker-matomo/meta/schema.yml @@ -1,8 +1,4 @@ credentials: - database_password: - description: "Password for the Matomo database user" - algorithm: "bcrypt" - validation: "^\\$2[aby]\\$.{56}$" auth_token: description: "Authentication token for the Matomo HTTP API (used for automation and integrations)" diff --git a/roles/docker-moodle/meta/schema.yml b/roles/docker-moodle/meta/schema.yml index e783fcc5..1483b6f7 100644 --- a/roles/docker-moodle/meta/schema.yml +++ b/roles/docker-moodle/meta/schema.yml @@ -1,8 +1,4 @@ credentials: - database_password: - description: "Password for the Moodle database user" - algorithm: "bcrypt" - validation: "^\\$2[aby]\\$.{56}$" user_password: description: "Initial password for the Moodle admin user" algorithm: "sha256" diff --git a/roles/docker-nextcloud/meta/schema.yml b/roles/docker-nextcloud/meta/schema.yml index d5436076..f769ba93 100644 --- a/roles/docker-nextcloud/meta/schema.yml +++ b/roles/docker-nextcloud/meta/schema.yml @@ -1,8 +1,4 @@ credentials: - database_password: - description: "Password for the Nextcloud database user" - algorithm: "bcrypt" - validation: "^\\$2[aby]\\$.{56}$" administrator_password: description: "Initial password for the Nextcloud administrator (change immediately and enable 2FA)" diff --git a/roles/docker-openproject/meta/schema.yml b/roles/docker-openproject/meta/schema.yml index 090f4744..3796655b 100644 --- a/roles/docker-openproject/meta/schema.yml +++ b/roles/docker-openproject/meta/schema.yml @@ -1,8 +1,4 @@ credentials: - database_password: - description: "Password for the OpenProject PostgreSQL database" - algorithm: "bcrypt" - validation: "^\\$2[aby]\\$.{56}$" oauth2_proxy_cookie_secret: description: "Secret used to encrypt cookies for the OAuth2 proxy (hex-encoded, 16 bytes)" diff --git a/roles/docker-pixelfed/meta/schema.yml b/roles/docker-pixelfed/meta/schema.yml index 052a2e26..7c9b2ed1 100644 --- a/roles/docker-pixelfed/meta/schema.yml +++ b/roles/docker-pixelfed/meta/schema.yml @@ -1,9 +1,4 @@ credentials: - database_password: - description: "Password for the Pixelfed database user" - algorithm: "bcrypt" - validation: "^\\$2[aby]\\$.{56}$" - app_key: description: "Application key used for encryption in Pixelfed (.env APP_KEY)" algorithm: "plain" diff --git a/roles/docker-snipe-it/meta/schema.yml b/roles/docker-snipe-it/meta/schema.yml index 6228bf35..05b58487 100644 --- a/roles/docker-snipe-it/meta/schema.yml +++ b/roles/docker-snipe-it/meta/schema.yml @@ -1,9 +1,4 @@ credentials: - database_password: - description: "Password for the Snipe-IT database user" - algorithm: "bcrypt" - validation: "^\\$2[aby]\\$.{56}$" - app_key: description: "Application encryption key for Snipe-IT (.env APP_KEY)" algorithm: "plain" diff --git a/roles/docker-taiga/meta/schema.yml b/roles/docker-taiga/meta/schema.yml index 9a024413..91e0b8d2 100644 --- a/roles/docker-taiga/meta/schema.yml +++ b/roles/docker-taiga/meta/schema.yml @@ -1,9 +1,4 @@ credentials: - database_password: - description: "Password for the Taiga PostgreSQL database user" - algorithm: "bcrypt" - validation: "^\\$2[aby]\\$.{56}$" - secret_key: description: "Django SECRET_KEY used for cryptographic signing in Taiga" algorithm: "sha256" diff --git a/roles/docker-wordpress/meta/schema.yml b/roles/docker-wordpress/meta/schema.yml index cb92954a..ecee70a6 100644 --- a/roles/docker-wordpress/meta/schema.yml +++ b/roles/docker-wordpress/meta/schema.yml @@ -1,9 +1,4 @@ credentials: - database_password: - description: "Password for the WordPress database user" - algorithm: "bcrypt" - validation: "^\\$2[aby]\\$.{56}$" - administrator_password: description: "Initial password for the WordPress admin account" algorithm: "sha256"