1
0

rotate_passwords.py 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. import pymysql
  2. import os
  3. import secrets
  4. import string
  5. import subprocess
  6. def generate_password(length=16):
  7. characters = string.ascii_letters + string.digits + "!@#$%^&*"
  8. return ''.join(secrets.choice(characters) for _ in range(length))
  9. def update_env_file(passwords):
  10. env_file = '.env'
  11. lines = []
  12. if os.path.exists(env_file):
  13. with open(env_file, 'r') as f:
  14. lines = f.readlines()
  15. # Remove old password lines
  16. lines = [l for l in lines if not any(l.startswith(f"{k}=") for k in passwords.keys())]
  17. # Add new passwords
  18. for key, val in passwords.items():
  19. lines.append(f"{key}={val}\n")
  20. with open(env_file, 'w') as f:
  21. f.writelines(lines)
  22. print("✅ .env file updated with new synchronized passwords.")
  23. def main():
  24. print("🔄 Starting Password Synchronization Routine...")
  25. # 1. Connect to MySQL as root
  26. try:
  27. conn = pymysql.connect(
  28. host='127.0.0.1', # Assuming we run this from host to mapped port, or within a container network
  29. user='root',
  30. password='root_pass',
  31. database='food_db'
  32. )
  33. except Exception as e:
  34. print(f"❌ Could not connect to MySQL: {e}")
  35. return
  36. # 2. Generate new passwords
  37. new_passwords = {
  38. 'DB_READER_PASS': generate_password(),
  39. 'DB_LOADER_PASS': generate_password(),
  40. 'DB_APP_AUTH_PASS': generate_password()
  41. }
  42. # 3. Update MySQL Users
  43. try:
  44. with conn.cursor() as cursor:
  45. cursor.execute("ALTER USER 'db_reader'@'%' IDENTIFIED BY %s", (new_passwords['DB_READER_PASS'],))
  46. cursor.execute("ALTER USER 'db_loader'@'%' IDENTIFIED BY %s", (new_passwords['DB_LOADER_PASS'],))
  47. cursor.execute("ALTER USER 'db_app_auth'@'%' IDENTIFIED BY %s", (new_passwords['DB_APP_AUTH_PASS'],))
  48. cursor.execute("FLUSH PRIVILEGES")
  49. conn.commit()
  50. print("✅ Database user passwords rotated successfully.")
  51. except Exception as e:
  52. print(f"❌ Failed to alter database users: {e}")
  53. finally:
  54. conn.close()
  55. # 4. Update .env file so Docker Compose picks it up
  56. update_env_file(new_passwords)
  57. # 5. Gracefully restart client containers to sync connection
  58. print("🔄 Restarting App and Ingest containers to synchronize new credentials...")
  59. try:
  60. subprocess.run(["docker-compose", "up", "-d", "app"], check=True)
  61. # We don't necessarily need to restart ingest if it's manual, but we can recreate it if it was running.
  62. print("✅ Client containers synchronized with new database passwords!")
  63. except Exception as e:
  64. print(f"⚠️ Failed to restart docker containers: {e}")
  65. if __name__ == "__main__":
  66. main()