Skip to content

Commit d2fb4f0

Browse files
authored
Merge pull request #602 from jetstack/VC-35738/feature
[VC-35738] Feature Branch
2 parents d375793 + 1690dd9 commit d2fb4f0

File tree

19 files changed

+955
-158
lines changed

19 files changed

+955
-158
lines changed

cmd/agent.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import (
77
"github.com/spf13/cobra"
88

99
"github.com/jetstack/preflight/pkg/agent"
10-
"github.com/jetstack/preflight/pkg/logs"
1110
"github.com/jetstack/preflight/pkg/permissions"
1211
)
1312

@@ -16,7 +15,7 @@ var agentCmd = &cobra.Command{
1615
Short: "start the preflight agent",
1716
Long: `The agent will periodically gather data for the configured data
1817
gatherers and send it to a remote backend for evaluation`,
19-
Run: agent.Run,
18+
RunE: agent.Run,
2019
}
2120

2221
var agentInfoCmd = &cobra.Command{
@@ -34,24 +33,25 @@ var agentRBACCmd = &cobra.Command{
3433
Use: "rbac",
3534
Short: "print the agent's minimal RBAC manifest",
3635
Long: `Print RBAC string by reading GVRs`,
37-
Run: func(cmd *cobra.Command, args []string) {
36+
RunE: func(cmd *cobra.Command, args []string) error {
3837

3938
b, err := os.ReadFile(agent.Flags.ConfigFilePath)
4039
if err != nil {
41-
logs.Log.Fatalf("Failed to read config file: %s", err)
40+
return fmt.Errorf("Failed to read config file: %s", err)
4241
}
4342
cfg, err := agent.ParseConfig(b)
4443
if err != nil {
45-
logs.Log.Fatalf("Failed to parse config file: %s", err)
44+
return fmt.Errorf("Failed to parse config file: %s", err)
4645
}
4746

4847
err = agent.ValidateDataGatherers(cfg.DataGatherers)
4948
if err != nil {
50-
logs.Log.Fatalf("Failed to validate data gatherers: %s", err)
49+
return fmt.Errorf("Failed to validate data gatherers: %s", err)
5150
}
5251

5352
out := permissions.GenerateFullManifest(cfg.DataGatherers)
5453
fmt.Print(out)
54+
return nil
5555
},
5656
}
5757

cmd/agent_test.go

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package cmd
2+
3+
import (
4+
"bytes"
5+
"context"
6+
"os"
7+
"os/exec"
8+
"testing"
9+
"time"
10+
11+
"github.com/stretchr/testify/require"
12+
)
13+
14+
// TestAgentRunOneShot runs the agent in `--one-shot` mode and verifies that it exits
15+
// after the first data gathering iteration.
16+
func TestAgentRunOneShot(t *testing.T) {
17+
if _, found := os.LookupEnv("GO_CHILD"); found {
18+
// Silence the warning about missing pod name for event generation
19+
// TODO(wallrj): This should not be required when an `--input-file` has been supplied.
20+
t.Setenv("POD_NAME", "venafi-kubernetes-e2e")
21+
// Silence the error about missing kubeconfig.
22+
// TODO(wallrj): This should not be required when an `--input-file` has been supplied.
23+
t.Setenv("KUBECONFIG", "testdata/agent/one-shot/success/kubeconfig.yaml")
24+
25+
os.Args = []string{
26+
"preflight",
27+
"agent",
28+
"--one-shot",
29+
// TODO(wallrj): This should not be required when an `--input-file` has been supplied.
30+
"--api-token=should-not-be-required",
31+
// TODO(wallrj): This should not be required when an `--input-file` has been supplied.
32+
"--install-namespace=default",
33+
"--agent-config-file=testdata/agent/one-shot/success/config.yaml",
34+
"--input-path=testdata/agent/one-shot/success/input.json",
35+
"--output-path=/dev/null",
36+
"-v=1",
37+
}
38+
Execute()
39+
return
40+
}
41+
t.Log("Running child process")
42+
ctx, cancel := context.WithTimeout(context.Background(), time.Second*3)
43+
defer cancel()
44+
cmd := exec.CommandContext(ctx, os.Args[0], "-test.run=^TestAgentRunOneShot$")
45+
var (
46+
stdout bytes.Buffer
47+
stderr bytes.Buffer
48+
)
49+
cmd.Stdout = &stdout
50+
cmd.Stderr = &stderr
51+
cmd.Env = append(
52+
os.Environ(),
53+
"GO_CHILD=true",
54+
)
55+
err := cmd.Run()
56+
57+
stdoutStr := stdout.String()
58+
stderrStr := stderr.String()
59+
t.Logf("STDOUT\n%s\n", stdoutStr)
60+
t.Logf("STDERR\n%s\n", stderrStr)
61+
require.NoError(t, err, context.Cause(ctx))
62+
}

cmd/echo.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ var echoCmd = &cobra.Command{
1111
Short: "starts an echo server to test the agent",
1212
Long: `The agent sends data to a server. This echo server
1313
can be used to act as the server part and echo the data received by the agent.`,
14-
Run: echo.Echo,
14+
RunE: echo.Echo,
1515
}
1616

1717
func init() {

cmd/root.go

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
package cmd
22

33
import (
4+
"context"
45
"fmt"
56
"os"
67
"strings"
78

89
"github.com/spf13/cobra"
910
"github.com/spf13/pflag"
11+
"k8s.io/klog/v2"
12+
13+
"github.com/jetstack/preflight/pkg/logs"
1014
)
1115

1216
// rootCmd represents the base command when called without any subcommands
@@ -17,6 +21,17 @@ var rootCmd = &cobra.Command{
1721
configuration checks using Open Policy Agent (OPA).
1822
1923
Preflight checks are bundled into Packages`,
24+
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
25+
return logs.Initialize()
26+
},
27+
// SilenceErrors and SilenceUsage prevents this command or any sub-command
28+
// from printing arbitrary text to stderr.
29+
// Why? To ensure that each line of output can be parsed as a single message
30+
// for consumption by logging agents such as fluentd.
31+
// Usage information is still available on stdout with the `-h` and `--help`
32+
// flags.
33+
SilenceErrors: true,
34+
SilenceUsage: true,
2035
}
2136

2237
func init() {
@@ -27,11 +42,17 @@ func init() {
2742

2843
// Execute adds all child commands to the root command and sets flags appropriately.
2944
// This is called by main.main(). It only needs to happen once to the rootCmd.
45+
// If the root command or sub-command returns an error, the error message will
46+
// will be logged and the process will exit with status 1.
3047
func Execute() {
31-
if err := rootCmd.Execute(); err != nil {
32-
fmt.Println(err)
33-
os.Exit(1)
48+
logs.AddFlags(rootCmd.PersistentFlags())
49+
ctx := klog.NewContext(context.Background(), klog.Background())
50+
var exitCode int
51+
if err := rootCmd.ExecuteContext(ctx); err != nil {
52+
exitCode = 1
53+
klog.ErrorS(err, "Exiting due to error", "exit-code", exitCode)
3454
}
55+
klog.FlushAndExit(klog.ExitFlushTimeout, exitCode)
3556
}
3657

3758
func setFlagsFromEnv(prefix string, fs *pflag.FlagSet) {
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Just enough venafi-kubernetes-agent config to allow it to run with an input
2+
# file in one-shot mode.
3+
cluster_id: "venafi-kubernetes-agent-e2e"
4+
organization_id: "venafi-kubernetes-agent-e2e"
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[]
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Just enough kubeconfig to satisfy client-go
2+
apiVersion: v1
3+
kind: Config
4+
current-context: cluster-1
5+
contexts:
6+
- name: cluster-1
7+
context:
8+
cluster: cluster-1
9+
user: user-1
10+
clusters:
11+
- name: cluster-1
12+
cluster:
13+
server: https://192.0.2.1:8443
14+
preferences: {}
15+
users: []

go.mod

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ module github.com/jetstack/preflight
33
go 1.22.0
44

55
require (
6+
github.com/Venafi/vcert/v5 v5.7.1
67
github.com/cenkalti/backoff v2.2.1+incompatible
78
github.com/d4l3k/messagediff v1.2.1
89
github.com/fatih/color v1.17.0
@@ -22,13 +23,13 @@ require (
2223
k8s.io/api v0.31.1
2324
k8s.io/apimachinery v0.31.1
2425
k8s.io/client-go v0.31.1
26+
k8s.io/component-base v0.31.0
2527
sigs.k8s.io/controller-runtime v0.19.0
2628
sigs.k8s.io/yaml v1.4.0
2729
)
2830

2931
require (
3032
github.com/Khan/genqlient v0.7.0 // indirect
31-
github.com/Venafi/vcert/v5 v5.7.1 // indirect
3233
github.com/antlr4-go/antlr/v4 v4.13.0 // indirect
3334
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
3435
github.com/aymerick/douceur v0.2.0 // indirect
@@ -37,6 +38,7 @@ require (
3738
github.com/fsnotify/fsnotify v1.7.0 // indirect
3839
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
3940
github.com/go-http-utils/headers v0.0.0-20181008091004-fed159eddc2a // indirect
41+
github.com/go-logr/zapr v1.3.0 // indirect
4042
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
4143
github.com/google/cel-go v0.20.1 // indirect
4244
github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 // indirect
@@ -62,7 +64,6 @@ require (
6264
gopkg.in/ini.v1 v1.67.0 // indirect
6365
k8s.io/apiextensions-apiserver v0.31.0 // indirect
6466
k8s.io/apiserver v0.31.0 // indirect
65-
k8s.io/component-base v0.31.0 // indirect
6667
)
6768

6869
require (
@@ -100,7 +101,7 @@ require (
100101
google.golang.org/protobuf v1.34.2 // indirect
101102
gopkg.in/inf.v0 v0.9.1 // indirect
102103
gopkg.in/yaml.v3 v3.0.1
103-
k8s.io/klog/v2 v2.130.1 // indirect
104+
k8s.io/klog/v2 v2.130.1
104105
k8s.io/kube-openapi v0.0.0-20240430033511-f0e62f92d13f // indirect
105106
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect
106107
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect

hack/e2e/test.sh

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -191,14 +191,11 @@ EOF
191191
envsubst <application-team-1.yaml | kubectl apply -f -
192192
kubectl -n team-1 wait certificate app-0 --for=condition=Ready
193193

194-
# Wait for log message indicating success.
195-
# Filter out distracting data gatherer errors and warnings.
196-
# Show other useful log messages on stderr.
194+
# Wait 60s for log message indicating success.
195+
# Parse logs as JSON using jq to ensure logs are all JSON formatted.
197196
# Disable pipefail to prevent SIGPIPE (141) errors from tee
198197
# See https://unix.stackexchange.com/questions/274120/pipe-fail-141-when-piping-output-into-tee-why
199-
set +o pipefail
200198
kubectl logs deployments/venafi-kubernetes-agent \
201-
--follow \
202-
--namespace venafi \
203-
| tee >(grep -v -e "reflector\.go" -e "datagatherer" -e "data gatherer" >/dev/stderr) \
204-
| grep -q "Data sent successfully"
199+
--follow \
200+
--namespace venafi \
201+
| timeout 60 jq 'if .msg | test("Data sent successfully") then . | halt_error(0) end'

hack/e2e/values.venafi-kubernetes-agent.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,6 @@ config:
66
authentication:
77
venafiConnection:
88
enabled: true
9+
10+
extraArgs:
11+
- --logging-format=json

0 commit comments

Comments
 (0)