package suites import ( "fmt" "os/exec" "strings" "time" "github.com/authelia/authelia/internal/utils" ) var kindImageName = "authelia-kind-proxy" var dockerCmdLine = fmt.Sprintf("docker-compose -f docker-compose.yml -f example/compose/kind/docker-compose.yml run --rm %s", kindImageName) // Kind used for running kind commands type Kind struct{} func kindCommand(cmdline string) *exec.Cmd { cmd := fmt.Sprintf("%s %s", dockerCmdLine, cmdline) return utils.Shell(cmd) } // CreateCluster create a new Kubernetes cluster func (k Kind) CreateCluster() error { cmd := kindCommand("kind create cluster --config /etc/kind/config.yml") if err := cmd.Run(); err != nil { return err } cmd = kindCommand("patch-kubeconfig.sh") if err := cmd.Run(); err != nil { return err } // This command is necessary to fix the coredns loop detected when using user-defined docker network // In that case /etc/resolv.conf use 127.0.0.11 as DNS and CoreDNS thinks it is talking to itself which is wrong. // This IP is the docker internal DNS so it is safe to disable the loop check. cmd = kindCommand("sh -c 'kubectl -n kube-system get configmap/coredns -o yaml | grep -v loop | kubectl replace -f -'") if err := cmd.Run(); err != nil { return err } return nil } // DeleteCluster delete a Kubernetes cluster func (k Kind) DeleteCluster() error { cmd := kindCommand("kind delete cluster") return cmd.Run() } // ClusterExists check whether a cluster exists func (k Kind) ClusterExists() (bool, error) { cmd := kindCommand("kind get clusters") cmd.Stdout = nil cmd.Stderr = nil output, err := cmd.Output() if err != nil { return false, err } return strings.Contains(string(output), "kind"), nil } // LoadImage load an image in the Kubernetes container func (k Kind) LoadImage(imageName string) error { cmd := kindCommand(fmt.Sprintf("kind load docker-image %s", imageName)) return cmd.Run() } // Kubectl used for running kubectl commands type Kubectl struct{} // StartProxy start a proxy func (k Kubectl) StartProxy() error { cmd := utils.Shell("docker-compose -f docker-compose.yml -f example/compose/kind/docker-compose.yml up -d authelia-kind-proxy") return cmd.Run() } // StopProxy stop a proxy func (k Kubectl) StopProxy() error { cmd := utils.Shell("docker-compose -f docker-compose.yml -f example/compose/kind/docker-compose.yml rm -s -f authelia-kind-proxy") return cmd.Run() } // StartDashboard start Kube dashboard func (k Kubectl) StartDashboard() error { if err := kindCommand("sh -c 'cd /authelia && ./bootstrap-dashboard.sh'").Run(); err != nil { return err } if err := utils.Shell("docker-compose -f docker-compose.yml -f example/compose/kind/docker-compose.yml up -d kube-dashboard").Run(); err != nil { return err } return nil } // StopDashboard stop kube dashboard func (k Kubectl) StopDashboard() error { cmd := utils.Shell("docker-compose -f docker-compose.yml -f example/compose/kind/docker-compose.yml rm -s -f kube-dashboard") return cmd.Run() } // DeployThirdparties deploy thirdparty services (ldap, db, ingress controllers, etc...) func (k Kubectl) DeployThirdparties() error { cmd := kindCommand("sh -c 'cd /authelia && ./bootstrap.sh'") return cmd.Run() } // DeployAuthelia deploy Authelia application func (k Kubectl) DeployAuthelia() error { cmd := kindCommand("sh -c 'cd /authelia && ./bootstrap-authelia.sh'") return cmd.Run() } // WaitPodsReady wait for all pods to be ready func (k Kubectl) WaitPodsReady(timeout time.Duration) error { return utils.CheckUntil(5*time.Second, timeout, func() (bool, error) { cmd := kindCommand("kubectl get -n authelia pods --no-headers") cmd.Stdout = nil cmd.Stderr = nil output, _ := cmd.Output() lines := strings.Split(string(output), "\n") nonEmptyLines := make([]string, 0) for _, line := range lines { if line != "" { nonEmptyLines = append(nonEmptyLines, line) } } for _, line := range nonEmptyLines { if !strings.Contains(line, "1/1") { return false, nil } } return true, nil }) }