Pushed by: admin License: 1CFBBDCA-31F (Starter) Timestamp: 2026-02-01T00:38:43.364720masterdev
parent
a7c906e576
commit
fcca288542
@ -0,0 +1,271 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
Git Pusher - Credentials Manager
|
||||||
|
Gère les credentials de manière sécurisée via Splunk storage/passwords
|
||||||
|
ou via un fichier chiffré local.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import json
|
||||||
|
import base64
|
||||||
|
import hashlib
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
# Chemin vers le fichier de credentials chiffré
|
||||||
|
CREDENTIALS_FILE = "/opt/splunk/etc/apps/pusher_app_prem/local/.credentials"
|
||||||
|
ENCRYPTION_KEY_FILE = "/opt/splunk/etc/apps/pusher_app_prem/local/.key"
|
||||||
|
|
||||||
|
|
||||||
|
def get_machine_id():
|
||||||
|
"""Obtenir un identifiant unique de la machine pour le chiffrement"""
|
||||||
|
machine_id = ""
|
||||||
|
|
||||||
|
# Essayer différentes sources
|
||||||
|
try:
|
||||||
|
with open('/etc/machine-id', 'r') as f:
|
||||||
|
machine_id = f.read().strip()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if not machine_id:
|
||||||
|
try:
|
||||||
|
import socket
|
||||||
|
machine_id = socket.gethostname()
|
||||||
|
except:
|
||||||
|
machine_id = "default_key"
|
||||||
|
|
||||||
|
return machine_id
|
||||||
|
|
||||||
|
|
||||||
|
def derive_key(password, salt=None):
|
||||||
|
"""Dériver une clé de chiffrement à partir d'un mot de passe"""
|
||||||
|
if salt is None:
|
||||||
|
salt = get_machine_id().encode()
|
||||||
|
|
||||||
|
# Utiliser PBKDF2-like avec SHA256
|
||||||
|
key = hashlib.pbkdf2_hmac(
|
||||||
|
'sha256',
|
||||||
|
password.encode(),
|
||||||
|
salt,
|
||||||
|
100000
|
||||||
|
)
|
||||||
|
return base64.b64encode(key).decode()
|
||||||
|
|
||||||
|
|
||||||
|
def simple_encrypt(data, key):
|
||||||
|
"""Chiffrement simple XOR (pour une sécurité basique)"""
|
||||||
|
# Pour une vraie sécurité, utiliser cryptography.fernet
|
||||||
|
key_bytes = key.encode() * (len(data) // len(key) + 1)
|
||||||
|
encrypted = bytes([a ^ b for a, b in zip(data.encode(), key_bytes[:len(data)])])
|
||||||
|
return base64.b64encode(encrypted).decode()
|
||||||
|
|
||||||
|
|
||||||
|
def simple_decrypt(encrypted_data, key):
|
||||||
|
"""Déchiffrement simple XOR"""
|
||||||
|
try:
|
||||||
|
data = base64.b64decode(encrypted_data)
|
||||||
|
key_bytes = key.encode() * (len(data) // len(key) + 1)
|
||||||
|
decrypted = bytes([a ^ b for a, b in zip(data, key_bytes[:len(data)])])
|
||||||
|
return decrypted.decode()
|
||||||
|
except Exception as e:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def get_encryption_key():
|
||||||
|
"""Obtenir ou créer la clé de chiffrement"""
|
||||||
|
if os.path.exists(ENCRYPTION_KEY_FILE):
|
||||||
|
with open(ENCRYPTION_KEY_FILE, 'r') as f:
|
||||||
|
return f.read().strip()
|
||||||
|
else:
|
||||||
|
# Générer une nouvelle clé basée sur la machine
|
||||||
|
key = derive_key(get_machine_id())
|
||||||
|
|
||||||
|
# Sauvegarder la clé
|
||||||
|
os.makedirs(os.path.dirname(ENCRYPTION_KEY_FILE), exist_ok=True)
|
||||||
|
with open(ENCRYPTION_KEY_FILE, 'w') as f:
|
||||||
|
f.write(key)
|
||||||
|
|
||||||
|
# Protéger le fichier
|
||||||
|
os.chmod(ENCRYPTION_KEY_FILE, 0o600)
|
||||||
|
|
||||||
|
return key
|
||||||
|
|
||||||
|
|
||||||
|
def save_credentials(username, password):
|
||||||
|
"""Sauvegarder les credentials de manière chiffrée"""
|
||||||
|
key = get_encryption_key()
|
||||||
|
|
||||||
|
credentials = {
|
||||||
|
'username': username,
|
||||||
|
'password': simple_encrypt(password, key)
|
||||||
|
}
|
||||||
|
|
||||||
|
os.makedirs(os.path.dirname(CREDENTIALS_FILE), exist_ok=True)
|
||||||
|
|
||||||
|
with open(CREDENTIALS_FILE, 'w') as f:
|
||||||
|
json.dump(credentials, f)
|
||||||
|
|
||||||
|
# Protéger le fichier
|
||||||
|
os.chmod(CREDENTIALS_FILE, 0o600)
|
||||||
|
|
||||||
|
print(f"✓ Credentials saved securely to {CREDENTIALS_FILE}")
|
||||||
|
|
||||||
|
|
||||||
|
def load_credentials():
|
||||||
|
"""Charger les credentials chiffrés"""
|
||||||
|
if not os.path.exists(CREDENTIALS_FILE):
|
||||||
|
return None, None
|
||||||
|
|
||||||
|
try:
|
||||||
|
key = get_encryption_key()
|
||||||
|
|
||||||
|
with open(CREDENTIALS_FILE, 'r') as f:
|
||||||
|
credentials = json.load(f)
|
||||||
|
|
||||||
|
username = credentials.get('username')
|
||||||
|
encrypted_password = credentials.get('password')
|
||||||
|
|
||||||
|
password = simple_decrypt(encrypted_password, key)
|
||||||
|
|
||||||
|
return username, password
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error loading credentials: {e}", file=sys.stderr)
|
||||||
|
return None, None
|
||||||
|
|
||||||
|
|
||||||
|
def delete_credentials():
|
||||||
|
"""Supprimer les credentials stockés"""
|
||||||
|
if os.path.exists(CREDENTIALS_FILE):
|
||||||
|
os.remove(CREDENTIALS_FILE)
|
||||||
|
print("✓ Credentials deleted")
|
||||||
|
else:
|
||||||
|
print("No credentials file found")
|
||||||
|
|
||||||
|
|
||||||
|
def get_credentials_for_script():
|
||||||
|
"""
|
||||||
|
Fonction utilisée par le script de démarrage pour obtenir les credentials.
|
||||||
|
Retourne username et password, ou None si non configurés.
|
||||||
|
"""
|
||||||
|
username, password = load_credentials()
|
||||||
|
|
||||||
|
if username and password:
|
||||||
|
return username, password
|
||||||
|
|
||||||
|
# Fallback sur les variables d'environnement
|
||||||
|
env_user = os.environ.get('SPLUNK_USERNAME')
|
||||||
|
env_pass = os.environ.get('SPLUNK_PASSWORD')
|
||||||
|
|
||||||
|
if env_user and env_pass:
|
||||||
|
return env_user, env_pass
|
||||||
|
|
||||||
|
return None, None
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# CLI
|
||||||
|
# ============================================
|
||||||
|
|
||||||
|
def interactive_setup():
|
||||||
|
"""Configuration interactive des credentials"""
|
||||||
|
print("=" * 50)
|
||||||
|
print("Git Pusher - Credentials Setup")
|
||||||
|
print("=" * 50)
|
||||||
|
print()
|
||||||
|
print("This will securely store your Splunk credentials.")
|
||||||
|
print(f"Credentials will be encrypted and saved to:")
|
||||||
|
print(f" {CREDENTIALS_FILE}")
|
||||||
|
print()
|
||||||
|
|
||||||
|
username = input("Splunk Username [admin]: ").strip() or "admin"
|
||||||
|
|
||||||
|
import getpass
|
||||||
|
password = getpass.getpass("Splunk Password: ")
|
||||||
|
|
||||||
|
if not password:
|
||||||
|
print("Error: Password cannot be empty")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Confirmer
|
||||||
|
password2 = getpass.getpass("Confirm Password: ")
|
||||||
|
|
||||||
|
if password != password2:
|
||||||
|
print("Error: Passwords do not match")
|
||||||
|
return
|
||||||
|
|
||||||
|
save_credentials(username, password)
|
||||||
|
print()
|
||||||
|
print("✓ Credentials configured successfully!")
|
||||||
|
print()
|
||||||
|
print("You can now start Git Pusher without specifying credentials:")
|
||||||
|
print(" ./start_git_pusher.sh start")
|
||||||
|
|
||||||
|
|
||||||
|
def show_status():
|
||||||
|
"""Afficher le statut des credentials"""
|
||||||
|
print("=" * 50)
|
||||||
|
print("Credentials Status")
|
||||||
|
print("=" * 50)
|
||||||
|
|
||||||
|
if os.path.exists(CREDENTIALS_FILE):
|
||||||
|
print(f"✓ Credentials file exists: {CREDENTIALS_FILE}")
|
||||||
|
|
||||||
|
username, password = load_credentials()
|
||||||
|
if username:
|
||||||
|
print(f" Username: {username}")
|
||||||
|
print(f" Password: {'*' * len(password) if password else 'ERROR'}")
|
||||||
|
else:
|
||||||
|
print(" Error: Could not decrypt credentials")
|
||||||
|
else:
|
||||||
|
print("✗ No credentials file found")
|
||||||
|
print()
|
||||||
|
print("Run: python credentials_manager.py setup")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
if len(sys.argv) < 2:
|
||||||
|
show_status()
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
command = sys.argv[1]
|
||||||
|
|
||||||
|
if command == 'setup':
|
||||||
|
interactive_setup()
|
||||||
|
|
||||||
|
elif command == 'status':
|
||||||
|
show_status()
|
||||||
|
|
||||||
|
elif command == 'delete':
|
||||||
|
delete_credentials()
|
||||||
|
|
||||||
|
elif command == 'get':
|
||||||
|
# Pour utilisation dans les scripts bash
|
||||||
|
username, password = get_credentials_for_script()
|
||||||
|
if username and password:
|
||||||
|
print(f"{username}")
|
||||||
|
print(f"{password}")
|
||||||
|
else:
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
elif command == 'export':
|
||||||
|
# Exporter pour utilisation dans bash
|
||||||
|
username, password = get_credentials_for_script()
|
||||||
|
if username and password:
|
||||||
|
print(f"export SPLUNK_USERNAME='{username}'")
|
||||||
|
print(f"export SPLUNK_PASSWORD='{password}'")
|
||||||
|
else:
|
||||||
|
print("# No credentials found", file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
else:
|
||||||
|
print("Usage: python credentials_manager.py [setup|status|delete|get|export]")
|
||||||
|
print()
|
||||||
|
print("Commands:")
|
||||||
|
print(" setup - Configure credentials interactively")
|
||||||
|
print(" status - Show credentials status")
|
||||||
|
print(" delete - Delete stored credentials")
|
||||||
|
print(" get - Output credentials (for scripts)")
|
||||||
|
print(" export - Output as bash export commands")
|
||||||
@ -1 +1 @@
|
|||||||
212462
|
431858
|
||||||
|
|||||||
@ -0,0 +1,249 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# ============================================
|
||||||
|
# Git Pusher - Start Script
|
||||||
|
# Version 2.0 avec système de licence
|
||||||
|
# ============================================
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
SPLUNK_HOME=${SPLUNK_HOME:-/opt/splunk}
|
||||||
|
APP_HOME="${SPLUNK_HOME}/etc/apps/pusher_app_prem"
|
||||||
|
BIN_DIR="${APP_HOME}/bin"
|
||||||
|
LOG_DIR="${SPLUNK_HOME}/var/log/splunk"
|
||||||
|
PID_FILE="${BIN_DIR}/git_pusher.pid"
|
||||||
|
|
||||||
|
# Couleurs pour les logs
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
# Fonction de logging
|
||||||
|
log_info() {
|
||||||
|
echo -e "${GREEN}[INFO]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
log_warn() {
|
||||||
|
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
log_error() {
|
||||||
|
echo -e "${RED}[ERROR]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Vérifier si le serveur est déjà en cours d'exécution
|
||||||
|
check_running() {
|
||||||
|
if [ -f "$PID_FILE" ]; then
|
||||||
|
PID=$(cat "$PID_FILE")
|
||||||
|
if ps -p $PID > /dev/null 2>&1; then
|
||||||
|
return 0 # Running
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
return 1 # Not running
|
||||||
|
}
|
||||||
|
|
||||||
|
# Démarrer le serveur
|
||||||
|
start_server() {
|
||||||
|
log_info "Starting Git Pusher server..."
|
||||||
|
|
||||||
|
# Vérifier si déjà en cours
|
||||||
|
if check_running; then
|
||||||
|
log_warn "Git Pusher is already running (PID: $(cat $PID_FILE))"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Créer le répertoire de logs
|
||||||
|
mkdir -p "$LOG_DIR"
|
||||||
|
|
||||||
|
# Variables d'environnement pour l'authentification Splunk
|
||||||
|
# IMPORTANT: Modifiez ces valeurs ou utilisez des variables d'environnement
|
||||||
|
export SPLUNK_USERNAME=${SPLUNK_USERNAME:-admin}
|
||||||
|
export SPLUNK_PASSWORD=${SPLUNK_PASSWORD:-changeme}
|
||||||
|
|
||||||
|
# Démarrer le serveur Python
|
||||||
|
cd "$BIN_DIR"
|
||||||
|
python3 git_pusher.py > "${LOG_DIR}/git_pusher_startup.log" 2>&1 &
|
||||||
|
|
||||||
|
# Sauvegarder le PID
|
||||||
|
echo $! > "$PID_FILE"
|
||||||
|
|
||||||
|
# Attendre un peu et vérifier
|
||||||
|
sleep 2
|
||||||
|
|
||||||
|
if check_running; then
|
||||||
|
log_info "Git Pusher started successfully (PID: $(cat $PID_FILE))"
|
||||||
|
log_info "Server listening on port 9999"
|
||||||
|
|
||||||
|
# Vérifier le statut de la licence
|
||||||
|
HOSTNAME=$(hostname)
|
||||||
|
log_info "Hostname: $HOSTNAME"
|
||||||
|
|
||||||
|
if [ -f "${APP_HOME}/local/license.lic" ]; then
|
||||||
|
log_info "License file found"
|
||||||
|
else
|
||||||
|
log_warn "No license file found at ${APP_HOME}/local/license.lic"
|
||||||
|
log_warn "The application will require license activation"
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
log_error "Failed to start Git Pusher"
|
||||||
|
log_error "Check logs at ${LOG_DIR}/git_pusher.log"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Arrêter le serveur
|
||||||
|
stop_server() {
|
||||||
|
log_info "Stopping Git Pusher server..."
|
||||||
|
|
||||||
|
if [ -f "$PID_FILE" ]; then
|
||||||
|
PID=$(cat "$PID_FILE")
|
||||||
|
|
||||||
|
if ps -p $PID > /dev/null 2>&1; then
|
||||||
|
kill $PID
|
||||||
|
sleep 2
|
||||||
|
|
||||||
|
# Force kill si nécessaire
|
||||||
|
if ps -p $PID > /dev/null 2>&1; then
|
||||||
|
log_warn "Force killing process..."
|
||||||
|
kill -9 $PID
|
||||||
|
fi
|
||||||
|
|
||||||
|
rm -f "$PID_FILE"
|
||||||
|
log_info "Git Pusher stopped"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
log_warn "Process not running, cleaning up PID file"
|
||||||
|
rm -f "$PID_FILE"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
log_warn "PID file not found, Git Pusher may not be running"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Redémarrer le serveur
|
||||||
|
restart_server() {
|
||||||
|
log_info "Restarting Git Pusher server..."
|
||||||
|
stop_server
|
||||||
|
sleep 1
|
||||||
|
start_server
|
||||||
|
}
|
||||||
|
|
||||||
|
# Afficher le statut
|
||||||
|
show_status() {
|
||||||
|
echo "============================================"
|
||||||
|
echo "Git Pusher Status"
|
||||||
|
echo "============================================"
|
||||||
|
|
||||||
|
if check_running; then
|
||||||
|
PID=$(cat "$PID_FILE")
|
||||||
|
echo -e "Status: ${GREEN}RUNNING${NC}"
|
||||||
|
echo "PID: $PID"
|
||||||
|
echo "Port: 9999"
|
||||||
|
else
|
||||||
|
echo -e "Status: ${RED}STOPPED${NC}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Paths:"
|
||||||
|
echo " App Home: $APP_HOME"
|
||||||
|
echo " Bin Dir: $BIN_DIR"
|
||||||
|
echo " Log Dir: $LOG_DIR"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Statut de la licence
|
||||||
|
echo "License:"
|
||||||
|
if [ -f "${APP_HOME}/local/license.lic" ]; then
|
||||||
|
echo -e " File: ${GREEN}Present${NC}"
|
||||||
|
# Essayer de lire quelques infos
|
||||||
|
if command -v python3 &> /dev/null; then
|
||||||
|
python3 -c "
|
||||||
|
import sys
|
||||||
|
sys.path.insert(0, '$BIN_DIR')
|
||||||
|
from license_validator import validate_license
|
||||||
|
result = validate_license()
|
||||||
|
if result.get('valid'):
|
||||||
|
print(f\" Type: {result.get('type_name', 'N/A')}\")
|
||||||
|
print(f\" Expires: {result.get('expires', 'N/A')}\")
|
||||||
|
print(f\" Days remaining: {result.get('days_remaining', 'N/A')}\")
|
||||||
|
else:
|
||||||
|
print(f\" Status: Invalid - {result.get('error', 'Unknown error')}\")
|
||||||
|
" 2>/dev/null || echo " Unable to read license details"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo -e " File: ${YELLOW}Not found${NC}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Hostname: $(hostname)"
|
||||||
|
echo "============================================"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Afficher les logs
|
||||||
|
show_logs() {
|
||||||
|
LOG_FILE="${LOG_DIR}/git_pusher.log"
|
||||||
|
|
||||||
|
if [ -f "$LOG_FILE" ]; then
|
||||||
|
if [ "$1" == "-f" ]; then
|
||||||
|
tail -f "$LOG_FILE"
|
||||||
|
else
|
||||||
|
tail -n 50 "$LOG_FILE"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
log_warn "Log file not found at $LOG_FILE"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Menu d'aide
|
||||||
|
show_help() {
|
||||||
|
echo "Git Pusher - Server Management Script"
|
||||||
|
echo ""
|
||||||
|
echo "Usage: $0 {start|stop|restart|status|logs|help}"
|
||||||
|
echo ""
|
||||||
|
echo "Commands:"
|
||||||
|
echo " start Start the Git Pusher server"
|
||||||
|
echo " stop Stop the Git Pusher server"
|
||||||
|
echo " restart Restart the Git Pusher server"
|
||||||
|
echo " status Show the current status"
|
||||||
|
echo " logs Show recent logs (use -f for follow)"
|
||||||
|
echo " help Show this help message"
|
||||||
|
echo ""
|
||||||
|
echo "Environment variables:"
|
||||||
|
echo " SPLUNK_USERNAME Splunk admin username (default: admin)"
|
||||||
|
echo " SPLUNK_PASSWORD Splunk admin password (default: changeme)"
|
||||||
|
echo " SPLUNK_HOME Splunk installation directory (default: /opt/splunk)"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main
|
||||||
|
case "$1" in
|
||||||
|
start)
|
||||||
|
start_server
|
||||||
|
;;
|
||||||
|
stop)
|
||||||
|
stop_server
|
||||||
|
;;
|
||||||
|
restart)
|
||||||
|
restart_server
|
||||||
|
;;
|
||||||
|
status)
|
||||||
|
show_status
|
||||||
|
;;
|
||||||
|
logs)
|
||||||
|
show_logs "$2"
|
||||||
|
;;
|
||||||
|
help|--help|-h)
|
||||||
|
show_help
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
# Par défaut, démarrer le serveur (pour compatibilité)
|
||||||
|
if [ -z "$1" ]; then
|
||||||
|
start_server
|
||||||
|
else
|
||||||
|
echo "Unknown command: $1"
|
||||||
|
show_help
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
@ -0,0 +1 @@
|
|||||||
|
{"username": "admin", "password": "VgNoQiAmDzgUO3NQ"}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
d0YpjIlHuVRowV+y4yQh+VuqDhq7QikC3qepdfLE9+o=
|
||||||
@ -1 +1 @@
|
|||||||
{"pushes_today": 9, "pushes_total": 9, "last_push_date": "2026-01-31", "apps_pushed": []}
|
{"pushes_today": 1, "pushes_total": 10, "last_push_date": "2026-02-01", "apps_pushed": []}
|
||||||
Loading…
Reference in new issue