much cleanup
This commit is contained in:
parent
23852729c1
commit
7b83facc21
12
src/command/command.py
Normal file
12
src/command/command.py
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
class Command:
|
||||||
|
def __init__(self, name:str, description:str, usage:str):
|
||||||
|
self.name = name
|
||||||
|
self.description = description
|
||||||
|
self.usage = usage
|
||||||
|
|
||||||
|
async def execute(self, traefikConfig, args):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def printUsage(self):
|
||||||
|
print("Usage: %s" % self.usage)
|
||||||
|
pass
|
27
src/command/commandManager.py
Normal file
27
src/command/commandManager.py
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
from command.impl.addCommand import AddCommand
|
||||||
|
from command.impl.listCommand import ListCommand
|
||||||
|
from command.impl.removeCommand import RemoveCommand
|
||||||
|
|
||||||
|
class CommandManager:
|
||||||
|
|
||||||
|
commands = []
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.addCommand(AddCommand())
|
||||||
|
self.addCommand(RemoveCommand())
|
||||||
|
self.addCommand(ListCommand())
|
||||||
|
pass
|
||||||
|
|
||||||
|
def addCommand(self, command):
|
||||||
|
self.commands.append(command)
|
||||||
|
pass
|
||||||
|
|
||||||
|
def getCommand(self, name):
|
||||||
|
for command in self.commands:
|
||||||
|
if command.name == name:
|
||||||
|
return command
|
||||||
|
return None
|
||||||
|
|
||||||
|
def commandExists(self, name):
|
||||||
|
return self.getCommand(name) != None
|
||||||
|
|
31
src/command/impl/addCommand.py
Normal file
31
src/command/impl/addCommand.py
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
from command.command import Command
|
||||||
|
from traefik.traefikConfig import TraefikConfig
|
||||||
|
from utils.dockerUtils import restartTraefik
|
||||||
|
|
||||||
|
class AddCommand(Command):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__("add", "Add a domain", "add <name> <domain> <service host>")
|
||||||
|
|
||||||
|
def execute(self, traefikConfig:TraefikConfig, args):
|
||||||
|
if len(args) < 3:
|
||||||
|
self.printUsage()
|
||||||
|
return
|
||||||
|
|
||||||
|
name = args[0]
|
||||||
|
domain = args[1]
|
||||||
|
serviceHost = args[2]
|
||||||
|
|
||||||
|
if traefikConfig.hasRouter(name):
|
||||||
|
print(f"Router \"{name}\" already exists")
|
||||||
|
return
|
||||||
|
|
||||||
|
print(f"Adding \"{domain}\" -> \"{serviceHost}\"")
|
||||||
|
|
||||||
|
traefikConfig.addRouter(name, domain, serviceHost)
|
||||||
|
traefikConfig.addService(name, serviceHost)
|
||||||
|
|
||||||
|
traefikConfig.save()
|
||||||
|
|
||||||
|
restartTraefik()
|
||||||
|
|
||||||
|
print("Done!")
|
19
src/command/impl/listCommand.py
Normal file
19
src/command/impl/listCommand.py
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
from colorama import Fore
|
||||||
|
from command.command import Command
|
||||||
|
from traefik.traefikConfig import TraefikConfig
|
||||||
|
|
||||||
|
class ListCommand(Command):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__("list", "List all services", "list")
|
||||||
|
|
||||||
|
def execute(self, traefikConfig:TraefikConfig, args):
|
||||||
|
print("Listing all services:")
|
||||||
|
|
||||||
|
domains = traefikConfig.getAll()
|
||||||
|
|
||||||
|
# Print domains
|
||||||
|
for name, domain in domains.items():
|
||||||
|
print(f" - {Fore.CYAN}[{name}] {Fore.GREEN}http://{domain['domain']} {Fore.RESET}-> {Fore.YELLOW}{domain['serviceHost']}{Fore.RESET}")
|
||||||
|
|
||||||
|
print("")
|
||||||
|
print("Total: %s" % len(domains))
|
29
src/command/impl/removeCommand.py
Normal file
29
src/command/impl/removeCommand.py
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
from colorama import Fore
|
||||||
|
from command.command import Command
|
||||||
|
from traefik.traefikConfig import TraefikConfig
|
||||||
|
from utils.dockerUtils import restartTraefik
|
||||||
|
|
||||||
|
class RemoveCommand(Command):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__("remove", "Remove a domain", "remove <name>")
|
||||||
|
|
||||||
|
def execute(self, traefikConfig:TraefikConfig, args):
|
||||||
|
if len(args) < 0:
|
||||||
|
self.printUsage()
|
||||||
|
return
|
||||||
|
|
||||||
|
name = args[0]
|
||||||
|
|
||||||
|
if not traefikConfig.hasRouter(name):
|
||||||
|
print(f"Router \"{name}\" does not exist")
|
||||||
|
return
|
||||||
|
|
||||||
|
print(f"Removing \"{name}\"")
|
||||||
|
|
||||||
|
traefikConfig.removeRouter(name)
|
||||||
|
|
||||||
|
traefikConfig.save()
|
||||||
|
|
||||||
|
restartTraefik()
|
||||||
|
|
||||||
|
print(f"Removed \"{name}\"")
|
170
src/manage.py
170
src/manage.py
@ -1,171 +1,31 @@
|
|||||||
import sys
|
import sys
|
||||||
import subprocess
|
|
||||||
import yaml
|
|
||||||
import os
|
import os
|
||||||
from colorama import Fore
|
|
||||||
|
from command.commandManager import CommandManager
|
||||||
|
from traefik.traefikConfig import TraefikConfig
|
||||||
|
|
||||||
# Variables
|
# Variables
|
||||||
configFile = "./config.yml"
|
configFile = "./config.yml"
|
||||||
containerName = "traefik"
|
|
||||||
|
|
||||||
# Are we running in a Docker container?
|
# Are we running in a Docker container?
|
||||||
if os.environ.get("CONFIG_FILE"):
|
if os.environ.get("CONFIG_FILE"):
|
||||||
configFile = os.environ.get("CONFIG_FILE")
|
configFile = os.environ.get("CONFIG_FILE")
|
||||||
if os.environ.get("CONTAINER_NAME"):
|
|
||||||
containerName = os.environ.get("CONTAINER_NAME")
|
|
||||||
|
|
||||||
# DO NOT TOUCH
|
traefikConfig = TraefikConfig(configFile)
|
||||||
commands = ["add", "remove", "list", "update"]
|
if traefikConfig.isValid() == False:
|
||||||
|
print("Invalid traefik config file, please check your config.yml file")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
command = len(sys.argv) > 1 and sys.argv[1]
|
command = len(sys.argv) > 1 and sys.argv[1]
|
||||||
|
commandManager = CommandManager()
|
||||||
|
|
||||||
if command not in commands:
|
if not commandManager.commandExists(command):
|
||||||
print("")
|
print("Usage: manage [command]")
|
||||||
print("Usage: manage.py [command]")
|
|
||||||
print("")
|
print("")
|
||||||
print("Commands:")
|
print("Commands:")
|
||||||
print(" - add [name] [domain] [service host]")
|
for command in commandManager.commands:
|
||||||
print(" - remove [name]")
|
print(f" - {command.usage}")
|
||||||
print(" - update [name] [new service host]")
|
|
||||||
print(" - list")
|
|
||||||
exit()
|
exit()
|
||||||
|
|
||||||
with open(configFile, "r") as config:
|
args = sys.argv[2:]
|
||||||
configYml = yaml.safe_load(config)
|
commandManager.getCommand(command).execute(traefikConfig, args)
|
||||||
|
|
||||||
http = configYml["http"]
|
|
||||||
routers = http["routers"]
|
|
||||||
services = http["services"]
|
|
||||||
|
|
||||||
def restartTraefik():
|
|
||||||
print("Restarting Traefik, please wait this can take a while...")
|
|
||||||
|
|
||||||
# Restart Traefik in the base directory
|
|
||||||
subprocess.run(["docker", "restart", "traefik"])
|
|
||||||
|
|
||||||
print(f"{Fore.GREEN}Done!{Fore.RESET}")
|
|
||||||
|
|
||||||
def addDomain(name, domain, serviceHost):
|
|
||||||
# Check if name already exists
|
|
||||||
if name in routers:
|
|
||||||
print(f"Name \"{Fore.RED}{name}{Fore.RESET}\" already exists")
|
|
||||||
exit()
|
|
||||||
|
|
||||||
print(f"Adding domain \"{Fore.CYAN}{name}{Fore.RESET}\" -> \"{Fore.YELLOW}{serviceHost}{Fore.RESET}\"")
|
|
||||||
print(f"Domain: {Fore.GREEN}http://{domain}{Fore.RESET}")
|
|
||||||
|
|
||||||
# Add router
|
|
||||||
routers[name] = {
|
|
||||||
"entryPoints": ["https"],
|
|
||||||
"rule": "Host(`%s`)" % domain,
|
|
||||||
"middlewares": ["default-headers", "https-redirectscheme"],
|
|
||||||
"tls": {},
|
|
||||||
"service": name
|
|
||||||
}
|
|
||||||
|
|
||||||
# Add service
|
|
||||||
services[name] = {
|
|
||||||
"loadBalancer": {
|
|
||||||
"servers": [
|
|
||||||
{
|
|
||||||
"url": serviceHost
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Write to file
|
|
||||||
with open(configFile, "w") as config:
|
|
||||||
yaml.dump(configYml, config)
|
|
||||||
|
|
||||||
# Restart Traefik
|
|
||||||
restartTraefik()
|
|
||||||
|
|
||||||
def removeDomain(name):
|
|
||||||
# Check if name exists
|
|
||||||
if name not in routers:
|
|
||||||
print(f"Name \"{Fore.RED}{name}{Fore.RESET}\" does not exist")
|
|
||||||
exit()
|
|
||||||
|
|
||||||
print(f"Removing domain \"{Fore.CYAN}{name}{Fore.RESET}\"")
|
|
||||||
|
|
||||||
# Remove router
|
|
||||||
del routers[name]
|
|
||||||
|
|
||||||
# Remove service
|
|
||||||
del services[name]
|
|
||||||
|
|
||||||
# Write to file
|
|
||||||
with open(configFile, "w") as config:
|
|
||||||
yaml.dump(configYml, config)
|
|
||||||
|
|
||||||
# Restart Traefik
|
|
||||||
restartTraefik()
|
|
||||||
|
|
||||||
def listDomains():
|
|
||||||
print("Listing domains:")
|
|
||||||
|
|
||||||
# name and domain -> service host
|
|
||||||
domains = {}
|
|
||||||
|
|
||||||
# Loop through routers
|
|
||||||
for name, router in routers.items():
|
|
||||||
# Get domain
|
|
||||||
domain = router["rule"].split("`")[1]
|
|
||||||
|
|
||||||
# Get service host
|
|
||||||
serviceHost = services[name]["loadBalancer"]["servers"][0]["url"]
|
|
||||||
|
|
||||||
# Add to domains
|
|
||||||
domains[name] = {
|
|
||||||
"domain": domain,
|
|
||||||
"serviceHost": serviceHost
|
|
||||||
}
|
|
||||||
|
|
||||||
# Print domains
|
|
||||||
for name, domain in domains.items():
|
|
||||||
print(f" - {Fore.CYAN}[{name}] {Fore.GREEN}http://{domain['domain']} {Fore.RESET}-> {Fore.YELLOW}{domain['serviceHost']}{Fore.RESET}")
|
|
||||||
|
|
||||||
print("")
|
|
||||||
print("Total: %s" % len(domains))
|
|
||||||
|
|
||||||
def updateDomain(name, serviceHost):
|
|
||||||
# Check if name exists
|
|
||||||
if name not in routers:
|
|
||||||
print("Name \"%s\" does not exist" % name)
|
|
||||||
exit()
|
|
||||||
|
|
||||||
print(f"Updating domain \"{Fore.CYAN}{name}{Fore.RESET}\" -> \"{Fore.YELLOW}{serviceHost}{Fore.RESET}\"")
|
|
||||||
|
|
||||||
# Update service
|
|
||||||
services[name] = {
|
|
||||||
"loadBalancer": {
|
|
||||||
"servers": [
|
|
||||||
{
|
|
||||||
"url": serviceHost
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Write to file
|
|
||||||
with open(configFile, "w") as config:
|
|
||||||
yaml.dump(configYml, config)
|
|
||||||
|
|
||||||
# Restart Traefik
|
|
||||||
restartTraefik()
|
|
||||||
|
|
||||||
match command:
|
|
||||||
case "add":
|
|
||||||
name = sys.argv[2]
|
|
||||||
domain = sys.argv[3]
|
|
||||||
serviceHost = sys.argv[4]
|
|
||||||
addDomain(name, domain, serviceHost)
|
|
||||||
case "remove":
|
|
||||||
name = sys.argv[2]
|
|
||||||
removeDomain(name)
|
|
||||||
case "update":
|
|
||||||
name = sys.argv[2]
|
|
||||||
serviceHost = sys.argv[3]
|
|
||||||
updateDomain(name, serviceHost)
|
|
||||||
case "list":
|
|
||||||
listDomains()
|
|
||||||
|
96
src/traefik/traefikConfig.py
Normal file
96
src/traefik/traefikConfig.py
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
import yaml
|
||||||
|
|
||||||
|
|
||||||
|
class TraefikConfig:
|
||||||
|
|
||||||
|
def __init__(self, configFile) -> None:
|
||||||
|
self.configFile = configFile
|
||||||
|
with open(configFile, "r") as config:
|
||||||
|
self.configYml = yaml.safe_load(config)
|
||||||
|
|
||||||
|
def isValid(self) -> bool:
|
||||||
|
return "http" in self.configYml and "routers" in self.configYml["http"] and "services" in self.configYml["http"]
|
||||||
|
|
||||||
|
def getRouter(self, name):
|
||||||
|
return self.configYml["http"]["routers"][name]
|
||||||
|
|
||||||
|
def getService(self, name):
|
||||||
|
return self.configYml["http"]["services"][name]
|
||||||
|
|
||||||
|
def addRouter(self, name, domain, serviceHost):
|
||||||
|
# Add router
|
||||||
|
self.configYml["http"]["routers"][name] = {
|
||||||
|
"entryPoints": ["https"],
|
||||||
|
"rule": "Host(`%s`)" % domain,
|
||||||
|
"middlewares": ["default-headers", "https-redirectscheme"],
|
||||||
|
"tls": {},
|
||||||
|
"service": name
|
||||||
|
}
|
||||||
|
|
||||||
|
# Add service
|
||||||
|
self.configYml["http"]["services"][name] = {
|
||||||
|
"loadBalancer": {
|
||||||
|
"servers": [
|
||||||
|
{
|
||||||
|
"url": serviceHost
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def removeRouter(self, name):
|
||||||
|
# Remove router
|
||||||
|
del self.configYml["http"]["routers"][name]
|
||||||
|
|
||||||
|
# Remove service
|
||||||
|
del self.configYml["http"]["services"][name]
|
||||||
|
|
||||||
|
def hasRouter(self, name):
|
||||||
|
return name in self.configYml["http"]["routers"]
|
||||||
|
|
||||||
|
def addService(self, name, serviceHost):
|
||||||
|
# Add service
|
||||||
|
self.configYml["http"]["services"][name] = {
|
||||||
|
"loadBalancer": {
|
||||||
|
"servers": [
|
||||||
|
{
|
||||||
|
"url": serviceHost
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def hasService(self, name):
|
||||||
|
return name in self.configYml["http"]["services"]
|
||||||
|
|
||||||
|
def getRouters(self):
|
||||||
|
return self.configYml["http"]["routers"]
|
||||||
|
|
||||||
|
def getServices(self):
|
||||||
|
return self.configYml["http"]["services"]
|
||||||
|
|
||||||
|
def getAll(self):
|
||||||
|
domains = {}
|
||||||
|
|
||||||
|
routers = self.getRouters()
|
||||||
|
services = self.getServices()
|
||||||
|
|
||||||
|
# Loop through routers
|
||||||
|
for name, router in routers.items():
|
||||||
|
# Get domain
|
||||||
|
domain = router["rule"].split("`")[1]
|
||||||
|
|
||||||
|
# Get service host
|
||||||
|
serviceHost = services[name]["loadBalancer"]["servers"][0]["url"]
|
||||||
|
|
||||||
|
# Add to domains
|
||||||
|
domains[name] = {
|
||||||
|
"domain": domain,
|
||||||
|
"serviceHost": serviceHost
|
||||||
|
}
|
||||||
|
|
||||||
|
return domains
|
||||||
|
|
||||||
|
def save(self):
|
||||||
|
with open(self.configFile, "w") as config:
|
||||||
|
yaml.dump(self.configYml, config)
|
18
src/utils/dockerUtils.py
Normal file
18
src/utils/dockerUtils.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import subprocess
|
||||||
|
import os
|
||||||
|
|
||||||
|
containerName = "traefik"
|
||||||
|
if os.environ.get("CONTAINER_NAME"):
|
||||||
|
containerName = os.environ.get("CONTAINER_NAME")
|
||||||
|
|
||||||
|
def restartTraefik():
|
||||||
|
# Check if we're in Windows, if so, don't restart Traefik
|
||||||
|
if os.name == "nt":
|
||||||
|
print("Restarting Traefik is not supported on Windows.")
|
||||||
|
return
|
||||||
|
print("Restarting Traefik, please wait this can take a while...")
|
||||||
|
|
||||||
|
# Restart Traefik in the base directory
|
||||||
|
subprocess.run(["docker", "restart", containerName])
|
||||||
|
|
||||||
|
print("Done!")
|
Loading…
Reference in New Issue
Block a user