Compare commits
3 Commits
v0.0.1
...
b56ece2216
| Author | SHA1 | Date | |
|---|---|---|---|
|
b56ece2216
|
|||
|
0383b47b8e
|
|||
|
afd5286ef5
|
@@ -21,12 +21,10 @@ jobs:
|
|||||||
run : |
|
run : |
|
||||||
cd master
|
cd master
|
||||||
echo "${{ secrets.DOCKERGIT_TOKEN }}" | docker login git.woodburn.au -u nathanwoodburn --password-stdin
|
echo "${{ secrets.DOCKERGIT_TOKEN }}" | docker login git.woodburn.au -u nathanwoodburn --password-stdin
|
||||||
|
tag_num=$(git rev-parse --short HEAD)
|
||||||
echo "branch=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}"
|
echo "branch=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}"
|
||||||
tag=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}
|
tag=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}
|
||||||
tag=${tag//\//-}
|
tag=${tag//\//-}
|
||||||
tag_num=${GITHUB_RUN_NUMBER}
|
|
||||||
echo "tag_num=$tag_num"
|
|
||||||
|
|
||||||
if [[ "$tag" == "main" ]]; then
|
if [[ "$tag" == "main" ]]; then
|
||||||
tag="latest"
|
tag="latest"
|
||||||
else
|
else
|
||||||
@@ -62,10 +60,10 @@ jobs:
|
|||||||
run : |
|
run : |
|
||||||
cd discord-bot
|
cd discord-bot
|
||||||
echo "${{ secrets.DOCKERGIT_TOKEN }}" | docker login git.woodburn.au -u nathanwoodburn --password-stdin
|
echo "${{ secrets.DOCKERGIT_TOKEN }}" | docker login git.woodburn.au -u nathanwoodburn --password-stdin
|
||||||
|
tag_num=$(git rev-parse --short HEAD)
|
||||||
echo "branch=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}"
|
echo "branch=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}"
|
||||||
tag=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}
|
tag=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}
|
||||||
tag=${tag//\//-}
|
tag=${tag//\//-}
|
||||||
tag_num=${GITHUB_RUN_NUMBER}
|
|
||||||
if [[ "$tag" == "main" ]]; then
|
if [[ "$tag" == "main" ]]; then
|
||||||
tag="latest"
|
tag="latest"
|
||||||
else
|
else
|
||||||
@@ -76,4 +74,5 @@ jobs:
|
|||||||
docker tag hnshosting-bot:$tag_num git.woodburn.au/nathanwoodburn/hnshosting-bot:$tag_num
|
docker tag hnshosting-bot:$tag_num git.woodburn.au/nathanwoodburn/hnshosting-bot:$tag_num
|
||||||
docker push git.woodburn.au/nathanwoodburn/hnshosting-bot:$tag_num
|
docker push git.woodburn.au/nathanwoodburn/hnshosting-bot:$tag_num
|
||||||
docker tag hnshosting-bot:$tag_num git.woodburn.au/nathanwoodburn/hnshosting-bot:$tag
|
docker tag hnshosting-bot:$tag_num git.woodburn.au/nathanwoodburn/hnshosting-bot:$tag
|
||||||
docker push git.woodburn.au/nathanwoodburn/hnshosting-bot:$tag
|
docker push git.woodburn.au/nathanwoodburn/hnshosting-bot:$tag
|
||||||
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
name: Build Docker for Release
|
|
||||||
run-name: Build Docker Images
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
tags:
|
|
||||||
- '*'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
TEST:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
- name: Print tag
|
|
||||||
run: echo "tag=${GITHUB_REF#refs/tags/}"
|
|
||||||
@@ -24,7 +24,7 @@ The bot will be used to provide an easier way to manage the master server.
|
|||||||
After installing the master and discord bot you can use the following commands (as bot owner).
|
After installing the master and discord bot you can use the following commands (as bot owner).
|
||||||
|
|
||||||
```
|
```
|
||||||
/addworker <ip> <private ip> <name> | add a worker to the master server pool
|
/addworker <ip> <name> | add a worker to the master server pool (Make sure the master can access port 5000 on the worker, and don't allow anyone else to access it)
|
||||||
/listworkers | list all workers
|
/listworkers | list all workers
|
||||||
/licence | Creates a licence key (valid for 1 wp site)
|
/licence | Creates a licence key (valid for 1 wp site)
|
||||||
```
|
```
|
||||||
@@ -90,14 +90,9 @@ screen -dmS hnshosting-worker python3 main.py
|
|||||||
```
|
```
|
||||||
|
|
||||||
Add worker to master server pool:
|
Add worker to master server pool:
|
||||||
The master server will need to be able to access port 5000 on the worker server over the PRIVATE ip. This is not secured by the api key so make sure you don't allow anyone else to access it.
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
curl -X POST http://master-server-ip:5000/add-worker?worker=worker-name&ip=worker-server-ip&priv=worker-server-private-ip -H "key: api-key"
|
curl -X POST http://master-server-ip:5000/add-worker?worker=worker-name&ip=worker-server-ip -H "key: api-key"
|
||||||
```
|
|
||||||
Alternatively you can use the discord bot to add the worker to the master server pool.
|
|
||||||
```
|
|
||||||
/addworker <ip> <private ip> <name>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Discord bot install
|
## Discord bot install
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ from dotenv import load_dotenv
|
|||||||
import discord
|
import discord
|
||||||
from discord import app_commands
|
from discord import app_commands
|
||||||
import requests
|
import requests
|
||||||
import asyncio
|
|
||||||
|
|
||||||
load_dotenv()
|
load_dotenv()
|
||||||
TOKEN = os.getenv('DISCORD_TOKEN')
|
TOKEN = os.getenv('DISCORD_TOKEN')
|
||||||
@@ -22,9 +21,9 @@ client = discord.Client(intents=intents)
|
|||||||
tree = app_commands.CommandTree(client)
|
tree = app_commands.CommandTree(client)
|
||||||
|
|
||||||
@tree.command(name="addworker", description="Adds a worker to the master server")
|
@tree.command(name="addworker", description="Adds a worker to the master server")
|
||||||
async def addworker(ctx, ip: str,privateip: str, name: str):
|
async def addworker(ctx, ip: str, name: str):
|
||||||
if ctx.user.id == ADMINID:
|
if ctx.user.id == ADMINID:
|
||||||
r = requests.post(f"http://{Master_IP}:{Master_Port}/add-worker?worker={name}&ip={ip}&priv={privateip}",headers={"key":os.getenv('WORKER_KEY')})
|
r = requests.post(f"http://{Master_IP}:{Master_Port}/add-worker?worker={name}&ip={ip}",headers={"key":os.getenv('WORKER_KEY')})
|
||||||
if r.status_code == 200:
|
if r.status_code == 200:
|
||||||
await ctx.response.send_message(f"Worker {name} added to the master server",ephemeral=True)
|
await ctx.response.send_message(f"Worker {name} added to the master server",ephemeral=True)
|
||||||
else:
|
else:
|
||||||
@@ -70,22 +69,7 @@ async def createsite(ctx, domain: str, licence: str):
|
|||||||
if r.status_code == 200:
|
if r.status_code == 200:
|
||||||
json = r.json()
|
json = r.json()
|
||||||
if json['success'] == "true":
|
if json['success'] == "true":
|
||||||
await ctx.response.send_message(f"Site {domain} creating...\nI'll send you a message when it's ready")
|
await ctx.response.send_message(f"Site {domain} creating...\nPlease wait a few minutes and then send /siteinfo domain:{domain}")
|
||||||
|
|
||||||
ready = False
|
|
||||||
while ready == False:
|
|
||||||
ready = await check_site_ready(domain)
|
|
||||||
if ready == False:
|
|
||||||
await asyncio.sleep(5)
|
|
||||||
|
|
||||||
r = requests.get(f"http://{Master_IP}:{Master_Port}/site-info?domain={domain}")
|
|
||||||
json = r.json()
|
|
||||||
if json['success'] == "true":
|
|
||||||
await ctx.user.send(f"Site {domain} is ready!\nHere is the site info for {json['domain']}\nA: `{json['ip']}`\nTLSA: `{json['tlsa']}`\nMake sure you put the TLSA in either `_443._tcp.{domain}` or `*.{domain}`")
|
|
||||||
else:
|
|
||||||
await ctx.user.send(f"Error getting site info\n" + json['error'])
|
|
||||||
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
await ctx.response.send_message(f"Error creating site\n" + json['error'])
|
await ctx.response.send_message(f"Error creating site\n" + json['error'])
|
||||||
else:
|
else:
|
||||||
@@ -104,17 +88,6 @@ async def siteinfo(ctx, domain: str):
|
|||||||
else:
|
else:
|
||||||
await ctx.response.send_message(f"Error getting site info\n" + r.text)
|
await ctx.response.send_message(f"Error getting site info\n" + r.text)
|
||||||
|
|
||||||
async def check_site_ready(domain):
|
|
||||||
r = requests.get(f"http://{Master_IP}:{Master_Port}/site-info?domain={domain}")
|
|
||||||
if r.status_code == 200:
|
|
||||||
json = r.json()
|
|
||||||
if json['success'] == "true":
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
|
|
||||||
# When the bot is ready
|
# When the bot is ready
|
||||||
@client.event
|
@client.event
|
||||||
async def on_ready():
|
async def on_ready():
|
||||||
|
|||||||
@@ -107,10 +107,9 @@ def new_site():
|
|||||||
def add_worker():
|
def add_worker():
|
||||||
worker=request.args.get('worker')
|
worker=request.args.get('worker')
|
||||||
worker_IP=request.args.get('ip')
|
worker_IP=request.args.get('ip')
|
||||||
worker_PRIV=request.args.get('priv')
|
|
||||||
# Get API header
|
# Get API header
|
||||||
api_key = request.headers.get('key')
|
api_key = request.headers.get('key')
|
||||||
if api_key == None or worker == None or worker_IP == None or worker_PRIV == None:
|
if api_key == None or worker == None or worker_IP == None:
|
||||||
return jsonify({'error': 'Invalid API key or worker info', 'success': 'false'})
|
return jsonify({'error': 'Invalid API key or worker info', 'success': 'false'})
|
||||||
if api_key != os.getenv('WORKER_KEY'):
|
if api_key != os.getenv('WORKER_KEY'):
|
||||||
return jsonify({'error': 'Invalid API key', 'success': 'false'})
|
return jsonify({'error': 'Invalid API key', 'success': 'false'})
|
||||||
@@ -131,11 +130,11 @@ def add_worker():
|
|||||||
|
|
||||||
# Add worker to file
|
# Add worker to file
|
||||||
workers_file = open('/data/workers.txt', 'a')
|
workers_file = open('/data/workers.txt', 'a')
|
||||||
workers_file.write(worker + ":" + worker_PRIV + ":"+ worker_IP + '\n')
|
workers_file.write(worker + ":" + worker_IP + '\n')
|
||||||
workers_file.close()
|
workers_file.close()
|
||||||
|
|
||||||
online=True
|
online=True
|
||||||
resp=requests.get("http://"+worker_PRIV + ":5000/ping",timeout=2)
|
resp=requests.get("http://"+worker_IP + ":5000/ping",timeout=2)
|
||||||
if (resp.status_code != 200):
|
if (resp.status_code != 200):
|
||||||
online=False
|
online=False
|
||||||
|
|
||||||
@@ -175,14 +174,14 @@ def list_workers():
|
|||||||
resp=requests.get("http://"+worker.split(':')[1].strip('\n') + ":5000/status",timeout=2)
|
resp=requests.get("http://"+worker.split(':')[1].strip('\n') + ":5000/status",timeout=2)
|
||||||
if (resp.status_code != 200):
|
if (resp.status_code != 200):
|
||||||
online=False
|
online=False
|
||||||
worker_list.append({'worker': worker.split(':')[0],'ip': worker.split(':')[2].strip('\n'), 'online': online, 'sites': 0, 'status': 'offline'})
|
worker_list.append({'worker': worker.split(':')[0],'ip': worker.split(':')[1].strip('\n'), 'online': online, 'sites': 0, 'status': 'offline'})
|
||||||
continue
|
continue
|
||||||
sites = resp.json()['num_sites']
|
sites = resp.json()['num_sites']
|
||||||
availability = resp.json()['availability']
|
availability = resp.json()['availability']
|
||||||
if availability == True:
|
if availability == True:
|
||||||
worker_list.append({'worker': worker.split(':')[0],'ip': worker.split(':')[2].strip('\n'), 'online': online, 'sites': sites, 'status': 'ready'})
|
worker_list.append({'worker': worker.split(':')[0],'ip': worker.split(':')[1].strip('\n'), 'online': online, 'sites': sites, 'status': 'ready'})
|
||||||
else:
|
else:
|
||||||
worker_list.append({'worker': worker.split(':')[0],'ip': worker.split(':')[2].strip('\n'), 'online': online, 'sites': sites, 'status': 'full'})
|
worker_list.append({'worker': worker.split(':')[0],'ip': worker.split(':')[1].strip('\n'), 'online': online, 'sites': sites, 'status': 'full'})
|
||||||
|
|
||||||
if len(worker_list) == 0:
|
if len(worker_list) == 0:
|
||||||
return jsonify({'error': 'No workers available', 'success': 'false'})
|
return jsonify({'error': 'No workers available', 'success': 'false'})
|
||||||
@@ -204,18 +203,17 @@ def site_status():
|
|||||||
return jsonify({'error': 'Domain does not exist', 'success': 'false'})
|
return jsonify({'error': 'Domain does not exist', 'success': 'false'})
|
||||||
|
|
||||||
# Get worker ip
|
# Get worker ip
|
||||||
ip = workerIP_PRIV(worker)
|
ip = workerIP(worker)
|
||||||
|
|
||||||
# Get TLSA record
|
# Get TLSA record
|
||||||
resp=requests.get("http://"+ip + ":5000/tlsa?domain=" + domain,timeout=2)
|
resp=requests.get("http://"+ip + ":5000/tlsa?domain=" + domain,timeout=2)
|
||||||
json = resp.json()
|
json = resp.json()
|
||||||
publicIP = workerIP(worker)
|
|
||||||
|
|
||||||
if "tlsa" in json:
|
if "tlsa" in json:
|
||||||
tlsa = json['tlsa']
|
tlsa = json['tlsa']
|
||||||
return jsonify({'success': 'true', 'domain': domain, 'ip': publicIP, 'tlsa': tlsa})
|
return jsonify({'success': 'true', 'domain': domain, 'ip': ip, 'tlsa': tlsa})
|
||||||
else:
|
else:
|
||||||
return jsonify({'success': 'false', 'domain': domain, 'ip': publicIP, 'tlsa': 'none','error': 'No TLSA record found'})
|
return jsonify({'success': 'false', 'domain': domain, 'ip': ip, 'tlsa': 'none','error': 'No TLSA record found'})
|
||||||
|
|
||||||
|
|
||||||
@app.route('/tlsa', methods=['GET'])
|
@app.route('/tlsa', methods=['GET'])
|
||||||
@@ -234,7 +232,7 @@ def tlsa():
|
|||||||
return jsonify({'error': 'Domain does not exist', 'success': 'false'})
|
return jsonify({'error': 'Domain does not exist', 'success': 'false'})
|
||||||
|
|
||||||
# Get worker ip
|
# Get worker ip
|
||||||
ip = workerIP_PRIV(worker)
|
ip = workerIP(worker)
|
||||||
|
|
||||||
# Get TLSA record
|
# Get TLSA record
|
||||||
resp=requests.get("http://"+ip + ":5000/tlsa?domain=" + domain,timeout=2)
|
resp=requests.get("http://"+ip + ":5000/tlsa?domain=" + domain,timeout=2)
|
||||||
@@ -345,24 +343,6 @@ def site_worker(domain):
|
|||||||
sites_file.close()
|
sites_file.close()
|
||||||
return worker
|
return worker
|
||||||
|
|
||||||
def workerIP_PRIV(worker):
|
|
||||||
# If file doesn't exist, create it
|
|
||||||
try:
|
|
||||||
workers_file = open('/data/workers.txt', 'r')
|
|
||||||
except FileNotFoundError:
|
|
||||||
workers_file = open('/data/workers.txt', 'w')
|
|
||||||
workers_file.close()
|
|
||||||
workers_file = open('/data/workers.txt', 'r')
|
|
||||||
|
|
||||||
ip = None
|
|
||||||
for line in workers_file.readlines():
|
|
||||||
if worker == line.split(':')[0]:
|
|
||||||
ip = line.split(':')[2].strip('\n')
|
|
||||||
break
|
|
||||||
|
|
||||||
workers_file.close()
|
|
||||||
return ip
|
|
||||||
|
|
||||||
def workerIP(worker):
|
def workerIP(worker):
|
||||||
# If file doesn't exist, create it
|
# If file doesn't exist, create it
|
||||||
try:
|
try:
|
||||||
@@ -380,6 +360,7 @@ def workerIP(worker):
|
|||||||
|
|
||||||
workers_file.close()
|
workers_file.close()
|
||||||
return ip
|
return ip
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Start the server
|
# Start the server
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ KERNEL_VERSION=$(uname -r)
|
|||||||
sudo apt-mark hold linux-image-generic linux-headers-generic linux-generic linux-image-$KERNEL_VERSION linux-headers-$KERNEL_VERSION
|
sudo apt-mark hold linux-image-generic linux-headers-generic linux-generic linux-image-$KERNEL_VERSION linux-headers-$KERNEL_VERSION
|
||||||
|
|
||||||
# Install Docker
|
# Install Docker
|
||||||
sudo apt update
|
|
||||||
sudo apt install apt-transport-https ca-certificates curl software-properties-common python3-pip nginx -y
|
sudo apt install apt-transport-https ca-certificates curl software-properties-common python3-pip nginx -y
|
||||||
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
|
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
|
||||||
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
|
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||||||
|
|||||||
Reference in New Issue
Block a user