-
Notifications
You must be signed in to change notification settings - Fork 6
/
k8s_collector.go
106 lines (96 loc) · 3.82 KB
/
k8s_collector.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
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0
package k8stest // import "github.com/open-telemetry/opentelemetry-collector-contrib/internal/k8stest"
import (
"bytes"
"context"
"os"
"path/filepath"
"testing"
"text/template"
"time"
"github.com/stretchr/testify/require"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
)
func CreateCollectorObjects(t *testing.T, client *K8sClient, testID string, manifestsDir string) []*unstructured.Unstructured {
if manifestsDir == "" {
manifestsDir = filepath.Join(".", "testdata", "e2e", "collector")
}
manifestFiles, err := os.ReadDir(manifestsDir)
require.NoErrorf(t, err, "failed to read collector manifests directory %s", manifestsDir)
host := HostEndpoint(t)
var podNamespace string
var podLabels map[string]any
createdObjs := make([]*unstructured.Unstructured, 0, len(manifestFiles))
for _, manifestFile := range manifestFiles {
tmpl := template.Must(template.New(manifestFile.Name()).ParseFiles(filepath.Join(manifestsDir, manifestFile.Name())))
manifest := &bytes.Buffer{}
require.NoError(t, tmpl.Execute(manifest, map[string]string{
"Name": "otelcol-" + testID,
"HostEndpoint": host,
"TestID": testID,
}))
obj, err := CreateObject(client, manifest.Bytes())
require.NoErrorf(t, err, "failed to create collector object from manifest %s", manifestFile.Name())
objKind := obj.GetKind()
if objKind == "Deployment" || objKind == "DaemonSet" {
podNamespace = obj.GetNamespace()
selector := obj.Object["spec"].(map[string]any)["selector"]
podLabels = selector.(map[string]any)["matchLabels"].(map[string]any)
}
createdObjs = append(createdObjs, obj)
}
WaitForCollectorToStart(t, client, podNamespace, podLabels)
return createdObjs
}
func WaitForCollectorToStart(t *testing.T, client *K8sClient, podNamespace string, podLabels map[string]any) {
podGVR := schema.GroupVersionResource{Version: "v1", Resource: "pods"}
listOptions := metav1.ListOptions{LabelSelector: SelectorFromMap(podLabels).String()}
podTimeoutMinutes := 3
t.Logf("waiting for collector pods to be ready")
require.Eventuallyf(t, func() bool {
list, err := client.DynamicClient.Resource(podGVR).Namespace(podNamespace).List(context.Background(), listOptions)
require.NoError(t, err, "failed to list collector pods")
podsNotReady := len(list.Items)
if podsNotReady == 0 {
t.Log("did not find collector pods")
return false
}
var pods v1.PodList
err = runtime.DefaultUnstructuredConverter.FromUnstructured(list.UnstructuredContent(), &pods)
require.NoError(t, err, "failed to convert unstructured to podList")
for _, pod := range pods.Items {
podReady := false
if pod.Status.Phase != v1.PodRunning {
t.Logf("pod %v is not running, current phase: %v", pod.Name, pod.Status.Phase)
continue
}
for _, cond := range pod.Status.Conditions {
if cond.Type == v1.PodReady && cond.Status == v1.ConditionTrue {
podsNotReady--
podReady = true
}
}
// Add some debug logs for crashing pods
if !podReady {
for _, cs := range pod.Status.ContainerStatuses {
restartCount := cs.RestartCount
if restartCount > 0 && cs.LastTerminationState.Terminated != nil {
t.Logf("restart count = %d for container %s in pod %s, last terminated reason: %s", restartCount, cs.Name, pod.Name, cs.LastTerminationState.Terminated.Reason)
t.Logf("termination message: %s", cs.LastTerminationState.Terminated.Message)
}
}
}
}
if podsNotReady == 0 {
t.Logf("collector pods are ready")
return true
}
return false
}, time.Duration(podTimeoutMinutes)*time.Minute, 2*time.Second,
"collector pods were not ready within %d minutes", podTimeoutMinutes)
}