Skip to content

Commit dffd079

Browse files
Add environment.yaml file to diagnostics (#11484) (#11544)
Add an environment.yaml file to the diagnostics bundle. (cherry picked from commit bf4953d) Co-authored-by: Michel Laterman <[email protected]>
1 parent ccdb972 commit dffd079

File tree

4 files changed

+113
-0
lines changed

4 files changed

+113
-0
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Kind can be one of:
2+
# - breaking-change: a change to previously-documented behavior
3+
# - deprecation: functionality that is being removed in a later release
4+
# - bug-fix: fixes a problem in a previous version
5+
# - enhancement: extends functionality but does not break or fix existing behavior
6+
# - feature: new functionality
7+
# - known-issue: problems that we are aware of in a given version
8+
# - security: impacts on the security of a product or a user’s deployment.
9+
# - upgrade: important information for someone upgrading from a prior version
10+
# - other: does not fit into any of the other categories
11+
kind: bug-fix
12+
13+
# Change summary; a 80ish characters long description of the change.
14+
summary: Add environment.yaml file to diagnostics
15+
16+
# Long description; in case the summary is not enough to describe the change
17+
# this field accommodate a description without length limits.
18+
# NOTE: This field will be rendered only for breaking-change and known-issue kinds at the moment.
19+
#description:
20+
21+
# Affected component; usually one of "elastic-agent", "fleet-server", "filebeat", "metricbeat", "auditbeat", "all", etc.
22+
component: elastic-agent
23+
24+
# PR URL; optional; the PR number that added the changeset.
25+
# If not present is automatically filled by the tooling finding the PR where this changelog fragment has been added.
26+
# NOTE: the tooling supports backports, so it's able to fill the original PR number instead of the backport PR number.
27+
# Please provide it if you are adding a fragment for a different PR.
28+
#pr: https://github.com/owner/repo/1234
29+
30+
# Issue URL; optional; the GitHub issue related to this changeset (either closes or is part of).
31+
# If not present is automatically filled by the tooling with the issue linked to the PR number.
32+
issue: https://github.com/elastic/elastic-agent/issues/10966

internal/pkg/diagnostics/diagnostics.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,23 @@ func GlobalHooks() Hooks {
9595
return fileBytes
9696
},
9797
},
98+
{
99+
Name: "environment",
100+
Filename: "environment.yaml",
101+
Description: "Environment variables",
102+
ContentType: "application/yaml",
103+
Hook: func(_ context.Context) []byte {
104+
redacted, err := redactEnv()
105+
if err != nil {
106+
return []byte(err.Error())
107+
}
108+
out, err := yaml.Marshal(redacted)
109+
if err != nil {
110+
return []byte(fmt.Sprintf("Unable to marshall env vars into yaml: %v", err))
111+
}
112+
return out
113+
},
114+
},
98115
{
99116
Name: "goroutine",
100117
Filename: "goroutine.pprof.gz",
@@ -702,3 +719,17 @@ func addSecretMarkers(cfg *config.Config, secretPaths []string) error {
702719

703720
return aggregateError
704721
}
722+
723+
func redactEnv() (map[string]any, error) {
724+
envMap := map[string]any{}
725+
for _, e := range os.Environ() {
726+
pair := strings.SplitN(e, "=", 2)
727+
envMap[pair[0]] = pair[1]
728+
}
729+
var errOut bytes.Buffer
730+
redacted := Redact(envMap, &errOut)
731+
if errOut.Len() > 0 {
732+
return nil, errors.New(errOut.String())
733+
}
734+
return redacted, nil
735+
}

internal/pkg/diagnostics/diagnostics_test.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,7 @@ func TestGlobalHooks(t *testing.T) {
495495
assert.NoErrorf(t, err, "hook %q validation error: %v", err)
496496
case "package version":
497497
assert.Equal(t, testPkgVer, string(output), "hook package version does not match")
498+
case "environment":
498499
default:
499500
ok, err = isPprof(output)
500501
assert.Truef(t, ok, "hook %q returned incompatible data: %q", h.Name, hex.EncodeToString(output))
@@ -858,3 +859,51 @@ func TestRedactSSLKeyInInputs(t *testing.T) {
858859
require.Contains(t, sliceSSL, "key")
859860
assert.Equal(t, REDACTED, sliceSSL["key"])
860861
}
862+
863+
func TestRedactEnv(t *testing.T) {
864+
tests := []struct {
865+
name string
866+
env map[string]string
867+
expect map[string]any
868+
}{{
869+
name: "No redactions",
870+
env: map[string]string{
871+
"TEST_LEVEL": "test-val",
872+
"VAL1": "a,b,c",
873+
},
874+
expect: map[string]any{
875+
"TEST_LEVEL": "test-val",
876+
"VAL1": "a,b,c",
877+
},
878+
}, {
879+
name: "Redacts value based on key",
880+
env: map[string]string{
881+
"TEST_LEVEL": "test-val",
882+
"VAL1": "a,b,c",
883+
"API_KEY": "secret-value",
884+
"SERVICE_TOKEN": "secret-token",
885+
},
886+
expect: map[string]any{
887+
"TEST_LEVEL": "test-val",
888+
"VAL1": "a,b,c",
889+
"API_KEY": REDACTED,
890+
"SERVICE_TOKEN": REDACTED,
891+
},
892+
}}
893+
894+
for _, tt := range tests {
895+
t.Run(tt.name, func(t *testing.T) {
896+
for k, v := range tt.env {
897+
t.Setenv(k, v)
898+
}
899+
redacted, err := redactEnv()
900+
require.NoError(t, err)
901+
902+
// redacted includes full env vars, we want to check if the expected k:v's are present
903+
for k, v := range tt.expect {
904+
require.Contains(t, redacted, k)
905+
require.Equal(t, v, redacted[k])
906+
}
907+
})
908+
}
909+
}

testing/integration/ess/diagnostics_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ var diagnosticsFiles = []string{
4242
"components-actual.yaml",
4343
"components-expected.yaml",
4444
"computed-config.yaml",
45+
"environment.yaml",
4546
"goroutine.pprof.gz",
4647
"heap.pprof.gz",
4748
"local-config.yaml",

0 commit comments

Comments
 (0)