Compare commits
4 Commits
cec96f7014
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
| ce21869440 | |||
| 7ae8d4330a | |||
| ef160828c1 | |||
| 8cd904a34a |
@@ -43,6 +43,19 @@ doUpdate: true # set it to true to enable updater
|
|||||||
domains: [] # subdomains that you want auto-update (Example: { "name": "www.example.com", "proxied": true })
|
domains: [] # subdomains that you want auto-update (Example: { "name": "www.example.com", "proxied": true })
|
||||||
zone: null # zone of your domain name (such as example.com)
|
zone: null # zone of your domain name (such as example.com)
|
||||||
ddnsBroadcastCode: code-here # IMPORTANT: Replace it that only you know
|
ddnsBroadcastCode: code-here # IMPORTANT: Replace it that only you know
|
||||||
|
maintenancePageDNS: "" # Maintenance page DNS name, such as maintenance.example.com
|
||||||
|
maintenancePageURL: "" # Deprecated fallback. Use maintenancePageDNS instead.
|
||||||
```
|
```
|
||||||
|
|
||||||
Remember to restart the tool after you save the config file.
|
For dns item, use this template:
|
||||||
|
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"name": "www.example.com", # DNS name
|
||||||
|
"proxied": false, # Enable proxy (Enable this if you want to hide your server's real IP)
|
||||||
|
"type": "A", # or "CNAME", "AAA", "TEXT", "MX"
|
||||||
|
"allowMaintenance": true # Redirect to maintenancePageDNS if maintenance mode is enabled.
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Remember to restart the tool after you save the config file.
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import os
|
|||||||
import sys
|
import sys
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
|
from urllib.parse import urlparse
|
||||||
import requests
|
import requests
|
||||||
from utils.yaml import yaml_parser, yaml_writer
|
from utils.yaml import yaml_parser, yaml_writer
|
||||||
from settings import CONFIG_DIR
|
from settings import CONFIG_DIR
|
||||||
@@ -30,11 +31,13 @@ cf_config = {
|
|||||||
"cfSecret": None,
|
"cfSecret": None,
|
||||||
"allowedBroadcastServer": [
|
"allowedBroadcastServer": [
|
||||||
],
|
],
|
||||||
"ddnsBroadcastCode": "code-here"
|
"ddnsBroadcastCode": "code-here",
|
||||||
|
"maintenancePageDNS": "",
|
||||||
|
"maintenancePageURL": ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class CloudflareDDNSHelper(Helper):
|
class CloudflareHelper(Helper):
|
||||||
def __init__(self, dc):
|
def __init__(self, dc):
|
||||||
Helper.__init__(self)
|
Helper.__init__(self)
|
||||||
self.dc = dc
|
self.dc = dc
|
||||||
@@ -53,10 +56,13 @@ class CloudflareDDNSHelper(Helper):
|
|||||||
self.init = False
|
self.init = False
|
||||||
self.ip = None
|
self.ip = None
|
||||||
|
|
||||||
|
# maintenance mode
|
||||||
|
self.is_maintenance = False
|
||||||
|
|
||||||
self.config = cf_config
|
self.config = cf_config
|
||||||
self.allowed_broadcast_channels = {}
|
self.allowed_broadcast_channels = {}
|
||||||
|
|
||||||
@self.dc.handle_command("/cf:update_ddns")
|
@self.dc.handle_command("/cf:update_ddns", help="Update cloudflare DNS")
|
||||||
async def renew(client, message):
|
async def renew(client, message):
|
||||||
guild = getattr(message, "guild", None)
|
guild = getattr(message, "guild", None)
|
||||||
if guild is None:
|
if guild is None:
|
||||||
@@ -69,7 +75,7 @@ class CloudflareDDNSHelper(Helper):
|
|||||||
else:
|
else:
|
||||||
await message.channel.send(f"Unsupported server: {guild.name}")
|
await message.channel.send(f"Unsupported server: {guild.name}")
|
||||||
|
|
||||||
@self.dc.handle_command("/cf:add_channel")
|
@self.dc.handle_command("/cf:add_channel", help="Add channel to the cf operator list")
|
||||||
async def add_channel(client, message):
|
async def add_channel(client, message):
|
||||||
guild = getattr(message, "guild", None)
|
guild = getattr(message, "guild", None)
|
||||||
if guild is None:
|
if guild is None:
|
||||||
@@ -88,6 +94,37 @@ class CloudflareDDNSHelper(Helper):
|
|||||||
)
|
)
|
||||||
await message.channel.send(result)
|
await message.channel.send(result)
|
||||||
|
|
||||||
|
@self.dc.handle_command("/cf:maintenance", help="Toggle maintenance mode")
|
||||||
|
async def enable_maintenance(client, message):
|
||||||
|
guild = getattr(message, "guild", None)
|
||||||
|
if guild is None:
|
||||||
|
await message.channel.send("This command can only be used in server channels.")
|
||||||
|
return
|
||||||
|
|
||||||
|
if self.is_allowed_broadcast_server(guild.name):
|
||||||
|
if not self.is_maintenance:
|
||||||
|
self.is_maintenance = True
|
||||||
|
self.update_ddns()
|
||||||
|
await message.channel.send(f"Maintenance mode is enabled. Updating DDNS...")
|
||||||
|
else:
|
||||||
|
self.is_maintenance = False
|
||||||
|
self.update_ddns()
|
||||||
|
await message.channel.send(f"Maintenance mode is disabled. Updating DDNS...")
|
||||||
|
else:
|
||||||
|
await message.channel.send(f"Unsupported server: {guild.name}")
|
||||||
|
|
||||||
|
@self.dc.handle_command("/cf:status-maintenance", help="Check status of maintenance mode")
|
||||||
|
async def check_maintenance(client, message):
|
||||||
|
guild = getattr(message, "guild", None)
|
||||||
|
if guild is None:
|
||||||
|
await message.channel.send("This command can only be used in server channels.")
|
||||||
|
return
|
||||||
|
|
||||||
|
if self.is_allowed_broadcast_server(guild.name):
|
||||||
|
await message.channel.send("Maintenance mode is on" if self.is_maintenance else "Maintenance mode is off")
|
||||||
|
else:
|
||||||
|
await message.channel.send(f"Unsupported server: {guild.name}")
|
||||||
|
|
||||||
class DCStream:
|
class DCStream:
|
||||||
def __init__(self, helper):
|
def __init__(self, helper):
|
||||||
self.helper = helper
|
self.helper = helper
|
||||||
@@ -196,10 +233,20 @@ class CloudflareDDNSHelper(Helper):
|
|||||||
self.logger.error("An error occurred while getting DNS records: {}".format(e))
|
self.logger.error("An error occurred while getting DNS records: {}".format(e))
|
||||||
return
|
return
|
||||||
|
|
||||||
|
maintenance_dns = self.get_maintenance_page_dns()
|
||||||
|
start_maintenance = False
|
||||||
|
|
||||||
|
if self.is_maintenance and maintenance_dns:
|
||||||
|
self.logger.info("Maintenance mode is on. Redirecting support dns records to maintenance page...")
|
||||||
|
start_maintenance = True
|
||||||
|
elif self.is_maintenance:
|
||||||
|
self.logger.warning("Maintenance mode is on but maintenancePageDNS is not set yet. Ignoring...")
|
||||||
|
|
||||||
for item in domains:
|
for item in domains:
|
||||||
domain = item.get("name", None)
|
domain = item.get("name", None)
|
||||||
proxied = item.get("proxied", False)
|
proxied = item.get("proxied", False)
|
||||||
domain_type = item.get("type", "A")
|
domain_type = item.get("type", "A")
|
||||||
|
allow_maintenance = item.get("allowMaintenance", False)
|
||||||
|
|
||||||
if domain is None:
|
if domain is None:
|
||||||
continue
|
continue
|
||||||
@@ -208,9 +255,12 @@ class CloudflareDDNSHelper(Helper):
|
|||||||
|
|
||||||
for record in dns_records:
|
for record in dns_records:
|
||||||
name = record.get("name", None)
|
name = record.get("name", None)
|
||||||
record_type = record.get("type", None)
|
# record_type = record.get("type", None)
|
||||||
|
|
||||||
if name == domain and record_type == domain_type:
|
# if name == domain and record_type == domain_type:
|
||||||
|
# record_id = record.get("id", None)
|
||||||
|
|
||||||
|
if name == domain:
|
||||||
record_id = record.get("id", None)
|
record_id = record.get("id", None)
|
||||||
|
|
||||||
if record_id is None:
|
if record_id is None:
|
||||||
@@ -219,9 +269,9 @@ class CloudflareDDNSHelper(Helper):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
request_data = {
|
request_data = {
|
||||||
"type": domain_type,
|
"type": domain_type if not start_maintenance or not allow_maintenance else "CNAME",
|
||||||
"name": domain,
|
"name": domain,
|
||||||
"content": self.ip,
|
"content": self.ip if not start_maintenance or not allow_maintenance else maintenance_dns,
|
||||||
"ttl": 120,
|
"ttl": 120,
|
||||||
"proxied": proxied
|
"proxied": proxied
|
||||||
}
|
}
|
||||||
@@ -245,6 +295,22 @@ class CloudflareDDNSHelper(Helper):
|
|||||||
self.logger.error(f"Unable to update dns record for domain name {domain}: {e}")
|
self.logger.error(f"Unable to update dns record for domain name {domain}: {e}")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
def get_maintenance_page_dns(self):
|
||||||
|
value = self.config.get("maintenancePageDNS") or self.config.get("maintenancePageURL")
|
||||||
|
|
||||||
|
if value is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
value = str(value).strip()
|
||||||
|
if value == "":
|
||||||
|
return None
|
||||||
|
|
||||||
|
parsed = urlparse(value)
|
||||||
|
if parsed.hostname:
|
||||||
|
return parsed.hostname
|
||||||
|
|
||||||
|
return value.rstrip("/")
|
||||||
|
|
||||||
def parse_allowed_broadcast_channels(self):
|
def parse_allowed_broadcast_channels(self):
|
||||||
raw = self.config.get("allowedBroadcastServer", [])
|
raw = self.config.get("allowedBroadcastServer", [])
|
||||||
allowed = {}
|
allowed = {}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import os
|
|||||||
import discord
|
import discord
|
||||||
import dotenv
|
import dotenv
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
from helper import CloudflareDDNSHelper
|
from helper import CloudflareHelper
|
||||||
|
|
||||||
class DiscordServer(threading.Thread):
|
class DiscordServer(threading.Thread):
|
||||||
def __init__(self, daemon=False, **kwargs):
|
def __init__(self, daemon=False, **kwargs):
|
||||||
@@ -42,13 +42,25 @@ class DiscordServer(threading.Thread):
|
|||||||
else:
|
else:
|
||||||
await message.channel.send(f'You are in private chat.')
|
await message.channel.send(f'You are in private chat.')
|
||||||
|
|
||||||
|
if message.content.startswith('/help'):
|
||||||
|
msg = "Commands:\n"
|
||||||
|
for command in self.commands:
|
||||||
|
msg += f'- {command}: {self.commands[command].get('help') if self.commands[command].get('help') else "A command"}\n'
|
||||||
|
|
||||||
|
await message.channel.send(
|
||||||
|
msg
|
||||||
|
)
|
||||||
|
|
||||||
for command in self.commands:
|
for command in self.commands:
|
||||||
if message.content.startswith(command):
|
if message.content.startswith(command):
|
||||||
await self.commands[command](self.client, message)
|
await self.commands[command].get("func")(self.client, message)
|
||||||
|
|
||||||
def handle_command(self, command_prefix):
|
def handle_command(self, command_prefix, help=None):
|
||||||
def decorator(func):
|
def decorator(func):
|
||||||
self.commands[command_prefix] = func
|
self.commands[command_prefix] = {
|
||||||
|
"func": func,
|
||||||
|
"help": help
|
||||||
|
}
|
||||||
|
|
||||||
def inner(*args, **kwargs):
|
def inner(*args, **kwargs):
|
||||||
return func(*args, **kwargs)
|
return func(*args, **kwargs)
|
||||||
@@ -77,7 +89,7 @@ class App:
|
|||||||
self.logger.addHandler(sh)
|
self.logger.addHandler(sh)
|
||||||
|
|
||||||
self.dc_server = DiscordServer(daemon=True)
|
self.dc_server = DiscordServer(daemon=True)
|
||||||
self.cf_helper = CloudflareDDNSHelper(self.dc_server)
|
self.cf_helper = CloudflareHelper(self.dc_server)
|
||||||
|
|
||||||
def main(self):
|
def main(self):
|
||||||
try:
|
try:
|
||||||
|
|||||||
Reference in New Issue
Block a user