Skip to content

Commit

Permalink
feat: make load-cluster-specs the default (#1602)
Browse files Browse the repository at this point in the history
* make load-cluster-specs the default
  • Loading branch information
diamonwiggins authored Aug 26, 2024
1 parent 3aaffb4 commit e685cb9
Show file tree
Hide file tree
Showing 10 changed files with 116 additions and 30 deletions.
16 changes: 12 additions & 4 deletions cmd/troubleshoot/cli/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,17 @@ func RootCmd() *cobra.Command {
cmd := &cobra.Command{
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
from a server that can be used to assist when troubleshooting a Kubernetes cluster.`,
Short: "Generate a support bundle from a Kubernetes cluster or specified sources",
Long: `Generate a support bundle, an archive containing files, output, metrics, and cluster state to aid in troubleshooting Kubernetes clusters.
If no arguments are provided, specs are automatically loaded from the cluster by default.
**Argument Types**:
1. **Secret**: Load specs from a Kubernetes Secret. Format: "secret/namespace-name/secret-name[/data-key]"
2. **ConfigMap**: Load specs from a Kubernetes ConfigMap. Format: "configmap/namespace-name/configmap-name[/data-key]"
3. **File**: Load specs from a local file. Format: Local file path
4. **Standard Input**: Read specs from stdin. Format: "-"
5. **URL**: Load specs from a URL. Supports HTTP and OCI registry URLs.`,
SilenceUsage: true,
PersistentPreRun: func(cmd *cobra.Command, args []string) {
v := viper.GetViper()
Expand Down Expand Up @@ -69,7 +77,7 @@ from a server that can be used to assist when troubleshooting a Kubernetes clust
cmd.Flags().Bool("interactive", true, "enable/disable interactive mode")
cmd.Flags().Bool("collect-without-permissions", true, "always generate a support bundle, even if it some require additional permissions")
cmd.Flags().StringSliceP("selector", "l", []string{"troubleshoot.sh/kind=support-bundle"}, "selector to filter on for loading additional support bundle specs found in secrets within the cluster")
cmd.Flags().Bool("load-cluster-specs", false, "enable/disable loading additional troubleshoot specs found within the cluster. required when no specs are provided on the command line")
cmd.Flags().Bool("load-cluster-specs", false, "enable/disable loading additional troubleshoot specs found within the cluster. This is the default behavior if no spec is provided as an argument")
cmd.Flags().String("since-time", "", "force pod logs collectors to return logs after a specific date (RFC3339)")
cmd.Flags().String("since", "", "force pod logs collectors to return logs newer than a relative duration like 5s, 2m, or 3h.")
cmd.Flags().StringP("output", "o", "", "specify the output file path for the support bundle")
Expand Down
28 changes: 19 additions & 9 deletions cmd/troubleshoot/cli/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,6 @@ import (

func runTroubleshoot(v *viper.Viper, args []string) error {
ctx := context.Background()
if !v.GetBool("load-cluster-specs") && len(args) < 1 {
return errors.New("flag load-cluster-specs must be set if no specs are provided on the command line")
}

restConfig, err := k8sutil.GetRESTConfig()
if err != nil {
Expand Down Expand Up @@ -285,11 +282,24 @@ func loadSupportBundleSpecsFromURIs(ctx context.Context, kinds *loader.Troublesh
}

func loadSpecs(ctx context.Context, args []string, client kubernetes.Interface) (*troubleshootv1beta2.SupportBundle, *troubleshootv1beta2.Redactor, error) {
// Append redactor uris to the args
allArgs := append(args, viper.GetStringSlice("redactors")...)
kinds, err := specs.LoadFromCLIArgs(ctx, client, allArgs, viper.GetViper())
if err != nil {
return nil, nil, err
var (
kinds = loader.NewTroubleshootKinds()
vp = viper.GetViper()
allArgs = append(args, vp.GetStringSlice("redactors")...)
err error
)

if len(args) < 1 {
fmt.Println("\r\033[36mNo specs provided, attempting to load from cluster...\033[m")
kinds, err = specs.LoadFromCluster(ctx, client, vp.GetStringSlice("selector"), vp.GetString("namespace"))
if err != nil {
return nil, nil, errors.Wrap(err, "failed to load specs from cluster, and no specs were provided as arguments")
}
} else {
kinds, err = specs.LoadFromCLIArgs(ctx, client, allArgs, vp)
if err != nil {
return nil, nil, errors.Wrap(err, "failed to load specs from CLI args")
}
}

// Load additional specs from support bundle URIs
Expand All @@ -306,7 +316,7 @@ func loadSpecs(ctx context.Context, args []string, client kubernetes.Interface)
if len(kinds.CollectorsV1Beta2) == 0 &&
len(kinds.HostCollectorsV1Beta2) == 0 &&
len(kinds.SupportBundlesV1Beta2) == 0 {
return nil, nil, errors.New("no collectors specified to run")
return nil, nil, types.NewExitCodeError(constants.EXIT_CODE_CATCH_ALL, errors.Wrap(err, "no collectors specified to run. Use --debug and/or -v=2 to see more information"))
}

// Merge specs
Expand Down
3 changes: 2 additions & 1 deletion docs/preflight.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ preflight [url] [flags]
--kubeconfig string Path to the kubeconfig file to use for CLI requests.
--memprofile string File path to write memory profiling data
-n, --namespace string If present, the namespace scope for this CLI request
--no-uri When this flag is used, Preflight does not attempt to retrieve the spec referenced by the uri: field`
-o, --output string specify the output file path for the preflight checks
--request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0")
--selector string selector (label query) to filter remote collection nodes on.
Expand All @@ -54,4 +55,4 @@ preflight [url] [flags]
* [preflight oci-fetch](preflight_oci-fetch.md) - Fetch a preflight from an OCI registry and print it to standard out
* [preflight version](preflight_version.md) - Print the current version and exit

###### Auto generated by spf13/cobra on 25-Jan-2024
###### Auto generated by spf13/cobra on 23-Aug-2024
2 changes: 1 addition & 1 deletion docs/preflight_oci-fetch.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,4 @@ preflight oci-fetch [URI] [flags]

* [preflight](preflight.md) - Run and retrieve preflight checks in a cluster

###### Auto generated by spf13/cobra on 25-Jan-2024
###### Auto generated by spf13/cobra on 23-Aug-2024
2 changes: 1 addition & 1 deletion docs/preflight_version.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,4 @@ preflight version [flags]

* [preflight](preflight.md) - Run and retrieve preflight checks in a cluster

###### Auto generated by spf13/cobra on 25-Jan-2024
###### Auto generated by spf13/cobra on 23-Aug-2024
18 changes: 13 additions & 5 deletions docs/support-bundle.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
## support-bundle

Generate a support bundle
Generate a support bundle from a Kubernetes cluster or specified sources

### Synopsis

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.
Generate a support bundle, an archive containing files, output, metrics, and cluster state to aid in troubleshooting Kubernetes clusters.

If no arguments are provided, specs are automatically loaded from the cluster by default.

**Argument Types**:
1. **Secret**: Load specs from a Kubernetes Secret. Format: "secret/namespace-name/secret-name[/data-key]"
2. **ConfigMap**: Load specs from a Kubernetes ConfigMap. Format: "configmap/namespace-name/configmap-name[/data-key]"
3. **File**: Load specs from a local file. Format: Local file path
4. **Standard Input**: Read specs from stdin. Format: "-"
5. **URL**: Load specs from a URL. Supports HTTP and OCI registry URLs.

```
support-bundle [urls...] [flags]
Expand All @@ -32,7 +40,7 @@ support-bundle [urls...] [flags]
--insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
--interactive enable/disable interactive mode (default true)
--kubeconfig string Path to the kubeconfig file to use for CLI requests.
--load-cluster-specs enable/disable loading additional troubleshoot specs found within the cluster. required when no specs are provided on the command line
--load-cluster-specs enable/disable loading additional troubleshoot specs found within the cluster. This is the default behavior if no spec is provided as an argument
--memprofile string File path to write memory profiling data
-n, --namespace string If present, the namespace scope for this CLI request
--no-uri When this flag is used, Troubleshoot does not attempt to retrieve the spec referenced by the uri: field`
Expand All @@ -56,4 +64,4 @@ support-bundle [urls...] [flags]
* [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 25-Jan-2024
###### Auto generated by spf13/cobra on 23-Aug-2024
4 changes: 2 additions & 2 deletions docs/support-bundle_analyze.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,6 @@ support-bundle analyze [url] [flags]

### SEE ALSO

* [support-bundle](support-bundle.md) - Generate a support bundle
* [support-bundle](support-bundle.md) - Generate a support bundle from a Kubernetes cluster or specified sources

###### Auto generated by spf13/cobra on 25-Jan-2024
###### Auto generated by spf13/cobra on 23-Aug-2024
6 changes: 3 additions & 3 deletions docs/support-bundle_redact.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ 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]
Expand All @@ -37,6 +37,6 @@ support-bundle redact [urls...] [flags]

### SEE ALSO

* [support-bundle](support-bundle.md) - Generate a support bundle
* [support-bundle](support-bundle.md) - Generate a support bundle from a Kubernetes cluster or specified sources

###### Auto generated by spf13/cobra on 25-Jan-2024
###### Auto generated by spf13/cobra on 23-Aug-2024
4 changes: 2 additions & 2 deletions docs/support-bundle_version.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,6 @@ support-bundle version [flags]

### SEE ALSO

* [support-bundle](support-bundle.md) - Generate a support bundle
* [support-bundle](support-bundle.md) - Generate a support bundle from a Kubernetes cluster or specified sources

###### Auto generated by spf13/cobra on 25-Jan-2024
###### Auto generated by spf13/cobra on 23-Aug-2024
63 changes: 61 additions & 2 deletions test/validate-support-bundle-e2e.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ bundle_directory_name="support-bundle"

echo "====== Generating support bundle from k8s cluster ======"
recreate_tmpdir
./bin/support-bundle --debug --interactive=false examples/support-bundle/e2e.yaml --output=$tmpdir/$bundle_archive_name
./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 $?
Expand Down Expand Up @@ -111,6 +114,57 @@ if ! grep "labelled-support-bundle-4 \*\*\*HIDDEN\*\*\*" "$tmpdir/$bundle_direct
echo "Hidden content not found in redacted echo-hi-4 file"
exit 1
fi
kubectl delete -f "$PRJ_ROOT/testdata/supportbundle/labelled-specs"

echo "======= Generating support bundle from k8s cluster using 0 arguments and a spec in the cluster ======"
recreate_tmpdir
kubectl apply -f "$PRJ_ROOT/testdata/supportbundle/labelled-specs"
./bin/support-bundle -v1 --interactive=false --output=$tmpdir/$bundle_archive_name
if [ $? -ne 0 ]; then
echo "support-bundle command failed"
exit $?
fi

if ! tar -xvzf $tmpdir/$bundle_archive_name --directory $tmpdir; then
echo "A valid support bundle archive was not generated"
exit 1
fi

if ! grep "labelled-support-bundle-1 \*\*\*HIDDEN\*\*\*" "$tmpdir/$bundle_directory_name/echo-hi-1"; then
echo "$(cat $tmpdir/$bundle_directory_name/echo-hi-1)"
echo "Hidden content not found in redacted echo-hi-1 file"
exit 1
fi

if ! grep "labelled-support-bundle-2 \*\*\*HIDDEN\*\*\*" "$tmpdir/$bundle_directory_name/echo-hi-2"; then
echo "$(cat $tmpdir/$bundle_directory_name/echo-hi-2)"
echo "Hidden content not found in redacted echo-hi-2 file"
exit 1
fi

if ! grep "labelled-support-bundle-3 \*\*\*HIDDEN\*\*\*" "$tmpdir/$bundle_directory_name/echo-hi-3"; then
echo "$(cat $tmpdir/$bundle_directory_name/echo-hi-3)"
echo "Hidden content not found in redacted echo-hi-3 file"
exit 1
fi

if ! grep "labelled-support-bundle-4 \*\*\*HIDDEN\*\*\*" "$tmpdir/$bundle_directory_name/echo-hi-4"; then
echo "$(cat $tmpdir/$bundle_directory_name/echo-hi-4)"
echo "Hidden content not found in redacted echo-hi-4 file"
exit 1
fi
kubectl delete -f "$PRJ_ROOT/testdata/supportbundle/labelled-specs"

echo "======= Generating support bundle from k8s cluster using 0 arguments and no spec in the cluster ======"
recreate_tmpdir
set +e
./bin/support-bundle -v1 --interactive=false --output="$tmpdir/$bundle_archive_name"
exit_code=$?
set -e
if [ $exit_code -eq 0 ]; then
echo "support-bundle command should have failed"
exit 1
fi

echo "======= Generating support bundle from k8s secret/<namespace-name>/<secret-name>/<data-key> ======"
recreate_tmpdir
Expand All @@ -133,11 +187,15 @@ if ! grep "custom-spec-key \*\*\*HIDDEN\*\*\*" "$tmpdir/$bundle_directory_name/e
echo "Hidden content not found in redacted echo-hi-3 file"
exit 1
fi
kubectl delete -f "$PRJ_ROOT/testdata/supportbundle/labelled-specs"

echo "======= Generating support bundle from k8s configmap/<namespace-name>/<configmap-name> ======"
recreate_tmpdir
kubectl apply -f "$PRJ_ROOT/testdata/supportbundle/labelled-specs"
./bin/support-bundle -v1 --interactive=false configmap/labelled-specs/labelled-support-bundle-2 --output=$tmpdir/$bundle_archive_name
./bin/support-bundle -v1 \
--interactive=false \
configmap/labelled-specs/labelled-support-bundle-2 \
--output=$tmpdir/$bundle_archive_name
if [ $? -ne 0 ]; then
echo "support-bundle command failed"
exit $?
Expand All @@ -153,3 +211,4 @@ if ! grep "labelled-support-bundle-2 REDACT" "$tmpdir/$bundle_directory_name/ech
echo "Hidden content not found in redacted echo-hi-2 file"
exit 1
fi
kubectl delete -f "$PRJ_ROOT/testdata/supportbundle/labelled-specs"

0 comments on commit e685cb9

Please sign in to comment.