feat: rework filters

Signed-off-by: Matthis Holleville <matthish29@gmail.com>
This commit is contained in:
Matthis Holleville
2023-03-31 15:43:52 +02:00
parent 975813d328
commit 3ed545f33f
6 changed files with 65 additions and 31 deletions

View File

@@ -47,7 +47,7 @@ If you install gcc as suggested, the problem will persist. Therefore, you need t
* Currently the default AI provider is OpenAI, you will need to generate an API key from [OpenAI](https://openai.com) * Currently the default AI provider is OpenAI, you will need to generate an API key from [OpenAI](https://openai.com)
* You can do this by running `k8sgpt generate` to open a browser link to generate it * You can do this by running `k8sgpt generate` to open a browser link to generate it
* Run `k8sgpt auth` to set it in k8sgpt. * Run `k8sgpt auth` to set it in k8sgpt.
* Run `k8sgpt filters` to manage the default filters used by the analyzer. By default, all filters are executed during analysis. * Run `k8sgpt filters` to manage the active filters used by the analyzer. By default, all filters are executed during analysis.
* Run `k8sgpt analyze` to run a scan. * Run `k8sgpt analyze` to run a scan.
* And use `k8sgpt analyze --explain` to get a more detailed explanation of the issues. * And use `k8sgpt analyze --explain` to get a more detailed explanation of the issues.

View File

@@ -17,17 +17,18 @@ var addCmd = &cobra.Command{
Long: `The add command adds one or more new filters to the default set of filters used by the analyze.`, Long: `The add command adds one or more new filters to the default set of filters used by the analyze.`,
Args: cobra.ExactArgs(1), Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
filters := strings.Split(args[0], ",") inputFilters := strings.Split(args[0], ",")
availableFilters := analyzer.ListFilters()
// Verify filter exist // Verify filter exist
invalidFilters := []string{} invalidFilters := []string{}
for _, f := range filters { for _, f := range inputFilters {
if f == "" { if f == "" {
color.Red("Filter cannot be empty. Please use correct syntax.") color.Red("Filter cannot be empty. Please use correct syntax.")
os.Exit(1) os.Exit(1)
} }
foundFilter := false foundFilter := false
for _, filter := range analyzer.ListFilters() { for _, filter := range availableFilters {
if filter == f { if filter == f {
foundFilter = true foundFilter = true
break break
@@ -43,13 +44,13 @@ var addCmd = &cobra.Command{
os.Exit(1) os.Exit(1)
} }
// Get defined default_filters // Get defined active_filters
defaultFilters := viper.GetStringSlice("default_filters") activeFilters := viper.GetStringSlice("active_filters")
if len(defaultFilters) == 0 { if len(activeFilters) == 0 {
defaultFilters = []string{} activeFilters = availableFilters
} }
mergedFilters := append(defaultFilters, filters...) mergedFilters := append(activeFilters, inputFilters...)
uniqueFilters, dupplicatedFilters := util.RemoveDuplicates(mergedFilters) uniqueFilters, dupplicatedFilters := util.RemoveDuplicates(mergedFilters)
@@ -59,12 +60,12 @@ var addCmd = &cobra.Command{
os.Exit(1) os.Exit(1)
} }
viper.Set("default_filters", uniqueFilters) viper.Set("active_filters", uniqueFilters)
if err := viper.WriteConfig(); err != nil { if err := viper.WriteConfig(); err != nil {
color.Red("Error writing config file: %s", err.Error()) color.Red("Error writing config file: %s", err.Error())
os.Exit(1) os.Exit(1)
} }
color.Green("Filter %s added", strings.Join(filters, ", ")) color.Green("Filter %s added", strings.Join(inputFilters, ", "))
}, },
} }

View File

@@ -5,7 +5,9 @@ import (
"github.com/fatih/color" "github.com/fatih/color"
"github.com/k8sgpt-ai/k8sgpt/pkg/analyzer" "github.com/k8sgpt-ai/k8sgpt/pkg/analyzer"
"github.com/k8sgpt-ai/k8sgpt/pkg/util"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper"
) )
var listCmd = &cobra.Command{ var listCmd = &cobra.Command{
@@ -13,9 +15,25 @@ var listCmd = &cobra.Command{
Short: "List available filters", Short: "List available filters",
Long: `The list command displays a list of available filters that can be used to analyze Kubernetes resources.`, Long: `The list command displays a list of available filters that can be used to analyze Kubernetes resources.`,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
fmt.Printf("Available filters : \n") activeFilters := viper.GetStringSlice("active_filters")
for _, analyzer := range analyzer.ListFilters() { availableFilters := analyzer.ListFilters()
fmt.Printf("> %s\n", color.GreenString(analyzer))
if len(activeFilters) == 0 {
activeFilters = availableFilters
} }
inactiveFilters := util.SliceDiff(availableFilters, activeFilters)
fmt.Printf(color.YellowString("Active: \n"))
for _, filter := range activeFilters {
fmt.Printf("> %s\n", color.GreenString(filter))
}
// display inactive filters
if len(inactiveFilters) != 0 {
fmt.Printf(color.YellowString("Unused: \n"))
for _, filter := range inactiveFilters {
fmt.Printf("> %s\n", color.RedString(filter))
}
}
}, },
} }

View File

