aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorclarkzjw <[email protected]>2023-02-24 00:51:04 -0800
committerclarkzjw <[email protected]>2023-02-24 00:51:04 -0800
commit4bb5cbdc16ecf5f6e5961373816d4c741d54ee51 (patch)
treeea85f216881bacb54f579cae9814e2f85aa1abe5
parenta9fb6f252553ae49a2ba372434073824babe31e4 (diff)
parent391abe42adf3bf065d9543ada068b696b00efdcd (diff)
downloadswarm2fediverse-4bb5cbdc16ecf5f6e5961373816d4c741d54ee51.tar.gz
Merge branch 'deploy/cicd'
added Dockerfile and docker-compose.yaml with krakend api gateway and monitoring using influxdb and grafana dashboard
-rw-r--r--.dockerignore3
-rw-r--r--Dockerfile11
-rw-r--r--bot.py10
-rw-r--r--config.ini.example7
-rw-r--r--config.py11
-rw-r--r--contrib/docker-compose.yaml47
-rwxr-xr-xcontrib/influx/initdb.sh16
-rw-r--r--contrib/krakend.json84
-rw-r--r--dbstore/peewee_store.py2
-rw-r--r--requirements.txt8
10 files changed, 179 insertions, 20 deletions
diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000..8a229dd
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,3 @@
1.venv/
2*.db
3*.ini
diff --git a/Dockerfile b/Dockerfile
index 2d13273..6e97ed6 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1 +1,10 @@
1FROM python:3 1FROM python:3.10
2
3WORKDIR /usr/src/app
4
5COPY requirements.txt ./
6RUN pip install --no-cache-dir -r requirements.txt
7
8COPY . .
9
10CMD [ "python", "./bot.py" ]
diff --git a/bot.py b/bot.py
index 1d59f9e..bcfab8f 100644
--- a/bot.py
+++ b/bot.py
@@ -8,7 +8,7 @@ from config import BOT_TOKEN, TELEGRAM_WEBHOOK_URL, HEALTHCHECK_URL, FEDI_LOGIN_
8import uvicorn 8import uvicorn
9from starlette.applications import Starlette 9from starlette.applications import Starlette
10from starlette.requests import Request 10from starlette.requests import Request
11from starlette.responses import PlainTextResponse, Response 11from starlette.responses import PlainTextResponse, Response, JSONResponse
12from starlette.routing import Route 12from starlette.routing import Route
13from telegram import Update 13from telegram import Update
14from telegram.ext import ( 14from telegram.ext import (
@@ -188,12 +188,12 @@ async def main() -> None:
188 await application.bot.set_webhook(url=f"{BOT_DOMAIN}{TELEGRAM_WEBHOOK_URL}") 188 await application.bot.set_webhook(url=f"{BOT_DOMAIN}{TELEGRAM_WEBHOOK_URL}")
189 189
190 # Set up webserver 190 # Set up webserver
191 async def telegram_webhook(request: Request) -> Response: 191 async def telegram_webhook(request: Request) -> JSONResponse:
192 """Handle incoming Telegram updates by putting them into the `update_queue`""" 192 """Handle incoming Telegram updates by putting them into the `update_queue`"""
193 await application.update_queue.put( 193 await application.update_queue.put(
194 Update.de_json(data=await request.json(), bot=application.bot) 194 Update.de_json(data=await request.json(), bot=application.bot)
195 ) 195 )
196 return Response() 196 return JSONResponse({'OK': 200})
197 197
198 async def fedi_oauth_login_callback(request: Request) -> PlainTextResponse: 198 async def fedi_oauth_login_callback(request: Request) -> PlainTextResponse:
199 """ 199 """
@@ -221,7 +221,7 @@ async def main() -> None:
221 routes=[ 221 routes=[
222 Route(TELEGRAM_WEBHOOK_URL, telegram_webhook, methods=["POST"]), 222 Route(TELEGRAM_WEBHOOK_URL, telegram_webhook, methods=["POST"]),
223 Route(HEALTHCHECK_URL, healthcheck, methods=["GET"]), 223 Route(HEALTHCHECK_URL, healthcheck, methods=["GET"]),
224 Route(FEDI_LOGIN_CALLBACK_URL, fedi_oauth_login_callback, methods=["POST", "GET"]), 224 Route(FEDI_LOGIN_CALLBACK_URL, fedi_oauth_login_callback, methods=["GET"]),
225 ] 225 ]
226 ) 226 )
227 webserver = uvicorn.Server( 227 webserver = uvicorn.Server(
@@ -229,7 +229,7 @@ async def main() -> None:
229 app=starlette_app, 229 app=starlette_app,
230 port=BOT_PORT, 230 port=BOT_PORT,
231 use_colors=False, 231 use_colors=False,
232 host="100.93.242.2", 232 host="0.0.0.0",
233 ) 233 )
234 ) 234 )
235 235
diff --git a/config.ini.example b/config.ini.example
index e3a9121..d52a4d1 100644
--- a/config.ini.example
+++ b/config.ini.example
@@ -2,3 +2,10 @@
2BOT_TOKEN = 2BOT_TOKEN =
3FOURSQUARE_API_KEY = 3FOURSQUARE_API_KEY =
4ENCRYPT_KEY = 4ENCRYPT_KEY =
5
6[API]
7TELEGRAM_WEBHOOK_URL = "/checkinbot/webhook"
8HEALTHCHECK_URL = "/checkinbot/healthcheck"
9FEDI_LOGIN_CALLBACK_URL = "/checkinbot/fedi_login_callback"
10BOT_DOMAIN = "https://"
11BOT_PORT = 8080
diff --git a/config.py b/config.py
index 0fae9b1..fe69bd9 100644
--- a/config.py
+++ b/config.py
@@ -10,6 +10,12 @@ BOT_TOKEN = config["DEFAULT"]["BOT_TOKEN"]
10FSQ_API_KEY = config["DEFAULT"]["FOURSQUARE_API_KEY"] 10FSQ_API_KEY = config["DEFAULT"]["FOURSQUARE_API_KEY"]
11ENCRYPT_KEY = config["DEFAULT"]["ENCRYPT_KEY"] 11ENCRYPT_KEY = config["DEFAULT"]["ENCRYPT_KEY"]
12 12
13TELEGRAM_WEBHOOK_URL = config["API"]["TELEGRAM_WEBHOOK_URL"]
14HEALTHCHECK_URL = config["API"]["HEALTHCHECK_URL"]
15FEDI_LOGIN_CALLBACK_URL = config["API"]["FEDI_LOGIN_CALLBACK_URL"]
16BOT_DOMAIN = config["API"]["BOT_DOMAIN"]
17BOT_PORT = int(config["API"]["BOT_PORT"])
18
13MEDIA_GROUP_TIMEOUT = 3 19MEDIA_GROUP_TIMEOUT = 3
14 20
15FEDI_LOGIN, WAIT_VISIBILITY, WAIT_LOCATION, LOCATION_SEARCH_KEYWORD, LOCATION_CONFIRMATION, ADD_MEDIA, ADD_COMMENT = range(7) 21FEDI_LOGIN, WAIT_VISIBILITY, WAIT_LOCATION, LOCATION_SEARCH_KEYWORD, LOCATION_CONFIRMATION, ADD_MEDIA, ADD_COMMENT = range(7)
@@ -41,9 +47,4 @@ class MsgDict(TypedDict):
41KEY_TOOT_STATUS_ID = "toot_status_id" 47KEY_TOOT_STATUS_ID = "toot_status_id"
42KEY_TOOT_STATUS_CONTENT = "toot_status_content" 48KEY_TOOT_STATUS_CONTENT = "toot_status_content"
43 49
44TELEGRAM_WEBHOOK_URL = "/checkinbot/webhook"
45HEALTHCHECK_URL = "/checkinbot/healthcheck"
46FEDI_LOGIN_CALLBACK_URL = "/checkinbot/fedi_login_callback"
47BOT_DOMAIN = "https://zjw.social"
48BOT_PORT = 30010
49BOT_SCOPE = ['read:accounts', 'write:media', 'write:statuses'] 50BOT_SCOPE = ['read:accounts', 'write:media', 'write:statuses']
diff --git a/contrib/docker-compose.yaml b/contrib/docker-compose.yaml
new file mode 100644
index 0000000..8aeaff8
--- /dev/null
+++ b/contrib/docker-compose.yaml
@@ -0,0 +1,47 @@
1version: '3'
2services:
3 checkinbot:
4 image: "clarkzjw/checkin.bot:latest"
5 restart: always
6 volumes:
7 - "./config.ini:/usr/src/app/config.ini"
8 - sqlite3:/usr/src/app/database/
9 ports:
10 - "8080:8080"
11
12 krakend:
13 image: "devopsfaith/krakend:2.2"
14 restart: always
15 ports:
16 - "8081:8080"
17 - "9091:9091"
18 volumes:
19 - "./krakend.json:/etc/krakend/krakend.json"
20
21 influx:
22 image: influxdb:2.6.1
23 environment:
24 - "DOCKER_INFLUXDB_INIT_MODE=setup"
25 - "DOCKER_INFLUXDB_INIT_USERNAME=krakend"
26 - "DOCKER_INFLUXDB_INIT_PASSWORD=password"
27 - "DOCKER_INFLUXDB_INIT_ORG=my-org"
28 - "DOCKER_INFLUXDB_INIT_BUCKET=krakend"
29 - "DOCKER_INFLUXDB_INIT_RETENTION=1w"
30 - "DOCKER_INFLUXDB_INIT_ADMIN_TOKEN=my-super-secret-auth-token"
31 ports:
32 - "8086:8086"
33 volumes:
34 - "./influx/initdb.sh:/docker-entrypoint-initdb.d/initdb.sh"
35
36 grafana:
37 image: "grafana/grafana:9.3.6"
38 restart: always
39 ports:
40 - "3000:3000"
41 volumes:
42 - grafana:/var/lib/grafana
43
44volumes:
45 sqlite3:
46 grafana:
47 influxdb:
diff --git a/contrib/influx/initdb.sh b/contrib/influx/initdb.sh
new file mode 100755
index 0000000..b1d07af
--- /dev/null
+++ b/contrib/influx/initdb.sh
@@ -0,0 +1,16 @@
1#!/bin/bash
2# The following script creates the authentication for Grafana
3# and is meant to be added to InfluxDB docker-compose.yml file.
4# image: influxdb
5# volumes:
6# - "./config/influx:/docker-entrypoint-initdb.d"
7set -e
8
9# Retrieve the ID from the bucket created during setup
10BUCKET_ID=$(influx bucket list | grep "$DOCKER_INFLUXDB_INIT_BUCKET" | awk '{print $1}')
11
12influx v1 auth create \
13 --username ${DOCKER_INFLUXDB_INIT_USERNAME} \
14 --password ${DOCKER_INFLUXDB_INIT_PASSWORD} \
15 --write-bucket ${BUCKET_ID} \
16 --org ${DOCKER_INFLUXDB_INIT_ORG}
diff --git a/contrib/krakend.json b/contrib/krakend.json
new file mode 100644
index 0000000..2ed23d8
--- /dev/null
+++ b/contrib/krakend.json
@@ -0,0 +1,84 @@
1{
2 "$schema": "https://www.krakend.io/schema/v3.json",
3 "version": 3,
4 "name": "Checkin.bot API",
5 "extra_config": {
6 "telemetry/influx": {
7 "address": "http://influx:8086",
8 "ttl": "25s",
9 "buffer_size": 100,
10 "db": "krakend",
11 "username": "krakend",
12 "password": "password"
13 },
14 "telemetry/metrics": {
15 "collection_time": "60s",
16 "proxy_disabled": false,
17 "router_disabled": false,
18 "backend_disabled": false,
19 "endpoint_disabled": false,
20 "listen_address": ":8090"
21 }
22 },
23 "timeout": "3000ms",
24 "cache_ttl": "300s",
25 "output_encoding": "json",
26 "debug_endpoint": true,
27 "endpoints": [
28 {
29 "endpoint": "/checkinbot/webhook",
30 "method": "POST",
31 "output_encoding": "json",
32 "backend": [
33 {
34 "url_pattern": "/checkinbot/webhook",
35 "encoding": "json",
36 "sd": "static",
37 "method": "POST",
38 "host": [
39 "http://checkinbot:8080"
40 ],
41 "disable_host_sanitize": false
42 }
43 ]
44 },
45 {
46 "endpoint": "/checkinbot/healthcheck",
47 "method": "GET",
48 "output_encoding": "string",
49 "backend": [
50 {
51 "url_pattern": "/checkinbot/healthcheck",
52 "encoding": "string",
53 "sd": "static",
54 "method": "GET",
55 "host": [
56 "http://checkinbot:8080"
57 ],
58 "disable_host_sanitize": false
59 }
60 ]
61 },
62 {
63 "endpoint": "/checkinbot/fedi_login_callback",
64 "method": "GET",
65 "output_encoding": "string",
66 "backend": [
67 {
68 "url_pattern": "/checkinbot/fedi_login_callback",
69 "encoding": "string",
70 "sd": "static",
71 "method": "GET",
72 "disable_host_sanitize": false,
73 "host": [
74 "http://checkinbot:8080"
75 ]
76 }
77 ],
78 "input_query_strings": [
79 "code",
80 "state"
81 ]
82 }
83 ]
84} \ No newline at end of file
diff --git a/dbstore/peewee_store.py b/dbstore/peewee_store.py
index c8d9c22..d05c642 100644
--- a/dbstore/peewee_store.py
+++ b/dbstore/peewee_store.py
@@ -5,7 +5,7 @@ TOOT_VISIBILITY_UNLISTED = "unlisted"
5TOOT_VISIBILITY_PRIVATE = "private" 5TOOT_VISIBILITY_PRIVATE = "private"
6 6
7 7
8db = SqliteDatabase("checkinbot.db") 8db = SqliteDatabase("database/checkinbot.db")
9db.connect(reuse_if_open=True) 9db.connect(reuse_if_open=True)
10 10
11 11
diff --git a/requirements.txt b/requirements.txt
index d1e0036..39887b9 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,12 +1,10 @@
1anyio==3.6.2 1anyio==3.6.2
2APScheduler==3.10.0 2APScheduler==3.10.0
3asgiref==3.6.0
4blurhash==1.1.4 3blurhash==1.1.4
5certifi==2022.12.7 4certifi==2022.12.7
6cffi==1.15.1 5cffi==1.15.1
7charset-normalizer==3.0.1 6charset-normalizer==3.0.1
8click==8.1.3 7click==8.1.3
9crypto==1.4.1
10cryptography==39.0.1 8cryptography==39.0.1
11decorator==5.1.1 9decorator==5.1.1
12greenlet==2.0.2 10greenlet==2.0.2
@@ -18,24 +16,18 @@ httpx==0.23.3
18hyperframe==6.0.1 16hyperframe==6.0.1
19idna==3.4 17idna==3.4
20Mastodon.py @ git+https://cgit.jinwei.me/clarkzjw/mastodon.py@503d58d226c52901532067d3dcb5a7814699f7fb 18Mastodon.py @ git+https://cgit.jinwei.me/clarkzjw/mastodon.py@503d58d226c52901532067d3dcb5a7814699f7fb
21Naked==0.1.32
22peewee==3.15.4 19peewee==3.15.4
23Pillow==9.4.0
24pycparser==2.21 20pycparser==2.21
25pycrypto==2.6.1
26python-dateutil==2.8.2 21python-dateutil==2.8.2
27python-magic==0.4.27 22python-magic==0.4.27
28python-telegram-bot==20.1 23python-telegram-bot==20.1
29pytz==2022.7.1 24pytz==2022.7.1
30pytz-deprecation-shim==0.1.0.post0 25pytz-deprecation-shim==0.1.0.post0
31PyYAML==6.0
32requests==2.28.2 26requests==2.28.2
33rfc3986==1.5.0 27rfc3986==1.5.0
34shellescape==3.8.1
35six==1.16.0 28six==1.16.0
36sniffio==1.3.0 29sniffio==1.3.0
37SQLAlchemy==2.0.4 30SQLAlchemy==2.0.4
38sqlparse==0.4.3
39starlette==0.25.0 31starlette==0.25.0
40typing_extensions==4.5.0 32typing_extensions==4.5.0
41tzdata==2022.7 33tzdata==2022.7
Powered by cgit v1.2.3 (git 2.41.0)