2019-11-02 21:32:58 +07:00
|
|
|
package suites
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"os/exec"
|
|
|
|
"strings"
|
|
|
|
"time"
|
|
|
|
|
2021-08-11 08:04:35 +07:00
|
|
|
"github.com/authelia/authelia/v4/internal/utils"
|
2019-11-02 21:32:58 +07:00
|
|
|
)
|
|
|
|
|
|
|
|
var kindImageName = "authelia-kind-proxy"
|
2020-02-10 00:04:28 +07:00
|
|
|
var dockerCmdLine = fmt.Sprintf("docker-compose -p authelia -f internal/suites/docker-compose.yml -f internal/suites/example/compose/kind/docker-compose.yml run --rm %s", kindImageName)
|
2019-11-02 21:32:58 +07:00
|
|
|
|
2020-05-02 12:06:39 +07:00
|
|
|
// Kind used for running kind commands.
|
2019-11-02 21:32:58 +07:00
|
|
|
type Kind struct{}
|
|
|
|
|
|
|
|
func kindCommand(cmdline string) *exec.Cmd {
|
|
|
|
cmd := fmt.Sprintf("%s %s", dockerCmdLine, cmdline)
|
|
|
|
return utils.Shell(cmd)
|
|
|
|
}
|
|
|
|
|
2020-05-02 12:06:39 +07:00
|
|
|
// CreateCluster create a new Kubernetes cluster.
|
2019-11-02 21:32:58 +07:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2020-05-02 12:06:39 +07:00
|
|
|
// This command is necessary to fix the coredns loop detected when using user-defined docker network.
|
2019-11-02 21:32:58 +07:00
|
|
|
// 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 -'")
|
2021-06-11 07:30:53 +07:00
|
|
|
err := cmd.Run()
|
2020-05-06 02:35:32 +07:00
|
|
|
|
2021-06-11 07:30:53 +07:00
|
|
|
return err
|
2019-11-02 21:32:58 +07:00
|
|
|
}
|
|
|
|
|
2020-05-02 12:06:39 +07:00
|
|
|
// DeleteCluster delete a Kubernetes cluster.
|
2019-11-02 21:32:58 +07:00
|
|
|
func (k Kind) DeleteCluster() error {
|
|
|
|
cmd := kindCommand("kind delete cluster")
|
|
|
|
return cmd.Run()
|
|
|
|
}
|
|
|
|
|
2020-05-02 12:06:39 +07:00
|
|
|
// ClusterExists check whether a cluster exists.
|
2019-11-02 21:32:58 +07:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2020-05-02 12:06:39 +07:00
|
|
|
// LoadImage load an image in the Kubernetes container.
|
2019-11-02 21:32:58 +07:00
|
|
|
func (k Kind) LoadImage(imageName string) error {
|
|
|
|
cmd := kindCommand(fmt.Sprintf("kind load docker-image %s", imageName))
|
|
|
|
return cmd.Run()
|
|
|
|
}
|
|
|
|
|
2020-05-02 12:06:39 +07:00
|
|
|
// Kubectl used for running kubectl commands.
|
2019-11-02 21:32:58 +07:00
|
|
|
type Kubectl struct{}
|
|
|
|
|
2020-05-02 12:06:39 +07:00
|
|
|
// StartProxy start a proxy.
|
2019-11-02 21:32:58 +07:00
|
|
|
func (k Kubectl) StartProxy() error {
|
2020-02-10 00:04:28 +07:00
|
|
|
cmd := utils.Shell("docker-compose -p authelia -f internal/suites/docker-compose.yml -f internal/suites/example/compose/kind/docker-compose.yml up -d authelia-kind-proxy")
|
2019-11-02 21:32:58 +07:00
|
|
|
return cmd.Run()
|
|
|
|
}
|
|
|
|
|
2020-05-02 12:06:39 +07:00
|
|
|
// StopProxy stop a proxy.
|
2019-11-02 21:32:58 +07:00
|
|
|
func (k Kubectl) StopProxy() error {
|
2020-02-10 00:04:28 +07:00
|
|
|
cmd := utils.Shell("docker-compose -p authelia -f internal/suites/docker-compose.yml -f internal/suites/example/compose/kind/docker-compose.yml rm -s -f authelia-kind-proxy")
|
2019-11-02 21:32:58 +07:00
|
|
|
return cmd.Run()
|
|
|
|
}
|
|
|
|
|
2020-05-02 12:06:39 +07:00
|
|
|
// StartDashboard start Kube dashboard.
|
2019-11-16 22:22:10 +07:00
|
|
|
func (k Kubectl) StartDashboard() error {
|
|
|
|
if err := kindCommand("sh -c 'cd /authelia && ./bootstrap-dashboard.sh'").Run(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2021-06-11 07:30:53 +07:00
|
|
|
err := utils.Shell("docker-compose -p authelia -f internal/suites/docker-compose.yml -f internal/suites/example/compose/kind/docker-compose.yml up -d kube-dashboard").Run()
|
2020-05-06 02:35:32 +07:00
|
|
|
|
2021-06-11 07:30:53 +07:00
|
|
|
return err
|
2019-11-16 22:22:10 +07:00
|
|
|
}
|
|
|
|
|
2020-05-02 12:06:39 +07:00
|
|
|
// StopDashboard stop kube dashboard.
|
2019-11-16 22:22:10 +07:00
|
|
|
func (k Kubectl) StopDashboard() error {
|
2020-02-10 00:04:28 +07:00
|
|
|
cmd := utils.Shell("docker-compose -p authelia -f internal/suites/docker-compose.yml -f internal/suites/example/compose/kind/docker-compose.yml rm -s -f kube-dashboard")
|
2019-11-16 22:22:10 +07:00
|
|
|
return cmd.Run()
|
|
|
|
}
|
|
|
|
|
2020-05-02 12:06:39 +07:00
|
|
|
// DeployThirdparties deploy thirdparty services (ldap, db, ingress controllers, etc...).
|
2019-11-02 21:32:58 +07:00
|
|
|
func (k Kubectl) DeployThirdparties() error {
|
|
|
|
cmd := kindCommand("sh -c 'cd /authelia && ./bootstrap.sh'")
|
|
|
|
return cmd.Run()
|
|
|
|
}
|
|
|
|
|
2020-05-02 12:06:39 +07:00
|
|
|
// DeployAuthelia deploy Authelia application.
|
2019-11-02 21:32:58 +07:00
|
|
|
func (k Kubectl) DeployAuthelia() error {
|
|
|
|
cmd := kindCommand("sh -c 'cd /authelia && ./bootstrap-authelia.sh'")
|
|
|
|
return cmd.Run()
|
|
|
|
}
|
|
|
|
|
2020-05-02 12:06:39 +07:00
|
|
|
// WaitPodsReady wait for all pods to be ready.
|
2019-11-02 21:32:58 +07:00
|
|
|
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
|
|
|
|
})
|
|
|
|
}
|