@@ -15,6 +15,7 @@ services:
 | 
			
		||||
      - /var/run/docker.sock:/var/run/docker.sock
 | 
			
		||||
    networks:
 | 
			
		||||
      - configurator
 | 
			
		||||
      - queues-development
 | 
			
		||||
    deploy:
 | 
			
		||||
      mode: replicated
 | 
			
		||||
      restart_policy:
 | 
			
		||||
@@ -28,3 +29,5 @@ services:
 | 
			
		||||
networks:
 | 
			
		||||
  configurator:
 | 
			
		||||
    external: true
 | 
			
		||||
  queues-development:
 | 
			
		||||
    external: true
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										104
									
								
								main.py
									
									
									
									
									
								
							
							
						
						
									
										104
									
								
								main.py
									
									
									
									
									
								
							@@ -3,6 +3,8 @@ import io
 | 
			
		||||
import os
 | 
			
		||||
import subprocess
 | 
			
		||||
import time
 | 
			
		||||
 | 
			
		||||
from requests import post
 | 
			
		||||
from configurator import configurator
 | 
			
		||||
from mongo import mongo
 | 
			
		||||
from blob import minio
 | 
			
		||||
@@ -14,60 +16,92 @@ class Response:
 | 
			
		||||
    err: str
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def send_notification(text: str):
 | 
			
		||||
    post(
 | 
			
		||||
        "http://queues:1239/api/v1/put",
 | 
			
		||||
        headers={"queue": "botalka_mailbox"},
 | 
			
		||||
        json={
 | 
			
		||||
            "payload": {
 | 
			
		||||
                "project": "notifications-bot",
 | 
			
		||||
                "name": "telegram-bot",
 | 
			
		||||
                "body": {
 | 
			
		||||
                    "text": text,
 | 
			
		||||
                    "chat_id": 84367486,
 | 
			
		||||
                },
 | 
			
		||||
            },
 | 
			
		||||
            "seconds_to_execute": 1,
 | 
			
		||||
            "delay": None,
 | 
			
		||||
        },
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def call(command: str) -> Response:
 | 
			
		||||
    p = subprocess.Popen(command, stderr=subprocess.PIPE, stdout=subprocess.PIPE, shell=True)
 | 
			
		||||
    p = subprocess.Popen(
 | 
			
		||||
        command, stderr=subprocess.PIPE, stdout=subprocess.PIPE, shell=True
 | 
			
		||||
    )
 | 
			
		||||
    resp = p.wait()
 | 
			
		||||
    response = Response()
 | 
			
		||||
    response.code = resp
 | 
			
		||||
    response.out, response.err = p.stdout.read().decode('utf-8'), p.stderr.read().decode('utf-8')
 | 
			
		||||
    response.out, response.err = p.stdout.read().decode(
 | 
			
		||||
        "utf-8"
 | 
			
		||||
    ), p.stderr.read().decode("utf-8")
 | 
			
		||||
    return response
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_hosts() -> list[str]:
 | 
			
		||||
    if os.getenv("STAGE") == "development":
 | 
			
		||||
        return list(set(list(configurator.get_config("hosts")) + ["platform.develop.sprinthub.ru"]))
 | 
			
		||||
        return list(set(list(configurator.get_config("hosts"))))
 | 
			
		||||
    else:
 | 
			
		||||
        return list(set(list(configurator.get_config("hosts")) + ["platform.sprinthub.ru"]))
 | 
			
		||||
        return list(set(list(configurator.get_config("hosts"))))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def update_host(host: str) -> bool:
 | 
			
		||||
def update_host(host: str) -> str | None:
 | 
			
		||||
    if os.getenv("STAGE") == "development":
 | 
			
		||||
        container_id_run = call(f"echo $(docker ps -q -f name=infra-development_nginx)")
 | 
			
		||||
        container_id_run = call("echo $(docker ps -q -f name=infra-development_nginx)")
 | 
			
		||||
    else:
 | 
			
		||||
        container_id_run = call(f"echo $(docker ps -q -f name=infra_nginx)")
 | 
			
		||||
        container_id_run = call("echo $(docker ps -q -f name=infra_nginx)")
 | 
			
		||||
    if container_id_run.code != 0:
 | 
			
		||||
        print(f"something wrong {container_id_run.err}")
 | 
			
		||||
        return False
 | 
			
		||||
        return container_id_run.err
 | 
			
		||||
    container_name = container_id_run.out.strip()
 | 
			
		||||
    if not container_name:
 | 
			
		||||
        print("No nginx container")
 | 
			
		||||
        return False
 | 
			
		||||
        return "no nginx container"
 | 
			
		||||
 | 
			
		||||
    gen_command = f"docker exec {container_name} certbot --nginx --email emmtvv@gmail.com --agree-tos --non-interactive -d \"{host}\""
 | 
			
		||||
    print(gen_command)
 | 
			
		||||
    gen_command = f'docker exec {container_name} certbot --nginx --email emmtvv@gmail.com --agree-tos --non-interactive -d "{host}"'
 | 
			
		||||
 | 
			
		||||
    gen_cert = call(gen_command)
 | 
			
		||||
    if gen_cert.code != 0:
 | 
			
		||||
        print(f"failed generating certificate: {gen_cert.err}")
 | 
			
		||||
        print("Here is the log")
 | 
			
		||||
        print(call(f"docker exec {container_name} cat /var/log/letsencrypt/letsencrypt.log").out)
 | 
			
		||||
        return False
 | 
			
		||||
        log = call(
 | 
			
		||||
            f"docker exec {container_name} cat /var/log/letsencrypt/letsencrypt.log"
 | 
			
		||||
        ).out
 | 
			
		||||
        return f"failed generating certificate: {log}"
 | 
			
		||||
 | 
			
		||||
    fullchain_command = call(f"docker exec {container_name} cat /etc/letsencrypt/live/{host}/fullchain.pem")
 | 
			
		||||
    fullchain_command = call(
 | 
			
		||||
        f"docker exec {container_name} cat /etc/letsencrypt/live/{host}/fullchain.pem"
 | 
			
		||||
    )
 | 
			
		||||
    if fullchain_command.code != 0:
 | 
			
		||||
        print(f"failed getting fullchain: {fullchain_command.err}")
 | 
			
		||||
        return True
 | 
			
		||||
        return f"failed getting fullchain: {fullchain_command.err}"
 | 
			
		||||
 | 
			
		||||
    privkey_command = call(f"docker exec {container_name} cat /etc/letsencrypt/live/{host}/privkey.pem")
 | 
			
		||||
    privkey_command = call(
 | 
			
		||||
        f"docker exec {container_name} cat /etc/letsencrypt/live/{host}/privkey.pem"
 | 
			
		||||
    )
 | 
			
		||||
    if privkey_command.code != 0:
 | 
			
		||||
        print(f"failed getting fullchain: {privkey_command.err}")
 | 
			
		||||
        return True
 | 
			
		||||
        return f"failed getting fullchain: {privkey_command.err}"
 | 
			
		||||
 | 
			
		||||
    fullchain = fullchain_command.out.encode("utf-8")
 | 
			
		||||
    privkey = privkey_command.out.encode("utf-8")
 | 
			
		||||
    minio.put_object("certupdater", f"certificates/{host}/fullchain.pem", io.BytesIO(fullchain), len(fullchain))
 | 
			
		||||
    minio.put_object("certupdater", f"certificates/{host}/privkey.pem", io.BytesIO(privkey), len(privkey))
 | 
			
		||||
    return True
 | 
			
		||||
    minio.put_object(
 | 
			
		||||
        "certupdater",
 | 
			
		||||
        f"certificates/{host}/fullchain.pem",
 | 
			
		||||
        io.BytesIO(fullchain),
 | 
			
		||||
        len(fullchain),
 | 
			
		||||
    )
 | 
			
		||||
    minio.put_object(
 | 
			
		||||
        "certupdater",
 | 
			
		||||
        f"certificates/{host}/privkey.pem",
 | 
			
		||||
        io.BytesIO(privkey),
 | 
			
		||||
        len(privkey),
 | 
			
		||||
    )
 | 
			
		||||
    return None
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
while True:
 | 
			
		||||
@@ -75,15 +109,26 @@ while True:
 | 
			
		||||
    mongo_hosts = mongo.hosts
 | 
			
		||||
    updated = False
 | 
			
		||||
    for host in get_hosts():
 | 
			
		||||
        if now + datetime.timedelta(days=14) > mongo_hosts.get(host, {"expire_time": datetime.datetime.fromtimestamp(1)})["expire_time"]:
 | 
			
		||||
        if (
 | 
			
		||||
            now + datetime.timedelta(days=14)
 | 
			
		||||
            > mongo_hosts.get(
 | 
			
		||||
                host, {"expire_time": datetime.datetime.fromtimestamp(1)}
 | 
			
		||||
            )["expire_time"]
 | 
			
		||||
        ):
 | 
			
		||||
            success = update_host(host)
 | 
			
		||||
            if success:
 | 
			
		||||
                print(f"Host {host} updated")
 | 
			
		||||
                send_notification(
 | 
			
		||||
                    f"host {host} was not updated with an error: {success}"
 | 
			
		||||
                )
 | 
			
		||||
            else:
 | 
			
		||||
                mongo.update_date(host)
 | 
			
		||||
                updated = True
 | 
			
		||||
                send_notification(f"host {host} updated")
 | 
			
		||||
    if updated:
 | 
			
		||||
        if os.getenv("STAGE") == "development":
 | 
			
		||||
            container_id_run = call("echo $(docker ps -q -f name=infra-development_nginx)")
 | 
			
		||||
            container_id_run = call(
 | 
			
		||||
                "echo $(docker ps -q -f name=infra-development_nginx)"
 | 
			
		||||
            )
 | 
			
		||||
        else:
 | 
			
		||||
            container_id_run = call("echo $(docker ps -q -f name=infra_nginx)")
 | 
			
		||||
 | 
			
		||||
@@ -94,5 +139,6 @@ while True:
 | 
			
		||||
 | 
			
		||||
        restart = call(command)
 | 
			
		||||
        print(restart.code, restart.out, restart.err)
 | 
			
		||||
        send_notification(f"Balancer for {os.getenv("STAGE")} was restarted")
 | 
			
		||||
 | 
			
		||||
    time.sleep(30)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user