Skip to content

Commit 852d47c

Browse files
Docker image running Elastic Agent in Otel mode (#5248)
* working otel image * keep otel as close to agent as possible * otel mode based on ENV * playing with tests * otel tests separately * revert configmap --------- Co-authored-by: Blake Rouse <blake.rouse@elastic.co>
1 parent 1813c59 commit 852d47c

File tree

2 files changed

+131
-3
lines changed

2 files changed

+131
-3
lines changed

dev-tools/packaging/templates/docker/docker-entrypoint.elastic-agent.tmpl

+5
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,9 @@ set -eo pipefail
1111
# `./elastic-agent container --help`
1212
#
1313

14+
if [[ "$ELASTIC_AGENT_OTEL" == "true" ]]
15+
then
16+
exec {{ .BeatName }} otel "$@"
17+
else
1418
exec {{ .BeatName }} container "$@"
19+
fi

testing/integration/kubernetes_agent_standalone_test.go

+126-3
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,124 @@ func TestKubernetesAgentStandalone(t *testing.T) {
205205

206206
ctx := context.Background()
207207

208-
deployK8SAgent(t, ctx, client, k8sObjects, testNamespace, tc.runK8SInnerTests, testLogsBasePath)
208+
deployK8SAgent(t, ctx, client, k8sObjects, testNamespace, tc.runK8SInnerTests, testLogsBasePath, nil)
209+
})
210+
}
211+
212+
}
213+
214+
func TestKubernetesAgentOtel(t *testing.T) {
215+
info := define.Require(t, define.Requirements{
216+
Stack: &define.Stack{},
217+
Local: false,
218+
Sudo: false,
219+
OS: []define.OS{
220+
{Type: define.Kubernetes},
221+
},
222+
Group: define.Kubernetes,
223+
})
224+
225+
agentImage := os.Getenv("AGENT_IMAGE")
226+
require.NotEmpty(t, agentImage, "AGENT_IMAGE must be set")
227+
228+
client, err := info.KubeClient()
229+
require.NoError(t, err)
230+
require.NotNil(t, client)
231+
232+
testLogsBasePath := os.Getenv("K8S_TESTS_POD_LOGS_BASE")
233+
require.NotEmpty(t, testLogsBasePath, "K8S_TESTS_POD_LOGS_BASE must be set")
234+
235+
err = os.MkdirAll(filepath.Join(testLogsBasePath, t.Name()), 0755)
236+
require.NoError(t, err, "failed to create test logs directory")
237+
238+
namespace := info.Namespace
239+
240+
esHost := os.Getenv("ELASTICSEARCH_HOST")
241+
require.NotEmpty(t, esHost, "ELASTICSEARCH_HOST must be set")
242+
243+
esAPIKey, err := generateESAPIKey(info.ESClient, namespace)
244+
require.NoError(t, err, "failed to generate ES API key")
245+
require.NotEmpty(t, esAPIKey, "failed to generate ES API key")
246+
247+
renderedManifest, err := renderKustomize(agentK8SKustomize)
248+
require.NoError(t, err, "failed to render kustomize")
249+
250+
testCases := []struct {
251+
name string
252+
envAdd []corev1.EnvVar
253+
runK8SInnerTests bool
254+
componentPresence map[string]bool
255+
}{
256+
257+
{
258+
"run agent in otel mode",
259+
[]corev1.EnvVar{
260+
{Name: "ELASTIC_AGENT_OTEL", Value: "true"},
261+
},
262+
false,
263+
map[string]bool{
264+
"beat/metrics-monitoring": false,
265+
"filestream-monitoring": false,
266+
"system/metrics-default": false,
267+
},
268+
},
269+
}
270+
271+
for _, tc := range testCases {
272+
tc := tc
273+
t.Run(tc.name, func(t *testing.T) {
274+
hasher := sha256.New()
275+
hasher.Write([]byte(tc.name))
276+
testNamespace := strings.ToLower(base64.URLEncoding.EncodeToString(hasher.Sum(nil)))
277+
testNamespace = noSpecialCharsRegexp.ReplaceAllString(testNamespace, "")
278+
279+
k8sObjects, err := yamlToK8SObjects(bufio.NewReader(bytes.NewReader(renderedManifest)))
280+
require.NoError(t, err, "failed to convert yaml to k8s objects")
281+
282+
adjustK8SAgentManifests(k8sObjects, testNamespace, "elastic-agent-standalone",
283+
func(container *corev1.Container) {
284+
// set agent image
285+
container.Image = agentImage
286+
// set ImagePullPolicy to "Never" to avoid pulling the image
287+
// as the image is already loaded by the kubernetes provisioner
288+
container.ImagePullPolicy = "Never"
289+
290+
// set Elasticsearch host and API key
291+
for idx, env := range container.Env {
292+
if env.Name == "ES_HOST" {
293+
container.Env[idx].Value = esHost
294+
container.Env[idx].ValueFrom = nil
295+
}
296+
if env.Name == "API_KEY" {
297+
container.Env[idx].Value = esAPIKey
298+
container.Env[idx].ValueFrom = nil
299+
}
300+
}
301+
302+
if len(tc.envAdd) > 0 {
303+
container.Env = append(container.Env, tc.envAdd...)
304+
}
305+
306+
// drop arguments overriding default config
307+
container.Args = []string{}
308+
},
309+
func(pod *corev1.PodSpec) {
310+
for volumeIdx, volume := range pod.Volumes {
311+
// need to update the volume path of the state directory
312+
// to match the test namespace
313+
if volume.Name == "elastic-agent-state" {
314+
hostPathType := corev1.HostPathDirectoryOrCreate
315+
pod.Volumes[volumeIdx].VolumeSource.HostPath = &corev1.HostPathVolumeSource{
316+
Type: &hostPathType,
317+
Path: fmt.Sprintf("/var/lib/elastic-agent-standalone/%s/state", testNamespace),
318+
}
319+
}
320+
}
321+
})
322+
323+
ctx := context.Background()
324+
325+
deployK8SAgent(t, ctx, client, k8sObjects, testNamespace, tc.runK8SInnerTests, testLogsBasePath, tc.componentPresence)
209326
})
210327
}
211328

@@ -214,7 +331,7 @@ func TestKubernetesAgentStandalone(t *testing.T) {
214331
// deployK8SAgent is a helper function to deploy the elastic-agent in k8s and invoke the inner k8s tests if
215332
// runK8SInnerTests is true
216333
func deployK8SAgent(t *testing.T, ctx context.Context, client klient.Client, objects []k8s.Object, namespace string,
217-
runInnerK8STests bool, testLogsBasePath string) {
334+
runInnerK8STests bool, testLogsBasePath string, componentPresence map[string]bool) {
218335

219336
objects = append([]k8s.Object{&corev1.Namespace{
220337
ObjectMeta: metav1.ObjectMeta{
@@ -288,9 +405,10 @@ func deployK8SAgent(t *testing.T, ctx context.Context, client klient.Client, obj
288405
time.Sleep(time.Second * 1)
289406
}
290407

408+
statusString := stdout.String()
291409
if agentHealthyErr != nil {
292410
t.Errorf("elastic-agent never reported healthy: %v", agentHealthyErr)
293-
t.Logf("stdout: %s\n", stdout.String())
411+
t.Logf("stdout: %s\n", statusString)
294412
t.Logf("stderr: %s\n", stderr.String())
295413
t.FailNow()
296414
return
@@ -299,6 +417,11 @@ func deployK8SAgent(t *testing.T, ctx context.Context, client klient.Client, obj
299417
stdout.Reset()
300418
stderr.Reset()
301419

420+
for component, shouldBePresent := range componentPresence {
421+
isPresent := strings.Contains(statusString, component)
422+
require.Equal(t, shouldBePresent, isPresent)
423+
}
424+
302425
if runInnerK8STests {
303426
err := client.Resources().ExecInPod(ctx, namespace, agentPodName, "elastic-agent-standalone",
304427
[]string{"/usr/share/elastic-agent/k8s-inner-tests", "-test.v"}, &stdout, &stderr)

0 commit comments

Comments
 (0)