Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package kubectl-gather for openSUSE:Factory 
checked in at 2026-10-15 12:21:41
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/kubectl-gather (Old)
 and      /work/SRC/openSUSE:Factory/.kubectl-gather.new.3698736 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "kubectl-gather"

Thu Oct 15 12:21:41 2026 rev:9 rq:1384909 version:0.15.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/kubectl-gather/kubectl-gather.changes    
2026-07-31 16:08:40.239274641 +0200
+++ 
/work/SRC/openSUSE:Factory/.kubectl-gather.new.3698736/kubectl-gather.changes   
    2026-10-15 12:21:44.090071200 +0200
@@ -1,0 +2,19 @@
+Thu Oct 15 04:55:58 UTC 2026 - Johannes Kastl 
<[email protected]>
+
+- Update to version 0.15.0:
+  * build: drop version from release asset name
+  * docs: document --insecure-secrets flag
+  * test: verify InsecureSecrets skips sanitization
+  * e2e: test --insecure-secrets disables sanitization
+  * gather: add --insecure-secrets flag
+  * go: Update go to 1.26.0 and toolchain to 1.27.2
+  * e2e: make commands.Run() more useful
+  * Use --output-dir in gather script
+  * cmd: make output directory flags mutually exclusive
+  * cmd: replace directory flag with output-dir
+  * README:Harden Linux/macOS install snippet in README
+  * go: Update toolchain to go1.26.5
+  * lint: Add golines formatter and make fmt target
+  * Add spell checking using codespell
+
+-------------------------------------------------------------------

Old:
----
  kubectl-gather-0.14.0.obscpio

New:
----
  kubectl-gather-0.15.0.obscpio

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ kubectl-gather.spec ++++++
--- /var/tmp/diff_new_pack.oTlxMN/_old  2026-10-15 12:21:45.151115598 +0200
+++ /var/tmp/diff_new_pack.oTlxMN/_new  2026-10-15 12:21:45.154115723 +0200
@@ -17,14 +17,14 @@
 
 
 Name:           kubectl-gather
-Version:        0.14.0
+Version:        0.15.0
 Release:        0
 Summary:        Kubectl plugin to gather data about your cluster
 License:        Apache-2.0
 URL:            https://github.com/nirs/kubectl-gather
 Source:         %{name}-%{version}.tar.gz
 Source1:        vendor.tar.gz
-BuildRequires:  golang(API) >= 1.25
+BuildRequires:  go1.27 >= 1.27.2
 
 %description
 This is a kubectl plugin for gathering data about your cluster that may help to

++++++ _service ++++++
--- /var/tmp/diff_new_pack.oTlxMN/_old  2026-10-15 12:21:45.194117397 +0200
+++ /var/tmp/diff_new_pack.oTlxMN/_new  2026-10-15 12:21:45.196117481 +0200
@@ -3,7 +3,7 @@
     <param name="url">https://github.com/nirs/kubectl-gather.git</param>
     <param name="scm">git</param>
     <param name="exclude">.git</param>
-    <param name="revision">refs/tags/v0.14.0</param>
+    <param name="revision">refs/tags/v0.15.0</param>
     <param name="versionformat">@PARENT_TAG@</param>
     <param name="versionrewrite-pattern">v(.*)</param>
     <param name="changesgenerate">enable</param>

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.oTlxMN/_old  2026-10-15 12:21:45.220118485 +0200
+++ /var/tmp/diff_new_pack.oTlxMN/_new  2026-10-15 12:21:45.224118652 +0200
@@ -3,6 +3,6 @@
                 <param 
name="url">https://github.com/nirs/kubectl-gather</param>
               <param 
name="changesrevision">62c6089cb7cb3552a81b6f74b8394d4b1433fd70</param></service><service
 name="tar_scm">
                 <param 
name="url">https://github.com/nirs/kubectl-gather.git</param>
-              <param 
name="changesrevision">8e26ef87c72fc49d9120a1b1eacc88500928f877</param></service></servicedata>
+              <param 
name="changesrevision">f1707eecd630c2c0653800f7ad6d91b31f965382</param></service></servicedata>
 (No newline at EOF)
 

++++++ kubectl-gather-0.14.0.obscpio -> kubectl-gather-0.15.0.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kubectl-gather-0.14.0/.golangci.yaml 
new/kubectl-gather-0.15.0/.golangci.yaml
--- old/kubectl-gather-0.14.0/.golangci.yaml    2026-07-29 15:34:14.000000000 
+0200
+++ new/kubectl-gather-0.15.0/.golangci.yaml    2026-10-14 14:18:42.000000000 
+0200
@@ -27,9 +27,13 @@
   enable:
     - gofmt
     - goimports
+    - golines
   exclusions:
     generated: lax
     paths:
       - third_party$
       - builtin$
       - examples$
+  settings:
+    golines:
+      shorten-comments: true
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kubectl-gather-0.14.0/Makefile 
new/kubectl-gather-0.15.0/Makefile
--- old/kubectl-gather-0.14.0/Makefile  2026-07-29 15:34:14.000000000 +0200
+++ new/kubectl-gather-0.15.0/Makefile  2026-10-14 14:18:42.000000000 +0200
@@ -37,6 +37,8 @@
        all \
        kubectl-gather \
        lint \
+       fmt \
+       spell \
        test \
        unit-tests \
        e2e-tests \
@@ -57,6 +59,12 @@
 lint:
        golangci-lint run ./...
 
+fmt:
+       golangci-lint fmt
+
+spell:
+       codespell -w --skip="go.sum,out,e2e/out"
+
 test: unit-tests e2e-tests
 
 unit-tests:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kubectl-gather-0.14.0/README.md 
new/kubectl-gather-0.15.0/README.md
--- old/kubectl-gather-0.14.0/README.md 2026-07-29 15:34:14.000000000 +0200
+++ new/kubectl-gather-0.15.0/README.md 2026-10-14 14:18:42.000000000 +0200
@@ -32,14 +32,17 @@
 To install the latest version on Linux and macOS, run:
 
 ```
-tag="$(curl -fsSL 
https://api.github.com/repos/nirs/kubectl-gather/releases/latest | jq -r 
.tag_name)"
+bash -o pipefail <<'EOF'
 os="$(uname | tr '[:upper:]' '[:lower:]')"
 machine="$(uname -m)"
 if [ "$machine" = "aarch64" ]; then machine="arm64"; fi
 if [ "$machine" = "x86_64" ]; then machine="amd64"; fi
-curl -L -o kubectl-gather 
https://github.com/nirs/kubectl-gather/releases/download/$tag/kubectl-gather-$tag-$os-$machine
+curl --fail --silent --show-error --location --output kubectl-gather \
+    
https://github.com/nirs/kubectl-gather/releases/latest/download/kubectl-gather-$os-$machine
 sudo install kubectl-gather /usr/local/bin
 rm kubectl-gather
+EOF
+kubectl gather --version
 ```
 
 ## Shell completion
@@ -63,7 +66,7 @@
 "hub":
 
 ```
-$ kubectl gather -d gather.one
+$ kubectl gather -o gather.one
 2024-05-27T23:03:58.838+0300   INFO    gather  Using kubeconfig 
"/home/nsoffer/.kube/config"
 2024-05-27T23:03:58.840+0300   INFO    gather  Using current context "hub"
 2024-05-27T23:03:58.841+0300   INFO    gather  Gathering from all namespaces
@@ -129,7 +132,7 @@
 To gather data from all clusters run:
 
 ```
-$ kubectl gather --contexts hub,dr1,dr2 -d gather.all
+$ kubectl gather --contexts hub,dr1,dr2 -o gather.all
 2024-05-27T23:16:16.459+0300   INFO    gather  Using kubeconfig 
