mirror of
https://github.com/crowdsecurity/crowdsec.git
synced 2025-05-10 20:05:55 +02:00
143 lines
3.4 KiB
Go
143 lines
3.4 KiB
Go
package clihub
|
|
|
|
import (
|
|
"encoding/csv"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"slices"
|
|
"strings"
|
|
|
|
"github.com/crowdsecurity/crowdsec/pkg/cwhub"
|
|
)
|
|
|
|
// selectItems returns a slice of items of a given type, selected by name and sorted by case-insensitive name
|
|
func SelectItems(hub *cwhub.Hub, itemType string, args []string, installedOnly bool) ([]*cwhub.Item, error) {
|
|
allItems := hub.GetItemsByType(itemType, true)
|
|
|
|
itemNames := make([]string, len(allItems))
|
|
for idx, item := range allItems {
|
|
itemNames[idx] = item.Name
|
|
}
|
|
|
|
notExist := []string{}
|
|
|
|
if len(args) > 0 {
|
|
for _, arg := range args {
|
|
if !slices.Contains(itemNames, arg) {
|
|
notExist = append(notExist, arg)
|
|
}
|
|
}
|
|
}
|
|
|
|
if len(notExist) > 0 {
|
|
return nil, fmt.Errorf("item(s) '%s' not found in %s", strings.Join(notExist, ", "), itemType)
|
|
}
|
|
|
|
if len(args) > 0 {
|
|
itemNames = args
|
|
installedOnly = false
|
|
}
|
|
|
|
wantedItems := make([]*cwhub.Item, 0, len(itemNames))
|
|
|
|
for _, itemName := range itemNames {
|
|
item := hub.GetItem(itemType, itemName)
|
|
if installedOnly && !item.State.IsInstalled() {
|
|
continue
|
|
}
|
|
|
|
wantedItems = append(wantedItems, item)
|
|
}
|
|
|
|
return wantedItems, nil
|
|
}
|
|
|
|
func ListItems(out io.Writer, wantColor string, itemTypes []string, items map[string][]*cwhub.Item, omitIfEmpty bool, output string) error {
|
|
switch output {
|
|
case "human":
|
|
nothingToDisplay := true
|
|
|
|
for _, itemType := range itemTypes {
|
|
if omitIfEmpty && len(items[itemType]) == 0 {
|
|
continue
|
|
}
|
|
|
|
listHubItemTable(out, wantColor, strings.ToUpper(itemType), items[itemType])
|
|
|
|
nothingToDisplay = false
|
|
}
|
|
|
|
if nothingToDisplay {
|
|
fmt.Println("No items to display")
|
|
}
|
|
case "json":
|
|
type itemHubStatus struct {
|
|
Name string `json:"name"`
|
|
LocalVersion string `json:"local_version"`
|
|
LocalPath string `json:"local_path"`
|
|
Description string `json:"description"`
|
|
UTF8Status string `json:"utf8_status"`
|
|
Status string `json:"status"`
|
|
}
|
|
|
|
hubStatus := make(map[string][]itemHubStatus)
|
|
for _, itemType := range itemTypes {
|
|
// empty slice in case there are no items of this type
|
|
hubStatus[itemType] = make([]itemHubStatus, len(items[itemType]))
|
|
|
|
for i, item := range items[itemType] {
|
|
status := item.State.Text()
|
|
statusEmo := item.State.Emoji()
|
|
hubStatus[itemType][i] = itemHubStatus{
|
|
Name: item.Name,
|
|
LocalVersion: item.State.LocalVersion,
|
|
LocalPath: item.State.LocalPath,
|
|
Description: strings.TrimSpace(item.Description),
|
|
Status: status,
|
|
UTF8Status: fmt.Sprintf("%v %s", statusEmo, status),
|
|
}
|
|
}
|
|
}
|
|
|
|
x, err := json.MarshalIndent(hubStatus, "", " ")
|
|
if err != nil {
|
|
return fmt.Errorf("failed to parse: %w", err)
|
|
}
|
|
|
|
fmt.Fprint(out, string(x))
|
|
case "raw":
|
|
csvwriter := csv.NewWriter(out)
|
|
|
|
header := []string{"name", "status", "version", "description"}
|
|
if len(itemTypes) > 1 {
|
|
header = append(header, "type")
|
|
}
|
|
|
|
if err := csvwriter.Write(header); err != nil {
|
|
return fmt.Errorf("failed to write header: %w", err)
|
|
}
|
|
|
|
for _, itemType := range itemTypes {
|
|
for _, item := range items[itemType] {
|
|
row := []string{
|
|
item.Name,
|
|
item.State.Text(),
|
|
item.State.LocalVersion,
|
|
strings.TrimSpace(item.Description),
|
|
}
|
|
if len(itemTypes) > 1 {
|
|
row = append(row, itemType)
|
|
}
|
|
|
|
if err := csvwriter.Write(row); err != nil {
|
|
return fmt.Errorf("failed to write raw output: %w", err)
|
|
}
|
|
}
|
|
}
|
|
|
|
csvwriter.Flush()
|
|
}
|
|
|
|
return nil
|
|
}
|