Skip to content

Commit 7a55554

Browse files
ryanroldsnfuden
andauthored
Collect Gloo metrics and some snapshots on test failure (#10400)
Co-authored-by: changelog-bot <changelog-bot> Co-authored-by: Nathan Fudenberg <[email protected]>
1 parent 5716048 commit 7a55554

File tree

10 files changed

+330
-158
lines changed

10 files changed

+330
-158
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
changelog:
2+
- type: NON_USER_FACING
3+
description: >-
4+
Gloo Gateway controller metrics and xds/krt snaphots are now collected and included
5+
the test failure artifacts.
6+
After encountering some test failures that proved difficult to debug without knowing more
7+
about the state of the cluster, we have added additional artifacts to be collected when
8+
a test fails.
9+
This will help us to more easily diagnose the cause of test failures.
10+
- type: NON_USER_FACING
11+
description: >-
12+
Unified the kube2e and kubernetes/e2e test failure artifact collection.
13+
Previously, the test failure artifacts for kube2e and kubernetes/e2e tests were different
14+
and produced by their own logic.

pkg/utils/glooadminutils/admincli/client.go

+12
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ import (
1414

1515
const (
1616
InputSnapshotPath = "/snapshots/input"
17+
xdsSnapshotPath = "/snapshots/xds"
18+
krtSnapshotPath = "/snapshots/krt"
1719
)
1820

1921
// Client is a utility for executing requests against the Gloo Admin API
@@ -84,6 +86,16 @@ func (c *Client) InputSnapshotCmd(ctx context.Context) cmdutils.Cmd {
8486
return c.Command(ctx, curl.WithPath(InputSnapshotPath))
8587
}
8688

89+
// XdsSnapshotCmd returns the cmdutils.Cmd that can be run, and will execute a request against the XDS Snapshot path
90+
func (c *Client) XdsSnapshotCmd(ctx context.Context) cmdutils.Cmd {
91+
return c.Command(ctx, curl.WithPath(xdsSnapshotPath))
92+
}
93+
94+
// KrtSnapshotCmd returns the cmdutils.Cmd that can be run, and will execute a request against the KRT Snapshot path
95+
func (c *Client) KrtSnapshotCmd(ctx context.Context) cmdutils.Cmd {
96+
return c.Command(ctx, curl.WithPath(krtSnapshotPath))
97+
}
98+
8799
// GetInputSnapshot returns the data that is available at the input snapshot endpoint
88100
func (c *Client) GetInputSnapshot(ctx context.Context) ([]interface{}, error) {
89101
var outLocation threadsafe.Buffer

pkg/utils/kubeutils/kubectl/cli.go

+25
Original file line numberDiff line numberDiff line change
@@ -342,3 +342,28 @@ func (c *Cli) GetContainerLogs(ctx context.Context, namespace string, name strin
342342
stdout, stderr, err := c.Execute(ctx, "-n", namespace, "logs", name)
343343
return stdout + stderr, err
344344
}
345+
346+
// GetPodsInNsWithLabel returns the pods in the specified namespace with the specified label
347+
func (c *Cli) GetPodsInNsWithLabel(ctx context.Context, namespace string, label string) ([]string, error) {
348+
podStdOut := bytes.NewBuffer(nil)
349+
podStdErr := bytes.NewBuffer(nil)
350+
351+
// Fetch the name of the Gloo Gateway controller pod
352+
getGlooPodNamesCmd := c.Command(ctx, "get", "pod", "-n", namespace,
353+
"--selector", label, "--output", "jsonpath='{.items[*].metadata.name}'")
354+
err := getGlooPodNamesCmd.WithStdout(podStdOut).WithStderr(podStdErr).Run().Cause()
355+
if err != nil {
356+
fmt.Printf("error running get gloo pod name command: %v\n", err)
357+
}
358+
359+
// Clean up and check the output
360+
glooPodNamesString := strings.Trim(podStdOut.String(), "'")
361+
if glooPodNamesString == "" {
362+
fmt.Printf("no %s pods found in namespace %s\n", label, namespace)
363+
return []string{}, nil
364+
}
365+
366+
// Split the string on whitespace to get the pod names
367+
glooPodNames := strings.Fields(glooPodNamesString)
368+
return glooPodNames, nil
369+
}

projects/gloo/pkg/servers/iosnapshot/history_test.go

+19-18
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package iosnapshot
1+
package iosnapshot_test
22

33
import (
44
"context"
@@ -8,6 +8,7 @@ import (
88
gomegatypes "github.com/onsi/gomega/types"
99
"github.com/solo-io/gloo/pkg/schemes"
1010
gloov1 "github.com/solo-io/gloo/projects/gloo/pkg/api/v1/kube/apis/gloo.solo.io/v1"
11+
"github.com/solo-io/gloo/projects/gloo/pkg/servers/iosnapshot"
1112
apiv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1"
1213

1314
wellknownkube "github.com/solo-io/gloo/projects/gloo/pkg/api/v1/kube/wellknown"
@@ -52,16 +53,16 @@ var _ = Describe("History", func() {
5253
ctx context.Context
5354

5455
clientBuilder *fake.ClientBuilder
55-
history History
56+
history iosnapshot.History
5657

57-
historyFactorParams HistoryFactoryParameters
58+
historyFactorParams iosnapshot.HistoryFactoryParameters
5859
)
5960

6061
BeforeEach(func() {
6162
ctx = context.Background()
6263
clientBuilder = fake.NewClientBuilder().WithScheme(schemes.DefaultScheme())
6364

64-
historyFactorParams = HistoryFactoryParameters{
65+
historyFactorParams = iosnapshot.HistoryFactoryParameters{
6566
Settings: &v1.Settings{
6667
Metadata: &core.Metadata{
6768
Name: "my-settings",
@@ -98,11 +99,11 @@ var _ = Describe("History", func() {
9899
},
99100
}
100101

101-
history = NewHistory(
102+
history = iosnapshot.NewHistory(
102103
historyFactorParams.Cache,
103104
historyFactorParams.Settings,
104105
clientBuilder.WithObjects(clientObjects...).Build(),
105-
append(CompleteInputSnapshotGVKs, deploymentGvk), // include the Deployment GVK
106+
append(iosnapshot.CompleteInputSnapshotGVKs, deploymentGvk), // include the Deployment GVK
106107
)
107108
})
108109

@@ -136,15 +137,15 @@ var _ = Describe("History", func() {
136137
},
137138
}
138139

139-
history = NewHistory(&xds.MockXdsCache{},
140+
history = iosnapshot.NewHistory(&xds.MockXdsCache{},
140141
&v1.Settings{
141142
Metadata: &core.Metadata{
142143
Name: "my-settings",
143144
Namespace: defaults.GlooSystem,
144145
},
145146
},
146147
clientBuilder.WithObjects(clientObjects...).Build(),
147-
CompleteInputSnapshotGVKs, // do not include the Deployment GVK
148+
iosnapshot.CompleteInputSnapshotGVKs, // do not include the Deployment GVK
148149
)
149150
})
150151

@@ -377,11 +378,11 @@ var _ = Describe("History", func() {
377378
},
378379
}
379380

380-
history = NewHistory(
381+
history = iosnapshot.NewHistory(
381382
historyFactorParams.Cache,
382383
historyFactorParams.Settings,
383384
clientBuilder.WithObjects(clientObjects...).Build(),
384-
CompleteInputSnapshotGVKs)
385+
iosnapshot.CompleteInputSnapshotGVKs)
385386
})
386387

387388
Context("Kubernetes Core Resources", func() {
@@ -663,11 +664,11 @@ var _ = Describe("History", func() {
663664
Context("GetEdgeApiSnapshot", func() {
664665

665666
BeforeEach(func() {
666-
history = NewHistory(
667+
history = iosnapshot.NewHistory(
667668
historyFactorParams.Cache,
668669
historyFactorParams.Settings,
669670
clientBuilder.Build(), // no objects, because this API doesn't rely on the kube client
670-
CompleteInputSnapshotGVKs,
671+
iosnapshot.CompleteInputSnapshotGVKs,
671672
)
672673
})
673674

@@ -758,11 +759,11 @@ var _ = Describe("History", func() {
758759
Context("GetProxySnapshot", func() {
759760

760761
BeforeEach(func() {
761-
history = NewHistory(
762+
history = iosnapshot.NewHistory(
762763
historyFactorParams.Cache,
763764
historyFactorParams.Settings,
764765
clientBuilder.Build(), // no objects, because this API doesn't rely on the kube client
765-
CompleteInputSnapshotGVKs,
766+
iosnapshot.CompleteInputSnapshotGVKs,
766767
)
767768
})
768769

@@ -794,7 +795,7 @@ var _ = Describe("History", func() {
794795

795796
})
796797

797-
func getInputSnapshotObjects(ctx context.Context, history History) []client.Object {
798+
func getInputSnapshotObjects(ctx context.Context, history iosnapshot.History) []client.Object {
798799
snapshotResponse := history.GetInputSnapshot(ctx)
799800
Expect(snapshotResponse.Error).NotTo(HaveOccurred())
800801

@@ -804,7 +805,7 @@ func getInputSnapshotObjects(ctx context.Context, history History) []client.Obje
804805
return responseObjects
805806
}
806807

807-
func getProxySnapshotResources(ctx context.Context, history History) []crdv1.Resource {
808+
func getProxySnapshotResources(ctx context.Context, history iosnapshot.History) []crdv1.Resource {
808809
snapshotResponse := history.GetProxySnapshot(ctx)
809810
Expect(snapshotResponse.Error).NotTo(HaveOccurred())
810811

@@ -814,7 +815,7 @@ func getProxySnapshotResources(ctx context.Context, history History) []crdv1.Res
814815
return responseObjects
815816
}
816817

817-
func getEdgeApiSnapshot(ctx context.Context, history History) *v1snap.ApiSnapshot {
818+
func getEdgeApiSnapshot(ctx context.Context, history iosnapshot.History) *v1snap.ApiSnapshot {
818819
snapshotResponse := history.GetEdgeApiSnapshot(ctx)
819820
Expect(snapshotResponse.Error).NotTo(HaveOccurred())
820821

@@ -827,7 +828,7 @@ func getEdgeApiSnapshot(ctx context.Context, history History) *v1snap.ApiSnapsho
827828
// setSnapshotOnHistory sets the ApiSnapshot on the history, and blocks until it has been processed
828829
// This is a utility method to help developers write tests, without having to worry about the asynchronous
829830
// nature of the `Set` API on the History
830-
func setSnapshotOnHistory(ctx context.Context, history History, snap *v1snap.ApiSnapshot) {
831+
func setSnapshotOnHistory(ctx context.Context, history iosnapshot.History, snap *v1snap.ApiSnapshot) {
831832
gwSignal := &gatewayv1.Gateway{
832833
// We append a custom Gateway to the Snapshot, and then use that object
833834
// to verify the Snapshot has been processed

0 commit comments

Comments
 (0)