Compare commits

..

No commits in common. "911c6225dcaef4ec9c9b2808dcd1508587dbdabc" and "a85e7d4ee2dc4ced2f35876c06120b1d3b6271c1" have entirely different histories.

4 changed files with 78 additions and 94 deletions

View File

@ -15,7 +15,6 @@ services:
- /var/run/docker.sock:/var/run/docker.sock - /var/run/docker.sock:/var/run/docker.sock
networks: networks:
- configurator - configurator
- queues-development
deploy: deploy:
mode: replicated mode: replicated
restart_policy: restart_policy:
@ -29,5 +28,3 @@ services:
networks: networks:
configurator: configurator:
external: true external: true
queues-development:
external: true

View File

@ -15,7 +15,6 @@ services:
- /var/run/docker.sock:/var/run/docker.sock - /var/run/docker.sock:/var/run/docker.sock
networks: networks:
- configurator - configurator
- queues
deploy: deploy:
mode: replicated mode: replicated
restart_policy: restart_policy:
@ -29,5 +28,3 @@ services:
networks: networks:
configurator: configurator:
external: true external: true
queues:
external: true

124
main.py
View File

@ -3,8 +3,6 @@ import io
import os import os
import subprocess import subprocess
import time import time
from requests import post
from configurator import configurator from configurator import configurator
from mongo import mongo from mongo import mongo
from blob import minio from blob import minio
@ -16,92 +14,60 @@ class Response:
err: str 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: def call(command: str) -> Response:
p = subprocess.Popen( p = subprocess.Popen(command, stderr=subprocess.PIPE, stdout=subprocess.PIPE, shell=True)
command, stderr=subprocess.PIPE, stdout=subprocess.PIPE, shell=True
)
resp = p.wait() resp = p.wait()
response = Response() response = Response()
response.code = resp response.code = resp
response.out, response.err = p.stdout.read().decode( response.out, response.err = p.stdout.read().decode('utf-8'), p.stderr.read().decode('utf-8')
"utf-8"
), p.stderr.read().decode("utf-8")
return response return response
def get_hosts() -> list[str]: def get_hosts() -> list[str]:
if os.getenv("STAGE") == "development": if os.getenv("STAGE") == "development":
return list(set(list(configurator.get_config("hosts")))) return list(set(list(configurator.get_config("hosts")) + ["platform.develop.sprinthub.ru"]))
else: else:
return list(set(list(configurator.get_config("hosts")))) return list(set(list(configurator.get_config("hosts")) + ["platform.sprinthub.ru"]))
def update_host(host: str) -> str | None: def update_host(host: str) -> bool:
if os.getenv("STAGE") == "development": if os.getenv("STAGE") == "development":
container_id_run = call("echo $(docker ps -q -f name=infra-development_nginx)") container_id_run = call(f"echo $(docker ps -q -f name=infra-development_nginx)")
else: else:
container_id_run = call("echo $(docker ps -q -f name=infra_nginx)") container_id_run = call(f"echo $(docker ps -q -f name=infra_nginx)")
if container_id_run.code != 0: if container_id_run.code != 0:
return container_id_run.err print(f"something wrong {container_id_run.err}")
return False
container_name = container_id_run.out.strip() container_name = container_id_run.out.strip()
if not container_name: if not container_name:
return "no nginx container" print("No nginx container")
return False
gen_command = f'docker exec {container_name} certbot --nginx --email emmtvv@gmail.com --agree-tos --non-interactive -d "{host}"'
gen_command = f"docker exec {container_name} certbot --nginx --email emmtvv@gmail.com --agree-tos --non-interactive -d \"{host}\""
print(gen_command)
gen_cert = call(gen_command) gen_cert = call(gen_command)
if gen_cert.code != 0: if gen_cert.code != 0:
log = call( print(f"failed generating certificate: {gen_cert.err}")
f"docker exec {container_name} cat /var/log/letsencrypt/letsencrypt.log" print("Here is the log")
).out print(call(f"docker exec {container_name} cat /var/log/letsencrypt/letsencrypt.log").out)
return f"failed generating certificate: {log}" return False
fullchain_command = call( fullchain_command = call(f"docker exec {container_name} cat /etc/letsencrypt/live/{host}/fullchain.pem")
f"docker exec {container_name} cat /etc/letsencrypt/live/{host}/fullchain.pem"
)
if fullchain_command.code != 0: if fullchain_command.code != 0:
return f"failed getting fullchain: {fullchain_command.err}" print(f"failed getting fullchain: {fullchain_command.err}")
return True
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: if privkey_command.code != 0:
return f"failed getting fullchain: {privkey_command.err}" print(f"failed getting fullchain: {privkey_command.err}")
return True
fullchain = fullchain_command.out.encode("utf-8") fullchain = fullchain_command.out.encode("utf-8")
privkey = privkey_command.out.encode("utf-8") privkey = privkey_command.out.encode("utf-8")
minio.put_object( minio.put_object("certupdater", f"certificates/{host}/fullchain.pem", io.BytesIO(fullchain), len(fullchain))
"certupdater", minio.put_object("certupdater", f"certificates/{host}/privkey.pem", io.BytesIO(privkey), len(privkey))
f"certificates/{host}/fullchain.pem", return True
io.BytesIO(fullchain),
len(fullchain),
)
minio.put_object(
"certupdater",
f"certificates/{host}/privkey.pem",
io.BytesIO(privkey),
len(privkey),
)
return None
while True: while True:
@ -109,36 +75,18 @@ while True:
mongo_hosts = mongo.hosts mongo_hosts = mongo.hosts
updated = False updated = False
for host in get_hosts(): for host in get_hosts():
if ( if now + datetime.timedelta(days=14) > mongo_hosts.get(host, {"expire_time": datetime.datetime.fromtimestamp(1)})["expire_time"]:
now + datetime.timedelta(days=14)
> mongo_hosts.get(
host, {"expire_time": datetime.datetime.fromtimestamp(1)}
)["expire_time"]
):
success = update_host(host) success = update_host(host)
if success: if success:
send_notification( print(f"Host {host} updated")
f"host {host} was not updated with an error: {success}"
)
else:
mongo.update_date(host) mongo.update_date(host)
updated = True updated = True
send_notification(f"host {host} updated")
if updated: if updated:
if os.getenv("STAGE") == "development": if os.getenv("STAGE") == "development":
container_id_run = call( container_id_run = call(f"echo $(docker ps -q -f name=infra-development_nginx)")
"echo $(docker ps -q -f name=infra-development_nginx)" result = call(f"docker restart {container_id_run.out}")
)
else: else:
container_id_run = call("echo $(docker ps -q -f name=infra_nginx)") result = call("docker service update --force infra_nginx")
print(container_id_run.code, container_id_run.out, container_id_run.err)
command = f"docker exec {container_id_run.out.strip()} ./refre.sh"
print(command)
restart = call(command)
print(restart.code, restart.out, restart.err)
send_notification(f"Balancer for {os.getenv("STAGE")} was restarted")
print(result.err, result.out)
time.sleep(30) time.sleep(30)

