Init commit
This commit is contained in:
35
README.md
Normal file
35
README.md
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
# Git Hooks
|
||||||
|
|
||||||
|
Коллекция моих собственных git hooks, написанных преимущественно на Python.
|
||||||
|
|
||||||
|
## Описание
|
||||||
|
|
||||||
|
Этот репозиторий содержит набор пользовательских git hooks для автоматизации проверок и обеспечения качества кода в процессе разработки.
|
||||||
|
|
||||||
|
## Структура
|
||||||
|
|
||||||
|
### pre-commit/
|
||||||
|
|
||||||
|
- **check-secrets-encrypted-with-ansible-vault.py** - Проверяет, что файлы с секретами (содержащие 'secret' или 'secrets' в имени) зашифрованы с помощью Ansible Vault перед коммитом
|
||||||
|
|
||||||
|
## Использование
|
||||||
|
|
||||||
|
### Ручная установка
|
||||||
|
|
||||||
|
1. Скопируйте нужный hook в директорию `.git/hooks/` вашего проекта
|
||||||
|
2. Переименуйте файл, убрав расширение (например, `pre-commit`)
|
||||||
|
3. Сделайте файл исполняемым: `chmod +x .git/hooks/pre-commit`
|
||||||
|
|
||||||
|
### Использование с lefthook
|
||||||
|
|
||||||
|
Hooks также можно использовать вместе с инструментом [lefthook](https://github.com/evilmartians/lefthook) для более удобного управления git hooks в проекте.
|
||||||
|
|
||||||
|
## Требования
|
||||||
|
|
||||||
|
- Python 3.x
|
||||||
|
- Git
|
||||||
|
- Для некоторых hooks могут потребоваться дополнительные зависимости (указаны в комментариях к файлам)
|
||||||
|
|
||||||
|
## Лицензия
|
||||||
|
|
||||||
|
Личная коллекция для собственного использования.
|
88
pre-commit/check-secrets-encrypted-with-ansible-vault.py
Executable file
88
pre-commit/check-secrets-encrypted-with-ansible-vault.py
Executable file
@@ -0,0 +1,88 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Pre-commit hook to prevent committing secret files that are not encrypted with Ansible Vault.
|
||||||
|
|
||||||
|
This hook checks if any staged files contain 'secret' or 'secrets' in their filename.
|
||||||
|
If such files are found and they don't start with '$ANSIBLE_VAULT', the commit is blocked.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import subprocess
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
ANSIBLE_VAULT_MARKER = '$ANSIBLE_VAULT'
|
||||||
|
|
||||||
|
|
||||||
|
def get_staged_files():
|
||||||
|
"""Get list of staged files for commit."""
|
||||||
|
try:
|
||||||
|
result = subprocess.run(
|
||||||
|
['git', 'diff', '--cached', '--name-only'],
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
check=True
|
||||||
|
)
|
||||||
|
return result.stdout.strip().split('\n') if result.stdout.strip() else []
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
print(f"Error getting staged files: {e}")
|
||||||
|
return []
|
||||||
|
|
||||||
|
|
||||||
|
def has_secret_in_name(filename):
|
||||||
|
"""Check if filename contains 'secret' or 'secrets'."""
|
||||||
|
basename = os.path.basename(filename).lower()
|
||||||
|
return 'secret' in basename or 'secrets' in basename
|
||||||
|
|
||||||
|
|
||||||
|
def is_ansible_vault_file(filepath):
|
||||||
|
"""Check if file starts with special vault marker."""
|
||||||
|
try:
|
||||||
|
if not os.path.exists(filepath):
|
||||||
|
return False
|
||||||
|
|
||||||
|
with open(filepath, 'r', encoding='utf-8') as f:
|
||||||
|
first_line = f.readline().strip()
|
||||||
|
return first_line.startswith(ANSIBLE_VAULT_MARKER)
|
||||||
|
except (IOError, UnicodeDecodeError):
|
||||||
|
# If we can't read the file or it's binary, assume it's not a vault file
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""Main function to check staged files."""
|
||||||
|
staged_files = get_staged_files()
|
||||||
|
|
||||||
|
if not staged_files:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
violations = []
|
||||||
|
|
||||||
|
for filepath in staged_files:
|
||||||
|
if has_secret_in_name(filepath):
|
||||||
|
if not is_ansible_vault_file(filepath):
|
||||||
|
violations.append(filepath)
|
||||||
|
|
||||||
|
if violations:
|
||||||
|
print("❌ COMMIT BLOCKED: Secret files must be encrypted with Ansible Vault!")
|
||||||
|
print("\nThe following files contain 'secret' or 'secrets' in their name")
|
||||||
|
print("but are not encrypted with Ansible Vault:")
|
||||||
|
print()
|
||||||
|
|
||||||
|
for violation in violations:
|
||||||
|
print(f" • {violation}")
|
||||||
|
|
||||||
|
print()
|
||||||
|
print("To fix this issue:")
|
||||||
|
print("1. Encrypt the file(s) with: ansible-vault encrypt <filename>")
|
||||||
|
print("2. Or rename the file(s) to not contain 'secret' or 'secrets'")
|
||||||
|
print("3. Or add the file(s) to .gitignore if they shouldn't be committed")
|
||||||
|
print()
|
||||||
|
|
||||||
|
return 1
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.exit(main())
|
Reference in New Issue
Block a user