"/home/nsoffer/.kube/config"
 2024-05-27T23:16:16.460+0300   INFO    gather  Gathering from all namespaces
 2024-05-27T23:16:16.460+0300   INFO    gather  Gathering from cluster "hub"
@@ -212,7 +215,7 @@
 `--kubeconfig`:
 
 ```
-$ kubectl gather --kubeconfig ocp/hub.yaml,ocp/c1.yaml,ocp/c2.yaml -d gather.dr
+$ kubectl gather --kubeconfig ocp/hub.yaml,ocp/c1.yaml,ocp/c2.yaml -o gather.dr
 2026-05-06T00:15:32.100+0300   INFO    gather  Using cluster "hub" from 
kubeconfig "ocp/hub.yaml"
 2026-05-06T00:15:32.101+0300   INFO    gather  Using cluster "c1" from 
kubeconfig "ocp/c1.yaml"
 2026-05-06T00:15:32.102+0300   INFO    gather  Using cluster "c2" from 
kubeconfig "ocp/c2.yaml"
@@ -251,7 +254,7 @@
 file:
 
 ```
-$ kubectl gather --kubeconfig hub.yaml -d gather.one
+$ kubectl gather --kubeconfig hub.yaml -o gather.one
 2026-05-06T00:15:32.100+0300   INFO    gather  Using cluster "hub" from 
kubeconfig "hub.yaml"
 2026-05-06T00:15:32.100+0300   INFO    gather  Gathering from all namespaces
 2026-05-06T00:15:32.100+0300   INFO    gather  Gathering from cluster "hub"
@@ -275,7 +278,7 @@
 To gather the "deployment-rbd" namespace from all clusters use:
 
 ```
-$ kubectl gather --contexts hub,dr1,dr2 -n deployment-rbd -d gather.before
+$ kubectl gather --contexts hub,dr1,dr2 -n deployment-rbd -o gather.before
 2024-05-27T23:33:45.883+0300   INFO    gather  Using kubeconfig 
"/home/nsoffer/.kube/config"
 2024-05-27T23:33:45.888+0300   INFO    gather  Gathering from namespaces 
[deployment-rbd]
 2024-05-27T23:33:45.888+0300   INFO    gather  Gathering from cluster "hub"
@@ -329,7 +332,7 @@
 failover:
 
 ```
-$ kubectl gather --contexts hub,dr1,dr2 -n deployment-rbd -d gather.after
+$ kubectl gather --contexts hub,dr1,dr2 -n deployment-rbd -o gather.after
 2024-05-27T23:45:20.292+0300   INFO    gather  Using kubeconfig 
"/home/nsoffer/.kube/config"
 2024-05-27T23:45:20.297+0300   INFO    gather  Gathering from namespaces 
[deployment-rbd]
 2024-05-27T23:45:20.297+0300   INFO    gather  Gathering from cluster "hub"
@@ -402,7 +405,7 @@
 To gather specific namespaces along with cluster scoped resources:
 
 ```
-$ kubectl-gather --contexts dr1,dr2 --namespaces=e2e-appset-deploy-cephfs 
--cluster --directory gather.mixed
+$ kubectl-gather --contexts dr1,dr2 --namespaces=e2e-appset-deploy-cephfs 
--cluster --output-dir gather.mixed
 2025-08-01T14:25:15.029+0530   INFO    gather  Using kubeconfig 
"/Users/pari/.kube/config"
 2025-08-01T14:25:15.031+0530   INFO    gather  Gathering from namespaces 
["e2e-appset-deploy-cephfs"]
 2025-08-01T14:25:15.031+0530   INFO    gather  Gathering cluster scoped 
resources
@@ -491,7 +494,7 @@
 configured for disaster recovery. Gathering everything takes more than 6
 minutes:
 
-    $ kubectl gather --contexts kevin-rdr-hub,kevin-rdr-c1,kevin-rdr-c2 
--remote --salt "$(openssl rand -base64 16)" --directory gather.remote
+    $ kubectl gather --contexts kevin-rdr-hub,kevin-rdr-c1,kevin-rdr-c2 
--remote --salt "$(openssl rand -base64 16)" --output-dir gather.remote
     2024-05-28T20:57:32.684+0300       INFO    gather  Using kubeconfig 
"/home/nsoffer/.kube/config"
     2024-05-28T20:57:32.686+0300       INFO    gather  Gathering from all 
namespaces
     2024-05-28T20:57:32.686+0300       INFO    gather  Gathering on remote 
cluster "kevin-rdr-c2"
@@ -567,7 +570,7 @@
 In this example we gather data related to single DR protected VM:
 
 ```
-$ kubectl gather --contexts kevin-rdr-hub,kevin-rdr-c1,kevin-rdr-c2 
--namespaces openshift-dr-ops,ui-vms3 --remote --salt "$(openssl rand -base64 
16)" -d gather.remote.app
+$ kubectl gather --contexts kevin-rdr-hub,kevin-rdr-c1,kevin-rdr-c2 
--namespaces openshift-dr-ops,ui-vms3 --remote --salt "$(openssl rand -base64 
16)" -o gather.remote.app
 2024-05-28T21:14:15.883+0300   INFO    gather  Using kubeconfig 
"/home/nsoffer/.kube/config"
 2024-05-28T21:14:15.884+0300   INFO    gather  Gathering from namespaces 
[openshift-dr-ops ui-vms3]
 2024-05-28T21:14:15.884+0300   INFO    gather  Gathering on remote cluster 
"kevin-rdr-c2"
@@ -631,7 +634,7 @@
 Gathering only resources:
 
 ```
-$ kubectl gather --contexts dr1,dr2 --addons= -d gather.resources
+$ kubectl gather --contexts dr1,dr2 --addons= -o gather.resources
 2024-06-01T02:13:08.117+0300   INFO    gather  Using kubeconfig 
"/home/nsoffer/.kube/config"
 2024-06-01T02:13:08.118+0300   INFO    gather  Gathering from all namespaces
 2024-06-01T02:13:08.119+0300   INFO    gather  Using addons []
@@ -645,7 +648,7 @@
 Gathering resource and pod container logs:
 
 ```
-$ kubectl gather --contexts dr1,dr2 --addons logs -d gather.logs
+$ kubectl gather --contexts dr1,dr2 --addons logs -o gather.logs
 2024-06-01T02:12:07.775+0300   INFO    gather  Using kubeconfig 
"/home/nsoffer/.kube/config"
 2024-06-01T02:12:07.776+0300   INFO    gather  Gathering from all namespaces
 2024-06-01T02:12:07.777+0300   INFO    gather  Using addons ["logs"]
@@ -659,7 +662,7 @@
 Gathering everything:
 
 ```
-$ kubectl gather --contexts dr1,dr2 -d gather.all
+$ kubectl gather --contexts dr1,dr2 -o gather.all
 2024-06-01T02:11:46.490+0300   INFO    gather  Using kubeconfig 
"/home/nsoffer/.kube/config"
 2024-06-01T02:11:46.492+0300   INFO    gather  Gathering from all namespaces
 2024-06-01T02:11:46.492+0300   INFO    gather  Using all addons
@@ -686,6 +689,10 @@
 and the `kubectl.kubernetes.io/last-applied-configuration` annotation
 is stripped to prevent plaintext leaks.
 
+Use `--insecure-secrets` to disable sanitization for debugging or in
+test environments where secrets are not sensitive.
+`--insecure-secrets` cannot be used with `--salt`.
+
 A `kubectl-gather.nirs.github.com/sanitized` annotation is added to
 each sanitized secret with the base64-encoded salt. The salt can be
 used to verify the original secret hash value.
@@ -707,10 +714,10 @@
 
 By default a random salt is generated. To use a specific salt, use the
 `--salt` flag with `--remote` to ensure all remote clusters use the
-same salt.
+same salt. `--salt` cannot be used with `--insecure-secrets`.
 
 ```
