Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
testing if my changes broke a test
Browse files Browse the repository at this point in the history
This reverts commit 06f707c.
AndersonQ committed Jun 30, 2022

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent 06f707c commit 715a639
Showing 3 changed files with 10 additions and 155 deletions.
1 change: 0 additions & 1 deletion CHANGELOG.next.asciidoc
Original file line number Diff line number Diff line change
@@ -186,4 +186,3 @@
- Support scheduled actions and cancellation of pending actions. {issue}393[393] {pull}419[419]
- Add `@metadata.input_id` and `@metadata.stream_id` when applying the inject stream processor {pull}527[527]
- Add liveness endpoint, allow fleet-gateway component to report degraded state, add update time and messages to status output. {issue}390[390] {pull}569[569]
- Redact sensitive information on diagnostics collect command. {issue}[241] {pull}[566]
84 changes: 7 additions & 77 deletions internal/pkg/agent/cmd/diagnostics.go
Original file line number Diff line number Diff line change
@@ -14,7 +14,6 @@ import (
"io/fs"
"os"
"path/filepath"
"reflect"
"runtime"
"strings"
"text/tabwriter"
@@ -35,17 +34,10 @@ import (
"github.com/elastic/elastic-agent/internal/pkg/config/operations"
)

const (
HUMAN = "human"
JSON = "json"
YAML = "yaml"
REDACTED = "<REDACTED>"
)

var diagOutputs = map[string]outputter{
HUMAN: humanDiagnosticsOutput,
JSON: jsonOutput,
YAML: yamlOutput,
"human": humanDiagnosticsOutput,
"json": jsonOutput,
"yaml": yamlOutput,
}

// DiagnosticsInfo a struct to track all information related to diagnostics for the agent.
@@ -91,7 +83,6 @@ func newDiagnosticsCommand(s []string, streams *cli.IOStreams) *cobra.Command {
}

func newDiagnosticsCollectCommandWithArgs(_ []string, streams *cli.IOStreams) *cobra.Command {

cmd := &cobra.Command{
Use: "collect",
Short: "Collect diagnostics information from the elastic-agent and write it to a zip archive.",
@@ -124,7 +115,7 @@ func newDiagnosticsCollectCommandWithArgs(_ []string, streams *cli.IOStreams) *c
}

cmd.Flags().StringP("file", "f", "", "name of the output diagnostics zip archive")
cmd.Flags().String("output", YAML, "Output the collected information in either json, or yaml (default: yaml)") // replace output flag with different options
cmd.Flags().String("output", "yaml", "Output the collected information in either json, or yaml (default: yaml)") // replace output flag with different options
cmd.Flags().Bool("pprof", false, "Collect all pprof data from all running applications.")
cmd.Flags().Duration("pprof-duration", time.Second*30, "The duration to collect trace and profiling data from the debug/pprof endpoints. (default: 30s)")
cmd.Flags().Duration("timeout", time.Second*30, "The timeout for the diagnostics collect command, will be either 30s or 30s+pprof-duration by default. Should be longer then pprof-duration when pprof is enabled as the command needs time to process/archive the response.")
@@ -699,77 +690,16 @@ func saveLogs(name string, logPath string, zw *zip.Writer) error {

// writeFile writes json or yaml data from the interface to the writer.
func writeFile(w io.Writer, outputFormat string, v interface{}) error {
redacted, err := redact(v)
if err != nil {
return err
}

if outputFormat == JSON {
if outputFormat == "json" {
je := json.NewEncoder(w)
je.SetIndent("", " ")
return je.Encode(redacted)
return je.Encode(v)
}

ye := yaml.NewEncoder(w)
err = ye.Encode(redacted)
err := ye.Encode(v)
return closeHandlers(err, ye)
}

func redact(v interface{}) (map[string]interface{}, error) {
redacted := map[string]interface{}{}
bs, err := yaml.Marshal(v)
if err != nil {
return nil, fmt.Errorf("could not marshal data to redact: %w", err)
}

err = yaml.Unmarshal(bs, &redacted)
if err != nil {
return nil, fmt.Errorf("could not unmarshal data to redact: %w", err)
}

return redactMap(redacted), nil
}

func toMapStr(v interface{}) map[string]interface{} {
mm := map[string]interface{}{}
m, ok := v.(map[interface{}]interface{})
if !ok {
return mm
}

for k, v := range m {
mm[k.(string)] = v
}
return mm
}

func redactMap(m map[string]interface{}) map[string]interface{} {
for k, v := range m {
if v != nil && reflect.TypeOf(v).Kind() == reflect.Map {
v = redactMap(toMapStr(v))
}
if redactKey(k) {
v = REDACTED
}
m[k] = v
}
return m
}

func redactKey(k string) bool {
// "routekey" shouldn't be redacted.
// Add any other exceptions here.
if k == "routekey" {
return false
}

return strings.Contains(k, "certificate") ||
strings.Contains(k, "passphrase") ||
strings.Contains(k, "password") ||
strings.Contains(k, "token") ||
strings.Contains(k, "key")
}

// closeHandlers will close all passed closers attaching any errors to the passed err and returning the result
func closeHandlers(err error, closers ...io.Closer) error {
var mErr *multierror.Error
80 changes: 3 additions & 77 deletions internal/pkg/agent/cmd/diagnostics_test.go
Original file line number Diff line number Diff line change
@@ -15,7 +15,6 @@ import (
"testing"
"time"

"github.com/elastic/elastic-agent-libs/transport/tlscommon"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

@@ -31,7 +30,7 @@ var testDiagnostics = DiagnosticsInfo{
BuildTime: time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC),
Snapshot: false,
},
ProcMeta: []client.ProcMeta{{
ProcMeta: []client.ProcMeta{client.ProcMeta{
Process: "filebeat",
Name: "filebeat",
Hostname: "test-host",
@@ -46,7 +45,7 @@ var testDiagnostics = DiagnosticsInfo{
BinaryArchitecture: "test-architecture",
RouteKey: "test",
ElasticLicensed: true,
}, {
}, client.ProcMeta{
Process: "filebeat",
Name: "filebeat_monitoring",
Hostname: "test-host",
@@ -61,7 +60,7 @@ var testDiagnostics = DiagnosticsInfo{
BinaryArchitecture: "test-architecture",
RouteKey: "test",
ElasticLicensed: true,
}, {
}, client.ProcMeta{
Name: "metricbeat",
RouteKey: "test",
Error: "failed to get metricbeat data",
@@ -138,76 +137,3 @@ func Test_collectEndpointSecurityLogs_noEndpointSecurity(t *testing.T) {
err := collectEndpointSecurityLogs(zw, specs)
assert.NoError(t, err, "collectEndpointSecurityLogs should not return an error")
}

func Test_redact(t *testing.T) {
tests := []struct {
name string
arg interface{}
wantRedacted []string
wantErr assert.ErrorAssertionFunc
}{
{
name: "tlscommon.Config",
arg: tlscommon.Config{
Enabled: nil,
VerificationMode: 0,
Versions: nil,
CipherSuites: nil,
CAs: []string{"ca1", "ca2"},
Certificate: tlscommon.CertificateConfig{
Certificate: "Certificate",
Key: "Key",
Passphrase: "Passphrase",
},
CurveTypes: nil,
Renegotiation: 0,
CASha256: nil,
CATrustedFingerprint: "",
},
wantRedacted: []string{
"certificate", "key", "key_passphrase", "certificate_authorities"},
},
{
name: "some map",
arg: map[string]interface{}{
"s": "sss",
"some_key": "hey, a key!",
"a_password": "changeme",
"my_token": "a_token",
"nested": map[string]string{
"4242": "4242",
"4242key": "4242key",
"4242password": "4242password",
"4242certificate": "4242certificate",
},
},
wantRedacted: []string{
"some_key", "a_password", "my_token", "4242key", "4242password", "4242certificate"},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := redact(tt.arg)
require.NoError(t, err)

for k, v := range got {
if contains(tt.wantRedacted, k) {
assert.Equal(t, v, REDACTED)
} else {
assert.NotEqual(t, v, REDACTED)
}
}
})
}
}

func contains(list []string, val string) bool {
for _, k := range list {
if val == k {
return true
}
}

return false
}

0 comments on commit 715a639

Please sign in to comment.