add decisions sync
This commit is contained in:
parent
e96a267144
commit
9acb0e7e7e
|
@ -20,7 +20,7 @@ import (
|
|||
)
|
||||
|
||||
var CAPIURLPrefix string = "v2"
|
||||
var CAPIBaseURL string = "https://api.crowdsec.net/"
|
||||
var CAPIBaseURL string = "https://api.dev.crowdsec.net/"
|
||||
|
||||
func NewCapiCmd() *cobra.Command {
|
||||
var cmdCapi = &cobra.Command{
|
||||
|
|
|
@ -7,11 +7,15 @@ import (
|
|||
"fmt"
|
||||
"io/fs"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/crowdsecurity/crowdsec/pkg/apiclient"
|
||||
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
|
||||
"github.com/crowdsecurity/crowdsec/pkg/cwhub"
|
||||
"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/go-openapi/strfmt"
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
@ -19,6 +23,35 @@ import (
|
|||
"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 {
|
||||
var cmdConsole = &cobra.Command{
|
||||
Use: "console [action]",
|
||||
|
@ -184,6 +217,85 @@ Disable given information push to the central API.`,
|
|||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
|
|
@ -32,6 +32,10 @@ type DecisionsDeleteOpts struct {
|
|||
ListOpts
|
||||
}
|
||||
|
||||
type SuccessReponse struct {
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
//to demo query arguments
|
||||
func (s *DecisionsService) List(ctx context.Context, opts DecisionsListOpts) (*models.GetDecisionsResponse, *Response, error) {
|
||||
var decisions models.GetDecisionsResponse
|
||||
|
@ -122,3 +126,35 @@ func (s *DecisionsService) DeleteOne(ctx context.Context, decision_id string) (*
|
|||
}
|
||||
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