diff --git a/cmd/analyze/cli/root.go b/cmd/analyze/cli/root.go index eebc25275..9761fba98 100644 --- a/cmd/analyze/cli/root.go +++ b/cmd/analyze/cli/root.go @@ -4,14 +4,10 @@ import ( "os" "strings" + "github.com/replicatedhq/troubleshoot/pkg/k8sutil" "github.com/replicatedhq/troubleshoot/pkg/logger" "github.com/spf13/cobra" "github.com/spf13/viper" - "k8s.io/cli-runtime/pkg/genericclioptions" -) - -var ( - KubernetesConfigFlags *genericclioptions.ConfigFlags ) func RootCmd() *cobra.Command { @@ -41,8 +37,7 @@ func RootCmd() *cobra.Command { viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_")) - KubernetesConfigFlags = genericclioptions.NewConfigFlags(false) - KubernetesConfigFlags.AddFlags(cmd.Flags()) + k8sutil.AddFlags(cmd.Flags()) return cmd } diff --git a/cmd/preflight/cli/root.go b/cmd/preflight/cli/root.go index e4df7624b..b9c0c0571 100644 --- a/cmd/preflight/cli/root.go +++ b/cmd/preflight/cli/root.go @@ -4,13 +4,9 @@ import ( "os" "strings" + "github.com/replicatedhq/troubleshoot/pkg/k8sutil" "github.com/spf13/cobra" "github.com/spf13/viper" - "k8s.io/cli-runtime/pkg/genericclioptions" -) - -var ( - KubernetesConfigFlags *genericclioptions.ConfigFlags ) func RootCmd() *cobra.Command { @@ -42,8 +38,7 @@ that a cluster meets the requirements to run an application.`, viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_")) - KubernetesConfigFlags = genericclioptions.NewConfigFlags(false) - KubernetesConfigFlags.AddFlags(cmd.Flags()) + k8sutil.AddFlags(cmd.Flags()) return cmd } diff --git a/cmd/preflight/cli/run.go b/cmd/preflight/cli/run.go index 68eb03cce..c0a27feb1 100644 --- a/cmd/preflight/cli/run.go +++ b/cmd/preflight/cli/run.go @@ -5,6 +5,7 @@ import ( "io/ioutil" "net/http" "os" + "strings" "time" cursor "github.com/ahmetalpbalkan/go-cursor" @@ -14,7 +15,9 @@ import ( troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2" troubleshootclientsetscheme "github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/scheme" "github.com/replicatedhq/troubleshoot/pkg/docrewrite" + "github.com/replicatedhq/troubleshoot/pkg/k8sutil" "github.com/replicatedhq/troubleshoot/pkg/preflight" + "github.com/replicatedhq/troubleshoot/pkg/specs" "github.com/spf13/viper" spin "github.com/tj/go-spin" "k8s.io/client-go/kubernetes/scheme" @@ -26,7 +29,20 @@ func runPreflights(v *viper.Viper, arg string) error { var preflightContent []byte var err error - if _, err = os.Stat(arg); err == nil { + if strings.HasPrefix(arg, "secret/") { + // format secret/namespace-name/secret-name + pathParts := strings.Split(arg, "/") + if len(pathParts) != 3 { + return errors.Errorf("path %s must have 3 components", arg) + } + + spec, err := specs.LoadFromSecret(pathParts[1], pathParts[2], "preflight-spec") + if err != nil { + return errors.Wrap(err, "failed to get spec from secret") + } + + preflightContent = spec + } else if _, err = os.Stat(arg); err == nil { b, err := ioutil.ReadFile(arg) if err != nil { return err @@ -101,7 +117,7 @@ func runPreflights(v *viper.Viper, arg string) error { close(finishedCh) }() - restConfig, err := KubernetesConfigFlags.ToRESTConfig() + restConfig, err := k8sutil.GetRESTConfig() if err != nil { return errors.Wrap(err, "failed to convert kube flags to rest config") } diff --git a/cmd/troubleshoot/cli/root.go b/cmd/troubleshoot/cli/root.go index 7d14f0063..2ac2410e9 100644 --- a/cmd/troubleshoot/cli/root.go +++ b/cmd/troubleshoot/cli/root.go @@ -6,14 +6,10 @@ import ( "strings" troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2" + "github.com/replicatedhq/troubleshoot/pkg/k8sutil" "github.com/replicatedhq/troubleshoot/pkg/logger" "github.com/spf13/cobra" "github.com/spf13/viper" - "k8s.io/cli-runtime/pkg/genericclioptions" -) - -var ( - KubernetesConfigFlags *genericclioptions.ConfigFlags ) func RootCmd() *cobra.Command { @@ -52,8 +48,7 @@ from a server that can be used to assist when troubleshooting a Kubernetes clust viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_")) - KubernetesConfigFlags = genericclioptions.NewConfigFlags(false) - KubernetesConfigFlags.AddFlags(cmd.Flags()) + k8sutil.AddFlags(cmd.Flags()) return cmd } diff --git a/cmd/troubleshoot/cli/run.go b/cmd/troubleshoot/cli/run.go index a8de5e1fc..2c2bbfb5e 100644 --- a/cmd/troubleshoot/cli/run.go +++ b/cmd/troubleshoot/cli/run.go @@ -31,11 +31,12 @@ import ( "github.com/replicatedhq/troubleshoot/pkg/collect" "github.com/replicatedhq/troubleshoot/pkg/convert" "github.com/replicatedhq/troubleshoot/pkg/docrewrite" + "github.com/replicatedhq/troubleshoot/pkg/k8sutil" "github.com/replicatedhq/troubleshoot/pkg/redact" + "github.com/replicatedhq/troubleshoot/pkg/specs" "github.com/spf13/viper" spin "github.com/tj/go-spin" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/kubernetes" ) var ( @@ -255,7 +256,7 @@ func loadSpec(v *viper.Viper, arg string) ([]byte, error) { return nil, errors.Errorf("path %s must have 3 components", arg) } - spec, err := loadSpecFromSecret(pathParts[1], pathParts[2]) + spec, err := specs.LoadFromSecret(pathParts[1], pathParts[2], "support-bundle-spec") if err != nil { return nil, errors.Wrap(err, "failed to get spec from secret") } @@ -281,30 +282,6 @@ func loadSpec(v *viper.Viper, arg string) ([]byte, error) { return spec, nil } -func loadSpecFromSecret(namespace string, secretName string) ([]byte, error) { - config, err := KubernetesConfigFlags.ToRESTConfig() - if err != nil { - return nil, errors.Wrap(err, "failed to convert kube flags to rest config") - } - - client, err := kubernetes.NewForConfig(config) - if err != nil { - return nil, errors.Wrap(err, "failed to convert create k8s client") - } - - foundSecret, err := client.CoreV1().Secrets(namespace).Get(context.TODO(), secretName, metav1.GetOptions{}) - if err != nil { - return nil, errors.Wrap(err, "failed to get secret") - } - - spec, ok := foundSecret.Data["support-bundle-spec"] - if !ok { - return nil, errors.Errorf("spec not found in secret %s", secretName) - } - - return spec, nil -} - func loadSpecFromURL(v *viper.Viper, arg string) ([]byte, error) { for { req, err := http.NewRequest("GET", arg, nil) @@ -407,7 +384,7 @@ func runCollectors(v *viper.Viper, collectors []*troubleshootv1beta2.Collect, ad collectSpecs = ensureCollectorInList(collectSpecs, troubleshootv1beta2.Collect{ClusterInfo: &troubleshootv1beta2.ClusterInfo{}}) collectSpecs = ensureCollectorInList(collectSpecs, troubleshootv1beta2.Collect{ClusterResources: &troubleshootv1beta2.ClusterResources{}}) - config, err := KubernetesConfigFlags.ToRESTConfig() + config, err := k8sutil.GetRESTConfig() if err != nil { return "", errors.Wrap(err, "failed to convert kube flags to rest config") } diff --git a/go.mod b/go.mod index 68825fa40..b2626dad3 100644 --- a/go.mod +++ b/go.mod @@ -37,6 +37,7 @@ require ( github.com/prometheus/procfs v0.0.5 // indirect github.com/replicatedhq/termui/v3 v3.1.1-0.20200811145416-f40076d26851 github.com/spf13/cobra v0.0.5 + github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.4.0 github.com/stretchr/testify v1.5.1 github.com/tj/go-spin v1.1.0 diff --git a/pkg/k8sutil/config.go b/pkg/k8sutil/config.go new file mode 100644 index 000000000..1ba097a5e --- /dev/null +++ b/pkg/k8sutil/config.go @@ -0,0 +1,23 @@ +package k8sutil + +import ( + flag "github.com/spf13/pflag" + "k8s.io/cli-runtime/pkg/genericclioptions" + "k8s.io/client-go/rest" +) + +var ( + kubernetesConfigFlags *genericclioptions.ConfigFlags +) + +func init() { + kubernetesConfigFlags = genericclioptions.NewConfigFlags(false) +} + +func AddFlags(flags *flag.FlagSet) { + kubernetesConfigFlags.AddFlags(flags) +} + +func GetRESTConfig() (*rest.Config, error) { + return kubernetesConfigFlags.ToRESTConfig() +} diff --git a/pkg/specs/secrets.go b/pkg/specs/secrets.go new file mode 100644 index 000000000..8106fe813 --- /dev/null +++ b/pkg/specs/secrets.go @@ -0,0 +1,34 @@ +package specs + +import ( + "context" + + "github.com/pkg/errors" + "github.com/replicatedhq/troubleshoot/pkg/k8sutil" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes" +) + +func LoadFromSecret(namespace string, secretName string, key string) ([]byte, error) { + config, err := k8sutil.GetRESTConfig() + if err != nil { + return nil, errors.Wrap(err, "failed to convert kube flags to rest config") + } + + client, err := kubernetes.NewForConfig(config) + if err != nil { + return nil, errors.Wrap(err, "failed to convert create k8s client") + } + + foundSecret, err := client.CoreV1().Secrets(namespace).Get(context.TODO(), secretName, metav1.GetOptions{}) + if err != nil { + return nil, errors.Wrap(err, "failed to get secret") + } + + spec, ok := foundSecret.Data[key] + if !ok { + return nil, errors.Errorf("spec not found in secret %s", secretName) + } + + return spec, nil +}