feat: Dry run flag to print preflight specs to std out (#1240)

This commit is contained in:
Evans Mungai
2023-09-12 14:42:10 +01:00
committed by GitHub
parent 53813502de
commit b9f4fc4390
25 changed files with 248 additions and 135 deletions

View File

@@ -4,7 +4,7 @@ import (
"os"
"strings"
"github.com/replicatedhq/troubleshoot/cmd/util"
"github.com/replicatedhq/troubleshoot/cmd/internal/util"
"github.com/replicatedhq/troubleshoot/pkg/k8sutil"
"github.com/replicatedhq/troubleshoot/pkg/logger"
"github.com/spf13/cobra"
@@ -43,6 +43,8 @@ func RootCmd() *cobra.Command {
cobra.OnInitialize(initConfig)
cmd.AddCommand(util.VersionCmd())
cmd.Flags().String("analyzers", "", "filename or url of the analyzers to use")
cmd.Flags().Bool("debug", false, "enable debug logging")

View File

@@ -4,7 +4,7 @@ import (
"os"
"strings"
"github.com/replicatedhq/troubleshoot/cmd/util"
"github.com/replicatedhq/troubleshoot/cmd/internal/util"
"github.com/replicatedhq/troubleshoot/pkg/k8sutil"
"github.com/replicatedhq/troubleshoot/pkg/logger"
"github.com/spf13/cobra"
@@ -43,7 +43,7 @@ func RootCmd() *cobra.Command {
cobra.OnInitialize(initConfig)
cmd.AddCommand(VersionCmd())
cmd.AddCommand(util.VersionCmd())
cmd.Flags().StringSlice("redactors", []string{}, "names of the additional redactors to use")
cmd.Flags().Bool("redact", true, "enable/disable default redactions")

View File

@@ -1,22 +0,0 @@
package cli
import (
"fmt"
"github.com/replicatedhq/troubleshoot/pkg/version"
"github.com/spf13/cobra"
)
func VersionCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "version",
Short: "Print the current version and exit",
Long: `Print the current version and exit`,
RunE: func(cmd *cobra.Command, args []string) error {
fmt.Printf("Replicated Collect %s\n", version.Version())
return nil
},
}
return cmd
}

View File

@@ -1,4 +1,4 @@
package cli
package util
import (
"fmt"

View File

@@ -6,7 +6,7 @@ import (
"os"
"strings"
"github.com/replicatedhq/troubleshoot/cmd/util"
"github.com/replicatedhq/troubleshoot/cmd/internal/util"
"github.com/replicatedhq/troubleshoot/internal/traces"
"github.com/replicatedhq/troubleshoot/pkg/constants"
"github.com/replicatedhq/troubleshoot/pkg/k8sutil"
@@ -64,10 +64,14 @@ that a cluster meets the requirements to run an application.`,
cobra.OnInitialize(initConfig)
cmd.AddCommand(VersionCmd())
cmd.AddCommand(util.VersionCmd())
cmd.AddCommand(OciFetchCmd())
preflight.AddFlags(cmd.PersistentFlags())
// Dry run flag should be in cmd.PersistentFlags() flags made available to all subcommands
// Adding here to avoid that
cmd.Flags().Bool("dry-run", false, "print the preflight spec without running preflight checks")
k8sutil.AddFlags(cmd.Flags())
// Initialize klog flags

View File

@@ -1,23 +0,0 @@
package cli
import (
"fmt"
"github.com/spf13/cobra"
"github.com/replicatedhq/troubleshoot/pkg/version"
)
func VersionCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "version",
Short: "Print the current version and exit",
Long: `Print the current version and exit`,
RunE: func(cmd *cobra.Command, args []string) error {
fmt.Printf("Replicated Preflight %s\n", version.Version())
return nil
},
}
return cmd
}

View File

@@ -5,7 +5,7 @@ import (
"os"
"strings"
"github.com/replicatedhq/troubleshoot/cmd/util"
"github.com/replicatedhq/troubleshoot/cmd/internal/util"
"github.com/replicatedhq/troubleshoot/internal/traces"
"github.com/replicatedhq/troubleshoot/pkg/k8sutil"
"github.com/replicatedhq/troubleshoot/pkg/logger"
@@ -62,7 +62,7 @@ from a server that can be used to assist when troubleshooting a Kubernetes clust
cmd.AddCommand(Analyze())
cmd.AddCommand(Redact())
cmd.AddCommand(VersionCmd())
cmd.AddCommand(util.VersionCmd())
cmd.Flags().StringSlice("redactors", []string{}, "names of the additional redactors to use")
cmd.Flags().Bool("redact", true, "enable/disable default redactions")

View File

@@ -29,6 +29,7 @@ preflight [url] [flags]
--cpuprofile string File path to write cpu profiling data
--debug enable debug logging
--disable-compression If true, opt-out of response compression for all requests to the server
--dry-run print the preflight spec without running preflight checks
--format string output format, one of human, json, yaml. only used when interactive is set to false (default "human")
-h, --help help for preflight
--insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
@@ -53,4 +54,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 8-Jun-2023
###### Auto generated by spf13/cobra on 31-Aug-2023

View File

@@ -33,4 +33,4 @@ preflight oci-fetch [URI] [flags]
* [preflight](preflight.md) - Run and retrieve preflight checks in a cluster
###### Auto generated by spf13/cobra on 8-Jun-2023
###### Auto generated by spf13/cobra on 31-Aug-2023

View File

@@ -37,4 +37,4 @@ preflight version [flags]
* [preflight](preflight.md) - Run and retrieve preflight checks in a cluster
###### Auto generated by spf13/cobra on 3-Jan-2023
###### Auto generated by spf13/cobra on 31-Aug-2023

View File

@@ -55,4 +55,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 8-Jun-2023
###### Auto generated by spf13/cobra on 31-Aug-2023

View File

@@ -30,4 +30,4 @@ support-bundle analyze [url] [flags]
* [support-bundle](support-bundle.md) - Generate a support bundle
###### Auto generated by spf13/cobra on 3-Jan-2023
###### Auto generated by spf13/cobra on 31-Aug-2023

View File

@@ -39,4 +39,4 @@ support-bundle redact [urls...] [flags]
* [support-bundle](support-bundle.md) - Generate a support bundle
###### Auto generated by spf13/cobra on 3-Jan-2023
###### Auto generated by spf13/cobra on 31-Aug-2023

View File

@@ -27,4 +27,4 @@ support-bundle version [flags]
* [support-bundle](support-bundle.md) - Generate a support bundle
###### Auto generated by spf13/cobra on 3-Jan-2023
###### Auto generated by spf13/cobra on 31-Aug-2023

2
go.mod
View File

@@ -245,7 +245,7 @@ require (
sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 // indirect
sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
sigs.k8s.io/yaml v1.3.0 // indirect
sigs.k8s.io/yaml v1.3.0
)
replace (

View File

@@ -15,7 +15,10 @@ import (
func GetTestFixture(t *testing.T, path string) string {
t.Helper()
p := filepath.Join("../../testdata", path)
p := path
if !filepath.IsAbs(path) {
p = filepath.Join("../../testdata", path)
}
b, err := os.ReadFile(p)
require.NoError(t, err)
return string(b)

View File

@@ -2,6 +2,8 @@ package loader
import (
"context"
"reflect"
"strings"
"github.com/pkg/errors"
"github.com/replicatedhq/troubleshoot/internal/util"
@@ -10,10 +12,10 @@ import (
"github.com/replicatedhq/troubleshoot/pkg/constants"
"github.com/replicatedhq/troubleshoot/pkg/docrewrite"
"github.com/replicatedhq/troubleshoot/pkg/types"
"gopkg.in/yaml.v2"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/klog/v2"
"sigs.k8s.io/yaml"
)
var decoder runtime.Decoder
@@ -97,6 +99,33 @@ func (kinds *TroubleshootKinds) Add(other *TroubleshootKinds) {
kinds.SupportBundlesV1Beta2 = append(kinds.SupportBundlesV1Beta2, other.SupportBundlesV1Beta2...)
}
// ToYaml returns a yaml document/multi-doc of all the parsed specs
// This function utilises reflection to iterate over all the fields
// of the TroubleshootKinds object then marshals them to yaml.
func (kinds *TroubleshootKinds) ToYaml() (string, error) {
rawList := []string{}
obj := reflect.ValueOf(*kinds)
for i := 0; i < obj.NumField(); i++ {
field := obj.Field(i)
if field.Kind() != reflect.Slice {
continue
}
// skip empty slices to avoid empty yaml documents
for count := 0; count < field.Len(); count++ {
val := field.Index(count)
yamlOut, err := yaml.Marshal(val.Interface())
if err != nil {
return "", err
}
rawList = append(rawList, string(yamlOut))
}
}
return strings.Join(rawList, "---\n"), nil
}
func NewTroubleshootKinds() *TroubleshootKinds {
return &TroubleshootKinds{}
}

View File

@@ -522,3 +522,60 @@ func TestAddingKinds(t *testing.T) {
}
assert.Equal(t, k2, k1)
}
func TestToYaml(t *testing.T) {
k := &TroubleshootKinds{
AnalyzersV1Beta2: []troubleshootv1beta2.Analyzer{
{
TypeMeta: metav1.TypeMeta{
Kind: "Analyzer",
APIVersion: "troubleshoot.sh/v1beta2",
},
Spec: troubleshootv1beta2.AnalyzerSpec{
Analyzers: []*troubleshootv1beta2.Analyze{
{
ClusterVersion: &troubleshootv1beta2.ClusterVersion{
Outcomes: []*troubleshootv1beta2.Outcome{
{
Pass: &troubleshootv1beta2.SingleOutcome{
Message: "Cluster is up to date",
},
},
},
},
},
},
},
},
},
SupportBundlesV1Beta2: []troubleshootv1beta2.SupportBundle{
{
TypeMeta: metav1.TypeMeta{
Kind: "SupportBundle",
APIVersion: "troubleshoot.sh/v1beta2",
},
Spec: troubleshootv1beta2.SupportBundleSpec{
Collectors: []*troubleshootv1beta2.Collect{
{
ClusterResources: &troubleshootv1beta2.ClusterResources{
IgnoreRBAC: true,
},
},
},
},
},
},
}
y, err := k.ToYaml()
require.NoError(t, err)
assert.Contains(t, string(y), `apiVersion: troubleshoot.sh/v1beta2
kind: SupportBundle
metadata:
creationTimestamp: null
spec:
collectors:
- clusterResources:
ignoreRBAC: true`)
assert.Contains(t, string(y), "message: Cluster is up to date")
}

View File

@@ -16,6 +16,7 @@ const (
flagSince = "since"
flagOutput = "output"
flagDebug = "debug"
flagDryRun = "dry-run"
)
type PreflightFlags struct {

View File

@@ -7,46 +7,55 @@ import (
"github.com/replicatedhq/troubleshoot/internal/specs"
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
"github.com/replicatedhq/troubleshoot/pkg/k8sutil"
"github.com/replicatedhq/troubleshoot/pkg/loader"
"github.com/spf13/viper"
"k8s.io/client-go/kubernetes"
)
type PreflightSpecs struct {
PreflightSpec *troubleshootv1beta2.Preflight
HostPreflightSpec *troubleshootv1beta2.HostPreflight
UploadResultSpecs []*troubleshootv1beta2.Preflight
}
func (p *PreflightSpecs) Read(args []string) error {
func readSpecs(args []string) (*loader.TroubleshootKinds, error) {
config, err := k8sutil.GetRESTConfig()
if err != nil {
return errors.Wrap(err, "failed to convert kube flags to rest config")
return nil, errors.Wrap(err, "failed to convert kube flags to rest config")
}
client, err := kubernetes.NewForConfig(config)
if err != nil {
return errors.Wrap(err, "failed to convert create k8s client")
return nil, errors.Wrap(err, "failed to convert create k8s client")
}
ctx := context.Background()
kinds, err := specs.LoadFromCLIArgs(ctx, client, args, viper.GetViper())
if err != nil {
return err
return nil, err
}
ret := loader.NewTroubleshootKinds()
// Concatenate all preflight inclusterSpecs that don't have an upload destination
inclusterSpecs := []troubleshootv1beta2.Preflight{}
var concatenatedSpec *troubleshootv1beta2.Preflight
for _, v := range kinds.PreflightsV1Beta2 {
v := v // https://golang.org/doc/faq#closures_and_goroutines
if v.Spec.UploadResultsTo == "" {
p.PreflightSpec = ConcatPreflightSpec(p.PreflightSpec, &v)
concatenatedSpec = ConcatPreflightSpec(concatenatedSpec, &v)
} else {
p.UploadResultSpecs = append(p.UploadResultSpecs, &v)
inclusterSpecs = append(inclusterSpecs, v)
}
}
if concatenatedSpec != nil {
inclusterSpecs = append(inclusterSpecs, *concatenatedSpec)
}
ret.PreflightsV1Beta2 = inclusterSpecs
var hostSpec *troubleshootv1beta2.HostPreflight
for _, v := range kinds.HostPreflightsV1Beta2 {
v := v // https://golang.org/doc/faq#closures_and_goroutines
p.HostPreflightSpec = ConcatHostPreflightSpec(p.HostPreflightSpec, &v)
hostSpec = ConcatHostPreflightSpec(hostSpec, &v)
}
if hostSpec != nil {
ret.HostPreflightsV1Beta2 = []troubleshootv1beta2.HostPreflight{*hostSpec}
}
return nil
return ret, nil
}

View File

@@ -1,13 +1,13 @@
package preflight
import (
"log"
"os"
"path/filepath"
"testing"
"github.com/replicatedhq/troubleshoot/internal/testutils"
troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
"github.com/replicatedhq/troubleshoot/pkg/loader"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -26,7 +26,7 @@ type PreflightSpecsReadTest struct {
// TODOLATER: tests around this
wantHostPreflightSpec *troubleshootv1beta2.HostPreflight
// TODOLATER: tests around this
wantUploadResultSpecs []*troubleshootv1beta2.Preflight
wantUploadResultSpecs []troubleshootv1beta2.Preflight
}
// TODO: Simplify tests and rely on the loader tests
@@ -273,6 +273,32 @@ func TestPreflightSpecsRead(t *testing.T) {
wantHostPreflightSpec: nil,
wantUploadResultSpecs: nil,
},
PreflightSpecsReadTest{
name: "stdin-secret and support-bundle secret",
args: []string{
"-",
filepath.Join(testutils.FileDir(), "../../testdata/supportbundle/labelled-specs/sb-spec-1.yaml"),
},
customStdin: true,
stdinDataFile: preflightSecretFile,
wantErr: false,
wantPreflightSpec: &expectSecretPreflightSpec,
wantHostPreflightSpec: nil,
wantUploadResultSpecs: nil,
},
PreflightSpecsReadTest{
name: "stdin-secret and redact secret",
args: []string{
"-",
filepath.Join(testutils.FileDir(), "../../testdata/supportbundle/labelled-specs/redact-spec-1.yaml"),
},
customStdin: true,
stdinDataFile: preflightSecretFile,
wantErr: false,
wantPreflightSpec: &expectSecretPreflightSpec,
wantHostPreflightSpec: nil,
wantUploadResultSpecs: nil,
},
/*
/* TODOLATER: needs a cluster with a spec installed?
PreflightSpecsReadTest{
@@ -290,23 +316,48 @@ func TestPreflightSpecsRead(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt := tt // pin
specs := PreflightSpecs{}
tErr := singleTestPreflightSpecsRead(t, &tt, &specs)
specs, tErr := singleTestPreflightSpecsRead(t, &tt)
require.Equal(t, tt.wantErr, tErr != nil)
if tt.wantErr {
assert.Error(t, tErr)
} else {
require.NoError(t, tErr)
if tt.wantPreflightSpec != nil {
assert.Truef(t,
contains(specs.PreflightsV1Beta2, *tt.wantPreflightSpec),
"expected %v to contain %v", specs.PreflightsV1Beta2, *tt.wantPreflightSpec,
)
}
for _, wantUploadResultSpec := range tt.wantUploadResultSpecs {
assert.Truef(t,
contains(specs.PreflightsV1Beta2, wantUploadResultSpec),
"expected %v to contain %v", specs.PreflightsV1Beta2, wantUploadResultSpec,
)
}
if tt.wantHostPreflightSpec != nil {
assert.Truef(t,
contains(specs.HostPreflightsV1Beta2, *tt.wantHostPreflightSpec),
"expected %v to contain %v", testutils.AsJSON(t, specs.HostPreflightsV1Beta2), testutils.AsJSON(t, specs.HostPreflightsV1Beta2),
)
}
assert.Equal(t, specs.PreflightSpec, tt.wantPreflightSpec)
assert.Equal(t, specs.HostPreflightSpec, tt.wantHostPreflightSpec)
assert.Equal(t, specs.UploadResultSpecs, tt.wantUploadResultSpecs)
assert.Len(t, specs.SupportBundlesV1Beta2, 0)
assert.Len(t, specs.RedactorsV1Beta2, 0)
assert.Len(t, specs.AnalyzersV1Beta2, 0)
assert.Len(t, specs.CollectorsV1Beta2, 0)
assert.Len(t, specs.RemoteCollectorsV1Beta2, 0)
assert.Len(t, specs.HostCollectorsV1Beta2, 0)
})
}
}
func contains[T any](list []T, obj T) bool {
for _, item := range list {
if assert.ObjectsAreEqual(item, obj) {
return true
}
}
return false
}
func concatSpecs(target troubleshootv1beta2.Preflight, source troubleshootv1beta2.Preflight) *troubleshootv1beta2.Preflight {
newSpec := target.DeepCopy()
newSpec.Spec.Collectors = append(newSpec.Spec.Collectors, source.Spec.Collectors...)
@@ -317,7 +368,7 @@ func concatSpecs(target troubleshootv1beta2.Preflight, source troubleshootv1beta
}
// Structured as a separate function so we can use defer appropriately
func singleTestPreflightSpecsRead(t *testing.T, tt *PreflightSpecsReadTest, specs *PreflightSpecs) error {
func singleTestPreflightSpecsRead(t *testing.T, tt *PreflightSpecsReadTest) (*loader.TroubleshootKinds, error) {
var tmpfile *os.File
var err error
if tt.customStdin == true {
@@ -349,13 +400,13 @@ func singleTestPreflightSpecsRead(t *testing.T, tt *PreflightSpecsReadTest, spec
os.Stdin = tmpfile
}
err = specs.Read(tt.args)
kinds, err := readSpecs(tt.args)
if tt.customStdin == true {
if err = tmpfile.Close(); err != nil {
log.Fatal(err)
t.Fatal(err)
}
}
return err
return kinds, err
}

View File

@@ -41,19 +41,26 @@ func RunPreflights(interactive bool, output string, format string, args []string
os.Exit(1)
}()
specs := PreflightSpecs{}
err := specs.Read(args)
specs, err := readSpecs(args)
if err != nil {
return err
return types.NewExitCodeError(constants.EXIT_CODE_SPEC_ISSUES, err)
}
warning := validatePreflight(specs)
if warning != nil {
fmt.Println(warning.Warning())
return nil
}
if viper.GetBool("dry-run") {
out, err := specs.ToYaml()
if err != nil {
return types.NewExitCodeError(constants.EXIT_CODE_CATCH_ALL, errors.Wrap(err, "failed to convert specs to yaml"))
}
fmt.Printf("%s", out)
return nil
}
var collectResults []CollectResult
var uploadCollectResults []CollectResult
preflightSpecName := ""
@@ -74,41 +81,37 @@ func RunPreflights(interactive bool, output string, format string, args []string
uploadResultsMap := make(map[string][]CollectResult)
if specs.PreflightSpec != nil {
r, err := collectInCluster(ctx, specs.PreflightSpec, progressCh)
for _, spec := range specs.PreflightsV1Beta2 {
r, err := collectInCluster(ctx, &spec, progressCh)
if err != nil {
return types.NewExitCodeError(constants.EXIT_CODE_CATCH_ALL, errors.Wrap(err, "failed to collect in cluster"))
}
collectResults = append(collectResults, *r)
preflightSpecName = specs.PreflightSpec.Name
}
if specs.UploadResultSpecs != nil {
for _, spec := range specs.UploadResultSpecs {
r, err := collectInCluster(ctx, spec, progressCh)
if err != nil {
return types.NewExitCodeError(constants.EXIT_CODE_CATCH_ALL, errors.Wrap(err, "failed to collect in cluster"))
}
if spec.Spec.UploadResultsTo != "" {
uploadResultsMap[spec.Spec.UploadResultsTo] = append(uploadResultsMap[spec.Spec.UploadResultsTo], *r)
uploadCollectResults = append(collectResults, *r)
preflightSpecName = spec.Name
} else {
collectResults = append(collectResults, *r)
}
// TODO: This spec name will be overwritten by the next spec. Is this intentional?
preflightSpecName = spec.Name
}
if specs.HostPreflightSpec != nil {
if len(specs.HostPreflightSpec.Spec.Collectors) > 0 {
r, err := collectHost(ctx, specs.HostPreflightSpec, progressCh)
for _, spec := range specs.HostPreflightsV1Beta2 {
if len(spec.Spec.Collectors) > 0 {
r, err := collectHost(ctx, &spec, progressCh)
if err != nil {
return types.NewExitCodeError(constants.EXIT_CODE_CATCH_ALL, errors.Wrap(err, "failed to collect from host"))
}
collectResults = append(collectResults, *r)
}
if len(specs.HostPreflightSpec.Spec.RemoteCollectors) > 0 {
r, err := collectRemote(ctx, specs.HostPreflightSpec, progressCh)
if len(spec.Spec.RemoteCollectors) > 0 {
r, err := collectRemote(ctx, &spec, progressCh)
if err != nil {
return types.NewExitCodeError(constants.EXIT_CODE_CATCH_ALL, errors.Wrap(err, "failed to collect remotely"))
}
collectResults = append(collectResults, *r)
}
preflightSpecName = specs.HostPreflightSpec.Name
preflightSpecName = spec.Name
}
if collectResults == nil && uploadCollectResults == nil {

View File

@@ -4,45 +4,37 @@ import (
"reflect"
"github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2"
"github.com/replicatedhq/troubleshoot/pkg/loader"
"github.com/replicatedhq/troubleshoot/pkg/multitype"
"github.com/replicatedhq/troubleshoot/pkg/types"
)
// validatePreflight validates the preflight spec and returns a warning if there is any
func validatePreflight(specs PreflightSpecs) *types.ExitCodeWarning {
func validatePreflight(kinds *loader.TroubleshootKinds) *types.ExitCodeWarning {
if specs.PreflightSpec == nil && specs.HostPreflightSpec == nil && specs.UploadResultSpecs == nil {
if len(kinds.PreflightsV1Beta2) == 0 && len(kinds.HostPreflightsV1Beta2) == 0 {
return types.NewExitCodeWarning("no preflight or host preflight spec was found")
}
if specs.PreflightSpec != nil {
warning := validatePreflightSpecItems(specs.PreflightSpec.Spec.Collectors, specs.PreflightSpec.Spec.Analyzers)
for _, spec := range kinds.PreflightsV1Beta2 {
warning := validatePreflightSpecItems(spec.Spec.Collectors, spec.Spec.Analyzers)
if warning != nil {
return warning
}
}
if specs.HostPreflightSpec != nil {
warning := validateHostPreflightSpecItems(specs.HostPreflightSpec.Spec.Collectors, specs.HostPreflightSpec.Spec.Analyzers)
for _, spec := range kinds.HostPreflightsV1Beta2 {
warning := validateHostPreflightSpecItems(spec.Spec.Collectors, spec.Spec.Analyzers)
if warning != nil {
return warning
}
}
if specs.UploadResultSpecs != nil {
for _, preflight := range specs.UploadResultSpecs {
warning := validatePreflightSpecItems(preflight.Spec.Collectors, preflight.Spec.Analyzers)
if warning != nil {
return warning
}
}
}
return nil
}
// validatePreflightSpecItems validates the preflight spec items and returns a warning if there is any
// clusterResources and clusterInfo collectors are added automatically to the preflight spec, cannot be excluded
// validatePreflightSpecItems validates the preflight spec items and returns a warning if there are any
// clusterResources or clusterInfo collectors added automatically to the preflight spec. It cannot be excluded
func validatePreflightSpecItems(collectors []*v1beta2.Collect, analyzers []*v1beta2.Analyze) *types.ExitCodeWarning {
var numberOfExcludedCollectors, numberOfExcludedAnalyzers int
var numberOfExcludedDefaultCollectors int

View File

@@ -5,8 +5,10 @@ import (
"testing"
"github.com/replicatedhq/troubleshoot/internal/testutils"
"github.com/replicatedhq/troubleshoot/pkg/loader"
"github.com/replicatedhq/troubleshoot/pkg/types"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestValidatePreflight(t *testing.T) {
@@ -93,10 +95,14 @@ func TestValidatePreflight(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
testFilePath := filepath.Join(testutils.FileDir(), "../../testdata/preflightspec/"+tt.preflightSpec)
specs := PreflightSpecs{}
specs.Read([]string{testFilePath})
gotWarning := validatePreflight(specs)
kinds := loader.NewTroubleshootKinds()
if tt.preflightSpec != "" {
testFilePath := filepath.Join(testutils.FileDir(), "../../testdata/preflightspec/"+tt.preflightSpec)
var err error
kinds, err = readSpecs([]string{testFilePath})
require.NoError(t, err)
}
gotWarning := validatePreflight(kinds)
assert.Equal(t, tt.wantWarning, gotWarning)
})
}