Ver código fonte

add suggestion on cscli install items (#1686)

AlteredCoder 2 anos atrás
pai
commit
fe5f9bfc28

+ 6 - 0
cmd/crowdsec-cli/collections.go

@@ -59,6 +59,12 @@ func NewCollectionsCmd() *cobra.Command {
 		DisableAutoGenTag: true,
 		DisableAutoGenTag: true,
 		Run: func(cmd *cobra.Command, args []string) {
 		Run: func(cmd *cobra.Command, args []string) {
 			for _, name := range args {
 			for _, name := range args {
+				t := cwhub.GetItem(cwhub.COLLECTIONS, name)
+				if t == nil {
+					nearestItem, score := GetDistance(cwhub.COLLECTIONS, name)
+					Suggest(cwhub.COLLECTIONS, name, nearestItem.Name, score, ignoreError)
+					continue
+				}
 				if err := cwhub.InstallItem(csConfig, name, cwhub.COLLECTIONS, forceAction, downloadOnly); err != nil {
 				if err := cwhub.InstallItem(csConfig, name, cwhub.COLLECTIONS, forceAction, downloadOnly); err != nil {
 					if !ignoreError {
 					if !ignoreError {
 						log.Fatalf("Error while installing '%s': %s", name, err)
 						log.Fatalf("Error while installing '%s': %s", name, err)

+ 6 - 0
cmd/crowdsec-cli/parsers.go

@@ -62,6 +62,12 @@ cscli parsers remove crowdsecurity/sshd-logs
 		},
 		},
 		Run: func(cmd *cobra.Command, args []string) {
 		Run: func(cmd *cobra.Command, args []string) {
 			for _, name := range args {
 			for _, name := range args {
+				t := cwhub.GetItem(cwhub.PARSERS, name)
+				if t == nil {
+					nearestItem, score := GetDistance(cwhub.PARSERS, name)
+					Suggest(cwhub.PARSERS, name, nearestItem.Name, score, ignoreError)
+					continue
+				}
 				if err := cwhub.InstallItem(csConfig, name, cwhub.PARSERS, forceAction, downloadOnly); err != nil {
 				if err := cwhub.InstallItem(csConfig, name, cwhub.PARSERS, forceAction, downloadOnly); err != nil {
 					if ignoreError {
 					if ignoreError {
 						log.Errorf("Error while installing '%s': %s", name, err)
 						log.Errorf("Error while installing '%s': %s", name, err)

+ 6 - 0
cmd/crowdsec-cli/postoverflows.go

@@ -61,6 +61,12 @@ func NewPostOverflowsCmd() *cobra.Command {
 		},
 		},
 		Run: func(cmd *cobra.Command, args []string) {
 		Run: func(cmd *cobra.Command, args []string) {
 			for _, name := range args {
 			for _, name := range args {
+				t := cwhub.GetItem(cwhub.PARSERS_OVFLW, name)
+				if t == nil {
+					nearestItem, score := GetDistance(cwhub.PARSERS_OVFLW, name)
+					Suggest(cwhub.PARSERS_OVFLW, name, nearestItem.Name, score, ignoreError)
+					continue
+				}
 				if err := cwhub.InstallItem(csConfig, name, cwhub.PARSERS_OVFLW, forceAction, downloadOnly); err != nil {
 				if err := cwhub.InstallItem(csConfig, name, cwhub.PARSERS_OVFLW, forceAction, downloadOnly); err != nil {
 					if ignoreError {
 					if ignoreError {
 						log.Errorf("Error while installing '%s': %s", name, err)
 						log.Errorf("Error while installing '%s': %s", name, err)

+ 6 - 1
cmd/crowdsec-cli/scenarios.go

@@ -5,7 +5,6 @@ import (
 
 
 	"github.com/crowdsecurity/crowdsec/pkg/cwhub"
 	"github.com/crowdsecurity/crowdsec/pkg/cwhub"
 	"github.com/pkg/errors"
 	"github.com/pkg/errors"
-
 	log "github.com/sirupsen/logrus"
 	log "github.com/sirupsen/logrus"
 
 
 	"github.com/spf13/cobra"
 	"github.com/spf13/cobra"
@@ -65,6 +64,12 @@ cscli scenarios remove crowdsecurity/ssh-bf
 		DisableAutoGenTag: true,
 		DisableAutoGenTag: true,
 		Run: func(cmd *cobra.Command, args []string) {
 		Run: func(cmd *cobra.Command, args []string) {
 			for _, name := range args {
 			for _, name := range args {
+				t := cwhub.GetItem(cwhub.SCENARIOS, name)
+				if t == nil {
+					nearestItem, score := GetDistance(cwhub.SCENARIOS, name)
+					Suggest(cwhub.SCENARIOS, name, nearestItem.Name, score, ignoreError)
+					continue
+				}
 				if err := cwhub.InstallItem(csConfig, name, cwhub.SCENARIOS, forceAction, downloadOnly); err != nil {
 				if err := cwhub.InstallItem(csConfig, name, cwhub.SCENARIOS, forceAction, downloadOnly); err != nil {
 					if ignoreError {
 					if ignoreError {
 						log.Errorf("Error while installing '%s': %s", name, err)
 						log.Errorf("Error while installing '%s': %s", name, err)

+ 36 - 0
cmd/crowdsec-cli/utils.go

@@ -21,9 +21,12 @@ import (
 	"github.com/prometheus/prom2json"
 	"github.com/prometheus/prom2json"
 	log "github.com/sirupsen/logrus"
 	log "github.com/sirupsen/logrus"
 	"github.com/spf13/cobra"
 	"github.com/spf13/cobra"
+	"github.com/texttheater/golang-levenshtein/levenshtein"
 	"gopkg.in/yaml.v2"
 	"gopkg.in/yaml.v2"
 )
 )
 
 
+const MaxDistance = 7
+
 func printHelp(cmd *cobra.Command) {
 func printHelp(cmd *cobra.Command) {
 	err := cmd.Help()
 	err := cmd.Help()
 	if err != nil {
 	if err != nil {
@@ -68,6 +71,39 @@ func LoadHub() error {
 	return nil
 	return nil
 }
 }
 
 
+func Suggest(itemType string, baseItem string, suggestItem string, score int, ignoreErr bool) {
+	errMsg := ""
+	if score < MaxDistance {
+		errMsg = fmt.Sprintf("unable to find %s '%s', did you mean %s ?", itemType, baseItem, suggestItem)
+	} else {
+		errMsg = fmt.Sprintf("unable to find %s '%s'", itemType, baseItem)
+	}
+	if ignoreErr {
+		log.Error(errMsg)
+	} else {
+		log.Fatalf(errMsg)
+	}
+}
+
+func GetDistance(itemType string, itemName string) (*cwhub.Item, int) {
+	allItems := make([]string, 0)
+	nearestScore := 100
+	nearestItem := &cwhub.Item{}
+	hubItems := cwhub.GetHubStatusForItemType(itemType, "", true)
+	for _, item := range hubItems {
+		allItems = append(allItems, item.Name)
+	}
+
+	for _, s := range allItems {
+		d := levenshtein.DistanceForStrings([]rune(itemName), []rune(s), levenshtein.DefaultOptions)
+		if d < nearestScore {
+			nearestScore = d
+			nearestItem = cwhub.GetItem(itemType, s)
+		}
+	}
+	return nearestItem, nearestScore
+}
+
 func compAllItems(itemType string, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
 func compAllItems(itemType string, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
 	if err := LoadHub(); err != nil {
 	if err := LoadHub(); err != nil {
 		return nil, cobra.ShellCompDirectiveDefault
 		return nil, cobra.ShellCompDirectiveDefault

+ 1 - 0
go.mod

@@ -152,6 +152,7 @@ require (
 	github.com/robfig/cron/v3 v3.0.1 // indirect
 	github.com/robfig/cron/v3 v3.0.1 // indirect
 	github.com/russross/blackfriday/v2 v2.1.0 // indirect
 	github.com/russross/blackfriday/v2 v2.1.0 // indirect
 	github.com/spf13/pflag v1.0.5 // indirect
 	github.com/spf13/pflag v1.0.5 // indirect
+	github.com/texttheater/golang-levenshtein/levenshtein v0.0.0-20200805054039-cae8b0eaed6c // indirect
 	github.com/tidwall/gjson v1.13.0 // indirect
 	github.com/tidwall/gjson v1.13.0 // indirect
 	github.com/ugorji/go/codec v1.2.6 // indirect
 	github.com/ugorji/go/codec v1.2.6 // indirect
 	github.com/vjeantet/grok v1.0.1 // indirect
 	github.com/vjeantet/grok v1.0.1 // indirect

+ 2 - 0
go.sum

@@ -719,6 +719,8 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.7.1-0.20210427113832-6241f9ab9942 h1:t0lM6y/M5IiUZyvbBTcngso8SZEZICH7is9B6g/obVU=
 github.com/stretchr/testify v1.7.1-0.20210427113832-6241f9ab9942 h1:t0lM6y/M5IiUZyvbBTcngso8SZEZICH7is9B6g/obVU=
 github.com/stretchr/testify v1.7.1-0.20210427113832-6241f9ab9942/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.7.1-0.20210427113832-6241f9ab9942/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/texttheater/golang-levenshtein/levenshtein v0.0.0-20200805054039-cae8b0eaed6c h1:HelZ2kAFadG0La9d+4htN4HzQ68Bm2iM9qKMSMES6xg=
+github.com/texttheater/golang-levenshtein/levenshtein v0.0.0-20200805054039-cae8b0eaed6c/go.mod h1:JlzghshsemAMDGZLytTFY8C1JQxQPhnatWqNwUXjggo=
 github.com/tidwall/gjson v1.12.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
 github.com/tidwall/gjson v1.12.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
 github.com/tidwall/gjson v1.13.0 h1:3TFY9yxOQShrvmjdM76K+jc66zJeT6D3/VFFYCGQf7M=
 github.com/tidwall/gjson v1.13.0 h1:3TFY9yxOQShrvmjdM76K+jc66zJeT6D3/VFFYCGQf7M=
 github.com/tidwall/gjson v1.13.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
 github.com/tidwall/gjson v1.13.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=