papi.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. package main
  2. import (
  3. "fmt"
  4. "time"
  5. log "github.com/sirupsen/logrus"
  6. "github.com/spf13/cobra"
  7. "gopkg.in/tomb.v2"
  8. "github.com/crowdsecurity/go-cs-lib/ptr"
  9. "github.com/crowdsecurity/crowdsec/cmd/crowdsec-cli/require"
  10. "github.com/crowdsecurity/crowdsec/pkg/apiserver"
  11. "github.com/crowdsecurity/crowdsec/pkg/database"
  12. )
  13. type cliPapi struct {
  14. cfg configGetter
  15. }
  16. func NewCLIPapi(cfg configGetter) *cliPapi {
  17. return &cliPapi{
  18. cfg: cfg,
  19. }
  20. }
  21. func (cli *cliPapi) NewCommand() *cobra.Command {
  22. cmd := &cobra.Command{
  23. Use: "papi [action]",
  24. Short: "Manage interaction with Polling API (PAPI)",
  25. Args: cobra.MinimumNArgs(1),
  26. DisableAutoGenTag: true,
  27. PersistentPreRunE: func(_ *cobra.Command, _ []string) error {
  28. cfg := cli.cfg()
  29. if err := require.LAPI(cfg); err != nil {
  30. return err
  31. }
  32. if err := require.CAPI(cfg); err != nil {
  33. return err
  34. }
  35. if err := require.PAPI(cfg); err != nil {
  36. return err
  37. }
  38. return nil
  39. },
  40. }
  41. cmd.AddCommand(cli.NewStatusCmd())
  42. cmd.AddCommand(cli.NewSyncCmd())
  43. return cmd
  44. }
  45. func (cli *cliPapi) NewStatusCmd() *cobra.Command {
  46. cmd := &cobra.Command{
  47. Use: "status",
  48. Short: "Get status of the Polling API",
  49. Args: cobra.MinimumNArgs(0),
  50. DisableAutoGenTag: true,
  51. RunE: func(_ *cobra.Command, _ []string) error {
  52. var err error
  53. cfg := cli.cfg()
  54. dbClient, err = database.NewClient(cfg.DbConfig)
  55. if err != nil {
  56. return fmt.Errorf("unable to initialize database client: %s", err)
  57. }
  58. apic, err := apiserver.NewAPIC(cfg.API.Server.OnlineClient, dbClient, cfg.API.Server.ConsoleConfig, cfg.API.Server.CapiWhitelists)
  59. if err != nil {
  60. return fmt.Errorf("unable to initialize API client: %s", err)
  61. }
  62. papi, err := apiserver.NewPAPI(apic, dbClient, cfg.API.Server.ConsoleConfig, log.GetLevel())
  63. if err != nil {
  64. return fmt.Errorf("unable to initialize PAPI client: %s", err)
  65. }
  66. perms, err := papi.GetPermissions()
  67. if err != nil {
  68. return fmt.Errorf("unable to get PAPI permissions: %s", err)
  69. }
  70. var lastTimestampStr *string
  71. lastTimestampStr, err = dbClient.GetConfigItem(apiserver.PapiPullKey)
  72. if err != nil {
  73. lastTimestampStr = ptr.Of("never")
  74. }
  75. log.Infof("You can successfully interact with Polling API (PAPI)")
  76. log.Infof("Console plan: %s", perms.Plan)
  77. log.Infof("Last order received: %s", *lastTimestampStr)
  78. log.Infof("PAPI subscriptions:")
  79. for _, sub := range perms.Categories {
  80. log.Infof(" - %s", sub)
  81. }
  82. return nil
  83. },
  84. }
  85. return cmd
  86. }
  87. func (cli *cliPapi) NewSyncCmd() *cobra.Command {
  88. cmd := &cobra.Command{
  89. Use: "sync",
  90. Short: "Sync with the Polling API, pulling all non-expired orders for the instance",
  91. Args: cobra.MinimumNArgs(0),
  92. DisableAutoGenTag: true,
  93. RunE: func(_ *cobra.Command, _ []string) error {
  94. var err error
  95. cfg := cli.cfg()
  96. t := tomb.Tomb{}
  97. dbClient, err = database.NewClient(cfg.DbConfig)
  98. if err != nil {
  99. return fmt.Errorf("unable to initialize database client: %s", err)
  100. }
  101. apic, err := apiserver.NewAPIC(cfg.API.Server.OnlineClient, dbClient, cfg.API.Server.ConsoleConfig, cfg.API.Server.CapiWhitelists)
  102. if err != nil {
  103. return fmt.Errorf("unable to initialize API client: %s", err)
  104. }
  105. t.Go(apic.Push)
  106. papi, err := apiserver.NewPAPI(apic, dbClient, cfg.API.Server.ConsoleConfig, log.GetLevel())
  107. if err != nil {
  108. return fmt.Errorf("unable to initialize PAPI client: %s", err)
  109. }
  110. t.Go(papi.SyncDecisions)
  111. err = papi.PullOnce(time.Time{}, true)
  112. if err != nil {
  113. return fmt.Errorf("unable to sync decisions: %s", err)
  114. }
  115. log.Infof("Sending acknowledgements to CAPI")
  116. apic.Shutdown()
  117. papi.Shutdown()
  118. t.Wait()
  119. time.Sleep(5 * time.Second) //FIXME: the push done by apic.Push is run inside a sub goroutine, sleep to make sure it's done
  120. return nil
  121. },
  122. }
  123. return cmd
  124. }