Compare commits

...

12 Commits

Author SHA1 Message Date
911c6225dc Merge pull request 'master' (#48) from master into prod
Reviewed-on: #48
2025-06-12 01:58:33 +03:00
Egor Matveev
fb7716e8fb fix
All checks were successful
Deploy Dev / Build (pull_request) Successful in 17s
Deploy Dev / Push (pull_request) Successful in 10s
Deploy Dev / Deploy dev (pull_request) Successful in 9s
Deploy Prod / Build (pull_request) Successful in 5s
Deploy Prod / Push (pull_request) Successful in 9s
Deploy Prod / Deploy prod (pull_request) Successful in 7s
2025-06-12 01:10:55 +03:00
Egor Matveev
32377d93fe fix
All checks were successful
Deploy Dev / Build (pull_request) Successful in 6s
Deploy Dev / Push (pull_request) Successful in 11s
Deploy Dev / Deploy dev (pull_request) Successful in 14s
2025-06-12 00:54:10 +03:00
Egor Matveev
cab3256c10 fix
All checks were successful
Deploy Dev / Build (pull_request) Successful in 5s
Deploy Dev / Push (pull_request) Successful in 10s
Deploy Dev / Deploy dev (pull_request) Successful in 11s
2025-06-10 02:04:24 +03:00
Egor Matveev
f7b2b7b7ee fix
All checks were successful
Deploy Dev / Build (pull_request) Successful in 6s
Deploy Dev / Push (pull_request) Successful in 10s
Deploy Dev / Deploy dev (pull_request) Successful in 10s
2025-06-10 02:02:10 +03:00
Egor Matveev
4baf1c94fa fix
All checks were successful
Deploy Dev / Build (pull_request) Successful in 6s
Deploy Dev / Push (pull_request) Successful in 9s
Deploy Dev / Deploy dev (pull_request) Successful in 10s
2025-06-10 01:48:47 +03:00
Egor Matveev
fa0fc6f3bc fix
All checks were successful
Deploy Dev / Build (pull_request) Successful in 5s
Deploy Dev / Push (pull_request) Successful in 10s
Deploy Dev / Deploy dev (pull_request) Successful in 10s
2025-06-08 11:49:18 +03:00
Egor Matveev
9b89423d95 fix
All checks were successful
Deploy Dev / Build (pull_request) Successful in 16s
Deploy Dev / Push (pull_request) Successful in 9s
Deploy Dev / Deploy dev (pull_request) Successful in 10s
2025-06-08 11:38:06 +03:00
Egor Matveev
66eefeb324 fix
All checks were successful
Deploy Dev / Build (pull_request) Successful in 5s
Deploy Dev / Push (pull_request) Successful in 10s
Deploy Dev / Deploy dev (pull_request) Successful in 9s
2025-06-08 11:05:13 +03:00
Egor Matveev
7ef998d635 fix
All checks were successful
Deploy Dev / Build (pull_request) Successful in 5s
Deploy Dev / Push (pull_request) Successful in 10s
Deploy Dev / Deploy dev (pull_request) Successful in 9s
2025-06-08 11:01:53 +03:00
Egor Matveev
00c307fd1e fix
All checks were successful
Deploy Dev / Build (pull_request) Successful in 6s
Deploy Dev / Push (pull_request) Successful in 10s
Deploy Dev / Deploy dev (pull_request) Successful in 11s
2025-06-08 10:58:58 +03:00
Egor Matveev
8853542182 fix
All checks were successful
Deploy Dev / Build (pull_request) Successful in 1m14s
Deploy Dev / Push (pull_request) Successful in 21s
Deploy Dev / Deploy dev (pull_request) Successful in 14s
2025-06-07 13:23:40 +03:00
4 changed files with 94 additions and 78 deletions

View File

@ -15,6 +15,7 @@ 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:
@ -28,3 +29,5 @@ services:
networks: networks:
configurator: configurator:
external: true external: true
queues-development:
external: true

View File

@ -15,6 +15,7 @@ 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:
@ -28,3 +29,5 @@ services:
networks: networks:
configurator: configurator:
external: true external: true
queues:
external: true

124
main.py
View File

@ -3,6 +3,8 @@ 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
@ -14,60 +16,92 @@ 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(command, stderr=subprocess.PIPE, stdout=subprocess.PIPE, shell=True) p = subprocess.Popen(
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('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 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")) + ["platform.develop.sprinthub.ru"])) return list(set(list(configurator.get_config("hosts"))))
else: 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": 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: 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: if container_id_run.code != 0:
print(f"something wrong {container_id_run.err}") return 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:
print("No nginx container") return "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:
print(f"failed generating certificate: {gen_cert.err}") log = call(
print("Here is the log") f"docker exec {container_name} cat /var/log/letsencrypt/letsencrypt.log"
print(call(f"docker exec {container_name} cat /var/log/letsencrypt/letsencrypt.log").out) ).out
return False 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: if fullchain_command.code != 0:
print(f"failed getting fullchain: {fullchain_command.err}") return f"failed getting fullchain: {fullchain_command.err}"
return True
privkey_command = call(
privkey_command = call(f"docker exec {container_name} cat /etc/letsencrypt/live/{host}/privkey.pem") f"docker exec {container_name} cat /etc/letsencrypt/live/{host}/privkey.pem"
)
if privkey_command.code != 0: if privkey_command.code != 0:
print(f"failed getting fullchain: {privkey_command.err}") return 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("certupdater", f"certificates/{host}/fullchain.pem", io.BytesIO(fullchain), len(fullchain)) minio.put_object(
minio.put_object("certupdater", f"certificates/{host}/privkey.pem", io.BytesIO(privkey), len(privkey)) "certupdater",
return True 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: while True:
@ -75,18 +109,36 @@ 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 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) success = update_host(host)
if success: if success:
print(f"Host {host} updated") send_notification(
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(f"echo $(docker ps -q -f name=infra-development_nginx)") container_id_run = call(
result = call(f"docker restart {container_id_run.out}") "echo $(docker ps -q -f name=infra-development_nginx)"
)
else: else:
result = call("docker service update --force infra_nginx") container_id_run = call("echo $(docker ps -q -f name=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)

View File

@ -1,42 +0,0 @@
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})