helpers.go 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. package cwhub
  2. import (
  3. "fmt"
  4. "path/filepath"
  5. "github.com/crowdsecurity/crowdsec/pkg/csconfig"
  6. "github.com/crowdsecurity/crowdsec/pkg/cwversion"
  7. "github.com/enescakir/emoji"
  8. "github.com/pkg/errors"
  9. log "github.com/sirupsen/logrus"
  10. "golang.org/x/mod/semver"
  11. )
  12. // pick a hub branch corresponding to the current crowdsec version.
  13. func chooseHubBranch() (string, error) {
  14. latest, err := cwversion.Latest()
  15. if err != nil {
  16. return "master", err
  17. }
  18. csVersion := cwversion.VersionStrip()
  19. if csVersion == latest {
  20. return "master", nil
  21. }
  22. // if current version is greater than the latest we are in pre-release
  23. if semver.Compare(csVersion, latest) == 1 {
  24. log.Debugf("Your current crowdsec version seems to be a pre-release (%s)", csVersion)
  25. return "master", nil
  26. }
  27. if csVersion == "" {
  28. log.Warning("Crowdsec version is not set, using master branch for the hub")
  29. return "master", nil
  30. }
  31. log.Warnf("Crowdsec is not the latest version. "+
  32. "Current version is '%s' and the latest stable version is '%s'. Please update it!",
  33. csVersion, latest)
  34. log.Warnf("As a result, you will not be able to use parsers/scenarios/collections "+
  35. "added to Crowdsec Hub after CrowdSec %s", latest)
  36. return csVersion, nil
  37. }
  38. // SetHubBranch sets the package variable that points to the hub branch.
  39. func SetHubBranch() error {
  40. // a branch is already set, or specified from the flags
  41. if HubBranch != "" {
  42. return nil
  43. }
  44. // use the branch corresponding to the crowdsec version
  45. branch, err := chooseHubBranch()
  46. if err != nil {
  47. return err
  48. }
  49. HubBranch = branch
  50. log.Debugf("Using branch '%s' for the hub", HubBranch)
  51. return nil
  52. }
  53. func InstallItem(csConfig *csconfig.Config, name string, obtype string, force bool, downloadOnly bool) error {
  54. it := GetItem(obtype, name)
  55. if it == nil {
  56. return fmt.Errorf("unable to retrieve item: %s", name)
  57. }
  58. item := *it
  59. if downloadOnly && item.Downloaded && item.UpToDate {
  60. log.Warningf("%s is already downloaded and up-to-date", item.Name)
  61. if !force {
  62. return nil
  63. }
  64. }
  65. item, err := DownloadLatest(csConfig.Hub, item, force, true)
  66. if err != nil {
  67. return errors.Wrapf(err, "while downloading %s", item.Name)
  68. }
  69. if err := AddItem(obtype, item); err != nil {
  70. return errors.Wrapf(err, "while adding %s", item.Name)
  71. }
  72. if downloadOnly {
  73. log.Infof("Downloaded %s to %s", item.Name, filepath.Join(csConfig.Hub.HubDir, item.RemotePath))
  74. return nil
  75. }
  76. item, err = EnableItem(csConfig.Hub, item)
  77. if err != nil {
  78. return errors.Wrapf(err, "while enabling %s", item.Name)
  79. }
  80. if err := AddItem(obtype, item); err != nil {
  81. return errors.Wrapf(err, "while adding %s", item.Name)
  82. }
  83. log.Infof("Enabled %s", item.Name)
  84. return nil
  85. }
  86. // XXX this must return errors instead of log.Fatal
  87. func RemoveMany(csConfig *csconfig.Config, itemType string, name string, all bool, purge bool, forceAction bool) {
  88. var (
  89. err error
  90. disabled int
  91. )
  92. if name != "" {
  93. it := GetItem(itemType, name)
  94. if it == nil {
  95. log.Fatalf("unable to retrieve: %s", name)
  96. }
  97. item := *it
  98. item, err = DisableItem(csConfig.Hub, item, purge, forceAction)
  99. if err != nil {
  100. log.Fatalf("unable to disable %s : %v", item.Name, err)
  101. }
  102. if err := AddItem(itemType, item); err != nil {
  103. log.Fatalf("unable to add %s: %v", item.Name, err)
  104. }
  105. return
  106. }
  107. if !all {
  108. log.Fatal("removing item: no item specified")
  109. }
  110. // remove all
  111. for _, v := range GetItemMap(itemType) {
  112. if !v.Installed {
  113. continue
  114. }
  115. v, err = DisableItem(csConfig.Hub, v, purge, forceAction)
  116. if err != nil {
  117. log.Fatalf("unable to disable %s : %v", v.Name, err)
  118. }
  119. if err := AddItem(itemType, v); err != nil {
  120. log.Fatalf("unable to add %s: %v", v.Name, err)
  121. }
  122. disabled++
  123. }
  124. log.Infof("Disabled %d items", disabled)
  125. }
  126. func UpgradeConfig(csConfig *csconfig.Config, itemType string, name string, force bool) {
  127. var (
  128. err error
  129. updated int
  130. found bool
  131. )
  132. for _, v := range GetItemMap(itemType) {
  133. if name != "" && name != v.Name {
  134. continue
  135. }
  136. if !v.Installed {
  137. log.Tracef("skip %s, not installed", v.Name)
  138. continue
  139. }
  140. if !v.Downloaded {
  141. log.Warningf("%s : not downloaded, please install.", v.Name)
  142. continue
  143. }
  144. found = true
  145. if v.UpToDate {
  146. log.Infof("%s : up-to-date", v.Name)
  147. if err = DownloadDataIfNeeded(csConfig.Hub, v, force); err != nil {
  148. log.Fatalf("%s : download failed : %v", v.Name, err)
  149. }
  150. if !force {
  151. continue
  152. }
  153. }
  154. v, err = DownloadLatest(csConfig.Hub, v, force, true)
  155. if err != nil {
  156. log.Fatalf("%s : download failed : %v", v.Name, err)
  157. }
  158. if !v.UpToDate {
  159. if v.Tainted {
  160. log.Infof("%v %s is tainted, --force to overwrite", emoji.Warning, v.Name)
  161. } else if v.Local {
  162. log.Infof("%v %s is local", emoji.Prohibited, v.Name)
  163. }
  164. } else {
  165. // this is used while scripting to know if the hub has been upgraded
  166. // and a configuration reload is required
  167. fmt.Printf("updated %s\n", v.Name)
  168. log.Infof("%v %s : updated", emoji.Package, v.Name)
  169. updated++
  170. }
  171. if err := AddItem(itemType, v); err != nil {
  172. log.Fatalf("unable to add %s: %v", v.Name, err)
  173. }
  174. }
  175. if !found && name == "" {
  176. log.Infof("No %s installed, nothing to upgrade", itemType)
  177. } else if !found {
  178. log.Errorf("Item '%s' not found in hub", name)
  179. } else if updated == 0 && found {
  180. if name == "" {
  181. log.Infof("All %s are already up-to-date", itemType)
  182. } else {
  183. log.Infof("Item '%s' is up-to-date", name)
  184. }
  185. } else if updated != 0 {
  186. log.Infof("Upgraded %d items", updated)
  187. }
  188. }