From a523551da95cf8ba9fda77d344a278087f08f7e9 Mon Sep 17 00:00:00 2001 From: Evans Mungai Date: Tue, 3 Jan 2023 18:05:15 +0000 Subject: [PATCH] feat(redactors): Run redactors on an existing support bundle (#887) * feat(redactors): Run redactors on an existing support bundle Add redact subcommand to support-bundle to allow running redactors on an existing bundle to creating a new redacted bundle. The command will be launched like so support-bundle redact --bundle support-bundle.tar.gz Fixes: #705 --- .gitignore | 1 + Makefile | 6 +- README.md | 18 ++-- cmd/collect/cli/run.go | 17 ++-- cmd/troubleshoot/cli/redact.go | 85 ++++++++++++++++++ cmd/troubleshoot/cli/root.go | 3 +- cmd/troubleshoot/cli/run.go | 13 +-- cmd/troubleshoot/cli/version.go | 5 +- docs/preflight.md | 4 +- docs/preflight_version.md | 2 +- docs/support-bundle.md | 11 +-- docs/support-bundle_analyze.md | 2 +- docs/support-bundle_redact.md | 35 ++++++++ docs/support-bundle_version.md | 2 +- examples/redact/e2e.yaml | 10 +++ internal/testutils/utils.go | 24 +++++ pkg/analyze/download.go | 80 +++++++++++------ pkg/analyze/download_test.go | 49 ++++++++++ pkg/collect/postgres_test.go | 7 +- pkg/collect/redact.go | 21 ++++- pkg/collect/redis_test.go | 7 +- pkg/collect/result.go | 47 +++++++++- pkg/collect/result_test.go | 35 ++++++++ pkg/collect/util_test.go | 51 +++++------ pkg/constants/constants.go | 2 + pkg/supportbundle/collect.go | 2 - pkg/supportbundle/load.go | 56 +++++++----- pkg/supportbundle/supportbundle.go | 20 ++--- test/validate-support-bundle-e2e.sh | 38 ++++++-- .../pods/logs/default/static-hi/static-hi.log | 2 + .../supportbundle/extracted-sb/static-hi.log | 1 + testdata/supportbundle/missing-version.tar.gz | Bin 0 -> 1238 bytes testdata/supportbundle/support-bundle.tar.gz | Bin 0 -> 110657 bytes 33 files changed, 502 insertions(+), 154 deletions(-) create mode 100644 cmd/troubleshoot/cli/redact.go create mode 100644 docs/support-bundle_redact.md create mode 100644 examples/redact/e2e.yaml create mode 100644 internal/testutils/utils.go create mode 100644 pkg/analyze/download_test.go create mode 100644 testdata/supportbundle/extracted-sb/cluster-resources/pods/logs/default/static-hi/static-hi.log create mode 120000 testdata/supportbundle/extracted-sb/static-hi.log create mode 100644 testdata/supportbundle/missing-version.tar.gz create mode 100644 testdata/supportbundle/support-bundle.tar.gz diff --git a/.gitignore b/.gitignore index df59e932..af6bc42e 100644 --- a/.gitignore +++ b/.gitignore @@ -41,3 +41,4 @@ sbom/ # Ignore generated support bundles *.tar.gz +!testdata/supportbundle/*.tar.gz diff --git a/Makefile b/Makefile index 641fe9e4..e34dc3a2 100644 --- a/Makefile +++ b/Makefile @@ -35,7 +35,7 @@ endef BUILDFLAGS = -tags "netgo containers_image_ostree_stub exclude_graphdriver_devicemapper exclude_graphdriver_btrfs containers_image_openpgp" -installsuffix netgo -all: test support-bundle preflight collect +all: test support-bundle preflight collect analyze .PHONY: ffi ffi: fmt vet @@ -202,8 +202,8 @@ scan: .PHONY: lint lint: - golangci-lint run -c .golangci.yaml + golangci-lint run --new -c .golangci.yaml pkg/... cmd/... .PHONY: lint-and-fix lint-and-fix: - golangci-lint run --fix -c .golangci.yaml + golangci-lint run --new --fix -c .golangci.yaml pkg/... cmd/... diff --git a/README.md b/README.md index d255932d..dcfc2528 100644 --- a/README.md +++ b/README.md @@ -12,13 +12,13 @@ To run a sample preflight check from a sample application, install the preflight ``` curl https://krew.sh/preflight | bash ``` -and run, where https://preflight.replicated.com provides an **example** preflight spec: - + and run, where https://preflight.replicated.com provides an **example** preflight spec: + ``` kubectl preflight https://preflight.replicated.com ``` -**NOTE** this is an example. Do **not** use to validate real scenarios. +**NOTE** this is an example. Do **not** use to validate real scenarios. For more details on creating the custom resource files that drive preflight checks, visit [creating preflight checks](https://troubleshoot.sh/docs/preflight/introduction/). @@ -31,13 +31,13 @@ To collect a sample support bundle, install the troubleshoot kubectl plugin: ``` curl https://krew.sh/support-bundle | bash ``` -and run, where https://support-bundle.replicated.com provides an **example** support bundle spec: - + and run, where https://support-bundle.replicated.com provides an **example** support bundle spec: + ``` kubectl support-bundle https://support-bundle.replicated.com ``` -**NOTE** this is an example. Do **not** use to validate real scenarios. +**NOTE** this is an example. Do **not** use to validate real scenarios. For more details on creating the custom resource files that drive support-bundle collection, visit [creating collectors](https://troubleshoot.sh/docs/collect/) and [creating analyzers](https://troubleshoot.sh/docs/analyze/). @@ -47,9 +47,9 @@ And see our other tool [sbctl](https://github.com/replicatedhq/sbctl) that makes For questions about using Troubleshoot, there's a [Replicated Community](https://help.replicated.com/community) forum, and a [#app-troubleshoot channel in Kubernetes Slack](https://kubernetes.slack.com/channels/app-troubleshoot). -# Software Bill of Materials -A signed SBOM that includes Troubleshoot dependencies is included in each release. -- **troubleshoot-sbom.tgz** contains a software bill of materials for Troubleshoot. +# Software Bill of Materials +A signed SBOM that includes Troubleshoot dependencies is included in each release. +- **troubleshoot-sbom.tgz** contains a software bill of materials for Troubleshoot. - **troubleshoot-sbom.tgz.sig** is the digital signature for troubleshoot-sbom.tgz - **key.pub** is the public key from the key pair used to sign troubleshoot-sbom.tgz diff --git a/cmd/collect/cli/run.go b/cmd/collect/cli/run.go index d5388742..dc56f1ce 100644 --- a/cmd/collect/cli/run.go +++ b/cmd/collect/cli/run.go @@ -91,16 +91,15 @@ func runCollect(v *viper.Viper, arg string) error { troubleshootclientsetscheme.AddToScheme(scheme.Scheme) decode := scheme.Codecs.UniversalDeserializer().Decode - additionalRedactors := &troubleshootv1beta2.Redactor{} - for idx, redactor := range v.GetStringSlice("redactors") { - redactorObj, err := supportbundle.GetRedactorFromURI(redactor) - if err != nil { - return errors.Wrapf(err, "failed to get redactor spec %s, #%d", redactor, idx) - } + redactors, err := supportbundle.GetRedactorsFromURIs(v.GetStringSlice("redactors")) + if err != nil { + return errors.Wrap(err, "failed to get redactors") + } - if redactorObj != nil { - additionalRedactors.Spec.Redactors = append(additionalRedactors.Spec.Redactors, redactorObj.Spec.Redactors...) - } + additionalRedactors := &troubleshootv1beta2.Redactor{ + Spec: troubleshootv1beta2.RedactorSpec{ + Redactors: redactors, + }, } for i, additionalDoc := range multidocs { diff --git a/cmd/troubleshoot/cli/redact.go b/cmd/troubleshoot/cli/redact.go new file mode 100644 index 00000000..4031a670 --- /dev/null +++ b/cmd/troubleshoot/cli/redact.go @@ -0,0 +1,85 @@ +package cli + +import ( + "fmt" + "os" + "time" + + "github.com/pkg/errors" + analyzer "github.com/replicatedhq/troubleshoot/pkg/analyze" + "github.com/replicatedhq/troubleshoot/pkg/collect" + "github.com/replicatedhq/troubleshoot/pkg/logger" + "github.com/replicatedhq/troubleshoot/pkg/supportbundle" + "github.com/spf13/cobra" + "github.com/spf13/viper" +) + +func Redact() *cobra.Command { + cmd := &cobra.Command{ + Use: "redact [urls...]", + Args: cobra.MinimumNArgs(1), // TODO + Short: "Redact information from a generated support bundle archive", + Long: `Redaction is the process of masking sensitive information from collected data in a support bundle. +This is done using rules defined in the list of redactor manifests provided in the [urls...] command line +argument. Default built in redactors will also be run, but these would have been run when the support +bundle was generated. After redaction, the support bundle is archived once more. The resulting file will +be stored in the current directory in the path provided by the --output flag. + +The [urls...] argument is a list of either oci://.., http://.., https://.. or local paths to yaml files. + +For more information on redactors visit https://troubleshoot.sh/docs/redact/ + `, + PreRunE: func(cmd *cobra.Command, args []string) error { + return viper.BindPFlags(cmd.Flags()) + }, + RunE: func(cmd *cobra.Command, args []string) error { + v := viper.GetViper() + + logger.SetQuiet(v.GetBool("quiet")) + + // 1. Decode redactors from provided URLs + redactors, err := supportbundle.GetRedactorsFromURIs(args) + if err != nil { + return err + } + + // 2. Download the bundle and extract it + tmpDir, bundleDir, err := analyzer.DownloadAndExtractSupportBundle(v.GetString("bundle")) + if err != nil { + return err + } + defer os.RemoveAll(tmpDir) + + // 3. Represent bundle as a CollectorResult + collectorResult, err := collect.CollectorResultFromBundle(bundleDir) + if err != nil { + return err + } + + // 4. Perform redaction on the bundle + err = collect.RedactResult(bundleDir, collectorResult, redactors) + if err != nil { + return errors.Wrap(err, "failed to redact support bundle") + } + + // 5. Compress the bundle once more after redacting + output := v.GetString("output") + if output == "" { + output = fmt.Sprintf("redacted-support-bundle-%s.tar.gz", time.Now().Format("2006-01-02T15_04_05")) + } + err = collectorResult.ArchiveSupportBundle(bundleDir, output) + if err != nil { + return errors.Wrap(err, "failed to create support bundle archive") + } + fmt.Println("Redacted support bundle:", output) + return nil + }, + } + + cmd.Flags().String("bundle", "", "file path of the support bundle archive to redact") + cmd.MarkFlagRequired("bundle") + cmd.Flags().BoolP("quiet", "q", false, "enable/disable error messaging and only show parseable output") + cmd.Flags().StringP("output", "o", "", "file path of where to save the redacted support bundle archive (default \"redacted-support-bundle-YYYY-MM-DDTHH_MM_SS.tar.gz\")") + + return cmd +} diff --git a/cmd/troubleshoot/cli/root.go b/cmd/troubleshoot/cli/root.go index 6e12fd5a..2bf8cfac 100644 --- a/cmd/troubleshoot/cli/root.go +++ b/cmd/troubleshoot/cli/root.go @@ -15,7 +15,7 @@ import ( func RootCmd() *cobra.Command { cmd := &cobra.Command{ - Use: "support-bundle [url]", + Use: "support-bundle [urls...]", Args: cobra.MinimumNArgs(0), Short: "Generate a support bundle", Long: `A support bundle is an archive of files, output, metrics and state @@ -40,6 +40,7 @@ from a server that can be used to assist when troubleshooting a Kubernetes clust cobra.OnInitialize(initConfig) cmd.AddCommand(Analyze()) + cmd.AddCommand(Redact()) cmd.AddCommand(VersionCmd()) cmd.Flags().StringSlice("redactors", []string{}, "names of the additional redactors to use") diff --git a/cmd/troubleshoot/cli/run.go b/cmd/troubleshoot/cli/run.go index 00359739..e5ecce6a 100644 --- a/cmd/troubleshoot/cli/run.go +++ b/cmd/troubleshoot/cli/run.go @@ -208,16 +208,11 @@ func runTroubleshoot(v *viper.Viper, arg []string) error { return errors.New("no collectors specified in support bundle") } - for idx, redactor := range v.GetStringSlice("redactors") { - redactorObj, err := supportbundle.GetRedactorFromURI(redactor) - if err != nil { - return errors.Wrapf(err, "failed to get redactor spec %s, #%d", redactor, idx) - } - - if redactorObj != nil { - additionalRedactors.Spec.Redactors = append(additionalRedactors.Spec.Redactors, redactorObj.Spec.Redactors...) - } + redactors, err := supportbundle.GetRedactorsFromURIs(v.GetStringSlice("redactors")) + if err != nil { + return errors.Wrap(err, "failed to get redactors") } + additionalRedactors.Spec.Redactors = append(additionalRedactors.Spec.Redactors, redactors...) var collectorCB func(chan interface{}, string) progressChan := make(chan interface{}) // non-zero buffer can result in missed messages diff --git a/cmd/troubleshoot/cli/version.go b/cmd/troubleshoot/cli/version.go index a19d384a..7baf5805 100644 --- a/cmd/troubleshoot/cli/version.go +++ b/cmd/troubleshoot/cli/version.go @@ -7,6 +7,7 @@ import ( "path/filepath" troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2" + "github.com/replicatedhq/troubleshoot/pkg/constants" "github.com/replicatedhq/troubleshoot/pkg/version" "github.com/spf13/cobra" "gopkg.in/yaml.v2" @@ -26,8 +27,6 @@ func VersionCmd() *cobra.Command { return cmd } -const VersionFilename = "version.yaml" - func writeVersionFile(path string) error { version := troubleshootv1beta2.SupportBundleVersion{ ApiVersion: "troubleshoot.sh/v1beta2", @@ -41,7 +40,7 @@ func writeVersionFile(path string) error { return err } - filename := filepath.Join(path, VersionFilename) + filename := filepath.Join(path, constants.VersionFilename) err = ioutil.WriteFile(filename, b, 0644) if err != nil { return err diff --git a/docs/preflight.md b/docs/preflight.md index d34920bf..a43ddd7f 100644 --- a/docs/preflight.md +++ b/docs/preflight.md @@ -17,7 +17,7 @@ preflight [url] [flags] --as string Username to impersonate for the operation. User could be a regular user or a service account in a namespace. --as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups. --as-uid string UID to impersonate for the operation. - --cache-dir string Default cache directory (default "/Users/xavpaice/.kube/cache") + --cache-dir string Default cache directory (default "$HOME/.kube/cache") --certificate-authority string Path to a cert file for the certificate authority --client-certificate string Path to a client certificate file for TLS --client-key string Path to a client key file for TLS @@ -48,4 +48,4 @@ preflight [url] [flags] * [preflight version](preflight_version.md) - Print the current version and exit -###### Auto generated by spf13/cobra on 21-Nov-2022 +###### Auto generated by spf13/cobra on 22-Dec-2022 diff --git a/docs/preflight_version.md b/docs/preflight_version.md index 2744ea16..a26d1ea9 100644 --- a/docs/preflight_version.md +++ b/docs/preflight_version.md @@ -35,4 +35,4 @@ preflight version [flags] * [preflight](preflight.md) - Run and retrieve preflight checks in a cluster -###### Auto generated by spf13/cobra on 21-Nov-2022 +###### Auto generated by spf13/cobra on 22-Dec-2022 diff --git a/docs/support-bundle.md b/docs/support-bundle.md index c0dba200..88a68a3a 100644 --- a/docs/support-bundle.md +++ b/docs/support-bundle.md @@ -8,7 +8,7 @@ A support bundle is an archive of files, output, metrics and state from a server that can be used to assist when troubleshooting a Kubernetes cluster. ``` -support-bundle [url] [flags] +support-bundle [urls...] [flags] ``` ### Options @@ -17,7 +17,7 @@ support-bundle [url] [flags] --as string Username to impersonate for the operation. User could be a regular user or a service account in a namespace. --as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups. --as-uid string UID to impersonate for the operation. - --cache-dir string Default cache directory (default "/Users/xavpaice/.kube/cache") + --cache-dir string Default cache directory (default "$HOME/.kube/cache") --certificate-authority string Path to a cert file for the certificate authority --client-certificate string Path to a client certificate file for TLS --client-key string Path to a client key file for TLS @@ -47,7 +47,8 @@ support-bundle [url] [flags] ### SEE ALSO -* [support-bundle analyze](support-bundle_analyze.md) - analyze a support bundle -* [support-bundle version](support-bundle_version.md) - Print the current version and exit +* [support-bundle analyze](support-bundle_analyze.md) - analyze a support bundle +* [support-bundle redact](support-bundle_redact.md) - Redact information from a generated support bundle archive +* [support-bundle version](support-bundle_version.md) - Print the current version and exit -###### Auto generated by spf13/cobra on 21-Nov-2022 +###### Auto generated by spf13/cobra on 22-Dec-2022 diff --git a/docs/support-bundle_analyze.md b/docs/support-bundle_analyze.md index 535fd9b5..b0848b83 100644 --- a/docs/support-bundle_analyze.md +++ b/docs/support-bundle_analyze.md @@ -23,4 +23,4 @@ support-bundle analyze [url] [flags] * [support-bundle](support-bundle.md) - Generate a support bundle -###### Auto generated by spf13/cobra on 21-Nov-2022 +###### Auto generated by spf13/cobra on 22-Dec-2022 diff --git a/docs/support-bundle_redact.md b/docs/support-bundle_redact.md new file mode 100644 index 00000000..c6f3f22d --- /dev/null +++ b/docs/support-bundle_redact.md @@ -0,0 +1,35 @@ +## support-bundle redact + +Redact information from a generated support bundle archive + +### Synopsis + +Redaction is the process of masking sensitive information from collected data in a support bundle. +This is done using rules defined in the list of redactor manifests provided in the [urls...] command line +argument. Default built in redactors will also be run, but these would have been run when the support +bundle was generated. After redaction, the support bundle is archived once more. The resulting file will +be stored in the current directory in the path provided by the --output flag. + +The [urls...] argument is a list of either oci://.., http://.., https://.. or local paths to yaml files. + +For more information on redactors visit https://troubleshoot.sh/docs/redact/ + + +``` +support-bundle redact [urls...] [flags] +``` + +### Options + +``` + --bundle string file path of the support bundle archive to redact + -h, --help help for redact + -o, --output string file path of where to save the redacted support bundle archive (default "redacted-support-bundle-YYYY-MM-DDTHH_MM_SS.tar.gz") + -q, --quiet enable/disable error messaging and only show parseable output +``` + +### SEE ALSO + +* [support-bundle](support-bundle.md) - Generate a support bundle + +###### Auto generated by spf13/cobra on 22-Dec-2022 diff --git a/docs/support-bundle_version.md b/docs/support-bundle_version.md index 30cf864e..bfa3b7a0 100644 --- a/docs/support-bundle_version.md +++ b/docs/support-bundle_version.md @@ -20,4 +20,4 @@ support-bundle version [flags] * [support-bundle](support-bundle.md) - Generate a support bundle -###### Auto generated by spf13/cobra on 21-Nov-2022 +###### Auto generated by spf13/cobra on 22-Dec-2022 diff --git a/examples/redact/e2e.yaml b/examples/redact/e2e.yaml new file mode 100644 index 00000000..65b3833f --- /dev/null +++ b/examples/redact/e2e.yaml @@ -0,0 +1,10 @@ +apiVersion: troubleshoot.sh/v1beta2 +kind: Redactor +metadata: + name: e2e-redactor +spec: + redactors: + - name: redact-static-text + removals: + values: + - static diff --git a/internal/testutils/utils.go b/internal/testutils/utils.go new file mode 100644 index 00000000..cbb0a0f9 --- /dev/null +++ b/internal/testutils/utils.go @@ -0,0 +1,24 @@ +package testutils + +import ( + "os" + "path/filepath" + "runtime" + "testing" + + "github.com/stretchr/testify/require" +) + +func GetTestFixture(t *testing.T, path string) string { + t.Helper() + p := filepath.Join("../../testdata", path) + b, err := os.ReadFile(p) + require.NoError(t, err) + return string(b) +} + +// FileDir returns the directory of the current source file. +func FileDir() string { + _, filename, _, _ := runtime.Caller(0) + return filepath.Dir(filename) +} diff --git a/pkg/analyze/download.go b/pkg/analyze/download.go index 6b5cbe7c..2c0b112a 100644 --- a/pkg/analyze/download.go +++ b/pkg/analyze/download.go @@ -4,7 +4,6 @@ import ( "archive/tar" "compress/gzip" "io" - "io/ioutil" "os" "path/filepath" @@ -12,6 +11,7 @@ import ( "github.com/pkg/errors" troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2" troubleshootscheme "github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/scheme" + "github.com/replicatedhq/troubleshoot/pkg/constants" "github.com/replicatedhq/troubleshoot/pkg/docrewrite" "github.com/replicatedhq/troubleshoot/pkg/logger" "k8s.io/client-go/kubernetes/scheme" @@ -55,27 +55,13 @@ func AnalyzeLocal(localBundlePath string, analyzers []*troubleshootv1beta2.Analy } func DownloadAndAnalyze(bundleURL string, analyzersSpec string) ([]*AnalyzeResult, error) { - tmpDir, err := ioutil.TempDir("", "troubleshoot-k8s") - if err != nil { - return nil, errors.Wrap(err, "failed to create temp dir") - } - defer os.RemoveAll(tmpDir) - - if err := downloadTroubleshootBundle(bundleURL, tmpDir); err != nil { - return nil, errors.Wrap(err, "failed to download bundle") - } - - rootDir, err := FindBundleRootDir(tmpDir) + tmpDir, rootDir, err := DownloadAndExtractSupportBundle(bundleURL) if err != nil { return nil, errors.Wrap(err, "failed to find root dir") } + defer os.RemoveAll(tmpDir) - _, err = os.Stat(filepath.Join(rootDir, "version.yaml")) - if err != nil { - return nil, errors.Wrap(err, "failed to read version.yaml") - } - - analyzers := []*troubleshootv1beta2.Analyze{} + var analyzers []*troubleshootv1beta2.Analyze hostAnalyzers := []*troubleshootv1beta2.HostAnalyze{} if analyzersSpec == "" { @@ -96,7 +82,34 @@ func DownloadAndAnalyze(bundleURL string, analyzersSpec string) ([]*AnalyzeResul return AnalyzeLocal(rootDir, analyzers, hostAnalyzers) } +func DownloadAndExtractSupportBundle(bundleURL string) (string, string, error) { + tmpDir, err := os.MkdirTemp("", "troubleshoot-k8s") + if err != nil { + return "", "", errors.Wrap(err, "failed to create temp dir") + } + + if err := downloadTroubleshootBundle(bundleURL, tmpDir); err != nil { + os.RemoveAll(tmpDir) + return "", "", errors.Wrap(err, "failed to download bundle") + } + + bundleDir, err := FindBundleRootDir(tmpDir) + if err != nil { + os.RemoveAll(tmpDir) + return "", "", errors.Wrap(err, "failed to find root dir") + } + + _, err = os.Stat(filepath.Join(bundleDir, constants.VersionFilename)) + if err != nil { + os.RemoveAll(tmpDir) + return "", "", errors.Wrap(err, "failed to read "+constants.VersionFilename) + } + + return tmpDir, bundleDir, nil +} + func downloadTroubleshootBundle(bundleURL string, destDir string) error { + // TODO: Move to separate package support bundle utils package if bundleURL[0] == os.PathSeparator { f, err := os.Open(bundleURL) if err != nil { @@ -111,7 +124,7 @@ func downloadTroubleshootBundle(bundleURL string, destDir string) error { return errors.Wrap(err, "failed to get workdir") } - tmpDir, err := ioutil.TempDir("", "troubleshoot") + tmpDir, err := os.MkdirTemp("", "troubleshoot") if err != nil { return errors.Wrap(err, "failed to create tmp dir") } @@ -137,6 +150,8 @@ func downloadTroubleshootBundle(bundleURL string, destDir string) error { } func ExtractTroubleshootBundle(reader io.Reader, destDir string) error { + // TODO: Move to separate package e.g support bundle package, or sbutils + // if there are cyclic dependencies gzReader, err := gzip.NewReader(reader) if err != nil { return errors.Wrap(err, "failed to create gzip reader") @@ -159,14 +174,14 @@ func ExtractTroubleshootBundle(reader io.Reader, destDir string) error { return errors.Wrap(err, "failed to mkdir") } case tar.TypeReg: - name := filepath.Join(destDir, header.Name) + destFileName := filepath.Join(destDir, header.Name) - dirName := filepath.Dir(name) + dirName := filepath.Dir(destFileName) if err := os.MkdirAll(dirName, 0755); err != nil { return errors.Wrapf(err, "failed to mkdir for file %s", header.Name) } - file, err := os.OpenFile(name, os.O_RDWR|os.O_CREATE, os.FileMode(header.Mode)) + file, err := os.OpenFile(destFileName, os.O_RDWR|os.O_CREATE, os.FileMode(header.Mode)) if err != nil { return errors.Wrap(err, "failed to open tar file") } @@ -175,6 +190,21 @@ func ExtractTroubleshootBundle(reader io.Reader, destDir string) error { if err != nil { return errors.Wrap(err, "failed to extract file") } + case tar.TypeSymlink: + destFileName := filepath.Join(destDir, header.Name) + + dirName := filepath.Dir(destFileName) + if err := os.MkdirAll(dirName, 0755); err != nil { + return errors.Wrapf(err, "failed to mkdir for symlink %s", header.Name) + } + + // Symlink targets should be absolute paths after extraction + // for other parts of the code to work correctly e.g redaction, CollectorResult + targetPath := filepath.Join(filepath.Dir(destFileName), header.Linkname) + err = os.Symlink(targetPath, destFileName) + if err != nil { + return errors.Wrap(err, "failed to create symlink") + } } } @@ -251,7 +281,7 @@ func FindBundleRootDir(localBundlePath string) (string, error) { isInSubDir := true for _, name := range names { - if name == "version.yaml" { + if name == constants.VersionFilename { isInSubDir = false break } @@ -265,7 +295,7 @@ func FindBundleRootDir(localBundlePath string) (string, error) { } func (f fileContentProvider) getFileContents(fileName string) ([]byte, error) { - return ioutil.ReadFile(filepath.Join(f.rootDir, fileName)) + return os.ReadFile(filepath.Join(f.rootDir, fileName)) } func excludeFilePaths(files, excludeFiles []string) []string { @@ -306,7 +336,7 @@ func (f fileContentProvider) getChildFileContents(dirName string, excludeFiles [ fileArr := map[string][]byte{} for _, filePath := range files { - bytes, err := ioutil.ReadFile(filePath) + bytes, err := os.ReadFile(filePath) if err != nil { return nil, errors.Wrapf(err, "read %q", filePath) } diff --git a/pkg/analyze/download_test.go b/pkg/analyze/download_test.go new file mode 100644 index 00000000..2b76d636 --- /dev/null +++ b/pkg/analyze/download_test.go @@ -0,0 +1,49 @@ +package analyzer + +import ( + "os" + "path/filepath" + "testing" + + "github.com/replicatedhq/troubleshoot/internal/testutils" + "github.com/stretchr/testify/assert" +) + +func TestDownloadAndExtractSupportBundle(t *testing.T) { + // TODO: Add tests for web url downloads + tests := []struct { + name string + bundleURL string + wantErr bool + }{ + { + name: "extract a bundle from a local file path", + bundleURL: filepath.Join(testutils.FileDir(), "../../testdata/supportbundle/support-bundle.tar.gz"), + wantErr: false, + }, + { + name: "extract a bundle from a non-existent file path", + bundleURL: "/home/someone/gibberish", + wantErr: true, + }, + { + name: "extract an invalid support bundle which has no version file", + bundleURL: filepath.Join(testutils.FileDir(), "../../testdata/supportbundle/missing-version.tar.gz"), + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tmpDir, bundleDir, err := DownloadAndExtractSupportBundle(tt.bundleURL) + defer os.RemoveAll(tmpDir) // clean up. Ignore error + + if err == nil { + assert.DirExists(t, bundleDir) + assert.FileExists(t, filepath.Join(bundleDir, "version.yaml")) + } else { + assert.Equal(t, "", tmpDir) + assert.Equal(t, "", bundleDir) + } + }) + } +} diff --git a/pkg/collect/postgres_test.go b/pkg/collect/postgres_test.go index d2ddb3e1..476666f0 100644 --- a/pkg/collect/postgres_test.go +++ b/pkg/collect/postgres_test.go @@ -4,6 +4,7 @@ import ( "context" "testing" + "github.com/replicatedhq/troubleshoot/internal/testutils" "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -101,9 +102,9 @@ func TestCollectPostgres_createConnectConfigTLS(t *testing.T) { Collector: &v1beta2.Database{ URI: "postgresql://user:password@my-pghost:5432/defaultdb?sslmode=require", TLS: &v1beta2.TLSParams{ - CACert: getTestFixture(t, "db/ca.pem"), - ClientCert: getTestFixture(t, "db/client.pem"), - ClientKey: getTestFixture(t, "db/client-key.pem"), + CACert: testutils.GetTestFixture(t, "db/ca.pem"), + ClientCert: testutils.GetTestFixture(t, "db/client.pem"), + ClientKey: testutils.GetTestFixture(t, "db/client-key.pem"), }, }, } diff --git a/pkg/collect/redact.go b/pkg/collect/redact.go index 376d94e4..aa6b027e 100644 --- a/pkg/collect/redact.go +++ b/pkg/collect/redact.go @@ -13,6 +13,7 @@ import ( "github.com/pkg/errors" troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2" "github.com/replicatedhq/troubleshoot/pkg/redact" + "k8s.io/klog/v2" ) func RedactResult(bundlePath string, input CollectorResult, additionalRedactors []*troubleshootv1beta2.Redact) error { @@ -32,11 +33,25 @@ func RedactResult(bundlePath string, input CollectorResult, additionalRedactors } // Redact the target file of a symlink + // There is an opportunity for improving performance here by skipping symlinks + // if a target has been redacted already, but that would require + // some extra logic to ensure that a spec filtering only symlinks still works. if info.Mode().Type() == os.ModeSymlink { - file, err = os.Readlink(filepath.Join(bundlePath, file)) + symlink := file + target, err := os.Readlink(filepath.Join(bundlePath, symlink)) if err != nil { return errors.Wrap(err, "failed to read symlink") } + + // Get the relative path to the target file to conform with + // the path formats of the CollectorResult + file, err = filepath.Rel(bundlePath, target) + if err != nil { + return errors.Wrap(err, "failed to get relative path") + } + klog.V(4).Infof("Redacting %s (symlink => %s)\n", file, symlink) + } else { + klog.V(4).Infof("Redacting %s\n", file) } r, err := input.GetReader(bundlePath, file) if err != nil { @@ -53,8 +68,8 @@ func RedactResult(bundlePath string, input CollectorResult, additionalRedactors reader = bytes.NewBuffer(v) } - //If the file is .tar, .tgz or .tar.gz, it must not be redacted. Instead it is decompressed and each file inside the - //tar is decompressed, redacted and compressed back into the tar. + // If the file is .tar, .tgz or .tar.gz, it must not be redacted. Instead it is + // decompressed and each file inside the tar redacted and compressed back into the archive. if filepath.Ext(file) == ".tar" || filepath.Ext(file) == ".tgz" || strings.HasSuffix(file, ".tar.gz") { tmpDir, err := ioutil.TempDir("", "troubleshoot-subresult-") if err != nil { diff --git a/pkg/collect/redis_test.go b/pkg/collect/redis_test.go index debee832..e3a1c3e9 100644 --- a/pkg/collect/redis_test.go +++ b/pkg/collect/redis_test.go @@ -3,6 +3,7 @@ package collect import ( "testing" + "github.com/replicatedhq/troubleshoot/internal/testutils" v1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -90,9 +91,9 @@ func TestCollectRedis_createTLSClient(t *testing.T) { Collector: &v1beta2.Database{ URI: "redis://localhost:6379", TLS: &v1beta2.TLSParams{ - CACert: getTestFixture(t, "db/ca.pem"), - ClientCert: getTestFixture(t, "db/client.pem"), - ClientKey: getTestFixture(t, "db/client-key.pem"), + CACert: testutils.GetTestFixture(t, "db/ca.pem"), + ClientCert: testutils.GetTestFixture(t, "db/client.pem"), + ClientKey: testutils.GetTestFixture(t, "db/client-key.pem"), }, }, } diff --git a/pkg/collect/result.go b/pkg/collect/result.go index 3ee3f61f..d21c2007 100644 --- a/pkg/collect/result.go +++ b/pkg/collect/result.go @@ -65,7 +65,7 @@ func (r CollectorResult) SymLinkResult(bundlePath, relativeLinkPath, relativeFil // Create the symlink // NOTE: When creating an archive, relative paths are used // to make the bundle more portable. That implementation - // lives in TarSupportBundleDir function. This path needs to + // lives in CollectorResultFromBundle function. This path needs to // remain as-is to support memory only bundles e.g preflight err = os.Symlink(filePath, linkPath) if err != nil { @@ -222,7 +222,7 @@ func (r CollectorResult) CloseWriter(bundlePath string, relativePath string, wri return errors.Errorf("cannot close writer of type %T", writer) } -func TarSupportBundleDir(bundlePath string, input CollectorResult, outputFilename string) error { +func (r CollectorResult) ArchiveSupportBundle(bundlePath string, outputFilename string) error { fileWriter, err := os.Create(outputFilename) if err != nil { return errors.Wrap(err, "failed to create output file") @@ -235,7 +235,7 @@ func TarSupportBundleDir(bundlePath string, input CollectorResult, outputFilenam tarWriter := tar.NewWriter(gzipWriter) defer tarWriter.Close() - for relativeName := range input { + for relativeName := range r { filename := filepath.Join(bundlePath, relativeName) info, err := os.Lstat(filename) if err != nil { @@ -315,3 +315,44 @@ func TarSupportBundleDir(bundlePath string, input CollectorResult, outputFilenam return nil } + +// CollectorResultFromBundle creates a CollectorResult from a bundle directory +// The bundle directory is not necessarily a support bundle, it can be any directory +// of collected files as part of other operations or files that are already on disk. +func CollectorResultFromBundle(bundleDir string) (CollectorResult, error) { + // Check directory exists + if _, err := os.Stat(bundleDir); os.IsNotExist(err) { + return nil, errors.Wrap(err, "bundle directory does not exist") + } + + // Walk the directory and add all files to the collector result + result := make(CollectorResult) + err := filepath.Walk(bundleDir, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + if info.IsDir() { + return nil + } + + rel, err := filepath.Rel(bundleDir, path) + if err != nil { + return err + } + + result[rel] = nil + return nil + }) + if err != nil { + return nil, errors.Wrap(err, "failed to walk bundle directory") + } + + return result, nil +} + +// TarSupportBundleDir wraps ArchiveSupportBundle for backwards compatibility +// Deprecated: Remove in a future version (v1.0) +func TarSupportBundleDir(bundlePath string, input CollectorResult, outputFilename string) error { + // Is this used anywhere external anyway? + return input.ArchiveSupportBundle(bundlePath, outputFilename) +} diff --git a/pkg/collect/result_test.go b/pkg/collect/result_test.go index d3cdb63a..b06f7026 100644 --- a/pkg/collect/result_test.go +++ b/pkg/collect/result_test.go @@ -1,8 +1,10 @@ package collect import ( + "path/filepath" "testing" + "github.com/replicatedhq/troubleshoot/internal/testutils" "github.com/stretchr/testify/assert" ) @@ -16,3 +18,36 @@ func TestCollectorResult_AddResult(t *testing.T) { assert.Equal(t, []byte("a"), r["a"]) assert.Equal(t, []byte("b"), r["b"]) } + +func TestCollectorResultFromBundle(t *testing.T) { + tests := []struct { + name string + bundleDir string + want CollectorResult + wantErr bool + }{ + { + name: "creates collector results from a bundle successfully", + bundleDir: filepath.Join(testutils.FileDir(), "../../testdata/supportbundle/extracted-sb"), + want: CollectorResult{ + "cluster-resources/pods/logs/default/static-hi/static-hi.log": nil, + "static-hi.log": nil, + }, + wantErr: false, + }, + { + name: "fails to create collector results from a missing directory", + bundleDir: "gibberish", + want: nil, + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := CollectorResultFromBundle(tt.bundleDir) + assert.Equal(t, tt.want, got) + assert.Equal(t, (err != nil), tt.wantErr) + }) + } +} diff --git a/pkg/collect/util_test.go b/pkg/collect/util_test.go index 80783193..beffbdef 100644 --- a/pkg/collect/util_test.go +++ b/pkg/collect/util_test.go @@ -3,10 +3,9 @@ package collect import ( "context" "math/rand" - "os" - "path/filepath" "testing" + "github.com/replicatedhq/troubleshoot/internal/testutils" "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2" troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2" "github.com/stretchr/testify/assert" @@ -130,18 +129,18 @@ func Test_createTLSConfig(t *testing.T) { { name: "complete tls params creates config successfully", tlsParams: v1beta2.TLSParams{ - CACert: getTestFixture(t, "db/ca.pem"), - ClientCert: getTestFixture(t, "db/client.pem"), - ClientKey: getTestFixture(t, "db/client-key.pem"), + CACert: testutils.GetTestFixture(t, "db/ca.pem"), + ClientCert: testutils.GetTestFixture(t, "db/client.pem"), + ClientKey: testutils.GetTestFixture(t, "db/client-key.pem"), }, }, { name: "complete tls params in secret creates config successfully", tlsParams: v1beta2.TLSParams{ Secret: createTLSSecret(t, k8sClient, map[string]string{ - "cacert": getTestFixture(t, "db/ca.pem"), - "clientCert": getTestFixture(t, "db/client.pem"), - "clientKey": getTestFixture(t, "db/client-key.pem"), + "cacert": testutils.GetTestFixture(t, "db/ca.pem"), + "clientCert": testutils.GetTestFixture(t, "db/client.pem"), + "clientKey": testutils.GetTestFixture(t, "db/client-key.pem"), }), }, }, @@ -155,7 +154,7 @@ func Test_createTLSConfig(t *testing.T) { name: "tls params with CA cert only in secret creates config successfully", tlsParams: v1beta2.TLSParams{ Secret: createTLSSecret(t, k8sClient, map[string]string{ - "cacert": getTestFixture(t, "db/ca.pem"), + "cacert": testutils.GetTestFixture(t, "db/ca.pem"), }), }, caCertOnly: true, @@ -163,7 +162,7 @@ func Test_createTLSConfig(t *testing.T) { { name: "tls params with CA cert only creates config successfully", tlsParams: v1beta2.TLSParams{ - CACert: getTestFixture(t, "db/ca.pem"), + CACert: testutils.GetTestFixture(t, "db/ca.pem"), }, caCertOnly: true, }, @@ -174,24 +173,24 @@ func Test_createTLSConfig(t *testing.T) { { name: "missing CA cert fails to create config with error", tlsParams: v1beta2.TLSParams{ - ClientCert: getTestFixture(t, "db/client.pem"), - ClientKey: getTestFixture(t, "db/client-key.pem"), + ClientCert: testutils.GetTestFixture(t, "db/client.pem"), + ClientKey: testutils.GetTestFixture(t, "db/client-key.pem"), }, hasError: true, }, { name: "missing client cert fails to create config with error", tlsParams: v1beta2.TLSParams{ - CACert: getTestFixture(t, "db/ca.pem"), - ClientKey: getTestFixture(t, "db/client-key.pem"), + CACert: testutils.GetTestFixture(t, "db/ca.pem"), + ClientKey: testutils.GetTestFixture(t, "db/client-key.pem"), }, hasError: true, }, { name: "missing client key fails to create config with error", tlsParams: v1beta2.TLSParams{ - CACert: getTestFixture(t, "db/ca.pem"), - ClientCert: getTestFixture(t, "db/client.pem"), + CACert: testutils.GetTestFixture(t, "db/ca.pem"), + ClientCert: testutils.GetTestFixture(t, "db/client.pem"), }, hasError: true, }, @@ -199,8 +198,8 @@ func Test_createTLSConfig(t *testing.T) { name: "missing CA cert in secret fails to create config with error", tlsParams: v1beta2.TLSParams{ Secret: createTLSSecret(t, k8sClient, map[string]string{ - "clientCert": getTestFixture(t, "db/client.pem"), - "clientKey": getTestFixture(t, "db/client-key.pem"), + "clientCert": testutils.GetTestFixture(t, "db/client.pem"), + "clientKey": testutils.GetTestFixture(t, "db/client-key.pem"), }), }, hasError: true, @@ -209,8 +208,8 @@ func Test_createTLSConfig(t *testing.T) { name: "missing client cert in secret fails to create config with error", tlsParams: v1beta2.TLSParams{ Secret: createTLSSecret(t, k8sClient, map[string]string{ - "cacert": getTestFixture(t, "db/ca.pem"), - "clientKey": getTestFixture(t, "db/client-key.pem"), + "cacert": testutils.GetTestFixture(t, "db/ca.pem"), + "clientKey": testutils.GetTestFixture(t, "db/client-key.pem"), }), }, hasError: true, @@ -219,8 +218,8 @@ func Test_createTLSConfig(t *testing.T) { name: "missing client key in secret fails to create config with error", tlsParams: v1beta2.TLSParams{ Secret: createTLSSecret(t, k8sClient, map[string]string{ - "cacert": getTestFixture(t, "db/ca.pem"), - "clientCert": getTestFixture(t, "db/client.pem"), + "cacert": testutils.GetTestFixture(t, "db/ca.pem"), + "clientCert": testutils.GetTestFixture(t, "db/client.pem"), }), }, hasError: true, @@ -287,11 +286,3 @@ func createTLSSecret(t *testing.T, client kubernetes.Interface, secretData map[s Name: secretName, } } - -func getTestFixture(t *testing.T, path string) string { - t.Helper() - p := filepath.Join("../../testdata", path) - b, err := os.ReadFile(p) - require.NoError(t, err) - return string(b) -} diff --git a/pkg/constants/constants.go b/pkg/constants/constants.go index 4f140761..9a991465 100644 --- a/pkg/constants/constants.go +++ b/pkg/constants/constants.go @@ -7,4 +7,6 @@ const ( DEFAULT_CLIENT_BURST = 100 // DEFAULT_CLIENT_USER_AGENT is an field that specifies the caller of troubleshoot request. DEFAULT_CLIENT_USER_AGENT = "ReplicatedTroubleshoot" + // VersionFilename is the name of the file that contains the support bundle version. + VersionFilename = "version.yaml" ) diff --git a/pkg/supportbundle/collect.go b/pkg/supportbundle/collect.go index fc490e90..cb81b453 100644 --- a/pkg/supportbundle/collect.go +++ b/pkg/supportbundle/collect.go @@ -185,8 +185,6 @@ func findFileName(basename, extension string) (string, error) { } } -const VersionFilename = "version.yaml" - func getVersionFile() (io.Reader, error) { version := troubleshootv1beta2.SupportBundleVersion{ ApiVersion: "troubleshoot.sh/v1beta2", diff --git a/pkg/supportbundle/load.go b/pkg/supportbundle/load.go index e773d5b2..65988f73 100644 --- a/pkg/supportbundle/load.go +++ b/pkg/supportbundle/load.go @@ -105,24 +105,15 @@ func ParseSupportBundleFromDoc(doc []byte) (*troubleshootv1beta2.SupportBundle, } func GetRedactorFromURI(redactorURI string) (*troubleshootv1beta2.Redactor, error) { - decode := scheme.Codecs.UniversalDeserializer().Decode - redactorContent, err := LoadRedactorSpec(redactorURI) if err != nil { return nil, errors.Wrapf(err, "failed to load redactor spec %s", redactorURI) } - redactorContent, err = docrewrite.ConvertToV1Beta2(redactorContent) + redactor, ok, err := toRedactGVK([]byte(redactorContent)) if err != nil { - return nil, errors.Wrap(err, "failed to convert to v1beta2") + return nil, errors.Wrapf(err, "failed to parse redactor from doc") } - - obj, _, err := decode([]byte(redactorContent), nil, nil) - if err != nil { - return nil, errors.Wrapf(err, "failed to parse redactors %s", redactorURI) - } - - redactor, ok := obj.(*troubleshootv1beta2.Redactor) if !ok { return nil, fmt.Errorf("%s is not a troubleshootv1beta2 redactor type", redactorURI) } @@ -130,6 +121,22 @@ func GetRedactorFromURI(redactorURI string) (*troubleshootv1beta2.Redactor, erro return redactor, nil } +func GetRedactorsFromURIs(redactorURIs []string) ([]*troubleshootv1beta2.Redact, error) { + redactors := []*troubleshootv1beta2.Redact{} + for _, redactor := range redactorURIs { + redactorObj, err := GetRedactorFromURI(redactor) + if err != nil { + return nil, err + } + + if redactorObj != nil { + redactors = append(redactors, redactorObj.Spec.Redactors...) + } + } + + return redactors, nil +} + func LoadSupportBundleSpec(arg string) ([]byte, error) { if strings.HasPrefix(arg, "secret/") { // format secret/namespace-name/secret-name @@ -251,25 +258,32 @@ func loadSpecFromURL(arg string) ([]byte, error) { func ParseRedactorsFromDocs(docs []string) ([]*troubleshootv1beta2.Redact, error) { var redactors []*troubleshootv1beta2.Redact - decode := scheme.Codecs.UniversalDeserializer().Decode - for i, doc := range docs { - doc, err := docrewrite.ConvertToV1Beta2([]byte(doc)) - if err != nil { - return nil, errors.Wrap(err, "failed to convert to v1beta2") - } - - obj, _, err := decode(doc, nil, nil) + multidocRedactors, ok, err := toRedactGVK([]byte(doc)) if err != nil { return nil, errors.Wrapf(err, "failed to parse redactor from doc %d", i) } - - multidocRedactors, ok := obj.(*troubleshootv1beta2.Redactor) if !ok { continue } + redactors = append(redactors, multidocRedactors.Spec.Redactors...) } return redactors, nil } + +func toRedactGVK(doc []byte) (*troubleshootv1beta2.Redactor, bool, error) { + doc, err := docrewrite.ConvertToV1Beta2(doc) + if err != nil { + return nil, false, errors.Wrap(err, "failed to convert to v1beta2") + } + + obj, _, err := scheme.Codecs.UniversalDeserializer().Decode([]byte(doc), nil, nil) + if err != nil { + return nil, false, err + } + + multidocRedactors, ok := obj.(*troubleshootv1beta2.Redactor) + return multidocRedactors, ok, nil +} diff --git a/pkg/supportbundle/supportbundle.go b/pkg/supportbundle/supportbundle.go index aca3b380..8061fe40 100644 --- a/pkg/supportbundle/supportbundle.go +++ b/pkg/supportbundle/supportbundle.go @@ -14,6 +14,7 @@ import ( analyzer "github.com/replicatedhq/troubleshoot/pkg/analyze" troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2" "github.com/replicatedhq/troubleshoot/pkg/collect" + "github.com/replicatedhq/troubleshoot/pkg/constants" "github.com/replicatedhq/troubleshoot/pkg/convert" "k8s.io/client-go/rest" "k8s.io/klog/v2" @@ -127,7 +128,7 @@ func CollectSupportBundleFromSpec(spec *troubleshootv1beta2.SupportBundleSpec, a return nil, errors.Wrap(err, "failed to get version file") } - err = result.SaveResult(bundlePath, VersionFilename, version) + err = result.SaveResult(bundlePath, constants.VersionFilename, version) if err != nil { return nil, errors.Wrap(err, "failed to write version") } @@ -155,7 +156,7 @@ func CollectSupportBundleFromSpec(spec *troubleshootv1beta2.SupportBundleSpec, a return nil, errors.Wrap(err, "failed to write analysis") } - if err := collect.TarSupportBundleDir(bundlePath, result, filename); err != nil { + if err := result.ArchiveSupportBundle(bundlePath, filename); err != nil { return nil, errors.Wrap(err, "create bundle file") } @@ -188,17 +189,12 @@ func CollectSupportBundleFromURI(specURI string, redactorURIs []string, opts Sup return nil, errors.Wrap(err, "could not bundle from URI") } - additionalRedactors := &troubleshootv1beta2.Redactor{} - for _, redactor := range redactorURIs { - redactorObj, err := GetRedactorFromURI(redactor) - if err != nil { - return nil, errors.Wrapf(err, "failed to get redactor spec %s", redactor) - } - - if redactorObj != nil { - additionalRedactors.Spec.Redactors = append(additionalRedactors.Spec.Redactors, redactorObj.Spec.Redactors...) - } + redactors, err := GetRedactorsFromURIs(redactorURIs) + if err != nil { + return nil, err } + additionalRedactors := &troubleshootv1beta2.Redactor{} + additionalRedactors.Spec.Redactors = redactors return CollectSupportBundleFromSpec(&supportBundle.Spec, additionalRedactors, opts) } diff --git a/test/validate-support-bundle-e2e.sh b/test/validate-support-bundle-e2e.sh index f1a7941c..7c9300af 100755 --- a/test/validate-support-bundle-e2e.sh +++ b/test/validate-support-bundle-e2e.sh @@ -6,23 +6,23 @@ tmpdir="$(mktemp -d)" bundle_archive_name="support-bundle.tar.gz" bundle_directory_name="support-bundle" +echo "====== Generating support bundle from k8s cluster ======" ./bin/support-bundle --debug --interactive=false examples/support-bundle/e2e.yaml --output=$tmpdir/$bundle_archive_name if [ $? -ne 0 ]; then echo "support-bundle command failed" - exit $EXIT_STATUS + exit $? fi -EXIT_STATUS=0 if ! tar -xvzf $tmpdir/$bundle_archive_name --directory $tmpdir; then -echo "A valid support bundle archive was not generated" -EXIT_STATUS=1 + echo "A valid support bundle archive was not generated" + exit 1 fi echo "$(cat $tmpdir/$bundle_directory_name/analysis.json)" if grep -q "No matching files" "$tmpdir/$bundle_directory_name/analysis.json"; then -echo "Some files were not collected" -EXIT_STATUS=1 + echo "Some files were not collected" + exit 1 fi EXIT_STATUS=0 @@ -37,7 +37,29 @@ jq -r '.[].insight.severity' "$tmpdir/$bundle_directory_name/analysis.json" | wh echo "Analyzers with severity of \"warn\" found" fi done +if [ $EXIT_STATUS -ne 0 ]; then + echo "support-bundle command failed" + exit $EXIT_STATUS +fi -rm -rf "$tmpdir" +echo "======= Redact an existing support bundle ======" +redact_tmpdir="$(mktemp -d)" +redacted_archive_name="$redact_tmpdir/redacted-support-bundle.tar.gz" +./bin/support-bundle redact examples/redact/e2e.yaml --bundle=$tmpdir/$bundle_archive_name --output=$redacted_archive_name +if [ $? -ne 0 ]; then + echo "support-bundle redact command failed" + exit $? +fi -exit $EXIT_STATUS +if ! tar -xvzf $redacted_archive_name --directory $redact_tmpdir; then + echo "Failed to extract redacted support bundle archive" + exit 1 +fi + +if ! grep "\*\*\*HIDDEN\*\*\*" "$redact_tmpdir/$bundle_directory_name/static-hi.log"; then + echo "$(cat $redact_tmpdir/$bundle_directory_name/static-hi.log)" + echo "Hidden content not found in redacted static-hi.log file" + exit 1 +fi + +rm -rf "$tmpdir" "$redact_tmpdir" diff --git a/testdata/supportbundle/extracted-sb/cluster-resources/pods/logs/default/static-hi/static-hi.log b/testdata/supportbundle/extracted-sb/cluster-resources/pods/logs/default/static-hi/static-hi.log new file mode 100644 index 00000000..06459998 --- /dev/null +++ b/testdata/supportbundle/extracted-sb/cluster-resources/pods/logs/default/static-hi/static-hi.log @@ -0,0 +1,2 @@ +hi static! + diff --git a/testdata/supportbundle/extracted-sb/static-hi.log b/testdata/supportbundle/extracted-sb/static-hi.log new file mode 120000 index 00000000..062624ba --- /dev/null +++ b/testdata/supportbundle/extracted-sb/static-hi.log @@ -0,0 +1 @@ +cluster-resources/pods/logs/default/static-hi/static-hi.log \ No newline at end of file diff --git a/testdata/supportbundle/missing-version.tar.gz b/testdata/supportbundle/missing-version.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..5653b38aed4b04978761f6d731f72af9dab222bc GIT binary patch literal 1238 zcmV;{1S$I;iwFSjNuy%`1MQmMZ`(Ey$NSvB;^vpV%#0E{aZz9xwrm)NVnva(1BPWV zXo9S$}`%V<~!?G+Vwq$px`4GhxdB^+kzC4DAPU2W9Gn^$Nh}hYSKAPuw zlgmr6&#Ua|U5vA*Yj8duU3ypJ@nn1j9)1{IzJSYKW>ag4HdNtM*aH>1r5|>i&s*NR zIEv^0r0Lc5r-DY0nrrfhmZB>k$OBh))B0a{=aZ3J|IygB8rpW_SnoBYGs_Y)o8H+RyC{5V!1E$l_ z@1*7?9fB6mE8}b*?o088J*MwUCsRMdC1Gm1?yMN}LGg4@XiThMpPd;clUc-cD5W7f zJmX8cU^>g?znL1QL-biC4*jtB=Hu7rS9b}f-&Kge4GJg!R)XU~^F?UZqkA5tHc&f* zI0%dy5bHBmXj0k9-nj7LO<@jxX%0VNhVm#K^s7u1xY%IHn9*QD28#J|xnv?hb5sP7 zqXief205?zA$13uVMlK4yaF~$7R^h#-mUU7hjbe=Kkbm2aKjrk;$skUNfgrV>IQqj_09M2k!ldqz+7UL2QIAOoCI5i#FUb1yO6SOZ9=NN%Q`=A ziraK31;#C~r%Ht3_+`J!%iT@a-R+q~x#gj=>~iO#1D&-nYU8vAheNWc@vyF|I?9c~ zO>^|6a=rz3CdS%R%mLgSY@XU2{S@j?as0qdLLo!qM^tO3`%Qo6Y-*i#mio@>&|1y6 z%!^{FFZMm5ZAR3FX-5o)LQ%tE-8P-ioJH6W{A$@)a$m{&S9*06Zpd6LR`=XV_h0R(tX-(J zk=vEb!RXWoS-%yr{fxmv$^)nY%L7JWdDM$f7xACQhM2U()7mdCLNKYo{9>lJih1D#TxZzapMjf&1y z5J-F4d#d^4-Fb90{Vlr26ELox#_Avh^9?bQ^nEAdTy`c`XK$EpZAwNFmNob1zgMK; zXh+Fz!_$W7*$57bp@zcxuBh>+%o@1Bhei(DZbH&J<0gRRQ+#RiPxv@$@!L45ExMpF z$NiU@q~{xwfW?t~Try#%Ywq^Thtl#evz%|vlOi1^JF21)P8*;-02~rR4TN=F(FBGK zw~b-13ZZlgcj=(J!6$SVvUPG>grO-9NXSXQvM}r~Gj%a_rij$&(0!NY!H(JAK%kAn zZc+9XX)Rjorjp{f7#oEAi_HnXsYj2O+An`U_P;)y+Nqt|seRV%KfHL^5dbOx0Ht+q AdH?_b literal 0 HcmV?d00001 diff --git a/testdata/supportbundle/support-bundle.tar.gz b/testdata/supportbundle/support-bundle.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..30e2706a1c0a4ed8e4aa4bb0b3367f3122667cf3 GIT binary patch literal 110657 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 literal 0 HcmV?d00001