v3 capi and blocklists links support (#2019)

* v3 model generation

* v3 model generation

* comms

* fixes after master merge

* missing reader close

* use constants defined for types

---------

Co-authored-by: bui <thibault@crowdsec.net>
This commit is contained in:
Cristian Nitescu 2023-02-06 14:06:14 +01:00 committed by GitHub
parent b6be18ca65
commit 987f119c4b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
38 changed files with 3965 additions and 78 deletions

View file

@ -20,8 +20,7 @@ import (
) )
const CAPIBaseURL string = "https://api.crowdsec.net/" const CAPIBaseURL string = "https://api.crowdsec.net/"
const CAPIURLPrefix = "v2" const CAPIURLPrefix = "v3"
func NewCapiCmd() *cobra.Command { func NewCapiCmd() *cobra.Command {
var cmdCapi = &cobra.Command{ var cmdCapi = &cobra.Command{
@ -47,7 +46,6 @@ func NewCapiCmd() *cobra.Command {
return cmdCapi return cmdCapi
} }
func NewCapiRegisterCmd() *cobra.Command { func NewCapiRegisterCmd() *cobra.Command {
var capiUserPrefix string var capiUserPrefix string
var outputFile string var outputFile string
@ -122,7 +120,6 @@ func NewCapiRegisterCmd() *cobra.Command {
return cmdCapiRegister return cmdCapiRegister
} }
func NewCapiStatusCmd() *cobra.Command { func NewCapiStatusCmd() *cobra.Command {
var cmdCapiStatus = &cobra.Command{ var cmdCapiStatus = &cobra.Command{
Use: "status", Use: "status",

View file

@ -102,7 +102,7 @@ After running this command your will need to validate the enrollment in the weba
Scenarios: scenarios, Scenarios: scenarios,
UserAgent: fmt.Sprintf("crowdsec/%s", cwversion.VersionStr()), UserAgent: fmt.Sprintf("crowdsec/%s", cwversion.VersionStr()),
URL: apiURL, URL: apiURL,
VersionPrefix: "v2", VersionPrefix: "v3",
}) })
resp, err := c.Auth.EnrollWatcher(context.Background(), args[0], name, tags, overwrite) resp, err := c.Auth.EnrollWatcher(context.Background(), args[0], name, tags, overwrite)
if err != nil { if err != nil {

View file

@ -21,9 +21,13 @@ import (
*/ */
func setup() (mux *http.ServeMux, serverURL string, teardown func()) { func setup() (mux *http.ServeMux, serverURL string, teardown func()) {
return setupWithPrefix("v1")
}
func setupWithPrefix(urlPrefix string) (mux *http.ServeMux, serverURL string, teardown func()) {
// mux is the HTTP request multiplexer used with the test server. // mux is the HTTP request multiplexer used with the test server.
mux = http.NewServeMux() mux = http.NewServeMux()
baseURLPath := "/v1" baseURLPath := "/" + urlPrefix
apiHandler := http.NewServeMux() apiHandler := http.NewServeMux()
apiHandler.Handle(baseURLPath+"/", http.StripPrefix(baseURLPath, mux)) apiHandler.Handle(baseURLPath+"/", http.StripPrefix(baseURLPath, mux))

View file

@ -1,12 +1,18 @@
package apiclient package apiclient
import ( import (
"bufio"
"context" "context"
"fmt" "fmt"
"io"
"net/http" "net/http"
"github.com/crowdsecurity/crowdsec/pkg/models" "github.com/crowdsecurity/crowdsec/pkg/models"
"github.com/crowdsecurity/crowdsec/pkg/modelscapi"
"github.com/crowdsecurity/crowdsec/pkg/types"
qs "github.com/google/go-querystring/query" qs "github.com/google/go-querystring/query"
"github.com/pkg/errors"
log "github.com/sirupsen/logrus"
) )
type DecisionsService service type DecisionsService service
@ -67,15 +73,140 @@ func (s *DecisionsService) List(ctx context.Context, opts DecisionsListOpts) (*m
if err != nil { if err != nil {
return nil, resp, err return nil, resp, err
} }
return &decisions, resp, nil return &decisions, resp, nil
} }
func (s *DecisionsService) GetStream(ctx context.Context, opts DecisionsStreamOpts) (*models.DecisionsStreamResponse, *Response, error) { func (s *DecisionsService) FetchV2Decisions(ctx context.Context, url string) (*models.DecisionsStreamResponse, *Response, error) {
var decisions models.DecisionsStreamResponse var decisions models.DecisionsStreamResponse
req, err := s.client.NewRequest(http.MethodGet, url, nil)
if err != nil {
return nil, nil, err
}
resp, err := s.client.Do(ctx, req, &decisions)
if err != nil {
return nil, resp, err
}
return &decisions, resp, nil
}
func (s *DecisionsService) GetDecisionsFromGroups(decisionsGroups []*modelscapi.GetDecisionsStreamResponseNewItem) []*models.Decision {
var decisions []*models.Decision
for _, decisionsGroup := range decisionsGroups {
partialDecisions := make([]*models.Decision, len(decisionsGroup.Decisions))
for idx, decision := range decisionsGroup.Decisions {
partialDecisions[idx] = &models.Decision{
Scenario: decisionsGroup.Scenario,
Scope: decisionsGroup.Scope,
Type: types.StrPtr(types.DecisionTypeBan),
Value: decision.Value,
Duration: decision.Duration,
Origin: types.StrPtr(types.CAPIOrigin),
}
}
decisions = append(decisions, partialDecisions...)
}
return decisions
}
func (s *DecisionsService) FetchV3Decisions(ctx context.Context, url string) (*models.DecisionsStreamResponse, *Response, error) {
var decisions modelscapi.GetDecisionsStreamResponse
var v2Decisions models.DecisionsStreamResponse
scenarioDeleted := "deleted"
durationDeleted := "1h"
req, err := s.client.NewRequest(http.MethodGet, url, nil)
if err != nil {
return nil, nil, err
}
resp, err := s.client.Do(ctx, req, &decisions)
if err != nil {
return nil, resp, err
}
v2Decisions.New = s.GetDecisionsFromGroups(decisions.New)
for _, decisionsGroup := range decisions.Deleted {
partialDecisions := make([]*models.Decision, len(decisionsGroup.Decisions))
for idx, decision := range decisionsGroup.Decisions {
decision := decision // fix exportloopref linter message
partialDecisions[idx] = &models.Decision{
Scenario: &scenarioDeleted,
Scope: decisionsGroup.Scope,
Type: types.StrPtr(types.DecisionTypeBan),
Value: &decision,
Duration: &durationDeleted,
Origin: types.StrPtr(types.CAPIOrigin),
}
}
v2Decisions.Deleted = append(v2Decisions.Deleted, partialDecisions...)
}
return &v2Decisions, resp, nil
}
func (s *DecisionsService) GetDecisionsFromBlocklist(ctx context.Context, blocklist *modelscapi.BlocklistLink) ([]*models.Decision, error) {
if blocklist.URL == nil {
return nil, errors.New("blocklist URL is nil")
}
log.Debugf("Fetching blocklist %s", *blocklist.URL)
req, err := s.client.NewRequest(http.MethodGet, *blocklist.URL, nil)
if err != nil {
return nil, err
}
pr, pw := io.Pipe()
defer pr.Close()
go func() {
defer pw.Close()
_, err = s.client.Do(ctx, req, pw)
if err != nil {
log.Errorf("Error fetching blocklist %s: %s", *blocklist.URL, err)
}
}()
decisions := make([]*models.Decision, 0)
scanner := bufio.NewScanner(pr)
for scanner.Scan() {
decision := scanner.Text()
decisions = append(decisions, &models.Decision{
Scenario: blocklist.Name,
Scope: blocklist.Scope,
Type: blocklist.Remediation,
Value: &decision,
Duration: blocklist.Duration,
Origin: types.StrPtr(types.ListOrigin),
})
}
return decisions, nil
}
func (s *DecisionsService) GetStream(ctx context.Context, opts DecisionsStreamOpts) (*models.DecisionsStreamResponse, *Response, error) {
u, err := opts.addQueryParamsToURL(s.client.URLPrefix + "/decisions/stream") u, err := opts.addQueryParamsToURL(s.client.URLPrefix + "/decisions/stream")
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
if s.client.URLPrefix == "v3" {
return s.FetchV3Decisions(ctx, u)
} else {
return s.FetchV2Decisions(ctx, u)
}
}
func (s *DecisionsService) GetStreamV3(ctx context.Context, opts DecisionsStreamOpts) (*modelscapi.GetDecisionsStreamResponse, *Response, error) {
u, err := opts.addQueryParamsToURL(s.client.URLPrefix + "/decisions/stream")
if err != nil {
return nil, nil, err
}
var decisions modelscapi.GetDecisionsStreamResponse
req, err := s.client.NewRequest(http.MethodGet, u, nil) req, err := s.client.NewRequest(http.MethodGet, u, nil)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err

View file

@ -10,6 +10,7 @@ import (
"github.com/crowdsecurity/crowdsec/pkg/cwversion" "github.com/crowdsecurity/crowdsec/pkg/cwversion"
"github.com/crowdsecurity/crowdsec/pkg/models" "github.com/crowdsecurity/crowdsec/pkg/models"
"github.com/crowdsecurity/crowdsec/pkg/modelscapi"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@ -192,6 +193,263 @@ func TestDecisionsStream(t *testing.T) {
} }
} }
func TestDecisionsStreamV3Compatibility(t *testing.T) {
log.SetLevel(log.DebugLevel)
mux, urlx, teardown := setupWithPrefix("v3")
defer teardown()
mux.HandleFunc("/decisions/stream", func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, r.Header.Get("X-Api-Key"), "ixu")
testMethod(t, r, http.MethodGet)
if r.Method == http.MethodGet {
if r.URL.RawQuery == "startup=true" {
w.WriteHeader(http.StatusOK)
w.Write([]byte(`{"deleted":[{"scope":"ip","decisions":["1.2.3.5"]}],"new":[{"scope":"ip", "scenario": "manual 'ban' from '82929df7ee394b73b81252fe3b4e50203yaT2u6nXiaN7Ix9'", "decisions":[{"duration":"3h59m55.756182786s","value":"1.2.3.4"}]}]}`))
} else {
w.WriteHeader(http.StatusOK)
w.Write([]byte(`{"deleted":null,"new":null}`))
}
}
})
apiURL, err := url.Parse(urlx + "/")
if err != nil {
t.Fatalf("parsing api url: %s", apiURL)
}
//ok answer
auth := &APIKeyTransport{
APIKey: "ixu",
}
newcli, err := NewDefaultClient(apiURL, "v3", "toto", auth.Client())
if err != nil {
t.Fatalf("new api client: %s", err)
}
tduration := "3h59m55.756182786s"
torigin := "CAPI"
tscenario := "manual 'ban' from '82929df7ee394b73b81252fe3b4e50203yaT2u6nXiaN7Ix9'"
tscope := "ip"
ttype := "ban"
tvalue := "1.2.3.4"
tvalue1 := "1.2.3.5"
tscenarioDeleted := "deleted"
tdurationDeleted := "1h"
expected := &models.DecisionsStreamResponse{
New: models.GetDecisionsResponse{
&models.Decision{
Duration: &tduration,
Origin: &torigin,
Scenario: &tscenario,
Scope: &tscope,
Type: &ttype,
Value: &tvalue,
},
},
Deleted: models.GetDecisionsResponse{
&models.Decision{
Duration: &tdurationDeleted,
Origin: &torigin,
Scenario: &tscenarioDeleted,
Scope: &tscope,
Type: &ttype,
Value: &tvalue1,
},
},
}
// GetStream is supposed to consume v3 payload and return v2 response
decisions, resp, err := newcli.Decisions.GetStream(context.Background(), DecisionsStreamOpts{Startup: true})
require.NoError(t, err)
if resp.Response.StatusCode != http.StatusOK {
t.Errorf("Alerts.List returned status: %d, want %d", resp.Response.StatusCode, http.StatusOK)
}
if err != nil {
t.Fatalf("new api client: %s", err)
}
if !reflect.DeepEqual(*decisions, *expected) {
t.Fatalf("returned %+v, want %+v", resp, expected)
}
}
func TestDecisionsStreamV3(t *testing.T) {
log.SetLevel(log.DebugLevel)
mux, urlx, teardown := setupWithPrefix("v3")
defer teardown()
mux.HandleFunc("/decisions/stream", func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, r.Header.Get("X-Api-Key"), "ixu")
testMethod(t, r, http.MethodGet)
if r.Method == http.MethodGet {
w.WriteHeader(http.StatusOK)
w.Write([]byte(`{"deleted":[{"scope":"ip","decisions":["1.2.3.5"]}],
"new":[{"scope":"ip", "scenario": "manual 'ban' from '82929df7ee394b73b81252fe3b4e50203yaT2u6nXiaN7Ix9'", "decisions":[{"duration":"3h59m55.756182786s","value":"1.2.3.4"}]}],
"links": {"blocklists":[{"name":"blocklist1","url":"/v3/blocklist","scope":"ip","remediation":"ban","duration":"24h"}]}}`))
}
})
apiURL, err := url.Parse(urlx + "/")
if err != nil {
t.Fatalf("parsing api url: %s", apiURL)
}
//ok answer
auth := &APIKeyTransport{
APIKey: "ixu",
}
newcli, err := NewDefaultClient(apiURL, "v3", "toto", auth.Client())
if err != nil {
t.Fatalf("new api client: %s", err)
}
tduration := "3h59m55.756182786s"
tscenario := "manual 'ban' from '82929df7ee394b73b81252fe3b4e50203yaT2u6nXiaN7Ix9'"
tscope := "ip"
tvalue := "1.2.3.4"
tvalue1 := "1.2.3.5"
tdurationBlocklist := "24h"
tnameBlocklist := "blocklist1"
tremediationBlocklist := "ban"
tscopeBlocklist := "ip"
turlBlocklist := "/v3/blocklist"
expected := &modelscapi.GetDecisionsStreamResponse{
New: modelscapi.GetDecisionsStreamResponseNew{
&modelscapi.GetDecisionsStreamResponseNewItem{
Decisions: []*modelscapi.GetDecisionsStreamResponseNewItemDecisionsItems0{
{
Duration: &tduration,
Value: &tvalue,
},
},
Scenario: &tscenario,
Scope: &tscope,
},
},
Deleted: modelscapi.GetDecisionsStreamResponseDeleted{
&modelscapi.GetDecisionsStreamResponseDeletedItem{
Scope: &tscope,
Decisions: []string{
tvalue1,
},
},
},
Links: &modelscapi.GetDecisionsStreamResponseLinks{
Blocklists: []*modelscapi.BlocklistLink{
{
Duration: &tdurationBlocklist,
Name: &tnameBlocklist,
Remediation: &tremediationBlocklist,
Scope: &tscopeBlocklist,
URL: &turlBlocklist,
},
},
},
}
// GetStream is supposed to consume v3 payload and return v2 response
decisions, resp, err := newcli.Decisions.GetStreamV3(context.Background(), DecisionsStreamOpts{Startup: true})
require.NoError(t, err)
if resp.Response.StatusCode != http.StatusOK {
t.Errorf("Alerts.List returned status: %d, want %d", resp.Response.StatusCode, http.StatusOK)
}
if err != nil {
t.Fatalf("new api client: %s", err)
}
if !reflect.DeepEqual(*decisions, *expected) {
t.Fatalf("returned %+v, want %+v", resp, expected)
}
}
func TestDecisionsFromBlocklist(t *testing.T) {
log.SetLevel(log.DebugLevel)
mux, urlx, teardown := setupWithPrefix("v3")
defer teardown()
mux.HandleFunc("/blocklist", func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, r.Header.Get("X-Api-Key"), "ixu")
testMethod(t, r, http.MethodGet)
if r.Method == http.MethodGet {
w.WriteHeader(http.StatusOK)
w.Write([]byte("1.2.3.4\r\n1.2.3.5"))
}
})
apiURL, err := url.Parse(urlx + "/")
if err != nil {
t.Fatalf("parsing api url: %s", apiURL)
}
//ok answer
auth := &APIKeyTransport{
APIKey: "ixu",
}
newcli, err := NewDefaultClient(apiURL, "v3", "toto", auth.Client())
if err != nil {
t.Fatalf("new api client: %s", err)
}
tvalue1 := "1.2.3.4"
tvalue2 := "1.2.3.5"
tdurationBlocklist := "24h"
tnameBlocklist := "blocklist1"
tremediationBlocklist := "ban"
tscopeBlocklist := "ip"
turlBlocklist := "/v3/blocklist"
torigin := "lists"
expected := []*models.Decision{
{
Duration: &tdurationBlocklist,
Value: &tvalue1,
Scenario: &tnameBlocklist,
Scope: &tscopeBlocklist,
Type: &tremediationBlocklist,
Origin: &torigin,
},
{
Duration: &tdurationBlocklist,
Value: &tvalue2,
Scenario: &tnameBlocklist,
Scope: &tscopeBlocklist,
Type: &tremediationBlocklist,
Origin: &torigin,
},
}
decisions, err := newcli.Decisions.GetDecisionsFromBlocklist(context.Background(), &modelscapi.BlocklistLink{
URL: &turlBlocklist,
Scope: &tscopeBlocklist,
Remediation: &tremediationBlocklist,
Name: &tnameBlocklist,
Duration: &tdurationBlocklist,
})
require.NoError(t, err)
log.Infof("decision1: %+v", decisions[0])
log.Infof("expected1: %+v", expected[0])
log.Infof("decisions: %s, %s, %s, %s, %s, %s", *decisions[0].Value, *decisions[0].Duration, *decisions[0].Scenario, *decisions[0].Scope, *decisions[0].Type, *decisions[0].Origin)
log.Infof("expected : %s, %s, %s, %s, %s", *expected[0].Value, *expected[0].Duration, *expected[0].Scenario, *expected[0].Scope, *expected[0].Type)
log.Infof("decisions: %s, %s, %s, %s, %s", *decisions[1].Value, *decisions[1].Duration, *decisions[1].Scenario, *decisions[1].Scope, *decisions[1].Type)
if err != nil {
t.Fatalf("new api client: %s", err)
}
if !reflect.DeepEqual(decisions, expected) {
t.Fatalf("returned %+v, want %+v", decisions, expected)
}
}
func TestDeleteDecisions(t *testing.T) { func TestDeleteDecisions(t *testing.T) {
mux, urlx, teardown := setup() mux, urlx, teardown := setup()
mux.HandleFunc("/watchers/login", func(w http.ResponseWriter, r *http.Request) { mux.HandleFunc("/watchers/login", func(w http.ResponseWriter, r *http.Request) {

View file

@ -4,6 +4,7 @@ import (
"context" "context"
"fmt" "fmt"
"math/rand" "math/rand"
"net/http"
"net/url" "net/url"
"strconv" "strconv"
"strings" "strings"
@ -22,6 +23,7 @@ import (
"github.com/crowdsecurity/crowdsec/pkg/database/ent/alert" "github.com/crowdsecurity/crowdsec/pkg/database/ent/alert"
"github.com/crowdsecurity/crowdsec/pkg/database/ent/decision" "github.com/crowdsecurity/crowdsec/pkg/database/ent/decision"
"github.com/crowdsecurity/crowdsec/pkg/models" "github.com/crowdsecurity/crowdsec/pkg/models"
"github.com/crowdsecurity/crowdsec/pkg/modelscapi"
"github.com/crowdsecurity/crowdsec/pkg/types" "github.com/crowdsecurity/crowdsec/pkg/types"
) )
@ -188,7 +190,7 @@ func NewAPIC(config *csconfig.OnlineApiClientCfg, dbClient *database.Client, con
UserAgent: fmt.Sprintf("crowdsec/%s", cwversion.VersionStr()), UserAgent: fmt.Sprintf("crowdsec/%s", cwversion.VersionStr()),
URL: apiURL, URL: apiURL,
PapiURL: papiURL, PapiURL: papiURL,
VersionPrefix: "v2", VersionPrefix: "v3",
Scenarios: ret.scenarioList, Scenarios: ret.scenarioList,
UpdateScenario: ret.FetchScenariosListFromDB, UpdateScenario: ret.FetchScenariosListFromDB,
}) })
@ -380,11 +382,41 @@ func (a *apic) HandleDeletedDecisions(deletedDecisions []*models.Decision, delet
if err != nil { if err != nil {
return 0, errors.Wrapf(err, "converting db ret %d", dbCliDel) return 0, errors.Wrapf(err, "converting db ret %d", dbCliDel)
} }
updateCounterForDecision(delete_counters, decision, dbCliDel) updateCounterForDecision(delete_counters, decision.Origin, decision.Scenario, dbCliDel)
nbDeleted += dbCliDel nbDeleted += dbCliDel
} }
return nbDeleted, nil return nbDeleted, nil
}
func (a *apic) HandleDeletedDecisionsV3(deletedDecisions []*modelscapi.GetDecisionsStreamResponseDeletedItem, delete_counters map[string]map[string]int) (int, error) {
var filter map[string][]string
var nbDeleted int
for _, decisions := range deletedDecisions {
scope := decisions.Scope
for _, decision := range decisions.Decisions {
if strings.ToLower(*scope) == "ip" {
filter = make(map[string][]string, 1)
filter["value"] = []string{decision}
} else {
filter = make(map[string][]string, 2)
filter["value"] = []string{decision}
filter["scopes"] = []string{*scope}
}
filter["origin"] = []string{types.CAPIOrigin}
dbCliRet, _, err := a.dbClient.SoftDeleteDecisionsWithFilter(filter)
if err != nil {
return 0, errors.Wrap(err, "deleting decisions error")
}
dbCliDel, err := strconv.Atoi(dbCliRet)
if err != nil {
return 0, errors.Wrapf(err, "converting db ret %d", dbCliDel)
}
updateCounterForDecision(delete_counters, types.StrPtr(types.CAPIOrigin), nil, dbCliDel)
nbDeleted += dbCliDel
}
}
return nbDeleted, nil
} }
func createAlertsForDecisions(decisions []*models.Decision) []*models.Alert { func createAlertsForDecisions(decisions []*models.Decision) []*models.Alert {
@ -454,7 +486,7 @@ func createAlertForDecision(decision *models.Decision) *models.Alert {
func fillAlertsWithDecisions(alerts []*models.Alert, decisions []*models.Decision, add_counters map[string]map[string]int) []*models.Alert { func fillAlertsWithDecisions(alerts []*models.Alert, decisions []*models.Decision, add_counters map[string]map[string]int) []*models.Alert {
for _, decision := range decisions { for _, decision := range decisions {
//count and create separate alerts for each list //count and create separate alerts for each list
updateCounterForDecision(add_counters, decision, 1) updateCounterForDecision(add_counters, decision.Origin, decision.Scenario, 1)
/*CAPI might send lower case scopes, unify it.*/ /*CAPI might send lower case scopes, unify it.*/
switch strings.ToLower(*decision.Scope) { switch strings.ToLower(*decision.Scope) {
@ -489,7 +521,7 @@ func fillAlertsWithDecisions(alerts []*models.Alert, decisions []*models.Decisio
return alerts return alerts
} }
// we receive only one list of decisions, that we need to break-up : // we receive a list of decisions and links for blocklist and we need to create a list of alerts :
// one alert for "community blocklist" // one alert for "community blocklist"
// one alert per list we're subscribed to // one alert per list we're subscribed to
func (a *apic) PullTop() error { func (a *apic) PullTop() error {
@ -503,7 +535,7 @@ func (a *apic) PullTop() error {
log.Infof("Starting community-blocklist update") log.Infof("Starting community-blocklist update")
data, _, err := a.apiClient.Decisions.GetStream(context.Background(), apiclient.DecisionsStreamOpts{Startup: a.startup}) data, _, err := a.apiClient.Decisions.GetStreamV3(context.Background(), apiclient.DecisionsStreamOpts{Startup: a.startup})
if err != nil { if err != nil {
return errors.Wrap(err, "get stream") return errors.Wrap(err, "get stream")
} }
@ -512,10 +544,13 @@ func (a *apic) PullTop() error {
log.Debugf("Received %d new decisions", len(data.New)) log.Debugf("Received %d new decisions", len(data.New))
log.Debugf("Received %d deleted decisions", len(data.Deleted)) log.Debugf("Received %d deleted decisions", len(data.Deleted))
if data.Links != nil {
log.Debugf("Received %d blocklists links", len(data.Links.Blocklists))
}
add_counters, delete_counters := makeAddAndDeleteCounters() add_counters, delete_counters := makeAddAndDeleteCounters()
// process deleted decisions // process deleted decisions
if nbDeleted, err := a.HandleDeletedDecisions(data.Deleted, delete_counters); err != nil { if nbDeleted, err := a.HandleDeletedDecisionsV3(data.Deleted, delete_counters); err != nil {
return err return err
} else { } else {
log.Printf("capi/community-blocklist : %d explicit deletions", nbDeleted) log.Printf("capi/community-blocklist : %d explicit deletions", nbDeleted)
@ -526,12 +561,25 @@ func (a *apic) PullTop() error {
return nil return nil
} }
// we receive only one list of decisions, that we need to break-up : // create one alert for community blocklist using the first decision
// one alert for "community blocklist" decisions := a.apiClient.Decisions.GetDecisionsFromGroups(data.New)
// one alert per list we're subscribed to alert := createAlertForDecision(decisions[0])
alertsFromCapi := createAlertsForDecisions(data.New) alertsFromCapi := []*models.Alert{alert}
alertsFromCapi = fillAlertsWithDecisions(alertsFromCapi, data.New, add_counters) alertsFromCapi = fillAlertsWithDecisions(alertsFromCapi, decisions, add_counters)
err = a.SaveAlerts(alertsFromCapi, add_counters, delete_counters)
if err != nil {
return errors.Wrap(err, "while saving alerts")
}
// update blocklists
if err := a.UpdateBlocklists(data.Links, add_counters); err != nil {
return errors.Wrap(err, "while updating blocklists")
}
return nil
}
func (a *apic) SaveAlerts(alertsFromCapi []*models.Alert, add_counters map[string]map[string]int, delete_counters map[string]map[string]int) error {
for idx, alert := range alertsFromCapi { for idx, alert := range alertsFromCapi {
alertsFromCapi[idx] = setAlertScenario(add_counters, delete_counters, alert) alertsFromCapi[idx] = setAlertScenario(add_counters, delete_counters, alert)
log.Debugf("%s has %d decisions", *alertsFromCapi[idx].Source.Scope, len(alertsFromCapi[idx].Decisions)) log.Debugf("%s has %d decisions", *alertsFromCapi[idx].Source.Scope, len(alertsFromCapi[idx].Decisions))
@ -544,6 +592,49 @@ func (a *apic) PullTop() error {
} }
log.Printf("%s : added %d entries, deleted %d entries (alert:%d)", *alertsFromCapi[idx].Source.Scope, inserted, deleted, alertID) log.Printf("%s : added %d entries, deleted %d entries (alert:%d)", *alertsFromCapi[idx].Source.Scope, inserted, deleted, alertID)
} }
return nil
}
func (a *apic) UpdateBlocklists(links *modelscapi.GetDecisionsStreamResponseLinks, add_counters map[string]map[string]int) error {
if links == nil {
return nil
}
if links.Blocklists == nil {
return nil
}
// we must use a different http client than apiClient's because the transport of apiClient is jwtTransport or here we have signed apis that are incompatibles
// we can use the same baseUrl as the urls are absolute and the parse will take care of it
defaultClient, err := apiclient.NewDefaultClient(a.apiClient.BaseURL, "", "", &http.Client{})
if err != nil {
return errors.Wrap(err, "while creating default client")
}
for _, blocklist := range links.Blocklists {
if blocklist.Scope == nil {
log.Warningf("blocklist has no scope")
continue
}
if blocklist.Duration == nil {
log.Warningf("blocklist has no duration")
continue
}
decisions, err := defaultClient.Decisions.GetDecisionsFromBlocklist(context.Background(), blocklist)
if err != nil {
return errors.Wrapf(err, "while getting decisions from blocklist %s", *blocklist.Name)
}
if len(decisions) == 0 {
log.Infof("blocklist %s has no decisions", *blocklist.Name)
continue
}
alert := createAlertForDecision(decisions[0])
alertsFromCapi := []*models.Alert{alert}
alertsFromCapi = fillAlertsWithDecisions(alertsFromCapi, decisions, add_counters)
err = a.SaveAlerts(alertsFromCapi, add_counters, nil)
if err != nil {
return errors.Wrapf(err, "while saving alert from blocklist %s", *blocklist.Name)
}
}
return nil return nil
} }
@ -691,12 +782,12 @@ func makeAddAndDeleteCounters() (map[string]map[string]int, map[string]map[strin
return add_counters, delete_counters return add_counters, delete_counters
} }
func updateCounterForDecision(counter map[string]map[string]int, decision *models.Decision, totalDecisions int) { func updateCounterForDecision(counter map[string]map[string]int, origin *string, scenario *string, totalDecisions int) {
if *decision.Origin == types.CAPIOrigin { if *origin == types.CAPIOrigin {
counter[*decision.Origin]["all"] += totalDecisions counter[*origin]["all"] += totalDecisions
} else if *decision.Origin == types.ListOrigin { } else if *origin == types.ListOrigin {
counter[*decision.Origin][*decision.Scenario] += totalDecisions counter[*origin][*scenario] += totalDecisions
} else { } else {
log.Warningf("Unknown origin %s", *decision.Origin) log.Warningf("Unknown origin %s", *origin)
} }
} }

View file

@ -26,6 +26,7 @@ import (
"github.com/crowdsecurity/crowdsec/pkg/database/ent/decision" "github.com/crowdsecurity/crowdsec/pkg/database/ent/decision"
"github.com/crowdsecurity/crowdsec/pkg/database/ent/machine" "github.com/crowdsecurity/crowdsec/pkg/database/ent/machine"
"github.com/crowdsecurity/crowdsec/pkg/models" "github.com/crowdsecurity/crowdsec/pkg/models"
"github.com/crowdsecurity/crowdsec/pkg/modelscapi"
"github.com/crowdsecurity/crowdsec/pkg/types" "github.com/crowdsecurity/crowdsec/pkg/types"
) )
@ -220,7 +221,7 @@ func TestNewAPIC(t *testing.T) {
setConfig() setConfig()
httpmock.Activate() httpmock.Activate()
defer httpmock.DeactivateAndReset() defer httpmock.DeactivateAndReset()
httpmock.RegisterResponder("POST", "http://foobar/v2/watchers/login", httpmock.NewBytesResponder( httpmock.RegisterResponder("POST", "http://foobar/v3/watchers/login", httpmock.NewBytesResponder(
200, jsonMarshalX( 200, jsonMarshalX(
models.WatcherAuthResponse{ models.WatcherAuthResponse{
Code: 200, Code: 200,
@ -518,7 +519,7 @@ func TestFillAlertsWithDecisions(t *testing.T) {
func TestAPICPullTop(t *testing.T) { func TestAPICPullTop(t *testing.T) {
api := getAPIC(t) api := getAPIC(t)
api.dbClient.Ent.Decision.Create(). api.dbClient.Ent.Decision.Create().
SetOrigin(types.ListOrigin). SetOrigin(types.CAPIOrigin).
SetType("ban"). SetType("ban").
SetValue("9.9.9.9"). SetValue("9.9.9.9").
SetScope("Ip"). SetScope("Ip").
@ -531,62 +532,65 @@ func TestAPICPullTop(t *testing.T) {
defer httpmock.DeactivateAndReset() defer httpmock.DeactivateAndReset()
httpmock.RegisterResponder("GET", "http://api.crowdsec.net/api/decisions/stream", httpmock.NewBytesResponder( httpmock.RegisterResponder("GET", "http://api.crowdsec.net/api/decisions/stream", httpmock.NewBytesResponder(
200, jsonMarshalX( 200, jsonMarshalX(
models.DecisionsStreamResponse{ modelscapi.GetDecisionsStreamResponse{
Deleted: models.GetDecisionsResponse{ Deleted: modelscapi.GetDecisionsStreamResponseDeleted{
&models.Decision{ &modelscapi.GetDecisionsStreamResponseDeletedItem{
Origin: types.StrPtr(types.ListOrigin), Decisions: []string{
Scenario: types.StrPtr("crowdsecurity/ssh-bf"), "9.9.9.9", // This is already present in DB
Value: types.StrPtr("9.9.9.9"), "9.1.9.9", // This not present in DB
Scope: types.StrPtr("Ip"), },
Duration: types.StrPtr("24h"), Scope: types.StrPtr("Ip"),
Type: types.StrPtr("ban"),
}, // This is already present in DB }, // This is already present in DB
&models.Decision{
Origin: types.StrPtr(types.ListOrigin),
Scenario: types.StrPtr("crowdsecurity/ssh-bf"),
Value: types.StrPtr("9.1.9.9"),
Scope: types.StrPtr("Ip"),
Duration: types.StrPtr("24h"),
Type: types.StrPtr("ban"),
}, // This not present in DB.
}, },
New: models.GetDecisionsResponse{ New: modelscapi.GetDecisionsStreamResponseNew{
&models.Decision{ &modelscapi.GetDecisionsStreamResponseNewItem{
Origin: types.StrPtr(types.CAPIOrigin),
Scenario: types.StrPtr("crowdsecurity/test1"), Scenario: types.StrPtr("crowdsecurity/test1"),
Value: types.StrPtr("1.2.3.4"),
Scope: types.StrPtr("Ip"), Scope: types.StrPtr("Ip"),
Duration: types.StrPtr("24h"), Decisions: []*modelscapi.GetDecisionsStreamResponseNewItemDecisionsItems0{
Type: types.StrPtr("ban"), {
Value: types.StrPtr("1.2.3.4"),
Duration: types.StrPtr("24h"),
},
},
}, },
&models.Decision{ &modelscapi.GetDecisionsStreamResponseNewItem{
Origin: types.StrPtr(types.CAPIOrigin),
Scenario: types.StrPtr("crowdsecurity/test2"), Scenario: types.StrPtr("crowdsecurity/test2"),
Value: types.StrPtr("1.2.3.5"),
Scope: types.StrPtr("Ip"), Scope: types.StrPtr("Ip"),
Duration: types.StrPtr("24h"), Decisions: []*modelscapi.GetDecisionsStreamResponseNewItemDecisionsItems0{
Type: types.StrPtr("ban"), {
Value: types.StrPtr("1.2.3.5"),
Duration: types.StrPtr("24h"),
},
},
}, // These two are from community list. }, // These two are from community list.
&models.Decision{ },
Origin: types.StrPtr(types.ListOrigin), Links: &modelscapi.GetDecisionsStreamResponseLinks{
Scenario: types.StrPtr("crowdsecurity/http-bf"), Blocklists: []*modelscapi.BlocklistLink{
Value: types.StrPtr("1.2.3.6"), {
Scope: types.StrPtr("Ip"), URL: types.StrPtr("http://api.crowdsec.net/blocklist1"),
Duration: types.StrPtr("24h"), Name: types.StrPtr("crowdsecurity/http-bf"),
Type: types.StrPtr("ban"), Scope: types.StrPtr("Ip"),
Remediation: types.StrPtr("ban"),
Duration: types.StrPtr("24h"),
},
{
URL: types.StrPtr("http://api.crowdsec.net/blocklist2"),
Name: types.StrPtr("crowdsecurity/ssh-bf"),
Scope: types.StrPtr("Ip"),
Remediation: types.StrPtr("ban"),
Duration: types.StrPtr("24h"),
},
}, },
&models.Decision{
Origin: types.StrPtr(types.ListOrigin),
Scenario: types.StrPtr("crowdsecurity/ssh-bf"),
Value: types.StrPtr("1.2.3.7"),
Scope: types.StrPtr("Ip"),
Duration: types.StrPtr("24h"),
Type: types.StrPtr("ban"),
}, // These two are from list subscription.
}, },
}, },
), ),
)) ))
httpmock.RegisterResponder("GET", "http://api.crowdsec.net/blocklist1", httpmock.NewStringResponder(
200, "1.2.3.6",
))
httpmock.RegisterResponder("GET", "http://api.crowdsec.net/blocklist2", httpmock.NewStringResponder(
200, "1.2.3.7",
))
url, err := url.ParseRequestURI("http://api.crowdsec.net/") url, err := url.ParseRequestURI("http://api.crowdsec.net/")
require.NoError(t, err) require.NoError(t, err)
@ -845,15 +849,17 @@ func TestAPICPull(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
api.apiClient = apic api.apiClient = apic
httpmock.RegisterNoResponder(httpmock.NewBytesResponder(200, jsonMarshalX( httpmock.RegisterNoResponder(httpmock.NewBytesResponder(200, jsonMarshalX(
models.DecisionsStreamResponse{ modelscapi.GetDecisionsStreamResponse{
New: models.GetDecisionsResponse{ New: modelscapi.GetDecisionsStreamResponseNew{
&models.Decision{ &modelscapi.GetDecisionsStreamResponseNewItem{
Origin: types.StrPtr(types.CAPIOrigin), Scenario: types.StrPtr("crowdsecurity/ssh-bf"),
Scenario: types.StrPtr("crowdsecurity/test2"),
Value: types.StrPtr("1.2.3.5"),
Scope: types.StrPtr("Ip"), Scope: types.StrPtr("Ip"),
Duration: types.StrPtr("24h"), Decisions: []*modelscapi.GetDecisionsStreamResponseNewItemDecisionsItems0{
Type: types.StrPtr("ban"), {
Value: types.StrPtr("1.2.3.5"),
Duration: types.StrPtr("24h"),
},
},
}, },
}, },
}, },

View file

@ -276,7 +276,10 @@ func (c *Client) CreateAlert(machineID string, alertList []*models.Alert) ([]str
return ret, nil return ret, nil
} }
/*We can't bulk both the alert and the decision at the same time. With new consensus, we want to bulk a single alert with a lot of decisions.*/ // UpdateCommunityBlocklist is called to update either the community blocklist (or other lists the user subscribed to)
// it takes care of creating the new alert with the associated decisions, and it will as well deleted the "older" overlapping decisions:
// 1st pull, you get decisions [1,2,3]. it inserts [1,2,3]
// 2nd pull, you get decisions [1,2,3,4]. it inserts [1,2,3,4] and will try to delete [1,2,3,4] with a different alert ID and same origin
func (c *Client) UpdateCommunityBlocklist(alertItem *models.Alert) (int, int, int, error) { func (c *Client) UpdateCommunityBlocklist(alertItem *models.Alert) (int, int, int, error) {
var err error var err error

View file

@ -0,0 +1,75 @@
// Code generated by go-swagger; DO NOT EDIT.
package modelscapi
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"strconv"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// AddSignalsRequest add signals request
//
// # All signals request model
//
// swagger:model AddSignalsRequest
type AddSignalsRequest []*AddSignalsRequestItem
// Validate validates this add signals request
func (m AddSignalsRequest) Validate(formats strfmt.Registry) error {
var res []error
for i := 0; i < len(m); i++ {
if swag.IsZero(m[i]) { // not required
continue
}
if m[i] != nil {
if err := m[i].Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName(strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName(strconv.Itoa(i))
}
return err
}
}
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
// ContextValidate validate this add signals request based on the context it is used
func (m AddSignalsRequest) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
var res []error
for i := 0; i < len(m); i++ {
if m[i] != nil {
if err := m[i].ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName(strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName(strconv.Itoa(i))
}
return err
}
}
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View file

@ -0,0 +1,361 @@
// Code generated by go-swagger; DO NOT EDIT.
package modelscapi
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"strconv"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
"github.com/go-openapi/validate"
)
// AddSignalsRequestItem Signal
//
// swagger:model AddSignalsRequestItem
type AddSignalsRequestItem struct {
// alert id
AlertID int64 `json:"alert_id,omitempty"`
// context
Context []*AddSignalsRequestItemContextItems0 `json:"context"`
// created at
CreatedAt string `json:"created_at,omitempty"`
// decisions
Decisions AddSignalsRequestItemDecisions `json:"decisions,omitempty"`
// machine id
MachineID string `json:"machine_id,omitempty"`
// a human readable message
// Required: true
Message *string `json:"message"`
// scenario
// Required: true
Scenario *string `json:"scenario"`
// scenario hash
// Required: true
ScenarioHash *string `json:"scenario_hash"`
// scenario trust
ScenarioTrust string `json:"scenario_trust,omitempty"`
// scenario version
// Required: true
ScenarioVersion *string `json:"scenario_version"`
// source
// Required: true
Source *AddSignalsRequestItemSource `json:"source"`
// start at
// Required: true
StartAt *string `json:"start_at"`
// stop at
// Required: true
StopAt *string `json:"stop_at"`
}
// Validate validates this add signals request item
func (m *AddSignalsRequestItem) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateContext(formats); err != nil {
res = append(res, err)
}
if err := m.validateDecisions(formats); err != nil {
res = append(res, err)
}
if err := m.validateMessage(formats); err != nil {
res = append(res, err)
}
if err := m.validateScenario(formats); err != nil {
res = append(res, err)
}
if err := m.validateScenarioHash(formats); err != nil {
res = append(res, err)
}
if err := m.validateScenarioVersion(formats); err != nil {
res = append(res, err)
}
if err := m.validateSource(formats); err != nil {
res = append(res, err)
}
if err := m.validateStartAt(formats); err != nil {
res = append(res, err)
}
if err := m.validateStopAt(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *AddSignalsRequestItem) validateContext(formats strfmt.Registry) error {
if swag.IsZero(m.Context) { // not required
return nil
}
for i := 0; i < len(m.Context); i++ {
if swag.IsZero(m.Context[i]) { // not required
continue
}
if m.Context[i] != nil {
if err := m.Context[i].Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("context" + "." + strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("context" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
func (m *AddSignalsRequestItem) validateDecisions(formats strfmt.Registry) error {
if swag.IsZero(m.Decisions) { // not required
return nil
}
if err := m.Decisions.Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("decisions")
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("decisions")
}
return err
}
return nil
}
func (m *AddSignalsRequestItem) validateMessage(formats strfmt.Registry) error {
if err := validate.Required("message", "body", m.Message); err != nil {
return err
}
return nil
}
func (m *AddSignalsRequestItem) validateScenario(formats strfmt.Registry) error {
if err := validate.Required("scenario", "body", m.Scenario); err != nil {
return err
}
return nil
}
func (m *AddSignalsRequestItem) validateScenarioHash(formats strfmt.Registry) error {
if err := validate.Required("scenario_hash", "body", m.ScenarioHash); err != nil {
return err
}
return nil
}
func (m *AddSignalsRequestItem) validateScenarioVersion(formats strfmt.Registry) error {
if err := validate.Required("scenario_version", "body", m.ScenarioVersion); err != nil {
return err
}
return nil
}
func (m *AddSignalsRequestItem) validateSource(formats strfmt.Registry) error {
if err := validate.Required("source", "body", m.Source); err != nil {
return err
}
if m.Source != nil {
if err := m.Source.Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("source")
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("source")
}
return err
}
}
return nil
}
func (m *AddSignalsRequestItem) validateStartAt(formats strfmt.Registry) error {
if err := validate.Required("start_at", "body", m.StartAt); err != nil {
return err
}
return nil
}
func (m *AddSignalsRequestItem) validateStopAt(formats strfmt.Registry) error {
if err := validate.Required("stop_at", "body", m.StopAt); err != nil {
return err
}
return nil
}
// ContextValidate validate this add signals request item based on the context it is used
func (m *AddSignalsRequestItem) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
var res []error
if err := m.contextValidateContext(ctx, formats); err != nil {
res = append(res, err)
}
if err := m.contextValidateDecisions(ctx, formats); err != nil {
res = append(res, err)
}
if err := m.contextValidateSource(ctx, formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *AddSignalsRequestItem) contextValidateContext(ctx context.Context, formats strfmt.Registry) error {
for i := 0; i < len(m.Context); i++ {
if m.Context[i] != nil {
if err := m.Context[i].ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("context" + "." + strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("context" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
func (m *AddSignalsRequestItem) contextValidateDecisions(ctx context.Context, formats strfmt.Registry) error {
if err := m.Decisions.ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("decisions")
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("decisions")
}
return err
}
return nil
}
func (m *AddSignalsRequestItem) contextValidateSource(ctx context.Context, formats strfmt.Registry) error {
if m.Source != nil {
if err := m.Source.ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("source")
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("source")
}
return err
}
}
return nil
}
// MarshalBinary interface implementation
func (m *AddSignalsRequestItem) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *AddSignalsRequestItem) UnmarshalBinary(b []byte) error {
var res AddSignalsRequestItem
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}
// AddSignalsRequestItemContextItems0 add signals request item context items0
//
// swagger:model AddSignalsRequestItemContextItems0
type AddSignalsRequestItemContextItems0 struct {
// key
Key string `json:"key,omitempty"`
// value
Value string `json:"value,omitempty"`
}
// Validate validates this add signals request item context items0
func (m *AddSignalsRequestItemContextItems0) Validate(formats strfmt.Registry) error {
return nil
}
// ContextValidate validates this add signals request item context items0 based on context it is used
func (m *AddSignalsRequestItemContextItems0) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *AddSignalsRequestItemContextItems0) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *AddSignalsRequestItemContextItems0) UnmarshalBinary(b []byte) error {
var res AddSignalsRequestItemContextItems0
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View file

@ -0,0 +1,73 @@
// Code generated by go-swagger; DO NOT EDIT.
package modelscapi
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"strconv"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// AddSignalsRequestItemDecisions Decisions list
//
// swagger:model AddSignalsRequestItemDecisions
type AddSignalsRequestItemDecisions []*AddSignalsRequestItemDecisionsItem
// Validate validates this add signals request item decisions
func (m AddSignalsRequestItemDecisions) Validate(formats strfmt.Registry) error {
var res []error
for i := 0; i < len(m); i++ {
if swag.IsZero(m[i]) { // not required
continue
}
if m[i] != nil {
if err := m[i].Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName(strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName(strconv.Itoa(i))
}
return err
}
}
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
// ContextValidate validate this add signals request item decisions based on the context it is used
func (m AddSignalsRequestItemDecisions) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
var res []error
for i := 0; i < len(m); i++ {
if m[i] != nil {
if err := m[i].ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName(strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName(strconv.Itoa(i))
}
return err
}
}
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View file

@ -0,0 +1,179 @@
// Code generated by go-swagger; DO NOT EDIT.
package modelscapi
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
"github.com/go-openapi/validate"
)
// AddSignalsRequestItemDecisionsItem Decision
//
// swagger:model AddSignalsRequestItemDecisionsItem
type AddSignalsRequestItemDecisionsItem struct {
// duration
// Required: true
Duration *string `json:"duration"`
// (only relevant for GET ops) the unique id
// Required: true
ID *int64 `json:"id"`
// the origin of the decision : cscli, crowdsec
// Required: true
Origin *string `json:"origin"`
// scenario
// Required: true
Scenario *string `json:"scenario"`
// the scope of decision : does it apply to an IP, a range, a username, etc
// Required: true
Scope *string `json:"scope"`
// simulated
Simulated bool `json:"simulated,omitempty"`
// the type of decision, might be 'ban', 'captcha' or something custom. Ignored when watcher (cscli/crowdsec) is pushing to APIL.
// Required: true
Type *string `json:"type"`
// until
Until string `json:"until,omitempty"`
// the value of the decision scope : an IP, a range, a username, etc
// Required: true
Value *string `json:"value"`
}
// Validate validates this add signals request item decisions item
func (m *AddSignalsRequestItemDecisionsItem) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateDuration(formats); err != nil {
res = append(res, err)
}
if err := m.validateID(formats); err != nil {
res = append(res, err)
}
if err := m.validateOrigin(formats); err != nil {
res = append(res, err)
}
if err := m.validateScenario(formats); err != nil {
res = append(res, err)
}
if err := m.validateScope(formats); err != nil {
res = append(res, err)
}
if err := m.validateType(formats); err != nil {
res = append(res, err)
}
if err := m.validateValue(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *AddSignalsRequestItemDecisionsItem) validateDuration(formats strfmt.Registry) error {
if err := validate.Required("duration", "body", m.Duration); err != nil {
return err
}
return nil
}
func (m *AddSignalsRequestItemDecisionsItem) validateID(formats strfmt.Registry) error {
if err := validate.Required("id", "body", m.ID); err != nil {
return err
}
return nil
}
func (m *AddSignalsRequestItemDecisionsItem) validateOrigin(formats strfmt.Registry) error {
if err := validate.Required("origin", "body", m.Origin); err != nil {
return err
}
return nil
}
func (m *AddSignalsRequestItemDecisionsItem) validateScenario(formats strfmt.Registry) error {
if err := validate.Required("scenario", "body", m.Scenario); err != nil {
return err
}
return nil
}
func (m *AddSignalsRequestItemDecisionsItem) validateScope(formats strfmt.Registry) error {
if err := validate.Required("scope", "body", m.Scope); err != nil {
return err
}
return nil
}
func (m *AddSignalsRequestItemDecisionsItem) validateType(formats strfmt.Registry) error {
if err := validate.Required("type", "body", m.Type); err != nil {
return err
}
return nil
}
func (m *AddSignalsRequestItemDecisionsItem) validateValue(formats strfmt.Registry) error {
if err := validate.Required("value", "body", m.Value); err != nil {
return err
}
return nil
}
// ContextValidate validates this add signals request item decisions item based on context it is used
func (m *AddSignalsRequestItemDecisionsItem) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *AddSignalsRequestItemDecisionsItem) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *AddSignalsRequestItemDecisionsItem) UnmarshalBinary(b []byte) error {
var res AddSignalsRequestItemDecisionsItem
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View file

@ -0,0 +1,109 @@
// Code generated by go-swagger; DO NOT EDIT.
package modelscapi
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
"github.com/go-openapi/validate"
)
// AddSignalsRequestItemSource Source
//
// swagger:model AddSignalsRequestItemSource
type AddSignalsRequestItemSource struct {
// provided as a convenience when the source is an IP
AsName string `json:"as_name,omitempty"`
// provided as a convenience when the source is an IP
AsNumber string `json:"as_number,omitempty"`
// cn
Cn string `json:"cn,omitempty"`
// provided as a convenience when the source is an IP
IP string `json:"ip,omitempty"`
// latitude
Latitude float32 `json:"latitude,omitempty"`
// longitude
Longitude float32 `json:"longitude,omitempty"`
// provided as a convenience when the source is an IP
Range string `json:"range,omitempty"`
// the scope of a source : ip,range,username,etc
// Required: true
Scope *string `json:"scope"`
// the value of a source : the ip, the range, the username,etc
// Required: true
Value *string `json:"value"`
}
// Validate validates this add signals request item source
func (m *AddSignalsRequestItemSource) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateScope(formats); err != nil {
res = append(res, err)
}
if err := m.validateValue(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *AddSignalsRequestItemSource) validateScope(formats strfmt.Registry) error {
if err := validate.Required("scope", "body", m.Scope); err != nil {
return err
}
return nil
}
func (m *AddSignalsRequestItemSource) validateValue(formats strfmt.Registry) error {
if err := validate.Required("value", "body", m.Value); err != nil {
return err
}
return nil
}
// ContextValidate validates this add signals request item source based on context it is used
func (m *AddSignalsRequestItemSource) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *AddSignalsRequestItemSource) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *AddSignalsRequestItemSource) UnmarshalBinary(b []byte) error {
var res AddSignalsRequestItemSource
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View file

@ -0,0 +1,139 @@
// Code generated by go-swagger; DO NOT EDIT.
package modelscapi
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
"github.com/go-openapi/validate"
)
// BlocklistLink blocklist link
//
// swagger:model BlocklistLink
type BlocklistLink struct {
// duration
// Required: true
Duration *string `json:"duration"`
// the name of the blocklist
// Required: true
Name *string `json:"name"`
// the remediation that should be used for the blocklist
// Required: true
Remediation *string `json:"remediation"`
// the scope of decisions in the blocklist
// Required: true
Scope *string `json:"scope"`
// the url from which the blocklist content can be downloaded
// Required: true
URL *string `json:"url"`
}
// Validate validates this blocklist link
func (m *BlocklistLink) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateDuration(formats); err != nil {
res = append(res, err)
}
if err := m.validateName(formats); err != nil {
res = append(res, err)
}
if err := m.validateRemediation(formats); err != nil {
res = append(res, err)
}
if err := m.validateScope(formats); err != nil {
res = append(res, err)
}
if err := m.validateURL(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *BlocklistLink) validateDuration(formats strfmt.Registry) error {
if err := validate.Required("duration", "body", m.Duration); err != nil {
return err
}
return nil
}
func (m *BlocklistLink) validateName(formats strfmt.Registry) error {
if err := validate.Required("name", "body", m.Name); err != nil {
return err
}
return nil
}
func (m *BlocklistLink) validateRemediation(formats strfmt.Registry) error {
if err := validate.Required("remediation", "body", m.Remediation); err != nil {
return err
}
return nil
}
func (m *BlocklistLink) validateScope(formats strfmt.Registry) error {
if err := validate.Required("scope", "body", m.Scope); err != nil {
return err
}
return nil
}
func (m *BlocklistLink) validateURL(formats strfmt.Registry) error {
if err := validate.Required("url", "body", m.URL); err != nil {
return err
}
return nil
}
// ContextValidate validates this blocklist link based on context it is used
func (m *BlocklistLink) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *BlocklistLink) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *BlocklistLink) UnmarshalBinary(b []byte) error {
var res BlocklistLink
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View file

@ -0,0 +1,67 @@
// Code generated by go-swagger; DO NOT EDIT.
package modelscapi
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"strconv"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
)
// DecisionsDeleteRequest delete decisions
//
// delete decision model
//
// swagger:model DecisionsDeleteRequest
type DecisionsDeleteRequest []DecisionsDeleteRequestItem
// Validate validates this decisions delete request
func (m DecisionsDeleteRequest) Validate(formats strfmt.Registry) error {
var res []error
for i := 0; i < len(m); i++ {
if err := m[i].Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName(strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName(strconv.Itoa(i))
}
return err
}
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
// ContextValidate validate this decisions delete request based on the context it is used
func (m DecisionsDeleteRequest) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
var res []error
for i := 0; i < len(m); i++ {
if err := m[i].ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName(strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName(strconv.Itoa(i))
}
return err
}
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View file

@ -0,0 +1,27 @@
// Code generated by go-swagger; DO NOT EDIT.
package modelscapi
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"github.com/go-openapi/strfmt"
)
// DecisionsDeleteRequestItem decisionsIDs
//
// swagger:model DecisionsDeleteRequestItem
type DecisionsDeleteRequestItem string
// Validate validates this decisions delete request item
func (m DecisionsDeleteRequestItem) Validate(formats strfmt.Registry) error {
return nil
}
// ContextValidate validates this decisions delete request item based on context it is used
func (m DecisionsDeleteRequestItem) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
return nil
}

View file

@ -0,0 +1,75 @@
// Code generated by go-swagger; DO NOT EDIT.
package modelscapi
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"strconv"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// DecisionsSyncRequest sync decisions request
//
// sync decision model
//
// swagger:model DecisionsSyncRequest
type DecisionsSyncRequest []*DecisionsSyncRequestItem
// Validate validates this decisions sync request
func (m DecisionsSyncRequest) Validate(formats strfmt.Registry) error {
var res []error
for i := 0; i < len(m); i++ {
if swag.IsZero(m[i]) { // not required
continue
}
if m[i] != nil {
if err := m[i].Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName(strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName(strconv.Itoa(i))
}
return err
}
}
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
// ContextValidate validate this decisions sync request based on the context it is used
func (m DecisionsSyncRequest) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
var res []error
for i := 0; i < len(m); i++ {
if m[i] != nil {
if err := m[i].ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName(strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName(strconv.Itoa(i))
}
return err
}
}
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View file

@ -0,0 +1,263 @@
// Code generated by go-swagger; DO NOT EDIT.
package modelscapi
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
"github.com/go-openapi/validate"
)
// DecisionsSyncRequestItem Signal
//
// swagger:model DecisionsSyncRequestItem
type DecisionsSyncRequestItem struct {
// alert id
AlertID int64 `json:"alert_id,omitempty"`
// created at
CreatedAt string `json:"created_at,omitempty"`
// decisions
Decisions DecisionsSyncRequestItemDecisions `json:"decisions,omitempty"`
// machine id
MachineID string `json:"machine_id,omitempty"`
// a human readable message
// Required: true
Message *string `json:"message"`
// scenario
// Required: true
Scenario *string `json:"scenario"`
// scenario hash
// Required: true
ScenarioHash *string `json:"scenario_hash"`
// scenario trust
ScenarioTrust string `json:"scenario_trust,omitempty"`
// scenario version
// Required: true
ScenarioVersion *string `json:"scenario_version"`
// source
// Required: true
Source *DecisionsSyncRequestItemSource `json:"source"`
// start at
// Required: true
StartAt *string `json:"start_at"`
// stop at
// Required: true
StopAt *string `json:"stop_at"`
}
// Validate validates this decisions sync request item
func (m *DecisionsSyncRequestItem) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateDecisions(formats); err != nil {
res = append(res, err)
}
if err := m.validateMessage(formats); err != nil {
res = append(res, err)
}
if err := m.validateScenario(formats); err != nil {
res = append(res, err)
}
if err := m.validateScenarioHash(formats); err != nil {
res = append(res, err)
}
if err := m.validateScenarioVersion(formats); err != nil {
res = append(res, err)
}
if err := m.validateSource(formats); err != nil {
res = append(res, err)
}
if err := m.validateStartAt(formats); err != nil {
res = append(res, err)
}
if err := m.validateStopAt(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *DecisionsSyncRequestItem) validateDecisions(formats strfmt.Registry) error {
if swag.IsZero(m.Decisions) { // not required
return nil
}
if err := m.Decisions.Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("decisions")
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("decisions")
}
return err
}
return nil
}
func (m *DecisionsSyncRequestItem) validateMessage(formats strfmt.Registry) error {
if err := validate.Required("message", "body", m.Message); err != nil {
return err
}
return nil
}
func (m *DecisionsSyncRequestItem) validateScenario(formats strfmt.Registry) error {
if err := validate.Required("scenario", "body", m.Scenario); err != nil {
return err
}
return nil
}
func (m *DecisionsSyncRequestItem) validateScenarioHash(formats strfmt.Registry) error {
if err := validate.Required("scenario_hash", "body", m.ScenarioHash); err != nil {
return err
}
return nil
}
func (m *DecisionsSyncRequestItem) validateScenarioVersion(formats strfmt.Registry) error {
if err := validate.Required("scenario_version", "body", m.ScenarioVersion); err != nil {
return err
}
return nil
}
func (m *DecisionsSyncRequestItem) validateSource(formats strfmt.Registry) error {
if err := validate.Required("source", "body", m.Source); err != nil {
return err
}
if m.Source != nil {
if err := m.Source.Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("source")
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("source")
}
return err
}
}
return nil
}
func (m *DecisionsSyncRequestItem) validateStartAt(formats strfmt.Registry) error {
if err := validate.Required("start_at", "body", m.StartAt); err != nil {
return err
}
return nil
}
func (m *DecisionsSyncRequestItem) validateStopAt(formats strfmt.Registry) error {
if err := validate.Required("stop_at", "body", m.StopAt); err != nil {
return err
}
return nil
}
// ContextValidate validate this decisions sync request item based on the context it is used
func (m *DecisionsSyncRequestItem) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
var res []error
if err := m.contextValidateDecisions(ctx, formats); err != nil {
res = append(res, err)
}
if err := m.contextValidateSource(ctx, formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *DecisionsSyncRequestItem) contextValidateDecisions(ctx context.Context, formats strfmt.Registry) error {
if err := m.Decisions.ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("decisions")
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("decisions")
}
return err
}
return nil
}
func (m *DecisionsSyncRequestItem) contextValidateSource(ctx context.Context, formats strfmt.Registry) error {
if m.Source != nil {
if err := m.Source.ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("source")
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("source")
}
return err
}
}
return nil
}
// MarshalBinary interface implementation
func (m *DecisionsSyncRequestItem) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *DecisionsSyncRequestItem) UnmarshalBinary(b []byte) error {
var res DecisionsSyncRequestItem
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View file

@ -0,0 +1,73 @@
// Code generated by go-swagger; DO NOT EDIT.
package modelscapi
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"strconv"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// DecisionsSyncRequestItemDecisions Decisions list
//
// swagger:model DecisionsSyncRequestItemDecisions
type DecisionsSyncRequestItemDecisions []*DecisionsSyncRequestItemDecisionsItem
// Validate validates this decisions sync request item decisions
func (m DecisionsSyncRequestItemDecisions) Validate(formats strfmt.Registry) error {
var res []error
for i := 0; i < len(m); i++ {
if swag.IsZero(m[i]) { // not required
continue
}
if m[i] != nil {
if err := m[i].Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName(strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName(strconv.Itoa(i))
}
return err
}
}
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
// ContextValidate validate this decisions sync request item decisions based on the context it is used
func (m DecisionsSyncRequestItemDecisions) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
var res []error
for i := 0; i < len(m); i++ {
if m[i] != nil {
if err := m[i].ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName(strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName(strconv.Itoa(i))
}
return err
}
}
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View file

@ -0,0 +1,179 @@
// Code generated by go-swagger; DO NOT EDIT.
package modelscapi
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
"github.com/go-openapi/validate"
)
// DecisionsSyncRequestItemDecisionsItem Decision
//
// swagger:model DecisionsSyncRequestItemDecisionsItem
type DecisionsSyncRequestItemDecisionsItem struct {
// duration
// Required: true
Duration *string `json:"duration"`
// (only relevant for GET ops) the unique id
// Required: true
ID *int64 `json:"id"`
// the origin of the decision : cscli, crowdsec
// Required: true
Origin *string `json:"origin"`
// scenario
// Required: true
Scenario *string `json:"scenario"`
// the scope of decision : does it apply to an IP, a range, a username, etc
// Required: true
Scope *string `json:"scope"`
// simulated
Simulated bool `json:"simulated,omitempty"`
// the type of decision, might be 'ban', 'captcha' or something custom. Ignored when watcher (cscli/crowdsec) is pushing to APIL.
// Required: true
Type *string `json:"type"`
// until
Until string `json:"until,omitempty"`
// the value of the decision scope : an IP, a range, a username, etc
// Required: true
Value *string `json:"value"`
}
// Validate validates this decisions sync request item decisions item
func (m *DecisionsSyncRequestItemDecisionsItem) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateDuration(formats); err != nil {
res = append(res, err)
}
if err := m.validateID(formats); err != nil {
res = append(res, err)
}
if err := m.validateOrigin(formats); err != nil {
res = append(res, err)
}
if err := m.validateScenario(formats); err != nil {
res = append(res, err)
}
if err := m.validateScope(formats); err != nil {
res = append(res, err)
}
if err := m.validateType(formats); err != nil {
res = append(res, err)
}
if err := m.validateValue(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *DecisionsSyncRequestItemDecisionsItem) validateDuration(formats strfmt.Registry) error {
if err := validate.Required("duration", "body", m.Duration); err != nil {
return err
}
return nil
}
func (m *DecisionsSyncRequestItemDecisionsItem) validateID(formats strfmt.Registry) error {
if err := validate.Required("id", "body", m.ID); err != nil {
return err
}
return nil
}
func (m *DecisionsSyncRequestItemDecisionsItem) validateOrigin(formats strfmt.Registry) error {
if err := validate.Required("origin", "body", m.Origin); err != nil {
return err
}
return nil
}
func (m *DecisionsSyncRequestItemDecisionsItem) validateScenario(formats strfmt.Registry) error {
if err := validate.Required("scenario", "body", m.Scenario); err != nil {
return err
}
return nil
}
func (m *DecisionsSyncRequestItemDecisionsItem) validateScope(formats strfmt.Registry) error {
if err := validate.Required("scope", "body", m.Scope); err != nil {
return err
}
return nil
}
func (m *DecisionsSyncRequestItemDecisionsItem) validateType(formats strfmt.Registry) error {
if err := validate.Required("type", "body", m.Type); err != nil {
return err
}
return nil
}
func (m *DecisionsSyncRequestItemDecisionsItem) validateValue(formats strfmt.Registry) error {
if err := validate.Required("value", "body", m.Value); err != nil {
return err
}
return nil
}
// ContextValidate validates this decisions sync request item decisions item based on context it is used
func (m *DecisionsSyncRequestItemDecisionsItem) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *DecisionsSyncRequestItemDecisionsItem) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *DecisionsSyncRequestItemDecisionsItem) UnmarshalBinary(b []byte) error {
var res DecisionsSyncRequestItemDecisionsItem
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View file

@ -0,0 +1,109 @@
// Code generated by go-swagger; DO NOT EDIT.
package modelscapi
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
"github.com/go-openapi/validate"
)
// DecisionsSyncRequestItemSource Source
//
// swagger:model DecisionsSyncRequestItemSource
type DecisionsSyncRequestItemSource struct {
// provided as a convenience when the source is an IP
AsName string `json:"as_name,omitempty"`
// provided as a convenience when the source is an IP
AsNumber string `json:"as_number,omitempty"`
// cn
Cn string `json:"cn,omitempty"`
// provided as a convenience when the source is an IP
IP string `json:"ip,omitempty"`
// latitude
Latitude float32 `json:"latitude,omitempty"`
// longitude
Longitude float32 `json:"longitude,omitempty"`
// provided as a convenience when the source is an IP
Range string `json:"range,omitempty"`
// the scope of a source : ip,range,username,etc
// Required: true
Scope *string `json:"scope"`
// the value of a source : the ip, the range, the username,etc
// Required: true
Value *string `json:"value"`
}
// Validate validates this decisions sync request item source
func (m *DecisionsSyncRequestItemSource) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateScope(formats); err != nil {
res = append(res, err)
}
if err := m.validateValue(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *DecisionsSyncRequestItemSource) validateScope(formats strfmt.Registry) error {
if err := validate.Required("scope", "body", m.Scope); err != nil {
return err
}
return nil
}
func (m *DecisionsSyncRequestItemSource) validateValue(formats strfmt.Registry) error {
if err := validate.Required("value", "body", m.Value); err != nil {
return err
}
return nil
}
// ContextValidate validates this decisions sync request item source based on context it is used
func (m *DecisionsSyncRequestItemSource) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *DecisionsSyncRequestItemSource) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *DecisionsSyncRequestItemSource) UnmarshalBinary(b []byte) error {
var res DecisionsSyncRequestItemSource
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View file

@ -0,0 +1,87 @@
// Code generated by go-swagger; DO NOT EDIT.
package modelscapi
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
"github.com/go-openapi/validate"
)
// EnrollRequest enroll request
//
// enroll request model
//
// swagger:model EnrollRequest
type EnrollRequest struct {
// attachment_key is generated in your crowdsec backoffice account and allows you to enroll your machines to your BO account
// Required: true
// Pattern: ^[a-zA-Z0-9]+$
AttachmentKey *string `json:"attachment_key"`
// The name that will be display in the console for the instance
Name string `json:"name,omitempty"`
// To force enroll the instance
Overwrite bool `json:"overwrite,omitempty"`
// Tags to apply on the console for the instance
Tags []string `json:"tags"`
}
// Validate validates this enroll request
func (m *EnrollRequest) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateAttachmentKey(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *EnrollRequest) validateAttachmentKey(formats strfmt.Registry) error {
if err := validate.Required("attachment_key", "body", m.AttachmentKey); err != nil {
return err
}
if err := validate.Pattern("attachment_key", "body", *m.AttachmentKey, `^[a-zA-Z0-9]+$`); err != nil {
return err
}
return nil
}
// ContextValidate validates this enroll request based on context it is used
func (m *EnrollRequest) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *EnrollRequest) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *EnrollRequest) UnmarshalBinary(b []byte) error {
var res EnrollRequest
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View file

@ -0,0 +1,76 @@
// Code generated by go-swagger; DO NOT EDIT.
package modelscapi
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
"github.com/go-openapi/validate"
)
// ErrorResponse error response
//
// error response return by the API
//
// swagger:model ErrorResponse
type ErrorResponse struct {
// more detail on individual errors
Errors string `json:"errors,omitempty"`
// Error message
// Required: true
Message *string `json:"message"`
}
// Validate validates this error response
func (m *ErrorResponse) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateMessage(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *ErrorResponse) validateMessage(formats strfmt.Registry) error {
if err := validate.Required("message", "body", m.Message); err != nil {
return err
}
return nil
}
// ContextValidate validates this error response based on context it is used
func (m *ErrorResponse) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *ErrorResponse) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *ErrorResponse) UnmarshalBinary(b []byte) error {
var res ErrorResponse
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View file

@ -0,0 +1,190 @@
// Code generated by go-swagger; DO NOT EDIT.
package modelscapi
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// GetDecisionsStreamResponse get decisions stream response
//
// get decision response model
//
// swagger:model GetDecisionsStreamResponse
type GetDecisionsStreamResponse struct {
// deleted
Deleted GetDecisionsStreamResponseDeleted `json:"deleted,omitempty"`
// links
Links *GetDecisionsStreamResponseLinks `json:"links,omitempty"`
// new
New GetDecisionsStreamResponseNew `json:"new,omitempty"`
}
// Validate validates this get decisions stream response
func (m *GetDecisionsStreamResponse) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateDeleted(formats); err != nil {
res = append(res, err)
}
if err := m.validateLinks(formats); err != nil {
res = append(res, err)
}
if err := m.validateNew(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *GetDecisionsStreamResponse) validateDeleted(formats strfmt.Registry) error {
if swag.IsZero(m.Deleted) { // not required
return nil
}
if err := m.Deleted.Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("deleted")
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("deleted")
}
return err
}
return nil
}
func (m *GetDecisionsStreamResponse) validateLinks(formats strfmt.Registry) error {
if swag.IsZero(m.Links) { // not required
return nil
}
if m.Links != nil {
if err := m.Links.Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("links")
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("links")
}
return err
}
}
return nil
}
func (m *GetDecisionsStreamResponse) validateNew(formats strfmt.Registry) error {
if swag.IsZero(m.New) { // not required
return nil
}
if err := m.New.Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("new")
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("new")
}
return err
}
return nil
}
// ContextValidate validate this get decisions stream response based on the context it is used
func (m *GetDecisionsStreamResponse) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
var res []error
if err := m.contextValidateDeleted(ctx, formats); err != nil {
res = append(res, err)
}
if err := m.contextValidateLinks(ctx, formats); err != nil {
res = append(res, err)
}
if err := m.contextValidateNew(ctx, formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *GetDecisionsStreamResponse) contextValidateDeleted(ctx context.Context, formats strfmt.Registry) error {
if err := m.Deleted.ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("deleted")
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("deleted")
}
return err
}
return nil
}
func (m *GetDecisionsStreamResponse) contextValidateLinks(ctx context.Context, formats strfmt.Registry) error {
if m.Links != nil {
if err := m.Links.ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("links")
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("links")
}
return err
}
}
return nil
}
func (m *GetDecisionsStreamResponse) contextValidateNew(ctx context.Context, formats strfmt.Registry) error {
if err := m.New.ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("new")
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("new")
}
return err
}
return nil
}
// MarshalBinary interface implementation
func (m *GetDecisionsStreamResponse) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *GetDecisionsStreamResponse) UnmarshalBinary(b []byte) error {
var res GetDecisionsStreamResponse
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View file

@ -0,0 +1,73 @@
// Code generated by go-swagger; DO NOT EDIT.
package modelscapi
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"strconv"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// GetDecisionsStreamResponseDeleted Decisions list
//
// swagger:model GetDecisionsStreamResponseDeleted
type GetDecisionsStreamResponseDeleted []*GetDecisionsStreamResponseDeletedItem
// Validate validates this get decisions stream response deleted
func (m GetDecisionsStreamResponseDeleted) Validate(formats strfmt.Registry) error {
var res []error
for i := 0; i < len(m); i++ {
if swag.IsZero(m[i]) { // not required
continue
}
if m[i] != nil {
if err := m[i].Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName(strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName(strconv.Itoa(i))
}
return err
}
}
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
// ContextValidate validate this get decisions stream response deleted based on the context it is used
func (m GetDecisionsStreamResponseDeleted) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
var res []error
for i := 0; i < len(m); i++ {
if m[i] != nil {
if err := m[i].ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName(strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName(strconv.Itoa(i))
}
return err
}
}
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View file

@ -0,0 +1,88 @@
// Code generated by go-swagger; DO NOT EDIT.
package modelscapi
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
"github.com/go-openapi/validate"
)
// GetDecisionsStreamResponseDeletedItem get decisions stream response deleted item
//
// swagger:model GetDecisionsStreamResponseDeletedItem
type GetDecisionsStreamResponseDeletedItem struct {
// decisions
// Required: true
Decisions []string `json:"decisions"`
// the scope of decision : does it apply to an IP, a range, a username, etc
// Required: true
Scope *string `json:"scope"`
}
// Validate validates this get decisions stream response deleted item
func (m *GetDecisionsStreamResponseDeletedItem) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateDecisions(formats); err != nil {
res = append(res, err)
}
if err := m.validateScope(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *GetDecisionsStreamResponseDeletedItem) validateDecisions(formats strfmt.Registry) error {
if err := validate.Required("decisions", "body", m.Decisions); err != nil {
return err
}
return nil
}
func (m *GetDecisionsStreamResponseDeletedItem) validateScope(formats strfmt.Registry) error {
if err := validate.Required("scope", "body", m.Scope); err != nil {
return err
}
return nil
}
// ContextValidate validates this get decisions stream response deleted item based on context it is used
func (m *GetDecisionsStreamResponseDeletedItem) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *GetDecisionsStreamResponseDeletedItem) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *GetDecisionsStreamResponseDeletedItem) UnmarshalBinary(b []byte) error {
var res GetDecisionsStreamResponseDeletedItem
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View file

@ -0,0 +1,116 @@
// Code generated by go-swagger; DO NOT EDIT.
package modelscapi
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"strconv"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// GetDecisionsStreamResponseLinks Decisions list
//
// swagger:model GetDecisionsStreamResponseLinks
type GetDecisionsStreamResponseLinks struct {
// blocklists
Blocklists []*BlocklistLink `json:"blocklists"`
}
// Validate validates this get decisions stream response links
func (m *GetDecisionsStreamResponseLinks) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateBlocklists(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *GetDecisionsStreamResponseLinks) validateBlocklists(formats strfmt.Registry) error {
if swag.IsZero(m.Blocklists) { // not required
return nil
}
for i := 0; i < len(m.Blocklists); i++ {
if swag.IsZero(m.Blocklists[i]) { // not required
continue
}
if m.Blocklists[i] != nil {
if err := m.Blocklists[i].Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("blocklists" + "." + strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("blocklists" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
// ContextValidate validate this get decisions stream response links based on the context it is used
func (m *GetDecisionsStreamResponseLinks) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
var res []error
if err := m.contextValidateBlocklists(ctx, formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *GetDecisionsStreamResponseLinks) contextValidateBlocklists(ctx context.Context, formats strfmt.Registry) error {
for i := 0; i < len(m.Blocklists); i++ {
if m.Blocklists[i] != nil {
if err := m.Blocklists[i].ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("blocklists" + "." + strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("blocklists" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
// MarshalBinary interface implementation
func (m *GetDecisionsStreamResponseLinks) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *GetDecisionsStreamResponseLinks) UnmarshalBinary(b []byte) error {
var res GetDecisionsStreamResponseLinks
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View file

@ -0,0 +1,73 @@
// Code generated by go-swagger; DO NOT EDIT.
package modelscapi
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"strconv"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// GetDecisionsStreamResponseNew Decisions list
//
// swagger:model GetDecisionsStreamResponseNew
type GetDecisionsStreamResponseNew []*GetDecisionsStreamResponseNewItem
// Validate validates this get decisions stream response new
func (m GetDecisionsStreamResponseNew) Validate(formats strfmt.Registry) error {
var res []error
for i := 0; i < len(m); i++ {
if swag.IsZero(m[i]) { // not required
continue
}
if m[i] != nil {
if err := m[i].Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName(strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName(strconv.Itoa(i))
}
return err
}
}
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
// ContextValidate validate this get decisions stream response new based on the context it is used
func (m GetDecisionsStreamResponseNew) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
var res []error
for i := 0; i < len(m); i++ {
if m[i] != nil {
if err := m[i].ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName(strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName(strconv.Itoa(i))
}
return err
}
}
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View file

@ -0,0 +1,226 @@
// Code generated by go-swagger; DO NOT EDIT.
package modelscapi
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"strconv"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
"github.com/go-openapi/validate"
)
// GetDecisionsStreamResponseNewItem New Decisions
//
// swagger:model GetDecisionsStreamResponseNewItem
type GetDecisionsStreamResponseNewItem struct {
// decisions
// Required: true
Decisions []*GetDecisionsStreamResponseNewItemDecisionsItems0 `json:"decisions"`
// scenario
// Required: true
Scenario *string `json:"scenario"`
// the scope of decision : does it apply to an IP, a range, a username, etc
// Required: true
Scope *string `json:"scope"`
}
// Validate validates this get decisions stream response new item
func (m *GetDecisionsStreamResponseNewItem) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateDecisions(formats); err != nil {
res = append(res, err)
}
if err := m.validateScenario(formats); err != nil {
res = append(res, err)
}
if err := m.validateScope(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *GetDecisionsStreamResponseNewItem) validateDecisions(formats strfmt.Registry) error {
if err := validate.Required("decisions", "body", m.Decisions); err != nil {
return err
}
for i := 0; i < len(m.Decisions); i++ {
if swag.IsZero(m.Decisions[i]) { // not required
continue
}
if m.Decisions[i] != nil {
if err := m.Decisions[i].Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("decisions" + "." + strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("decisions" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
func (m *GetDecisionsStreamResponseNewItem) validateScenario(formats strfmt.Registry) error {
if err := validate.Required("scenario", "body", m.Scenario); err != nil {
return err
}
return nil
}
func (m *GetDecisionsStreamResponseNewItem) validateScope(formats strfmt.Registry) error {
if err := validate.Required("scope", "body", m.Scope); err != nil {
return err
}
return nil
}
// ContextValidate validate this get decisions stream response new item based on the context it is used
func (m *GetDecisionsStreamResponseNewItem) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
var res []error
if err := m.contextValidateDecisions(ctx, formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *GetDecisionsStreamResponseNewItem) contextValidateDecisions(ctx context.Context, formats strfmt.Registry) error {
for i := 0; i < len(m.Decisions); i++ {
if m.Decisions[i] != nil {
if err := m.Decisions[i].ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("decisions" + "." + strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("decisions" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
// MarshalBinary interface implementation
func (m *GetDecisionsStreamResponseNewItem) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *GetDecisionsStreamResponseNewItem) UnmarshalBinary(b []byte) error {
var res GetDecisionsStreamResponseNewItem
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}
// GetDecisionsStreamResponseNewItemDecisionsItems0 get decisions stream response new item decisions items0
//
// swagger:model GetDecisionsStreamResponseNewItemDecisionsItems0
type GetDecisionsStreamResponseNewItemDecisionsItems0 struct {
// duration
// Required: true
Duration *string `json:"duration"`
// the value of the decision scope : an IP, a range, a username, etc
// Required: true
Value *string `json:"value"`
}
// Validate validates this get decisions stream response new item decisions items0
func (m *GetDecisionsStreamResponseNewItemDecisionsItems0) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateDuration(formats); err != nil {
res = append(res, err)
}
if err := m.validateValue(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *GetDecisionsStreamResponseNewItemDecisionsItems0) validateDuration(formats strfmt.Registry) error {
if err := validate.Required("duration", "body", m.Duration); err != nil {
return err
}
return nil
}
func (m *GetDecisionsStreamResponseNewItemDecisionsItems0) validateValue(formats strfmt.Registry) error {
if err := validate.Required("value", "body", m.Value); err != nil {
return err
}
return nil
}
// ContextValidate validates this get decisions stream response new item decisions items0 based on context it is used
func (m *GetDecisionsStreamResponseNewItemDecisionsItems0) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *GetDecisionsStreamResponseNewItemDecisionsItems0) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *GetDecisionsStreamResponseNewItemDecisionsItems0) UnmarshalBinary(b []byte) error {
var res GetDecisionsStreamResponseNewItemDecisionsItems0
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View file

@ -0,0 +1,108 @@
// Code generated by go-swagger; DO NOT EDIT.
package modelscapi
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
"github.com/go-openapi/validate"
)
// LoginRequest login request
//
// # Login request model
//
// swagger:model LoginRequest
type LoginRequest struct {
// machine_id is a (username) generated by crowdsec
// Required: true
// Max Length: 48
// Min Length: 48
// Pattern: ^[a-zA-Z0-9]+$
MachineID *string `json:"machine_id"`
// Password, should respect the password policy (link to add)
// Required: true
Password *string `json:"password"`
// all scenarios installed
Scenarios []string `json:"scenarios"`
}
// Validate validates this login request
func (m *LoginRequest) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateMachineID(formats); err != nil {
res = append(res, err)
}
if err := m.validatePassword(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *LoginRequest) validateMachineID(formats strfmt.Registry) error {
if err := validate.Required("machine_id", "body", m.MachineID); err != nil {
return err
}
if err := validate.MinLength("machine_id", "body", *m.MachineID, 48); err != nil {
return err
}
if err := validate.MaxLength("machine_id", "body", *m.MachineID, 48); err != nil {
return err
}
if err := validate.Pattern("machine_id", "body", *m.MachineID, `^[a-zA-Z0-9]+$`); err != nil {
return err
}
return nil
}
func (m *LoginRequest) validatePassword(formats strfmt.Registry) error {
if err := validate.Required("password", "body", m.Password); err != nil {
return err
}
return nil
}
// ContextValidate validates this login request based on context it is used
func (m *LoginRequest) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *LoginRequest) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *LoginRequest) UnmarshalBinary(b []byte) error {
var res LoginRequest
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View file

@ -0,0 +1,58 @@
// Code generated by go-swagger; DO NOT EDIT.
package modelscapi
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// LoginResponse login response
//
// # Login request model
//
// swagger:model LoginResponse
type LoginResponse struct {
// code
Code int64 `json:"code,omitempty"`
// expire
Expire string `json:"expire,omitempty"`
// token
Token string `json:"token,omitempty"`
}
// Validate validates this login response
func (m *LoginResponse) Validate(formats strfmt.Registry) error {
return nil
}
// ContextValidate validates this login response based on context it is used
func (m *LoginResponse) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *LoginResponse) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *LoginResponse) UnmarshalBinary(b []byte) error {
var res LoginResponse
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View file

@ -0,0 +1,180 @@
// Code generated by go-swagger; DO NOT EDIT.
package modelscapi
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"strconv"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
"github.com/go-openapi/validate"
)
// MetricsRequest metrics
//
// push metrics model
//
// swagger:model MetricsRequest
type MetricsRequest struct {
// bouncers
// Required: true
Bouncers []*MetricsRequestBouncersItem `json:"bouncers"`
// machines
// Required: true
Machines []*MetricsRequestMachinesItem `json:"machines"`
}
// Validate validates this metrics request
func (m *MetricsRequest) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateBouncers(formats); err != nil {
res = append(res, err)
}
if err := m.validateMachines(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *MetricsRequest) validateBouncers(formats strfmt.Registry) error {
if err := validate.Required("bouncers", "body", m.Bouncers); err != nil {
return err
}
for i := 0; i < len(m.Bouncers); i++ {
if swag.IsZero(m.Bouncers[i]) { // not required
continue
}
if m.Bouncers[i] != nil {
if err := m.Bouncers[i].Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("bouncers" + "." + strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("bouncers" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
func (m *MetricsRequest) validateMachines(formats strfmt.Registry) error {
if err := validate.Required("machines", "body", m.Machines); err != nil {
return err
}
for i := 0; i < len(m.Machines); i++ {
if swag.IsZero(m.Machines[i]) { // not required
continue
}
if m.Machines[i] != nil {
if err := m.Machines[i].Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("machines" + "." + strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("machines" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
// ContextValidate validate this metrics request based on the context it is used
func (m *MetricsRequest) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
var res []error
if err := m.contextValidateBouncers(ctx, formats); err != nil {
res = append(res, err)
}
if err := m.contextValidateMachines(ctx, formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *MetricsRequest) contextValidateBouncers(ctx context.Context, formats strfmt.Registry) error {
for i := 0; i < len(m.Bouncers); i++ {
if m.Bouncers[i] != nil {
if err := m.Bouncers[i].ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("bouncers" + "." + strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("bouncers" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
func (m *MetricsRequest) contextValidateMachines(ctx context.Context, formats strfmt.Registry) error {
for i := 0; i < len(m.Machines); i++ {
if m.Machines[i] != nil {
if err := m.Machines[i].ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("machines" + "." + strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("machines" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
// MarshalBinary interface implementation
func (m *MetricsRequest) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *MetricsRequest) UnmarshalBinary(b []byte) error {
var res MetricsRequest
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View file

@ -0,0 +1,59 @@
// Code generated by go-swagger; DO NOT EDIT.
package modelscapi
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// MetricsRequestBouncersItem MetricsBouncerInfo
//
// swagger:model MetricsRequestBouncersItem
type MetricsRequestBouncersItem struct {
// bouncer name
CustomName string `json:"custom_name,omitempty"`
// last bouncer pull date
LastPull string `json:"last_pull,omitempty"`
// bouncer type (firewall, php...)
Name string `json:"name,omitempty"`
// bouncer version
Version string `json:"version,omitempty"`
}
// Validate validates this metrics request bouncers item
func (m *MetricsRequestBouncersItem) Validate(formats strfmt.Registry) error {
return nil
}
// ContextValidate validates this metrics request bouncers item based on context it is used
func (m *MetricsRequestBouncersItem) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *MetricsRequestBouncersItem) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *MetricsRequestBouncersItem) UnmarshalBinary(b []byte) error {
var res MetricsRequestBouncersItem
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View file

@ -0,0 +1,59 @@
// Code generated by go-swagger; DO NOT EDIT.
package modelscapi
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// MetricsRequestMachinesItem MetricsAgentInfo
//
// swagger:model MetricsRequestMachinesItem
type MetricsRequestMachinesItem struct {
// last agent push date
LastPush string `json:"last_push,omitempty"`
// last agent update date
LastUpdate string `json:"last_update,omitempty"`
// agent name
Name string `json:"name,omitempty"`
// agent version
Version string `json:"version,omitempty"`
}
// Validate validates this metrics request machines item
func (m *MetricsRequestMachinesItem) Validate(formats strfmt.Registry) error {
return nil
}
// ContextValidate validates this metrics request machines item based on context it is used
func (m *MetricsRequestMachinesItem) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *MetricsRequestMachinesItem) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *MetricsRequestMachinesItem) UnmarshalBinary(b []byte) error {
var res MetricsRequestMachinesItem
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View file

@ -0,0 +1,95 @@
// Code generated by go-swagger; DO NOT EDIT.
package modelscapi
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
"github.com/go-openapi/validate"
)
// RegisterRequest register request
//
// # Register request model
//
// swagger:model RegisterRequest
type RegisterRequest struct {
// machine_id is a (username) generated by crowdsec
// Required: true
// Pattern: ^[a-zA-Z0-9]+$
MachineID *string `json:"machine_id"`
// Password, should respect the password policy (link to add)
// Required: true
Password *string `json:"password"`
}
// Validate validates this register request
func (m *RegisterRequest) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateMachineID(formats); err != nil {
res = append(res, err)
}
if err := m.validatePassword(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *RegisterRequest) validateMachineID(formats strfmt.Registry) error {
if err := validate.Required("machine_id", "body", m.MachineID); err != nil {
return err
}
if err := validate.Pattern("machine_id", "body", *m.MachineID, `^[a-zA-Z0-9]+$`); err != nil {
return err
}
return nil
}
func (m *RegisterRequest) validatePassword(formats strfmt.Registry) error {
if err := validate.Required("password", "body", m.Password); err != nil {
return err
}
return nil
}
// ContextValidate validates this register request based on context it is used
func (m *RegisterRequest) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *RegisterRequest) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *RegisterRequest) UnmarshalBinary(b []byte) error {
var res RegisterRequest
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View file

@ -0,0 +1,105 @@
// Code generated by go-swagger; DO NOT EDIT.
package modelscapi
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
"github.com/go-openapi/validate"
)
// ResetPasswordRequest resetPassword
//
// # ResetPassword request model
//
// swagger:model ResetPasswordRequest
type ResetPasswordRequest struct {
// machine_id is a (username) generated by crowdsec
// Required: true
// Max Length: 48
// Min Length: 48
// Pattern: ^[a-zA-Z0-9]+$
MachineID *string `json:"machine_id"`
// Password, should respect the password policy (link to add)
// Required: true
Password *string `json:"password"`
}
// Validate validates this reset password request
func (m *ResetPasswordRequest) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateMachineID(formats); err != nil {
res = append(res, err)
}
if err := m.validatePassword(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *ResetPasswordRequest) validateMachineID(formats strfmt.Registry) error {
if err := validate.Required("machine_id", "body", m.MachineID); err != nil {
return err
}
if err := validate.MinLength("machine_id", "body", *m.MachineID, 48); err != nil {
return err
}
if err := validate.MaxLength("machine_id", "body", *m.MachineID, 48); err != nil {
return err
}
if err := validate.Pattern("machine_id", "body", *m.MachineID, `^[a-zA-Z0-9]+$`); err != nil {
return err
}
return nil
}
func (m *ResetPasswordRequest) validatePassword(formats strfmt.Registry) error {
if err := validate.Required("password", "body", m.Password); err != nil {
return err
}
return nil
}
// ContextValidate validates this reset password request based on context it is used
func (m *ResetPasswordRequest) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *ResetPasswordRequest) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *ResetPasswordRequest) UnmarshalBinary(b []byte) error {
var res ResetPasswordRequest
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View file

@ -0,0 +1,73 @@
// Code generated by go-swagger; DO NOT EDIT.
package modelscapi
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
"github.com/go-openapi/validate"
)
// SuccessResponse success response
//
// success response return by the API
//
// swagger:model SuccessResponse
type SuccessResponse struct {
// message
// Required: true
Message *string `json:"message"`
}
// Validate validates this success response
func (m *SuccessResponse) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateMessage(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *SuccessResponse) validateMessage(formats strfmt.Registry) error {
if err := validate.Required("message", "body", m.Message); err != nil {
return err
}
return nil
}
// ContextValidate validates this success response based on context it is used
func (m *SuccessResponse) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *SuccessResponse) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *SuccessResponse) UnmarshalBinary(b []byte) error {
var res SuccessResponse
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View file

@ -14,6 +14,8 @@ const CscliImportOrigin = "cscli-import"
const ListOrigin = "lists" const ListOrigin = "lists"
const CAPIOrigin = "CAPI" const CAPIOrigin = "CAPI"
const DecisionTypeBan = "ban"
func GetOrigins() []string { func GetOrigins() []string {
return []string{ return []string{
CscliOrigin, CscliOrigin,