-
Notifications
You must be signed in to change notification settings - Fork 121
/
setup.go
132 lines (105 loc) · 2.74 KB
/
setup.go
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// Copyright 2021-2023 Zenauth Ltd.
// SPDX-License-Identifier: Apache-2.0
//go:build e2e
package e2e
import (
"crypto/tls"
"fmt"
"net/http"
"time"
"github.com/go-cmd/cmd"
)
func Setup(ctx Ctx) error {
ctx.Logf("Setup for context %q (%+v)", ctx.ContextID, ctx.Config)
// `helmfile apply` requires `helm diff`. `helmfile init` checks for required plugins
if err := Cmd(ctx, "helmfile", "apply"); err != nil {
ctx.Logf("Deployment failed: %v", err)
return err
}
ctx.Logf("Deployment succeeded")
if !ctx.NoCleanup {
ctx.Cleanup(func() { _ = Teardown(ctx) })
}
return Retry(checkCerbosIsUp(ctx), 1*time.Minute, 1*time.Second)
}
func Teardown(ctx Ctx) error {
return Cmd(ctx, "helmfile", "destroy")
}
func Cmd(ctx Ctx, name string, args ...string) error {
return execCmd(ctx, false, name, args...)
}
func CmdWithOutput(ctx Ctx, name string, args ...string) error {
return execCmd(ctx, true, name, args...)
}
func execCmd(ctx Ctx, showOutput bool, name string, args ...string) error {
c := cmd.NewCmd(name, args...)
c.Env = ctx.Environ()
timeout, cancelFn := ctx.CommandTimeoutCtx()
defer cancelFn()
status := c.Start()
select {
case done := <-status:
if done.Complete && done.Error == nil && done.Exit == 0 {
if showOutput {
dumpOutput(ctx, done)
}
return nil
}
dumpOutput(ctx, done)
return fmt.Errorf("failed to run %q: exit=%d err=%v", done.Cmd, done.Exit, done.Error)
case <-timeout.Done():
_ = c.Stop()
return timeout.Err()
}
}
func dumpOutput(ctx Ctx, s cmd.Status) {
ctx.Logf("Command=[%s] Code=%d Error=%v", s.Cmd, s.Exit, s.Error)
ctx.Logf("-----Stdout-----")
for _, l := range s.Stdout {
ctx.Logf(l)
}
ctx.Logf("-----Stderr-----")
for _, l := range s.Stderr {
ctx.Logf(l)
}
}
func checkCerbosIsUp(ctx Ctx) func() error {
customTransport := http.DefaultTransport.(*http.Transport).Clone()
customTransport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} //nolint:gosec
client := &http.Client{Transport: customTransport}
healthURL := ctx.HealthURL()
return func() error {
ctx.Logf("Checking whether Cerbos is up")
resp, err := client.Get(healthURL)
if err != nil {
ctx.Logf("Error during healthcheck: %v", err)
return err
}
if resp.StatusCode != http.StatusOK {
ctx.Logf("Received health status: %q", resp.Status)
return fmt.Errorf("received status %q", resp.Status)
}
return nil
}
}
func Retry(op func() error, timeout time.Duration, interval time.Duration) error {
lastErr := op()
if lastErr == nil {
return nil
}
timer := time.NewTimer(timeout)
defer timer.Stop()
ticker := time.NewTicker(interval)
defer ticker.Stop()
for {
select {
case <-timer.C:
return lastErr
case <-ticker.C:
lastErr = op()
if lastErr == nil {
return nil
}
}
}
}