126 lines
3.7 KiB
Python
126 lines
3.7 KiB
Python
"""
|
|
Diagnostic script for ScrAIbe email (SMTP) connectivity.
|
|
|
|
Run inside the container to verify:
|
|
- Required env vars are set
|
|
- SMTP connection
|
|
- TLS (if configured)
|
|
- Authentication
|
|
|
|
Output is written to stdout/stderr so it appears in docker logs.
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
import smtplib
|
|
import logging
|
|
|
|
logging.basicConfig(
|
|
level=logging.INFO,
|
|
format="DIAG [%(levelname)s] %(message)s",
|
|
stream=sys.stdout,
|
|
force=True,
|
|
)
|
|
log = logging.getLogger("email_diagnostics")
|
|
|
|
|
|
def main():
|
|
# 1) Check required env vars
|
|
required = [
|
|
"EMAIL_SMTP_HOST",
|
|
"EMAIL_SMTP_PORT",
|
|
"EMAIL_SMTP_USER",
|
|
"EMAIL_SMTP_PASSWORD",
|
|
"EMAIL_FROM_ADDRESS",
|
|
]
|
|
missing = [v for v in required if not os.getenv(v)]
|
|
if missing:
|
|
log.error("Missing required env vars: %s", ", ".join(missing))
|
|
sys.exit(1)
|
|
|
|
smtp_host = os.getenv("EMAIL_SMTP_HOST")
|
|
smtp_port = int(os.getenv("EMAIL_SMTP_PORT"))
|
|
smtp_user = os.getenv("EMAIL_SMTP_USER")
|
|
smtp_password = os.getenv("EMAIL_SMTP_PASSWORD")
|
|
from_address = os.getenv("EMAIL_FROM_ADDRESS")
|
|
use_tls_str = (os.getenv("EMAIL_SMTP_USE_TLS") or "true").strip().lower()
|
|
use_tls = use_tls_str not in ("false", "0", "no")
|
|
|
|
log.info("SMTP config:")
|
|
log.info(" host: %s", smtp_host)
|
|
log.info(" port: %s", smtp_port)
|
|
log.info(" user: %s", smtp_user)
|
|
log.info(" from: %s", from_address)
|
|
log.info(" use_tls: %s", use_tls)
|
|
log.info(" password: %s", ("set" if smtp_password else "NOT SET"))
|
|
|
|
# 2) Connect to SMTP server
|
|
log.info("Attempting SMTP connection...")
|
|
try:
|
|
if use_tls:
|
|
server = smtplib.SMTP(smtp_host, smtp_port, timeout=15)
|
|
log.info("Connected (SMTP) to %s:%s", smtp_host, smtp_port)
|
|
else:
|
|
server = smtplib.SMTP(smtp_host, smtp_port, timeout=15)
|
|
log.info("Connected (SMTP, no TLS) to %s:%s", smtp_host, smtp_port)
|
|
except Exception as e:
|
|
log.error("SMTP connection failed: %s", e)
|
|
sys.exit(1)
|
|
|
|
# 3) EHLO
|
|
log.info("Sending EHLO...")
|
|
try:
|
|
ehlo_resp = server.ehlo()
|
|
log.info("EHLO response code: %s", ehlo_resp[0])
|
|
except Exception as e:
|
|
log.error("EHLO failed: %s", e)
|
|
server.quit()
|
|
sys.exit(1)
|
|
|
|
# 4) STARTTLS if configured
|
|
if use_tls:
|
|
log.info("Attempting STARTTLS...")
|
|
try:
|
|
server.starttls()
|
|
server.ehlo()
|
|
log.info("STARTTLS succeeded.")
|
|
except Exception as e:
|
|
log.error("STARTTLS failed: %s", e)
|
|
server.quit()
|
|
sys.exit(1)
|
|
else:
|
|
log.info("TLS not requested; continuing without STARTTLS.")
|
|
|
|
# 5) AUTH LOGIN
|
|
log.info("Attempting AUTH LOGIN with user: %s", smtp_user)
|
|
try:
|
|
server.login(smtp_user, smtp_password)
|
|
log.info("AUTH LOGIN succeeded.")
|
|
except smtplib.SMTPAuthenticationError as e:
|
|
log.error("AUTH LOGIN failed (bad credentials?): %s", e)
|
|
server.quit()
|
|
sys.exit(1)
|
|
except Exception as e:
|
|
log.error("AUTH LOGIN failed: %s", e)
|
|
server.quit()
|
|
sys.exit(1)
|
|
|
|
# 6) Optional: quick MAIL FROM / RCPT TO / QUIT test (no message sent)
|
|
log.info("Testing MAIL FROM / RCPT TO / RSET...")
|
|
try:
|
|
server.mail(from_address)
|
|
# Use from_address as recipient for test
|
|
server.rcpt(from_address)
|
|
server.reset()
|
|
log.info("MAIL FROM / RCPT TO / RSET succeeded.")
|
|
except Exception as e:
|
|
log.warning("MAIL FROM / RCPT TO / RSET failed (non-critical): %s", e)
|
|
|
|
# 7) Quit
|
|
server.quit()
|
|
log.info("All email diagnostics passed. SMTP is reachable and authenticated.")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|