-$ kubectl gather --contexts dr1,dr2,hub --remote --salt "$(openssl rand 
-base64 16)" -d gather.remote
+$ kubectl gather --contexts dr1,dr2,hub --remote --salt "$(openssl rand 
-base64 16)" -o gather.remote
 ```
 
 Specifying a salt is also useful when comparing changes between two
@@ -718,9 +725,9 @@
 
 ```
 salt=$(openssl rand -base64 16)
-kubectl gather --contexts hub,dr1,dr2 -d gather.a --salt "$salt"
+kubectl gather --contexts hub,dr1,dr2 -o gather.a --salt "$salt"
 sleep 60
-kubectl gather --contexts hub,dr1,dr2 -d gather.b --salt "$salt"
+kubectl gather --contexts hub,dr1,dr2 -o gather.b --salt "$salt"
 diff -ur gather.a gather.b
 ```
 
@@ -733,7 +740,7 @@
 ## Integrating with other programs
 
 When running the *kubectl gather* from another program you may want to
-use JSON logs to extract certain fileds from the gather logs.
+use JSON logs to extract certain fields from the gather logs.
 
 Example: extracting the "msg" field from gather JSON logs:
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kubectl-gather-0.14.0/cmd/local.go 
new/kubectl-gather-0.15.0/cmd/local.go
--- old/kubectl-gather-0.14.0/cmd/local.go      2026-07-29 15:34:14.000000000 
+0200
+++ new/kubectl-gather-0.15.0/cmd/local.go      2026-10-14 14:18:42.000000000 
+0200
@@ -36,13 +36,14 @@
                clusterDir := filepath.Join(directory, clusterConfig.Name)
 
                options := gather.Options{
-                       Kubeconfig: clusterConfig.Kubeconfig,
-                       Context:    clusterConfig.Context,
-                       Namespaces: namespaces,
-                       Addons:     addons,
-                       Cluster:    cluster,
-                       Salt:       parsedSalt,
-                       Log:        log.Named(clusterConfig.Name),
+                       Kubeconfig:      clusterConfig.Kubeconfig,
+                       Context:         clusterConfig.Context,
+                       Namespaces:      namespaces,
+                       Addons:          addons,
+                       Cluster:         cluster,
+                       InsecureSecrets: insecureSecrets,
+                       Salt:            parsedSalt,
+                       Log:             log.Named(clusterConfig.Name),
                }
 
                wg.Add(1)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kubectl-gather-0.14.0/cmd/remote.go 
new/kubectl-gather-0.15.0/cmd/remote.go
--- old/kubectl-gather-0.14.0/cmd/remote.go     2026-07-29 15:34:14.000000000 
+0200
+++ new/kubectl-gather-0.15.0/cmd/remote.go     2026-10-14 14:18:42.000000000 
+0200
@@ -99,9 +99,13 @@
                remoteArgs = append(remoteArgs, 
"--addons="+strings.Join(addons, ","))
        }
 
-       // Always pass the salt so all remote clusters use the same salt value,
-       // ensuring consistent hashes for comparing secrets across clusters.
-       remoteArgs = append(remoteArgs, "--salt="+salt)
+       if insecureSecrets {
+               remoteArgs = append(remoteArgs, "--insecure-secrets")
+       } else {
+               // Pass the salt so all remote clusters use the same salt value,
+               // ensuring consistent hashes for comparing secrets across 
clusters.
+               remoteArgs = append(remoteArgs, "--salt="+salt)
+       }
 
        if len(remoteArgs) > 0 {
                args = append(args, "--", "/usr/bin/gather")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kubectl-gather-0.14.0/cmd/root.go 
new/kubectl-gather-0.15.0/cmd/root.go
--- old/kubectl-gather-0.14.0/cmd/root.go       2026-07-29 15:34:14.000000000 
+0200
+++ new/kubectl-gather-0.15.0/cmd/root.go       2026-10-14 14:18:42.000000000 
+0200
@@ -29,6 +29,7 @@
 var addons []string
 var cluster bool
 var remote bool
+var insecureSecrets bool
 var salt string
 var parsedSalt gather.Salt
 var verbose bool
@@ -45,27 +46,27 @@
 
   # Gather data from all namespaces in clusters "dr1", "dr2" and "hub" and 
store
   # it in "gather.local/", using default kubeconfig (~/.kube/config).
-  kubectl gather --contexts dr1,dr2,hub --directory gather.local
+  kubectl gather --contexts dr1,dr2,hub --output-dir gather.local
 
   # Gather data from namespaces "my-ns" and "other-ns" in clusters "dr1", 
"dr2",
   # and "hub", and store it in "gather.ns/".
-  kubectl gather --contexts dr1,dr2,hub --namespaces my-ns,other-ns 
--directory gather.ns
+  kubectl gather --contexts dr1,dr2,hub --namespaces my-ns,other-ns 
--output-dir gather.ns
 
   # Gather data on the remote clusters "dr1", "dr2" and "hub" and download it 
to
   # "gather.remote/". Requires the "oc" command. Use --salt to ensure all 
remote
   # clusters use the same salt for consistent secret hashing.
-  kubectl gather --contexts dr1,dr2,hub --remote --salt "$(openssl rand 
-base64 16)" --directory gather.remote
+  kubectl gather --contexts dr1,dr2,hub --remote --salt "$(openssl rand 
-base64 16)" --output-dir gather.remote
 
   # Enable only the "logs" addon, gathering all resources and pod logs. Use
   # --addons= to disable all addons.
-  kubectl gather --contexts dr1,dr2,hub --addons logs --directory 
gather.resources+logs
+  kubectl gather --contexts dr1,dr2,hub --addons logs --output-dir 
gather.resources+logs
 
   # Gather both cluster and namespace resources from "my-ns" and "other-ns" in 
clusters
   # "dr1", "dr2", and "hub".
-  kubectl gather --contexts dr1,dr2,hub --namespaces my-ns,other-ns --cluster 
--directory gather.mixed
+  kubectl gather --contexts dr1,dr2,hub --namespaces my-ns,other-ns --cluster 
--output-dir gather.mixed
 
   # Gather only cluster resources from clusters "dr1", "dr2" and "hub".
-  kubectl gather --contexts dr1,dr2,hub --namespace="" --cluster --directory 
gather.cluster`
+  kubectl gather --contexts dr1,dr2,hub --namespace="" --cluster --output-dir 
gather.cluster`
 
 var rootCmd = &cobra.Command{
        Use:     "kubectl-gather",
@@ -85,8 +86,12 @@
 }
 
 func init() {
-       rootCmd.Flags().StringVarP(&directory, "directory", "d", "",
-               "directory for storing gathered data (default 
\"gather.{timestamp}\")")
+       rootCmd.Flags().StringVarP(&directory, "output-dir", "o", "",
+               "output directory for storing gathered data (default 
\"gather.{timestamp}\")")
+       // Keep the old flag for backward compatibility with existing scripts.
+       rootCmd.Flags().StringVarP(&directory, "directory", "d", "", "")
+       _ = rootCmd.Flags().MarkDeprecated("directory", "use -o, --output-dir")
+       rootCmd.MarkFlagsMutuallyExclusive("output-dir", "directory")
 
        // Don't set default kubeconfig, so kubeconfig is empty unless the user
        // specified the option. This is required to allow running remote 
commands
@@ -106,11 +111,15 @@
                        "specified, gather all resources")
        rootCmd.Flags().BoolVarP(&remote, "remote", "r", false,
                "run on the remote clusters (requires the \"oc\" command)")
+       rootCmd.Flags().BoolVar(&insecureSecrets, "insecure-secrets", false,
+               "disable secret sanitization for debugging or testing")
        rootCmd.Flags().StringVar(&salt, "salt", "",
                "base64-encoded 16-byte salt for secret hashing (default: 
randomly generated)")
+       rootCmd.MarkFlagsMutuallyExclusive("salt", "insecure-secrets")
        rootCmd.Flags().BoolVarP(&verbose, "verbose", "v", false,
                "be more verbose")
-       rootCmd.Flags().StringVar(&logFormat, "log-format", "text", "Set the 
logging format [text, json]")
+       rootCmd.Flags().StringVar(&logFormat, "log-format", "text",
+               "Set the logging format [text, json]")
        rootCmd.Flags().BoolVar(&mustGatherVersion, "must-gather-version", 
false,
                "print must-gather version info and exit")
 
@@ -163,10 +172,14 @@
                }
        }
 
-       if cmd.Flags().Changed("salt") {
-               log.Infof("Using user-provided salt %q", salt)
+       if insecureSecrets {
+               log.Info("Using insecure secrets")
        } else {
-               log.Infof("Using generated salt %q", salt)
+               if cmd.Flags().Changed("salt") {
+                       log.Infof("Using user-provided salt %q", salt)
+               } else {
+                       log.Infof("Using generated salt %q", salt)
+               }
        }
 
        if namespaces == nil {
@@ -185,7 +198,7 @@
                log.Infof("Using all addons")
        }
 
-       if !cmd.Flags().Changed("directory") {
+       if !cmd.Flags().Changed("output-dir") && 
!cmd.Flags().Changed("directory") {
                log.Infof("Storing data in %q", directory)
        }
 
@@ -201,16 +214,18 @@
                return fmt.Errorf("--contexts cannot be used with multiple 
--kubeconfig files")
        }
 
-       if salt != "" {
-               var err error
-               parsedSalt, err = validateSalt(salt)
-               if err != nil {
-                       return err
+       if !insecureSecrets {
+               if salt != "" {
+                       var err error
+                       parsedSalt, err = validateSalt(salt)
+                       if err != nil {
+                               return err
+                       }
+               } else {
+                       parsedSalt = gather.RandomSalt()
+                       // Keep the base64 salt string for logging and passing 
to remote clusters.
+                       salt = base64.StdEncoding.EncodeToString(parsedSalt[:])
                }
-       } else {
-               parsedSalt = gather.RandomSalt()
-               // Keep the base64 salt string for logging and passing to 
remote clusters.
-               salt = base64.StdEncoding.EncodeToString(parsedSalt[:])
        }
 
        // --namespaces=""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kubectl-gather-0.14.0/docs/internals.md 
new/kubectl-gather-0.15.0/docs/internals.md
--- old/kubectl-gather-0.14.0/docs/internals.md 2026-07-29 15:34:14.000000000 
+0200
+++ new/kubectl-gather-0.15.0/docs/internals.md 2026-10-14 14:18:42.000000000 
+0200
@@ -5,7 +5,7 @@
 kubectl-gather fetch and process data in a 3 steps pipeline:
 
 ```
