domain.go

94 lines
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
//go:build cgo

package commands

import (
	"encoding/json"
	"fmt"
	"net"
	"os"
	"strconv"
	"strings"

	"congo.gg/dev/models"
)

const domainUsage = `Manage domains in Congo Dev

Usage:
  congo domain <subcommand>

Subcommands:
  list                          List domains (JSON)
  add <host> <container> [port] Add a domain route (validates DNS)
  remove <host>                 Remove a domain route
`

func Domain() {
	if len(os.Args) < 3 {
		fmt.Print(domainUsage)
		os.Exit(1)
	}

	switch os.Args[2] {
	case "list":
		domains, _ := models.Domains.Search("WHERE Active = 1 ORDER BY Host")
		json.NewEncoder(os.Stdout).Encode(domains)
	case "add":
		domainAdd()
	case "remove":
		domainRemove()
	default:
		fmt.Fprintf(os.Stderr, "unknown domain subcommand %q\n", os.Args[2])
		os.Exit(1)
	}
}

func domainAdd() {
	if len(os.Args) < 5 {
		fmt.Fprintln(os.Stderr, "usage: congo domain add <host> <container> [port]")
		os.Exit(1)
	}
	host := os.Args[3]
	target := os.Args[4]
	port := 5000
	if len(os.Args) > 5 {
		if p, err := strconv.Atoi(os.Args[5]); err == nil {
			port = p
		}
	}

	// Validate DNS resolves
	ips, err := net.LookupHost(host)
	if err != nil {
		fmt.Fprintf(os.Stderr, "%s: DNS not found\n", host)
		os.Exit(1)
	}
	fmt.Fprintf(os.Stderr, "%s resolves to %s\n", host, strings.Join(ips, ","))

	// Store in DB
	models.Domains.Insert(&models.Domain{
		Host:   host,
		Target: target,
		Port:   port,
		Active: true,
	})
	fmt.Printf("added %s -> %s:%d\n", host, target, port)
}

func domainRemove() {
	if len(os.Args) < 4 {
		fmt.Fprintln(os.Stderr, "usage: congo domain remove <host>")
		os.Exit(1)
	}
	host := os.Args[3]

	domain, _ := models.Domains.First("WHERE Host = ?", host)
	if domain == nil {
		fmt.Fprintln(os.Stderr, "domain not found")
		os.Exit(1)
	}

	models.Domains.Delete(domain)
	fmt.Printf("removed %s\n", host)
}