42
storage.py Normal file
View File

@ -0,0 +1,42 @@
from cachetools import TTLCache
import os
from utils.mongo import mongo
CACHE_SIZE = int(os.getenv("CACHE_SIZE", 1000))
CACHE_TTL = int(os.getenv("CACHE_TTL", 3600))
cache = TTLCache(CACHE_SIZE, CACHE_TTL)
def get_chat_info(chat_id: int) -> dict:
cached_info = cache.get(chat_id)
if cached_info is not None:
return cached_info
mongo_info = mongo.chats_collection.find_one({"chat_id": chat_id})
if mongo_info is not None:
cache[chat_id] = mongo_info
return mongo_info
chat_info = {"chat_id": chat_id, "state": "default", "probability": 100}
mongo.chats_collection.insert_one(chat_info)
cache[chat_id] = chat_info
return chat_info
def set_values(chat_id: int, **values):
cached_info = cache.get(chat_id)
if cached_info is None:
mongo_info = mongo.chats_collection.find_one({"chat_id": chat_id})
if mongo_info is None:
chat_info = {"chat_id": chat_id, "state": "default", "probability": 100}
chat_info.update(values)
mongo.chats_collection.insert_one(chat_info)
cache[chat_id] = chat_info
else:
mongo.chats_collection.update_one({"chat_id": chat_id}, {"$set": values})
mongo_info = dict(mongo_info)
mongo_info.update(values)
cache[chat_id] = mongo_info
else:
cached_info.update(values)
mongo.chats_collection.update_one({"chat_id": chat_id}, {"$set": values})