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