mirror of
https://github.com/0rangebananaspy/authelia.git
synced 2024-09-14 22:47:21 +07:00
a991379a74
Some tests are not fully rewritten in Go, a typescript wrapper is called instead until we remove the remaining TS tests and dependencies. Also, dockerize every components (mainly Authelia backend, frontend and kind) so that the project does not interfere with user host anymore (open ports for instance). The only remaining intrusive change is the one done during bootstrap to add entries in /etc/hosts. It will soon be avoided using authelia.com domain that I own.
225 lines
5.5 KiB
Go
225 lines
5.5 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"io/ioutil"
|
|
"log"
|
|
"os"
|
|
"os/exec"
|
|
"strings"
|
|
|
|
"github.com/clems4ever/authelia/utils"
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
// HostEntry represents an entry in /etc/hosts
|
|
type HostEntry struct {
|
|
Domain string
|
|
IP string
|
|
}
|
|
|
|
var hostEntries = []HostEntry{
|
|
// For common tests
|
|
HostEntry{Domain: "login.example.com", IP: "192.168.240.100"},
|
|
HostEntry{Domain: "admin.example.com", IP: "192.168.240.100"},
|
|
HostEntry{Domain: "singlefactor.example.com", IP: "192.168.240.100"},
|
|
HostEntry{Domain: "dev.example.com", IP: "192.168.240.100"},
|
|
HostEntry{Domain: "home.example.com", IP: "192.168.240.100"},
|
|
HostEntry{Domain: "mx1.mail.example.com", IP: "192.168.240.100"},
|
|
HostEntry{Domain: "mx2.mail.example.com", IP: "192.168.240.100"},
|
|
HostEntry{Domain: "public.example.com", IP: "192.168.240.100"},
|
|
HostEntry{Domain: "secure.example.com", IP: "192.168.240.100"},
|
|
HostEntry{Domain: "mail.example.com", IP: "192.168.240.100"},
|
|
HostEntry{Domain: "duo.example.com", IP: "192.168.240.100"},
|
|
|
|
// For Traefik suite
|
|
HostEntry{Domain: "traefik.example.com", IP: "192.168.240.100"},
|
|
|
|
// For testing network ACLs
|
|
HostEntry{Domain: "proxy-client1.example.com", IP: "192.168.240.201"},
|
|
HostEntry{Domain: "proxy-client2.example.com", IP: "192.168.240.202"},
|
|
HostEntry{Domain: "proxy-client3.example.com", IP: "192.168.240.203"},
|
|
}
|
|
|
|
func runCommand(cmd string, args ...string) {
|
|
command := utils.CommandWithStdout(cmd, args...)
|
|
err := command.Run()
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
func installNpmPackages() {
|
|
runCommand("npm", "ci")
|
|
}
|
|
|
|
func checkCommandExist(cmd string) {
|
|
fmt.Print("Checking if '" + cmd + "' command is installed...")
|
|
command := exec.Command("bash", "-c", "command -v "+cmd)
|
|
err := command.Run()
|
|
|
|
if err != nil {
|
|
log.Fatal("[ERROR] You must install " + cmd + " on your machine.")
|
|
}
|
|
|
|
fmt.Println(" OK")
|
|
}
|
|
|
|
func installClientNpmPackages() {
|
|
command := utils.CommandWithStdout("npm", "ci")
|
|
command.Dir = "client"
|
|
err := command.Run()
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
func createTemporaryDirectory() {
|
|
err := os.MkdirAll("/tmp/authelia", 0755)
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
func bootstrapPrintln(args ...interface{}) {
|
|
a := make([]interface{}, 0)
|
|
a = append(a, "[BOOTSTRAP]")
|
|
a = append(a, args...)
|
|
fmt.Println(a...)
|
|
}
|
|
|
|
func shell(cmd string) {
|
|
runCommand("bash", "-c", cmd)
|
|
}
|
|
|
|
func buildHelperDockerImages() {
|
|
shell("docker build -t authelia-example-backend example/compose/nginx/backend")
|
|
shell("docker build -t authelia-duo-api example/compose/duo-api")
|
|
|
|
shell("docker-compose -f docker-compose.yml -f example/compose/kind/docker-compose.yml build")
|
|
shell("docker-compose -f docker-compose.yml -f example/compose/authelia/docker-compose.backend.yml build --build-arg USER_ID=$(id -u) --build-arg GROUP_ID=$(id -g)")
|
|
shell("docker-compose -f docker-compose.yml -f example/compose/authelia/docker-compose.frontend.yml build --build-arg USER_ID=$(id -u) --build-arg GROUP_ID=$(id -g)")
|
|
}
|
|
|
|
func prepareHostsFile() {
|
|
contentBytes, err := readHostsFile()
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
lines := strings.Split(string(contentBytes), "\n")
|
|
toBeAddedLine := make([]string, 0)
|
|
modified := false
|
|
|
|
for _, entry := range hostEntries {
|
|
domainInHostFile := false
|
|
for i, line := range lines {
|
|
domainFound := strings.Contains(line, entry.Domain)
|
|
ipFound := strings.Contains(line, entry.IP)
|
|
|
|
if domainFound {
|
|
domainInHostFile = true
|
|
|
|
// The IP is not up to date.
|
|
if ipFound {
|
|
break
|
|
} else {
|
|
lines[i] = entry.IP + " " + entry.Domain
|
|
modified = true
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
if !domainInHostFile {
|
|
toBeAddedLine = append(toBeAddedLine, entry.IP+" "+entry.Domain)
|
|
}
|
|
}
|
|
|
|
if len(toBeAddedLine) > 0 {
|
|
lines = append(lines, toBeAddedLine...)
|
|
modified = true
|
|
}
|
|
|
|
err = ioutil.WriteFile("/tmp/authelia/hosts", []byte(strings.Join(lines, "\n")), 0644)
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
if modified {
|
|
bootstrapPrintln("/etc/hosts needs to be updated")
|
|
shell("/usr/bin/sudo mv /tmp/authelia/hosts /etc/hosts")
|
|
}
|
|
}
|
|
|
|
// ReadHostsFile reads the hosts file.
|
|
func readHostsFile() ([]byte, error) {
|
|
bs, err := ioutil.ReadFile("/etc/hosts")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return bs, nil
|
|
}
|
|
|
|
func readVersion(cmd string, args ...string) {
|
|
command := exec.Command(cmd, args...)
|
|
b, err := command.Output()
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
fmt.Print(cmd + " => " + string(b))
|
|
}
|
|
|
|
func readVersions() {
|
|
readVersion("go", "version")
|
|
readVersion("node", "--version")
|
|
readVersion("docker", "--version")
|
|
readVersion("docker-compose", "--version")
|
|
}
|
|
|
|
// Bootstrap bootstrap authelia dev environment
|
|
func Bootstrap(cobraCmd *cobra.Command, args []string) {
|
|
bootstrapPrintln("Checking command installation...")
|
|
checkCommandExist("node")
|
|
checkCommandExist("docker")
|
|
checkCommandExist("docker-compose")
|
|
|
|
bootstrapPrintln("Getting versions of tools")
|
|
readVersions()
|
|
|
|
bootstrapPrintln("Checking if GOPATH is set")
|
|
|
|
goPathFound := false
|
|
for _, v := range os.Environ() {
|
|
if strings.HasPrefix(v, "GOPATH=") {
|
|
goPathFound = true
|
|
break
|
|
}
|
|
}
|
|
|
|
if !goPathFound {
|
|
log.Fatal("GOPATH is not set")
|
|
}
|
|
|
|
bootstrapPrintln("Installing NPM packages for development...")
|
|
installNpmPackages()
|
|
|
|
bootstrapPrintln("Building development Docker images...")
|
|
buildHelperDockerImages()
|
|
|
|
createTemporaryDirectory()
|
|
|
|
bootstrapPrintln("Preparing /etc/hosts to serve subdomains of example.com...")
|
|
prepareHostsFile()
|
|
|
|
bootstrapPrintln("Run 'authelia-scripts suites setup Standalone' to start Authelia and visit https://home.example.com:8080.")
|
|
bootstrapPrintln("More details at https://github.com/clems4ever/authelia/blob/master/docs/getting-started.md")
|
|
}
|