@@ -5,6 +5,7 @@ import (
"strings" "strings"
"github.com/fatih/color" "github.com/fatih/color"
"github.com/k8sgpt-ai/k8sgpt/pkg/analyzer"
"github.com/k8sgpt-ai/k8sgpt/pkg/util" "github.com/k8sgpt-ai/k8sgpt/pkg/util"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper" "github.com/spf13/viper"
@@ -16,16 +17,16 @@ var removeCmd = &cobra.Command{
Long: `The add command remove one or more filters to the default set of filters used by the analyze.`, Long: `The add command remove one or more filters to the default set of filters used by the analyze.`,
Args: cobra.ExactArgs(1), Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
filters := strings.Split(args[0], ",") inputFilters := strings.Split(args[0], ",")
// Get defined default_filters // Get defined active_filters
defaultFilters := viper.GetStringSlice("default_filters") activeFilters := viper.GetStringSlice("active_filters")
if len(defaultFilters) == 0 { if len(activeFilters) == 0 {
defaultFilters = []string{} activeFilters = analyzer.ListFilters()
} }
// Check if input filters is not empty // Check if input input filters is not empty
for _, f := range filters { for _, f := range inputFilters {
if f == "" { if f == "" {
color.Red("Filter cannot be empty. Please use correct syntax.") color.Red("Filter cannot be empty. Please use correct syntax.")
os.Exit(1) os.Exit(1)
@@ -33,7 +34,7 @@ var removeCmd = &cobra.Command{
} }
// verify dupplicate filters example: k8sgpt filters remove Pod Pod // verify dupplicate filters example: k8sgpt filters remove Pod Pod
uniqueFilters, dupplicatedFilters := util.RemoveDuplicates(filters) uniqueFilters, dupplicatedFilters := util.RemoveDuplicates(inputFilters)
if len(dupplicatedFilters) != 0 { if len(dupplicatedFilters) != 0 {
color.Red("Duplicate filters found: %s", strings.Join(dupplicatedFilters, ", ")) color.Red("Duplicate filters found: %s", strings.Join(dupplicatedFilters, ", "))
os.Exit(1) os.Exit(1)
@@ -43,10 +44,10 @@ var removeCmd = &cobra.Command{
filterNotFound := []string{} filterNotFound := []string{}
for _, filter := range uniqueFilters { for _, filter := range uniqueFilters {
foundFilter := false foundFilter := false
for i, f := range defaultFilters { for i, f := range activeFilters {
if f == filter { if f == filter {
foundFilter = true foundFilter = true
defaultFilters = append(defaultFilters[:i], defaultFilters[i+1:]...) activeFilters = append(activeFilters[:i], activeFilters[i+1:]...)
break break
} }
} }
@@ -60,12 +61,12 @@ var removeCmd = &cobra.Command{
os.Exit(1) os.Exit(1)
} }
viper.Set("default_filters", defaultFilters) viper.Set("active_filters", activeFilters)
if err := viper.WriteConfig(); err != nil { if err := viper.WriteConfig(); err != nil {
color.Red("Error writing config file: %s", err.Error()) color.Red("Error writing config file: %s", err.Error())
os.Exit(1) os.Exit(1)
} }
color.Green("Filter(s) %s removed", strings.Join(filters, ", ")) color.Green("Filter(s) %s removed", strings.Join(inputFilters, ", "))
}, },
} }

View File

@@ -24,10 +24,10 @@ func RunAnalysis(ctx context.Context, filters []string, config *AnalysisConfigur
client *kubernetes.Client, client *kubernetes.Client,
aiClient ai.IAI, analysisResults *[]Analysis) error { aiClient ai.IAI, analysisResults *[]Analysis) error {
defaultFilters := viper.GetStringSlice("default_filters") activeFilters := viper.GetStringSlice("active_filters")
// if there are no filters selected and no default_filters then run all of them // if there are no filters selected and no active_filters then run all of them
if len(filters) == 0 && len(defaultFilters) == 0 { if len(filters) == 0 && len(activeFilters) == 0 {
for _, analyzer := range analyzerMap { for _, analyzer := range analyzerMap {
if err := analyzer(ctx, config, client, aiClient, analysisResults); err != nil { if err := analyzer(ctx, config, client, aiClient, analysisResults); err != nil {
return err return err
@@ -48,8 +48,8 @@ func RunAnalysis(ctx context.Context, filters []string, config *AnalysisConfigur
return nil return nil
} }
// use default_filters // use active_filters
for _, filter := range defaultFilters { for _, filter := range activeFilters {
if analyzer, ok := analyzerMap[filter]; ok { if analyzer, ok := analyzerMap[filter]; ok {
if err := analyzer(ctx, config, client, aiClient, analysisResults); err != nil { if err := analyzer(ctx, config, client, aiClient, analysisResults); err != nil {
return err return err

View File

@@ -82,3 +82,17 @@ func RemoveDuplicates(slice []string) ([]string, []string) {
} }
return uniqueSlice, duplicates return uniqueSlice, duplicates
} }
func SliceDiff(source, dest []string) []string {
mb := make(map[string]struct{}, len(dest))
for _, x := range dest {
mb[x] = struct{}{}
}
var diff []string
for _, x := range source {
if _, found := mb[x]; !found {
diff = append(diff, x)
}
}
return diff
}