add decisions sync
This commit is contained in:
parent
e96a267144
commit
9acb0e7e7e
|
@ -20,7 +20,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var CAPIURLPrefix string = "v2"
|
var CAPIURLPrefix string = "v2"
|
||||||
var CAPIBaseURL string = "https://api.crowdsec.net/"
|
var CAPIBaseURL string = "https://api.dev.crowdsec.net/"
|
||||||
|
|
||||||
func NewCapiCmd() *cobra.Command {
|
func NewCapiCmd() *cobra.Command {
|
||||||
var cmdCapi = &cobra.Command{
|
var cmdCapi = &cobra.Command{
|
||||||
|
|
|
@ -7,11 +7,15 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/apiclient"
|
"github.com/crowdsecurity/crowdsec/pkg/apiclient"
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
|
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/cwhub"
|
"github.com/crowdsecurity/crowdsec/pkg/cwhub"
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/cwversion"
|
"github.com/crowdsecurity/crowdsec/pkg/cwversion"
|
||||||
|
"github.com/crowdsecurity/crowdsec/pkg/database"
|
||||||
|
"github.com/crowdsecurity/crowdsec/pkg/models"
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/types"
|
"github.com/crowdsecurity/crowdsec/pkg/types"
|
||||||
"github.com/go-openapi/strfmt"
|
"github.com/go-openapi/strfmt"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
|
@ -19,6 +23,35 @@ import (
|
||||||
"gopkg.in/yaml.v2"
|
"gopkg.in/yaml.v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func IsInSlice(a string, b []string) bool {
|
||||||
|
for _, v := range b {
|
||||||
|
if a == v {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func FetchScenariosListFromDB() ([]string, error) {
|
||||||
|
scenarios := make([]string, 0)
|
||||||
|
machines, err := dbClient.ListMachines()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("while listing machines: %s", err)
|
||||||
|
}
|
||||||
|
//merge all scenarios together
|
||||||
|
for _, v := range machines {
|
||||||
|
machineScenarios := strings.Split(v.Scenarios, ",")
|
||||||
|
log.Debugf("%d scenarios for machine %d", len(machineScenarios), v.ID)
|
||||||
|
for _, sv := range machineScenarios {
|
||||||
|
if !IsInSlice(sv, scenarios) && sv != "" {
|
||||||
|
scenarios = append(scenarios, sv)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.Debugf("Returning list of scenarios : %+v", scenarios)
|
||||||
|
return scenarios, nil
|
||||||
|
}
|
||||||
|
|
||||||
func NewConsoleCmd() *cobra.Command {
|
func NewConsoleCmd() *cobra.Command {
|
||||||
var cmdConsole = &cobra.Command{
|
var cmdConsole = &cobra.Command{
|
||||||
Use: "console [action]",
|
Use: "console [action]",
|
||||||
|
@ -184,6 +217,85 @@ Disable given information push to the central API.`,
|
||||||
}
|
}
|
||||||
|
|
||||||
cmdConsole.AddCommand(cmdStatus)
|
cmdConsole.AddCommand(cmdStatus)
|
||||||
|
cmdSync := &cobra.Command{
|
||||||
|
Use: "sync",
|
||||||
|
Short: "Sync current decisions to console",
|
||||||
|
DisableAutoGenTag: true,
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
var err error
|
||||||
|
if err := csConfig.LoadDBConfig(); err != nil {
|
||||||
|
log.Errorf("This command requires direct database access (must be run on the local API machine)")
|
||||||
|
log.Fatalf(err.Error())
|
||||||
|
}
|
||||||
|
dbClient, err = database.NewClient(csConfig.DbConfig)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("unable to create new database client: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
password := strfmt.Password(csConfig.API.Server.OnlineClient.Credentials.Password)
|
||||||
|
apiurl, err := url.Parse(csConfig.API.Server.OnlineClient.Credentials.URL)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("parsing api url ('%s'): %s", csConfig.API.Server.OnlineClient.Credentials.URL, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := csConfig.LoadHub(); err != nil {
|
||||||
|
log.Fatalf(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := cwhub.GetHubIdx(csConfig.Hub); err != nil {
|
||||||
|
log.Fatalf("Failed to load hub index : %s", err)
|
||||||
|
log.Infoln("Run 'sudo cscli hub update' to get the hub index")
|
||||||
|
}
|
||||||
|
scenarios, err := cwhub.GetUpstreamInstalledScenariosAsString()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("failed to get scenarios : %s", err.Error())
|
||||||
|
}
|
||||||
|
if len(scenarios) == 0 {
|
||||||
|
log.Fatalf("no scenarios installed, abort")
|
||||||
|
}
|
||||||
|
|
||||||
|
Client, err = apiclient.NewClient(&apiclient.Config{
|
||||||
|
MachineID: csConfig.API.Server.OnlineClient.Credentials.Login,
|
||||||
|
Password: password,
|
||||||
|
UserAgent: fmt.Sprintf("crowdsec/%s", cwversion.VersionStr()),
|
||||||
|
URL: apiurl,
|
||||||
|
VersionPrefix: "v2",
|
||||||
|
Scenarios: scenarios,
|
||||||
|
UpdateScenario: FetchScenariosListFromDB,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("init default client: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
filter := make(map[string][]string)
|
||||||
|
decisionsInDb, err := dbClient.QueryDecisionWithFilter(filter)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf(err.Error())
|
||||||
|
}
|
||||||
|
decisionsList := make([]*models.Decision, 0)
|
||||||
|
for _, dbDecision := range decisionsInDb {
|
||||||
|
duration := dbDecision.Until.Sub(time.Now()).String()
|
||||||
|
decision := &models.Decision{
|
||||||
|
ID: int64(dbDecision.ID),
|
||||||
|
Duration: &duration,
|
||||||
|
Scenario: &dbDecision.Scenario,
|
||||||
|
Scope: &dbDecision.Scope,
|
||||||
|
Value: &dbDecision.Value,
|
||||||
|
Type: &dbDecision.Type,
|
||||||
|
Origin: &dbDecision.Origin,
|
||||||
|
Until: dbDecision.Until.String(),
|
||||||
|
}
|
||||||
|
decisionsList = append(decisionsList, decision)
|
||||||
|
}
|
||||||
|
resp, _, err := Client.Decisions.SyncDecisions(context.Background(), decisionsList)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("unable to sync decisions with console: %s", err.Error())
|
||||||
|
}
|
||||||
|
log.Infof("Decisions sync: %+v", resp)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
cmdConsole.AddCommand(cmdSync)
|
||||||
|
|
||||||
return cmdConsole
|
return cmdConsole
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,10 @@ type DecisionsDeleteOpts struct {
|
||||||
ListOpts
|
ListOpts
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SuccessReponse struct {
|
||||||
|
Message string `json:"message"`
|
||||||
|
}
|
||||||
|
|
||||||
//to demo query arguments
|
//to demo query arguments
|
||||||
func (s *DecisionsService) List(ctx context.Context, opts DecisionsListOpts) (*models.GetDecisionsResponse, *Response, error) {
|
func (s *DecisionsService) List(ctx context.Context, opts DecisionsListOpts) (*models.GetDecisionsResponse, *Response, error) {
|
||||||
var decisions models.GetDecisionsResponse
|
var decisions models.GetDecisionsResponse
|
||||||
|
@ -122,3 +126,35 @@ func (s *DecisionsService) DeleteOne(ctx context.Context, decision_id string) (*
|
||||||
}
|
}
|
||||||
return &deleteDecisionResponse, resp, nil
|
return &deleteDecisionResponse, resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *DecisionsService) DeleteDecisions(ctx context.Context, decisionsID []string) (*SuccessReponse, *Response, error) {
|
||||||
|
var successReponse SuccessReponse
|
||||||
|
u := fmt.Sprintf("%s/decisions/delete", s.client.URLPrefix)
|
||||||
|
|
||||||
|
req, err := s.client.NewRequest("POST", u, &decisionsID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := s.client.Do(ctx, req, &successReponse)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
return &successReponse, resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *DecisionsService) SyncDecisions(ctx context.Context, decisions []*models.Decision) (*SuccessReponse, *Response, error) {
|
||||||
|
var successReponse SuccessReponse
|
||||||
|
|
||||||
|
u := fmt.Sprintf("%s/decisions/sync", s.client.URLPrefix)
|
||||||
|
req, err := s.client.NewRequest("POST", u, &decisions)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
resp, err := s.client.Do(ctx, req, &successReponse)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &successReponse, resp, nil
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue