items.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. package main
  2. import (
  3. "encoding/csv"
  4. "encoding/json"
  5. "fmt"
  6. "io"
  7. "slices"
  8. "sort"
  9. "strings"
  10. log "github.com/sirupsen/logrus"
  11. "gopkg.in/yaml.v2"
  12. "github.com/crowdsecurity/crowdsec/pkg/cwhub"
  13. )
  14. func selectItems(hub *cwhub.Hub, itemType string, args []string, installedOnly bool) ([]string, error) {
  15. itemNames := hub.GetItemNames(itemType)
  16. notExist := []string{}
  17. if len(args) > 0 {
  18. installedOnly = false
  19. for _, arg := range args {
  20. if !slices.Contains(itemNames, arg) {
  21. notExist = append(notExist, arg)
  22. }
  23. }
  24. }
  25. if len(notExist) > 0 {
  26. return nil, fmt.Errorf("item(s) '%s' not found in %s", strings.Join(notExist, ", "), itemType)
  27. }
  28. if len(args) > 0 {
  29. itemNames = args
  30. }
  31. if installedOnly {
  32. installed := []string{}
  33. for _, item := range itemNames {
  34. if hub.GetItem(itemType, item).Installed {
  35. installed = append(installed, item)
  36. }
  37. }
  38. return installed, nil
  39. }
  40. return itemNames, nil
  41. }
  42. func ListItems(out io.Writer, itemTypes []string, args []string, showType bool, showHeader bool, all bool) error {
  43. var err error
  44. hub, err := cwhub.GetHub()
  45. if err != nil {
  46. return err
  47. }
  48. items := make(map[string][]string)
  49. for _, itemType := range itemTypes {
  50. if items[itemType], err = selectItems(hub, itemType, args, !all); err != nil {
  51. return err
  52. }
  53. }
  54. if csConfig.Cscli.Output == "human" {
  55. for _, itemType := range itemTypes {
  56. listHubItemTable(out, "\n"+strings.ToUpper(itemType), itemType, items[itemType])
  57. }
  58. } else if csConfig.Cscli.Output == "json" {
  59. type itemHubStatus struct {
  60. Name string `json:"name"`
  61. LocalVersion string `json:"local_version"`
  62. LocalPath string `json:"local_path"`
  63. Description string `json:"description"`
  64. UTF8Status string `json:"utf8_status"`
  65. Status string `json:"status"`
  66. }
  67. hubStatus := make(map[string][]itemHubStatus)
  68. for _, itemType := range itemTypes {
  69. // empty slice in case there are no items of this type
  70. hubStatus[itemType] = make([]itemHubStatus, len(items[itemType]))
  71. for i, itemName := range items[itemType] {
  72. item := hub.GetItem(itemType, itemName)
  73. status, emo := item.Status()
  74. hubStatus[itemType][i] = itemHubStatus{
  75. Name: item.Name,
  76. LocalVersion: item.LocalVersion,
  77. LocalPath: item.LocalPath,
  78. Description: item.Description,
  79. Status: status,
  80. UTF8Status: fmt.Sprintf("%v %s", emo, status),
  81. }
  82. }
  83. h := hubStatus[itemType]
  84. sort.Slice(h, func(i, j int) bool { return h[i].Name < h[j].Name })
  85. }
  86. x, err := json.MarshalIndent(hubStatus, "", " ")
  87. if err != nil {
  88. log.Fatalf("failed to unmarshal")
  89. }
  90. out.Write(x)
  91. } else if csConfig.Cscli.Output == "raw" {
  92. csvwriter := csv.NewWriter(out)
  93. if showHeader {
  94. header := []string{"name", "status", "version", "description"}
  95. if showType {
  96. header = append(header, "type")
  97. }
  98. err := csvwriter.Write(header)
  99. if err != nil {
  100. log.Fatalf("failed to write header: %s", err)
  101. }
  102. }
  103. for _, itemType := range itemTypes {
  104. for _, itemName := range items[itemType] {
  105. item := hub.GetItem(itemType, itemName)
  106. status, _ := item.Status()
  107. if item.LocalVersion == "" {
  108. item.LocalVersion = "n/a"
  109. }
  110. row := []string{
  111. item.Name,
  112. status,
  113. item.LocalVersion,
  114. item.Description,
  115. }
  116. if showType {
  117. row = append(row, itemType)
  118. }
  119. err := csvwriter.Write(row)
  120. if err != nil {
  121. log.Fatalf("failed to write raw output : %s", err)
  122. }
  123. }
  124. }
  125. csvwriter.Flush()
  126. }
  127. return nil
  128. }
  129. func InspectItem(name string, itemType string, noMetrics bool) error {
  130. hub, err := cwhub.GetHub()
  131. if err != nil {
  132. return err
  133. }
  134. hubItem := hub.GetItem(itemType, name)
  135. if hubItem == nil {
  136. return fmt.Errorf("can't find '%s' in %s", name, itemType)
  137. }
  138. var b []byte
  139. switch csConfig.Cscli.Output {
  140. case "human", "raw":
  141. b, err = yaml.Marshal(*hubItem)
  142. if err != nil {
  143. return fmt.Errorf("unable to marshal item: %s", err)
  144. }
  145. case "json":
  146. b, err = json.MarshalIndent(*hubItem, "", " ")
  147. if err != nil {
  148. return fmt.Errorf("unable to marshal item: %s", err)
  149. }
  150. }
  151. fmt.Printf("%s", string(b))
  152. if noMetrics || csConfig.Cscli.Output == "json" || csConfig.Cscli.Output == "raw" {
  153. return nil
  154. }
  155. fmt.Printf("\nCurrent metrics: \n")
  156. ShowMetrics(hub, hubItem)
  157. return nil
  158. }