-prepare --> gather --> inpsect
+prepare --> gather --> inspect
 ```
 
 ### Prepare step
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kubectl-gather-0.14.0/e2e/commands/commands.go 
new/kubectl-gather-0.15.0/e2e/commands/commands.go
--- old/kubectl-gather-0.14.0/e2e/commands/commands.go  2026-07-29 
15:34:14.000000000 +0200
+++ new/kubectl-gather-0.15.0/e2e/commands/commands.go  2026-10-14 
14:18:42.000000000 +0200
@@ -2,22 +2,45 @@
 
 import (
        "bufio"
+       "bytes"
        "io"
        "os/exec"
 
        "go.uber.org/zap"
 )
 
-// Run a command logging lines from stderr.
-func Run(cmd *exec.Cmd, log *zap.SugaredLogger) error {
+// FailedToStart is Result.ExitCode when the process failed to start.
+const FailedToStart = -2
+
+// Result holds the outcome of a command run by Run.
+// Stdout and Stderr are what the process wrote.
+// ExitCode == 0 and Err == nil means the process exited successfully.
+// ExitCode == -1 means the process was terminated by a signal.
+// ExitCode == FailedToStart means the process failed to start.
+type Result struct {
+       ExitCode int
+       Stdout   []byte
+       Stderr   []byte
+       Err      error
+}
+
+// Run a command, logging lines from stderr and collecting output.
+func Run(cmd *exec.Cmd, log *zap.SugaredLogger) Result {
+       var stdout, stderr bytes.Buffer
+
        log.Debugf("Running %v", cmd)
+
+       cmd.Stdout = &stdout
+
        pipe, err := cmd.StderrPipe()
        if err != nil {
-               return err
+               return Result{Err: err, ExitCode: FailedToStart}
        }
+
        if err := cmd.Start(); err != nil {
-               return err
+               return Result{Err: err, ExitCode: FailedToStart}
        }
+
        reader := bufio.NewReader(pipe)
        for {
                line, _, err := reader.ReadLine()
@@ -28,8 +51,21 @@
                        break
                }
                log.Debug(string(line))
+               stderr.Write(line)
+               stderr.WriteByte('\n')
+       }
+
+       err = cmd.Wait()
+       result := Result{
+               Stdout: stdout.Bytes(),
+               Stderr: stderr.Bytes(),
+               Err:    err,
+       }
+       if ee, ok := err.(*exec.ExitError); ok {
+               result.ExitCode = ee.ExitCode()
        }
-       return cmd.Wait()
+
+       return result
 }
 
 func Stderr(err error) []byte {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kubectl-gather-0.14.0/e2e/gather_test.go 
new/kubectl-gather-0.15.0/e2e/gather_test.go
--- old/kubectl-gather-0.14.0/e2e/gather_test.go        2026-07-29 
15:34:14.000000000 +0200
+++ new/kubectl-gather-0.15.0/e2e/gather_test.go        2026-10-14 
14:18:42.000000000 +0200
@@ -102,10 +102,11 @@
        cmd := exec.Command(
                kubectlGather,
                "--contexts", strings.Join(clusters.Names, ","),
+               // Use the legacy option to verify that it remains supported.
                "--directory", outputDir,
        )
-       if err := commands.Run(cmd, t.Log); err != nil {
-               t.Errorf("kubectl-gather failed: %s", err)
+       if r := commands.Run(cmd, t.Log); r.Err != nil {
+               t.Errorf("kubectl-gather failed: %s", r.Err)
        }
 
        validateGatherAll(t, validate.New(outputDir))
@@ -119,10 +120,10 @@
                kubectlGather,
                "--contexts", strings.Join(clusters.Names, ","),
                "--cluster=true",
-               "--directory", outputDir,
+               "--output-dir", outputDir,
        )
-       if err := commands.Run(cmd, t.Log); err != nil {
-               t.Errorf("kubectl-gather failed: %s", err)
+       if r := commands.Run(cmd, t.Log); r.Err != nil {
+               t.Errorf("kubectl-gather failed: %s", r.Err)
        }
 
        validateGatherAll(t, validate.New(outputDir))
@@ -140,10 +141,10 @@
                kubectlGather,
                "--contexts", strings.Join(clusters.Names, ","),
                "--remote",
-               "--directory", outputDir,
+               "--output-dir", outputDir,
        )
-       if err := commands.Run(cmd, t.Log); err != nil {
-               t.Fatalf("kubectl-gather --remote failed: %s", err)
+       if r := commands.Run(cmd, t.Log); r.Err != nil {
+               t.Fatalf("kubectl-gather --remote failed: %s", r.Err)
        }
 
        dataRoot := findDataRoot(t, filepath.Join(outputDir, clusters.C1))
@@ -161,10 +162,10 @@
        cmd := exec.Command(
                kubectlGather,
                "--kubeconfig", strings.Join(kubeconfigs, ","),
-               "--directory", outputDir,
+               "--output-dir", outputDir,
        )
-       if err := commands.Run(cmd, t.Log); err != nil {
-               t.Errorf("kubectl-gather failed: %s", err)
+       if r := commands.Run(cmd, t.Log); r.Err != nil {
+               t.Errorf("kubectl-gather failed: %s", r.Err)
        }
 
        validateGatherAll(t, validate.New(outputDir))
@@ -184,10 +185,10 @@
                kubectlGather,
                "--kubeconfig", strings.Join(kubeconfigs, ","),
                "--remote",
-               "--directory", outputDir,
+               "--output-dir", outputDir,
        )
-       if err := commands.Run(cmd, t.Log); err != nil {
-               t.Fatalf("kubectl-gather --remote failed: %s", err)
+       if r := commands.Run(cmd, t.Log); r.Err != nil {
+               t.Fatalf("kubectl-gather --remote failed: %s", r.Err)
        }
 
        dataRoot := findDataRoot(t, filepath.Join(outputDir, clusters.C1))
@@ -204,10 +205,10 @@
                kubectlGather,
                "--contexts", strings.Join(clusters.Names, ","),
                "--cluster=false",
-               "--directory", outputDir,
+               "--output-dir", outputDir,
        )
-       if err := commands.Run(cmd, t.Log); err != nil {
-               t.Errorf("kubectl-gather failed: %s", err)
+       if r := commands.Run(cmd, t.Log); r.Err != nil {
+               t.Errorf("kubectl-gather failed: %s", r.Err)
        }
 
        v := validate.New(outputDir)
@@ -254,9 +255,9 @@
                kubectlGather,
                "--contexts", strings.Join(clusters.Names, ","),
                "--namespaces=", "",
-               "--directory", outputDir,
+               "--output-dir", outputDir,
        )
-       if err := commands.Run(cmd, t.Log); err == nil {
+       if r := commands.Run(cmd, t.Log); r.Err == nil {
                t.Errorf("kubectl-gather should fail, but it succeeded")
        }
 
@@ -272,9 +273,9 @@
                "--contexts", strings.Join(clusters.Names, ","),
                "--namespaces=", "",
                "--cluster=false",
-               "--directory", outputDir,
+               "--output-dir", outputDir,
        )
-       if err := commands.Run(cmd, t.Log); err == nil {
+       if r := commands.Run(cmd, t.Log); r.Err == nil {
                t.Errorf("kubectl-gather should fail, but it succeeded")
        }
 
@@ -290,10 +291,10 @@
                "--contexts", strings.Join(clusters.Names, ","),
                "--namespaces=", "",
                "--cluster=true",
-               "--directory", outputDir,
+               "--output-dir", outputDir,
        )
-       if err := commands.Run(cmd, t.Log); err != nil {
-               t.Errorf("kubectl-gather failed: %s", err)
+       if r := commands.Run(cmd, t.Log); r.Err != nil {
+               t.Errorf("kubectl-gather failed: %s", r.Err)
        }
 
        v := validate.New(outputDir)
@@ -340,10 +341,10 @@
                kubectlGather,
                "--contexts", strings.Join(clusters.Names, ","),
                "--namespaces", "test-common,test-c1",
-               "--directory", outputDir,
+               "--output-dir", outputDir,
        )
-       if err := commands.Run(cmd, t.Log); err != nil {
-               t.Errorf("kubectl-gather failed: %s", err)
+       if r := commands.Run(cmd, t.Log); r.Err != nil {
+               t.Errorf("kubectl-gather failed: %s", r.Err)
        }
 
        validateSpecificNamespaces(t, validate.New(outputDir))
@@ -358,10 +359,10 @@
                "--contexts", strings.Join(clusters.Names, ","),
                "--namespaces", "test-common,test-c1",
                "--cluster=false",
-               "--directory", outputDir,
+               "--output-dir", outputDir,
        )
-       if err := commands.Run(cmd, t.Log); err != nil {
-               t.Errorf("kubectl-gather failed: %s", err)
+       if r := commands.Run(cmd, t.Log); r.Err != nil {
+               t.Errorf("kubectl-gather failed: %s", r.Err)
        }
 
        validateSpecificNamespaces(t, validate.New(outputDir))
@@ -376,10 +377,10 @@
                "--contexts", strings.Join(clusters.Names, ","),
                "--namespaces", "test-common,test-c1",
                "--cluster=true",
-               "--directory", outputDir,
+               "--output-dir", outputDir,
        )
-       if err := commands.Run(cmd, t.Log); err != nil {
-               t.Errorf("kubectl-gather failed: %s", err)
+       if r := commands.Run(cmd, t.Log); r.Err != nil {
+               t.Errorf("kubectl-gather failed: %s", r.Err)
        }
 
        v := validate.New(outputDir)
@@ -421,10 +422,10 @@
                "--contexts", strings.Join(clusters.Names, ","),
                "--namespaces", "test-common,test-c1,test-c2",
                "--addons", "logs",
-               "--directory", outputDir,
+               "--output-dir", outputDir,
        )
-       if err := commands.Run(cmd, t.Log); err != nil {
-               t.Errorf("kubectl-gather failed: %s", err)
+       if r := commands.Run(cmd, t.Log); r.Err != nil {
+               t.Errorf("kubectl-gather failed: %s", r.Err)
        }
 
        v := validate.New(outputDir)
@@ -467,10 +468,10 @@
                "--contexts", strings.Join(clusters.Names, ","),
                "--namespaces", "test-common,test-c1,test-c2",
                "--addons", "pvcs",
-               "--directory", outputDir,
+               "--output-dir", outputDir,
        )
-       if err := commands.Run(cmd, t.Log); err != nil {
-               t.Errorf("kubectl-gather failed: %s", err)
+       if r := commands.Run(cmd, t.Log); r.Err != nil {
+               t.Errorf("kubectl-gather failed: %s", r.Err)
        }
 
        v := validate.New(outputDir)
@@ -510,10 +511,10 @@
                "--contexts", strings.Join(clusters.Names, ","),
                "--namespaces", "test-common,test-c1,test-c2",
                "--addons=",
-               "--directory", outputDir,
+               "--output-dir", outputDir,
        )
-       if err := commands.Run(cmd, t.Log); err != nil {
-               t.Errorf("kubectl-gather failed: %s", err)
+       if r := commands.Run(cmd, t.Log); r.Err != nil {
+               t.Errorf("kubectl-gather failed: %s", r.Err)
        }
 
        v := validate.New(outputDir)
@@ -558,11 +559,11 @@
        cmd := exec.Command(
                kubectlGather,
                "--contexts", strings.Join(clusters.Names, ","),
-               "--directory", outputDir,
+               "--output-dir", outputDir,
                "--log-format", "json",
        )
-       if err := commands.Run(cmd, t.Log); err != nil {
-               t.Errorf("kubectl-gather failed: %s", err)
+       if r := commands.Run(cmd, t.Log); r.Err != nil {
+               t.Errorf("kubectl-gather failed: %s", r.Err)
        }
 
        validate.JSONLog(t, logPath)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kubectl-gather-0.14.0/e2e/output_test.go 
new/kubectl-gather-0.15.0/e2e/output_test.go
--- old/kubectl-gather-0.14.0/e2e/output_test.go        2026-07-29 
15:34:14.000000000 +0200
+++ new/kubectl-gather-0.15.0/e2e/output_test.go        2026-10-14 
14:18:42.000000000 +0200
@@ -28,10 +28,10 @@
                cmd := exec.Command(
                        kubectlGather,
                        "--contexts", clusters.C1,
-                       "--directory", outputDir,
+                       "--output-dir", outputDir,
                )
-               if err := commands.Run(cmd, t.Log); err != nil {
-                       t.Fatal(err)
+               if r := commands.Run(cmd, t.Log); r.Err != nil {
+                       t.Fatal(r.Err)
                }
 
                reader := gather.NewOutputReader(filepath.Join(outputDir, 
clusters.C1))
@@ -51,10 +51,10 @@
                        kubectlGather,
                        "--contexts", clusters.C1,
                        "--remote",
-                       "--directory", outputDir,
+                       "--output-dir", outputDir,
                )
-               if err := commands.Run(cmd, t.Log); err != nil {
-                       t.Fatal(err)
+               if r := commands.Run(cmd, t.Log); r.Err != nil {
+                       t.Fatal(r.Err)
                }
 
                dataRoot := findDataRoot(t, filepath.Join(outputDir, 
clusters.C1))
@@ -173,10 +173,10 @@
                kubectlGather,
                "--contexts", strings.Join(clusters.Names, ","),
                "--salt", saltB64,
-               "--directory", outputDir,
+               "--output-dir", outputDir,
        )
-       if err := commands.Run(cmd, t.Log); err != nil {
-               t.Fatalf("kubectl-gather failed: %s", err)
+       if r := commands.Run(cmd, t.Log); r.Err != nil {
+               t.Fatalf("kubectl-gather failed: %s", r.Err)
        }
 
        for _, cluster := range clusters.Names {
@@ -199,10 +199,10 @@
        cmd := exec.Command(
                kubectlGather,
                "--contexts", strings.Join(clusters.Names, ","),
-               "--directory", outputDir,
+               "--output-dir", outputDir,
        )
-       if err := commands.Run(cmd, t.Log); err != nil {
-               t.Fatalf("kubectl-gather failed: %s", err)
+       if r := commands.Run(cmd, t.Log); r.Err != nil {
+               t.Fatalf("kubectl-gather failed: %s", r.Err)
        }
 
        salts := map[string]struct{}{}
@@ -220,6 +220,35 @@
        }
 }
 
+func TestSecretSanitizationDisabled(dt *testing.T) {
+       t := test.WithLog(dt)
+       outputDir := "out/test-secret-sanitization-disabled"
+
+       cmd := exec.Command(
+               kubectlGather,
+               "--contexts", strings.Join(clusters.Names, ","),
+               "--insecure-secrets",
+               "--output-dir", outputDir,
+       )
+       if r := commands.Run(cmd, t.Log); r.Err != nil {
+               t.Fatalf("kubectl-gather failed: %s", r.Err)
+       }
+
+       for _, cluster := range clusters.Names {
+               for _, secret := range gatheredSecrets(t, outputDir, cluster) {
+                       _, ok := 
secret.Annotations["kubectl-gather.nirs.github.com/sanitized"]
+                       if ok {
+                               t.Errorf("secret %s: should not be sanitized 
when --insecure-secrets is set", secret.Name)
+                       }
+                       for key, value := range secret.Data {
+                               if len(value) == 0 {
+                                       t.Errorf("secret %s: key %q has empty 
data", secret.Name, key)
+                               }
+                       }
+               }
+       }
+}
+
 // Test helpers
 
 // gatheredSecrets returns all secrets gathered for a cluster.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kubectl-gather-0.14.0/gather 
new/kubectl-gather-0.15.0/gather
--- old/kubectl-gather-0.14.0/gather    2026-07-29 15:34:14.000000000 +0200
+++ new/kubectl-gather-0.15.0/gather    2026-10-14 14:18:42.000000000 +0200
@@ -9,4 +9,4 @@
 
 kubectl-gather --must-gather-version > "$base/version"
 
-kubectl-gather --directory "$base" "$@"
+kubectl-gather --output-dir "$base" "$@"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kubectl-gather-0.14.0/go.mod 
new/kubectl-gather-0.15.0/go.mod
--- old/kubectl-gather-0.14.0/go.mod    2026-07-29 15:34:14.000000000 +0200
+++ new/kubectl-gather-0.15.0/go.mod    2026-10-14 14:18:42.000000000 +0200
@@ -1,8 +1,8 @@
 module github.com/nirs/kubectl-gather
 
-go 1.25.0
+go 1.26.0
 
-toolchain go1.26.2
+toolchain go1.27.2
 
 require (
        github.com/aymanbagabas/go-udiff v0.4.1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kubectl-gather-0.14.0/pkg/gather/addons.go 
new/kubectl-gather-0.15.0/pkg/gather/addons.go
--- old/kubectl-gather-0.14.0/pkg/gather/addons.go      2026-07-29 
15:34:14.000000000 +0200
+++ new/kubectl-gather-0.15.0/pkg/gather/addons.go      2026-10-14 
14:18:42.000000000 +0200
@@ -69,7 +69,12 @@
                        }
                        for _, resource := range addonInfo.Resources {
                                if other, exists := registry[resource]; exists {
-                                       return nil, fmt.Errorf("addon %q: 
resource %q already registered by addon %q", name, resource, other.Name())
+                                       return nil, fmt.Errorf(
+                                               "addon %q: resource %q already 
registered by addon %q",
+                                               name,
+                                               resource,
+                                               other.Name(),
+                                       )
                                }
                                registry[resource] = addon
                        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kubectl-gather-0.14.0/pkg/gather/agent.go 
new/kubectl-gather-0.15.0/pkg/gather/agent.go
--- old/kubectl-gather-0.14.0/pkg/gather/agent.go       2026-07-29 
15:34:14.000000000 +0200
+++ new/kubectl-gather-0.15.0/pkg/gather/agent.go       2026-10-14 
14:18:42.000000000 +0200
@@ -83,9 +83,13 @@
        agent *AgentPod
 }
 
-func (w *agentWatcher) WatchWithContext(ctx context.Context, opts 
metav1.ListOptions) (watch.Interface, error) {
+func (w *agentWatcher) WatchWithContext(
+       ctx context.Context,
+       opts metav1.ListOptions,
+) (watch.Interface, error) {
        w.agent.Log.Debugf("Watching agent pod %q", w.agent)
-       opts.FieldSelector = 
fields.OneTermEqualSelector(metav1.ObjectNameField, w.agent.Pod.Name).String()
+       opts.FieldSelector = 
fields.OneTermEqualSelector(metav1.ObjectNameField, w.agent.Pod.Name).
+               String()
        return w.agent.Client.CoreV1().Pods(w.agent.Pod.Namespace).Watch(ctx, 
opts)
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kubectl-gather-0.14.0/pkg/gather/commands.go 
new/kubectl-gather-0.15.0/pkg/gather/commands.go
--- old/kubectl-gather-0.14.0/pkg/gather/commands.go    2026-07-29 
15:34:14.000000000 +0200
+++ new/kubectl-gather-0.15.0/pkg/gather/commands.go    2026-10-14 
14:18:42.000000000 +0200
@@ -24,7 +24,12 @@
 
 var specialCharacters *regexp.Regexp
 
-func NewRemoteCommand(pod *corev1.Pod, opts *Options, log *zap.SugaredLogger, 
directory string) *RemoteCommand {
+func NewRemoteCommand(
+       pod *corev1.Pod,
+       opts *Options,
+       log *zap.SugaredLogger,
+       directory string,
+) *RemoteCommand {
        return &RemoteCommand{pod: pod, opts: opts, log: log, directory: 
directory}
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kubectl-gather-0.14.0/pkg/gather/gather.go 
new/kubectl-gather-0.15.0/pkg/gather/gather.go
--- old/kubectl-gather-0.14.0/pkg/gather/gather.go      2026-07-29 
15:34:14.000000000 +0200
+++ new/kubectl-gather-0.15.0/pkg/gather/gather.go      2026-10-14 
14:18:42.000000000 +0200
@@ -52,8 +52,12 @@
        Namespaces []string
        Addons     []string
        Cluster    bool
-       Salt       Salt
-       Log        *zap.SugaredLogger
+       // InsecureSecrets leaves Secret data unsanitized in the gathered
+       // output. By default (false), secret sanitization is always enabled
+       // regardless of Addons.
+       InsecureSecrets bool
+       Salt            Salt
+       Log             *zap.SugaredLogger
 }
 
 type Addon interface {
@@ -118,7 +122,7 @@
        }
 
        // Generate a random salt if the Salt option is not set.
-       if opts.Salt == (Salt{}) {
+       if !opts.InsecureSecrets && opts.Salt == (Salt{}) {
                opts.Salt = RandomSalt()
        }
 
@@ -306,7 +310,11 @@
                }
        }
 
-       g.log.Debugf("Listed %d api resources in %.3f seconds", len(resources), 
time.Since(start).Seconds())
+       g.log.Debugf(
+               "Listed %d api resources in %.3f seconds",
+               len(resources),
+               time.Since(start).Seconds(),
+       )
 
        return resources, nil
 }
@@ -449,7 +457,11 @@
        g.log.Debugf("Gathered %d %q in %.3f seconds", count, r.Name(), 
time.Since(start).Seconds())
 }
 
-func (g *Gatherer) listResources(r *resourceInfo, namespace string, opts 
metav1.ListOptions) (*unstructured.UnstructuredList, error) {
+func (g *Gatherer) listResources(
+       r *resourceInfo,
+       namespace string,
+       opts metav1.ListOptions,
+) (*unstructured.UnstructuredList, error) {
        start := time.Now()
 
        ctx := context.TODO()
@@ -469,7 +481,12 @@
                return nil, err
        }
 
-       g.log.Debugf("Listed %d %q in %.3f seconds", len(list.Items), r.Name(), 
time.Since(start).Seconds())
+       g.log.Debugf(
+               "Listed %d %q in %.3f seconds",
+               len(list.Items),
+               r.Name(),
+               time.Since(start).Seconds(),
+       )
 
        return list, nil
 }
@@ -498,7 +515,10 @@
        g.log.Debugf("Gathered %q in %.3f seconds", key, 
time.Since(start).Seconds())
 }
 
-func (g *Gatherer) getResource(r *resourceInfo, name types.NamespacedName) 
(*unstructured.Unstructured, error) {
+func (g *Gatherer) getResource(
+       r *resourceInfo,
+       name types.NamespacedName,
+) (*unstructured.Unstructured, error) {
        ctx := context.TODO()
        var opts metav1.GetOptions
 
@@ -530,7 +550,10 @@
        return writer.Flush()
 }
 
-func (g *Gatherer) createResource(r *resourceInfo, item 
*unstructured.Unstructured) (io.WriteCloser, error) {
+func (g *Gatherer) createResource(
+       r *resourceInfo,
+       item *unstructured.Unstructured,
+) (io.WriteCloser, error) {
        if r.Namespaced {
                return g.output.CreateNamespacedResource(item.GetNamespace(), 
r.Name(), item.GetName())
        } else {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kubectl-gather-0.14.0/pkg/gather/logs.go 
new/kubectl-gather-0.15.0/pkg/gather/logs.go
--- old/kubectl-gather-0.14.0/pkg/gather/logs.go        2026-07-29 
15:34:14.000000000 +0200
+++ new/kubectl-gather-0.15.0/pkg/gather/logs.go        2026-10-14 
14:18:42.000000000 +0200
@@ -183,7 +183,12 @@
 //
 // See also 
https://github.com/kubernetes/kubernetes/blob/master/pkg/kubelet/kubelet_pods.go#L1453
 func containerHasPreviousLog(status map[string]interface{}) bool {
-       containerID, found, err := unstructured.NestedString(status, 
"lastState", "terminated", "containerID")
+       containerID, found, err := unstructured.NestedString(
+               status,
+               "lastState",
+               "terminated",
+               "containerID",
+       )
        if err != nil || !found {
                return false
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kubectl-gather-0.14.0/pkg/gather/output.go 
new/kubectl-gather-0.15.0/pkg/gather/output.go
--- old/kubectl-gather-0.14.0/pkg/gather/output.go      2026-07-29 
15:34:14.000000000 +0200
+++ new/kubectl-gather-0.15.0/pkg/gather/output.go      2026-10-14 
14:18:42.000000000 +0200
@@ -21,7 +21,12 @@
        base string
 }
 
-func (o *OutputDirectory) CreateContainerLog(namespace string, pod string, 
container string, name string) (io.WriteCloser, error) {
+func (o *OutputDirectory) CreateContainerLog(
+       namespace string,
+       pod string,
+       container string,
+       name string,
+) (io.WriteCloser, error) {
        dir, err := createDirectory(o.base, namespacesDir, namespace, "pods", 
pod, container)
        if err != nil {
                return nil, err
@@ -29,7 +34,11 @@
        return createFile(dir, name+logSuffix)
 }
 
-func (o *OutputDirectory) CreateNamespacedResource(namespace string, resource 
string, name string) (io.WriteCloser, error) {
+func (o *OutputDirectory) CreateNamespacedResource(
+       namespace string,
+       resource string,
+       name string,
+) (io.WriteCloser, error) {
        dir, err := createDirectory(o.base, namespacesDir, namespace, resource)
        if err != nil {
                return nil, err
@@ -37,7 +46,10 @@
        return createFile(dir, name+resourceSuffix)
 }
 
-func (o *OutputDirectory) CreateClusterResource(resource string, name string) 
(io.WriteCloser, error) {
+func (o *OutputDirectory) CreateClusterResource(
+       resource string,
+       name string,
+) (io.WriteCloser, error) {
        dir, err := createDirectory(o.base, clusterDir, resource)
        if err != nil {
                return nil, err
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kubectl-gather-0.14.0/pkg/gather/output_reader.go 
new/kubectl-gather-0.15.0/pkg/gather/output_reader.go
--- old/kubectl-gather-0.14.0/pkg/gather/output_reader.go       2026-07-29 
15:34:14.000000000 +0200
+++ new/kubectl-gather-0.15.0/pkg/gather/output_reader.go       2026-10-14 
14:18:42.000000000 +0200
@@ -55,7 +55,13 @@
        if namespace == "" {
                resourcePath = filepath.Join(r.base, clusterDir, resource, 
name+resourceSuffix)
        } else {
-               resourcePath = filepath.Join(r.base, namespacesDir, namespace, 
resource, name+resourceSuffix)
+               resourcePath = filepath.Join(
+                       r.base,
+                       namespacesDir,
+                       namespace,
+                       resource,
+                       name+resourceSuffix,
+               )
        }
        return os.ReadFile(resourcePath)
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kubectl-gather-0.14.0/pkg/gather/rook.go 
new/kubectl-gather-0.15.0/pkg/gather/rook.go
--- old/kubectl-gather-0.14.0/pkg/gather/rook.go        2026-07-29 
15:34:14.000000000 +0200
+++ new/kubectl-gather-0.15.0/pkg/gather/rook.go        2026-10-14 
14:18:42.000000000 +0200
@@ -108,7 +108,12 @@
 }
 
 func (a *RookAddon) logCollectorEnabled(cephcluster 
*unstructured.Unstructured) bool {
-       enabled, found, err := unstructured.NestedBool(cephcluster.Object, 
"spec", "logCollector", "enabled")
+       enabled, found, err := unstructured.NestedBool(
+               cephcluster.Object,
+               "spec",
+               "logCollector",
+               "enabled",
+       )
        if err != nil {
                a.log.Warnf("Cannot get cephcluster .spec.logCollector.enabled: 
%s", err)
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kubectl-gather-0.14.0/pkg/gather/sanitize.go 
new/kubectl-gather-0.15.0/pkg/gather/sanitize.go
--- old/kubectl-gather-0.14.0/pkg/gather/sanitize.go    2026-07-29 
15:34:14.000000000 +0200
+++ new/kubectl-gather-0.15.0/pkg/gather/sanitize.go    2026-10-14 
14:18:42.000000000 +0200
@@ -46,8 +46,11 @@
 
 // sanitizeResource modifies the resource in place, replacing sensitive data
 // with deterministic hashes. Currently handles Secret resources, other 
resource
-// types pass through unchanged.
+// types pass through unchanged. Does nothing if InsecureSecrets is set.
 func (g *Gatherer) sanitizeResource(item *unstructured.Unstructured) {
+       if g.opts.InsecureSecrets {
+               return
+       }
        switch item.GetKind() {
        case "Secret":
                g.sanitizeSecret(item)
@@ -64,7 +67,12 @@
        saltB64 := base64.StdEncoding.EncodeToString(salt[:])
 
        // If already sanitized, skip to avoid double hashing.
-       existing, found, _ := unstructured.NestedString(obj, "metadata", 
"annotations", sanitizedAnnotation)
+       existing, found, _ := unstructured.NestedString(
+               obj,
+               "metadata",
+               "annotations",
+               sanitizedAnnotation,
+       )
        if found {
                if existing != saltB64 {
                        log.Warnf("Secret %q: already sanitized with different 
salt %q", name, existing)
@@ -98,7 +106,13 @@
        unstructured.RemoveNestedField(obj, "metadata", "annotations", 
lastAppliedConfigAnnotation)
 
        // Mark the secret as sanitized with the salt used.
-       if err := unstructured.SetNestedField(obj, saltB64, "metadata", 
"annotations", sanitizedAnnotation); err != nil {
+       if err := unstructured.SetNestedField(
+               obj,
+               saltB64,
+               "metadata",
+               "annotations",
+               sanitizedAnnotation,
+       ); err != nil {
                log.Warnf("Secret %q: failed to set sanitized annotation: %s", 
name, err)
        }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kubectl-gather-0.14.0/pkg/gather/sanitize_test.go 
new/kubectl-gather-0.15.0/pkg/gather/sanitize_test.go
--- old/kubectl-gather-0.14.0/pkg/gather/sanitize_test.go       2026-07-29 
15:34:14.000000000 +0200
+++ new/kubectl-gather-0.15.0/pkg/gather/sanitize_test.go       2026-10-14 
14:18:42.000000000 +0200
@@ -83,6 +83,47 @@
        }
 }
 
+func TestInsecureSecretsSkipsSanitization(t *testing.T) {
+       g := &Gatherer{
+               opts: &Options{
+                       InsecureSecrets: true,
+                       Salt:            testSalt,
+                       Log:             zap.NewNop().Sugar(),
+               },
+       }
+
+       obj := loadTestdata(t, "secret-with-data.yaml")
+       before := marshalYAML(t, obj.Object)
+
+       g.sanitizeResource(obj)
+       after := marshalYAML(t, obj.Object)
+
+       if before != after {
+               t.Fatalf("InsecureSecrets should skip sanitization:\n%s", 
unifiedDiff(t, before, after))
+       }
+}
+
+func TestSecureByDefault(t *testing.T) {
+       g := newTestGatherer(testSalt)
+
+       obj := loadTestdata(t, "secret-with-data.yaml")
+       before := marshalYAML(t, obj.Object)
+
+       g.sanitizeResource(obj)
+       after := marshalYAML(t, obj.Object)
+
+       if before == after {
+               t.Fatal("secret should be sanitized by default")
+       }
+
+       _, found, _ := unstructured.NestedString(
+               obj.Object, "metadata", "annotations", 
"kubectl-gather.nirs.github.com/sanitized",
+       )
+       if !found {
+               t.Fatal("sanitized annotation not found")
+       }
+}
+
 func TestRandomSalt(t *testing.T) {
        values := map[Salt]struct{}{}
        for range 1000 {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kubectl-gather-0.14.0/pkg/kubeconfig/kubeconfig.go 
new/kubectl-gather-0.15.0/pkg/kubeconfig/kubeconfig.go
--- old/kubectl-gather-0.14.0/pkg/kubeconfig/kubeconfig.go      2026-07-29 
15:34:14.000000000 +0200
+++ new/kubectl-gather-0.15.0/pkg/kubeconfig/kubeconfig.go      2026-10-14 
14:18:42.000000000 +0200
@@ -135,7 +135,12 @@
                        return nil, err
                }
                if prev, ok := hosts[restConfig.Host]; ok {
-                       return nil, fmt.Errorf("duplicate cluster %q from 
contexts %q and %q", restConfig.Host, prev, context)
+                       return nil, fmt.Errorf(
+                               "duplicate cluster %q from contexts %q and %q",
+                               restConfig.Host,
+                               prev,
+                               context,
+                       )
                }
                hosts[restConfig.Host] = context
                configs = append(configs, &Config{
@@ -190,7 +195,12 @@
                name := nameFromFilename(path)
 
                if prev, ok := names[name]; ok {
-                       return nil, fmt.Errorf("duplicate cluster name %q from 
files %q and %q", name, prev, path)
+                       return nil, fmt.Errorf(
+                               "duplicate cluster name %q from files %q and 
%q",
+                               name,
+                               prev,
+                               path,
+                       )
                }
                names[name] = path
 
@@ -211,7 +221,12 @@
                }
 
                if prev, ok := hosts[restConfig.Host]; ok {
-                       return nil, fmt.Errorf("duplicate cluster %q from files 
%q and %q", restConfig.Host, prev, path)
+                       return nil, fmt.Errorf(
+                               "duplicate cluster %q from files %q and %q",
+                               restConfig.Host,
+                               prev,
+                               path,
+                       )
                }
                hosts[restConfig.Host] = path
 

++++++ kubectl-gather.obsinfo ++++++
--- /var/tmp/diff_new_pack.oTlxMN/_old  2026-10-15 12:21:45.379125138 +0200
+++ /var/tmp/diff_new_pack.oTlxMN/_new  2026-10-15 12:21:45.384125348 +0200
@@ -1,5 +1,5 @@
 name: kubectl-gather
-version: 0.14.0
-mtime: 1785332054
-commit: 8e26ef87c72fc49d9120a1b1eacc88500928f877
+version: 0.15.0
+mtime: 1791980322
+commit: f1707eecd630c2c0653800f7ad6d91b31f965382
 

++++++ vendor.tar.gz ++++++

Reply via email to