mirror of
https://github.com/replicatedhq/troubleshoot.git
synced 2026-02-14 18:29:53 +00:00
154 lines
5.2 KiB
Go
154 lines
5.2 KiB
Go
package preflight
|
|
|
|
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(kinds *loader.TroubleshootKinds) *types.ExitCodeWarning {
|
|
|
|
if len(kinds.PreflightsV1Beta2) == 0 && len(kinds.HostPreflightsV1Beta2) == 0 {
|
|
return types.NewExitCodeWarning("no preflight or host preflight spec was found")
|
|
}
|
|
|
|
for _, spec := range kinds.PreflightsV1Beta2 {
|
|
warning := validatePreflightSpecItems(spec.Spec.Collectors, spec.Spec.Analyzers)
|
|
if warning != nil {
|
|
return warning
|
|
}
|
|
}
|
|
|
|
for _, spec := range kinds.HostPreflightsV1Beta2 {
|
|
warning := validateHostPreflightSpecItems(spec.Spec.Collectors, spec.Spec.Analyzers)
|
|
if warning != nil {
|
|
return warning
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// 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
|
|
numberOfCollectors := len(collectors) + 2
|
|
numberOfAnalyzers := len(analyzers)
|
|
|
|
if numberOfCollectors >= 0 {
|
|
collectorsInterface := make([]interface{}, len(collectors))
|
|
for i, v := range collectors {
|
|
if v.ClusterInfo != nil || v.ClusterResources != nil {
|
|
numberOfExcludedDefaultCollectors++
|
|
}
|
|
collectorsInterface[i] = v
|
|
}
|
|
|
|
numberOfExcludedCollectors += countExcludedItems(collectorsInterface)
|
|
|
|
if numberOfExcludedCollectors+numberOfExcludedDefaultCollectors == numberOfCollectors {
|
|
return types.NewExitCodeWarning("All collectors were excluded by the applied values")
|
|
}
|
|
}
|
|
|
|
// if there are no analyzers, return a warning
|
|
// else check if all analyzers are excluded
|
|
if numberOfAnalyzers == 0 {
|
|
return types.NewExitCodeWarning("No analyzers found")
|
|
} else {
|
|
analyzersInterface := make([]interface{}, len(analyzers))
|
|
for i, v := range analyzers {
|
|
analyzersInterface[i] = v
|
|
}
|
|
|
|
numberOfExcludedAnalyzers = countExcludedItems(analyzersInterface)
|
|
|
|
if numberOfExcludedAnalyzers == numberOfAnalyzers {
|
|
return types.NewExitCodeWarning("All analyzers were excluded by the applied values")
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// validateHostPreflightSpecItems validates the host preflight spec items and returns a warning if there is any
|
|
// no collectors are added or excluded automatically to the host preflight spec
|
|
func validateHostPreflightSpecItems(collectors []*v1beta2.HostCollect, analyzers []*v1beta2.HostAnalyze) *types.ExitCodeWarning {
|
|
var numberOfExcludedCollectors, numberOfExcludedAnalyzers int
|
|
numberOfCollectors := len(collectors)
|
|
numberOfAnalyzers := len(analyzers)
|
|
|
|
// if there are no collectors, return a warning
|
|
if numberOfCollectors == 0 {
|
|
return types.NewExitCodeWarning("No collectors found")
|
|
}
|
|
|
|
// if there are no analyzers, return a warning
|
|
if numberOfAnalyzers == 0 {
|
|
return types.NewExitCodeWarning("No analyzers found")
|
|
}
|
|
|
|
collectorsInterface := make([]interface{}, len(collectors))
|
|
for i, v := range collectors {
|
|
collectorsInterface[i] = v
|
|
}
|
|
|
|
analyzersInterface := make([]interface{}, len(analyzers))
|
|
for i, v := range analyzers {
|
|
analyzersInterface[i] = v
|
|
}
|
|
|
|
numberOfExcludedCollectors = countExcludedItems(collectorsInterface)
|
|
numberOfExcludedAnalyzers = countExcludedItems(analyzersInterface)
|
|
|
|
if numberOfExcludedCollectors == numberOfCollectors {
|
|
return types.NewExitCodeWarning("All collectors were excluded by the applied values")
|
|
}
|
|
|
|
if numberOfExcludedAnalyzers == numberOfAnalyzers {
|
|
return types.NewExitCodeWarning("All analyzers were excluded by the applied values")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// countExcludedItems counts and returns the number of excluded items in the given items slice.
|
|
// Items are assumed to be structures that may have an "Exclude" field as bool
|
|
// If the "Exclude" field is true, the item is considered excluded.
|
|
func countExcludedItems(items []interface{}) int {
|
|
numberOfExcludedItems := 0
|
|
for _, item := range items {
|
|
itemElem := reflect.ValueOf(item).Elem()
|
|
|
|
// Loop over all fields of the current item.
|
|
for i := 0; i < itemElem.NumField(); i++ {
|
|
// Get the value of the current field.
|
|
itemValue := itemElem.Field(i)
|
|
// If the current field is a pointer to a struct, check if it has an "Exclude" field.
|
|
if !itemValue.IsNil() {
|
|
elem := itemValue.Elem()
|
|
if elem.Kind() == reflect.Struct {
|
|
// Look for a field named "Exclude" in the struct.
|
|
excludeField := elem.FieldByName("Exclude")
|
|
if excludeField.IsValid() {
|
|
// Try to get the field's value as a *multitype.BoolOrString.
|
|
excludeValue, ok := excludeField.Interface().(*multitype.BoolOrString)
|
|
// If the field's value was successfully obtained and is not nil, and the value is true
|
|
if ok && excludeValue != nil {
|
|
if excludeValue.BoolOrDefaultFalse() {
|
|
numberOfExcludedItems++
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return numberOfExcludedItems
|
|
}
|