mirror of
https://github.com/MizuchiLabs/mantrae.git
synced 2025-12-16 20:05:17 -06:00
add additional start flags
This commit is contained in:
@@ -4,6 +4,10 @@ services:
|
||||
mantrae:
|
||||
image: ghcr.io/mizuchilabs/mantrae:latest
|
||||
container_name: mantrae
|
||||
command:
|
||||
- --url=http://traefik:8080
|
||||
- --username=admin
|
||||
- --password=admin
|
||||
ports:
|
||||
- 3000:3000
|
||||
networks:
|
||||
|
||||
23
main.go
23
main.go
@@ -40,6 +40,21 @@ func init() {
|
||||
func main() {
|
||||
version := flag.Bool("version", false, "Print version and exit")
|
||||
port := flag.Int("port", 3000, "Port to listen on")
|
||||
url := flag.String(
|
||||
"url",
|
||||
"",
|
||||
"Specify the URL of the Traefik instance (e.g. http://localhost:8080)",
|
||||
)
|
||||
username := flag.String(
|
||||
"username",
|
||||
"",
|
||||
"Specify the username for the Traefik instance",
|
||||
)
|
||||
password := flag.String(
|
||||
"password",
|
||||
"",
|
||||
"Specify the password for the Traefik instance",
|
||||
)
|
||||
flag.Parse()
|
||||
|
||||
if *version {
|
||||
@@ -47,6 +62,14 @@ func main() {
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
if *url != "" {
|
||||
var profiles traefik.Profiles
|
||||
if err := profiles.SetDefaultProfile(*url, *username, *password); err != nil {
|
||||
slog.Error("Failed to add default profile", "error", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
mux := api.Routes()
|
||||
middle := api.Chain(api.Log, api.Cors)
|
||||
|
||||
|
||||
@@ -78,6 +78,24 @@ func (p *Profiles) Save() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Profiles) SetDefaultProfile(url, username, password string) error {
|
||||
if err := p.Load(); err != nil {
|
||||
return fmt.Errorf("failed to load profiles: %w", err)
|
||||
}
|
||||
if len(p.Profiles) == 0 {
|
||||
p.Profiles = make(map[string]Profile)
|
||||
}
|
||||
|
||||
p.Profiles["default"] = Profile{
|
||||
Name: "default",
|
||||
URL: url,
|
||||
Username: username,
|
||||
Password: password,
|
||||
}
|
||||
|
||||
return p.Save()
|
||||
}
|
||||
|
||||
func Move(source, destination string) error {
|
||||
err := os.Rename(source, destination)
|
||||
if err != nil && strings.Contains(err.Error(), "invalid cross-device link") {
|
||||
|
||||
@@ -5,6 +5,8 @@ import (
|
||||
"net"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func (p *Profile) Verify() error {
|
||||
@@ -49,6 +51,11 @@ func (s *Service) Verify() error {
|
||||
}
|
||||
|
||||
func isValidURL(u string) bool {
|
||||
// If no scheme is provided, prepend "http://"
|
||||
if !strings.Contains(u, "://") {
|
||||
u = "http://" + u
|
||||
}
|
||||
|
||||
parsedURL, err := url.Parse(u)
|
||||
if err != nil || (parsedURL.Scheme != "http" && parsedURL.Scheme != "https") {
|
||||
return false
|
||||
@@ -62,18 +69,23 @@ func isValidURL(u string) bool {
|
||||
}
|
||||
}
|
||||
|
||||
// Check if it's an IP address (including loopback)
|
||||
ip := net.ParseIP(host)
|
||||
if ip != nil {
|
||||
return true
|
||||
}
|
||||
|
||||
if host != "localhost" {
|
||||
domainRegex := `^([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}$`
|
||||
matched, err := regexp.MatchString(domainRegex, host)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return matched
|
||||
// Check if it's localhost
|
||||
if !strings.Contains(host, ".") {
|
||||
_, err = strconv.Atoi(host)
|
||||
return err != nil // Valid if it's not just a number
|
||||
}
|
||||
return true
|
||||
|
||||
// Check if it's a valid domain name
|
||||
domainRegex := `^([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.[a-zA-Z]{2,}$`
|
||||
matched, err := regexp.MatchString(domainRegex, host)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return matched
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user