errors.Wrap -> fmt.Errorf (#2333)
This commit is contained in:
parent
486b56d1ed
commit
9967d60987
|
@ -322,7 +322,7 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// some features can require configuration or command-line options,
|
// some features can require configuration or command-line options,
|
||||||
// so wwe need to parse them asap. we'll load from feature.yaml later.
|
// so we need to parse them asap. we'll load from feature.yaml later.
|
||||||
if err := csconfig.LoadFeatureFlagsEnv(log.StandardLogger()); err != nil {
|
if err := csconfig.LoadFeatureFlagsEnv(log.StandardLogger()); err != nil {
|
||||||
log.Fatalf("failed to set feature flags from environment: %s", err)
|
log.Fatalf("failed to set feature flags from environment: %s", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,6 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-openapi/strfmt"
|
"github.com/go-openapi/strfmt"
|
||||||
"github.com/pkg/errors"
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/crowdsecurity/go-cs-lib/pkg/version"
|
"github.com/crowdsecurity/go-cs-lib/pkg/version"
|
||||||
|
@ -73,16 +72,16 @@ func runOutput(input chan types.Event, overflow chan types.Event, buckets *leaky
|
||||||
|
|
||||||
scenarios, err := cwhub.GetInstalledScenariosAsString()
|
scenarios, err := cwhub.GetInstalledScenariosAsString()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(err, "loading list of installed hub scenarios: %s", err)
|
return fmt.Errorf("loading list of installed hub scenarios: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
apiURL, err := url.Parse(apiConfig.URL)
|
apiURL, err := url.Parse(apiConfig.URL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(err, "parsing api url ('%s'): %s", apiConfig.URL, err)
|
return fmt.Errorf("parsing api url ('%s'): %w", apiConfig.URL, err)
|
||||||
}
|
}
|
||||||
papiURL, err := url.Parse(apiConfig.PapiURL)
|
papiURL, err := url.Parse(apiConfig.PapiURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(err, "parsing polling api url ('%s'): %s", apiConfig.PapiURL, err)
|
return fmt.Errorf("parsing polling api url ('%s'): %w", apiConfig.PapiURL, err)
|
||||||
}
|
}
|
||||||
password := strfmt.Password(apiConfig.Password)
|
password := strfmt.Password(apiConfig.Password)
|
||||||
|
|
||||||
|
@ -97,7 +96,7 @@ func runOutput(input chan types.Event, overflow chan types.Event, buckets *leaky
|
||||||
UpdateScenario: cwhub.GetInstalledScenariosAsString,
|
UpdateScenario: cwhub.GetInstalledScenariosAsString,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(err, "new client api: %s", err)
|
return fmt.Errorf("new client api: %w", err)
|
||||||
}
|
}
|
||||||
authResp, _, err := Client.Auth.AuthenticateWatcher(context.Background(), models.WatcherAuthRequest{
|
authResp, _, err := Client.Auth.AuthenticateWatcher(context.Background(), models.WatcherAuthRequest{
|
||||||
MachineID: &apiConfig.Login,
|
MachineID: &apiConfig.Login,
|
||||||
|
|
|
@ -84,7 +84,7 @@ func (a *apic) FetchScenariosListFromDB() ([]string, error) {
|
||||||
scenarios := make([]string, 0)
|
scenarios := make([]string, 0)
|
||||||
machines, err := a.dbClient.ListMachines()
|
machines, err := a.dbClient.ListMachines()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "while listing machines")
|
return nil, fmt.Errorf("while listing machines: %w", err)
|
||||||
}
|
}
|
||||||
//merge all scenarios together
|
//merge all scenarios together
|
||||||
for _, v := range machines {
|
for _, v := range machines {
|
||||||
|
@ -189,16 +189,16 @@ func NewAPIC(config *csconfig.OnlineApiClientCfg, dbClient *database.Client, con
|
||||||
password := strfmt.Password(config.Credentials.Password)
|
password := strfmt.Password(config.Credentials.Password)
|
||||||
apiURL, err := url.Parse(config.Credentials.URL)
|
apiURL, err := url.Parse(config.Credentials.URL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "while parsing '%s'", config.Credentials.URL)
|
return nil, fmt.Errorf("while parsing '%s': %w", config.Credentials.URL, err)
|
||||||
}
|
}
|
||||||
papiURL, err := url.Parse(config.Credentials.PapiURL)
|
papiURL, err := url.Parse(config.Credentials.PapiURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "while parsing '%s'", config.Credentials.PapiURL)
|
return nil, fmt.Errorf("while parsing '%s': %w", config.Credentials.PapiURL, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ret.scenarioList, err = ret.FetchScenariosListFromDB()
|
ret.scenarioList, err = ret.FetchScenariosListFromDB()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "while fetching scenarios from db")
|
return nil, fmt.Errorf("while fetching scenarios from db: %w", err)
|
||||||
}
|
}
|
||||||
ret.apiClient, err = apiclient.NewClient(&apiclient.Config{
|
ret.apiClient, err = apiclient.NewClient(&apiclient.Config{
|
||||||
MachineID: config.Credentials.Login,
|
MachineID: config.Credentials.Login,
|
||||||
|
@ -211,14 +211,14 @@ func NewAPIC(config *csconfig.OnlineApiClientCfg, dbClient *database.Client, con
|
||||||
UpdateScenario: ret.FetchScenariosListFromDB,
|
UpdateScenario: ret.FetchScenariosListFromDB,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "while creating api client")
|
return nil, fmt.Errorf("while creating api client: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// The watcher will be authenticated by the RoundTripper the first time it will call CAPI
|
// The watcher will be authenticated by the RoundTripper the first time it will call CAPI
|
||||||
// Explicit authentication will provoke an useless supplementary call to CAPI
|
// Explicit authentication will provoke an useless supplementary call to CAPI
|
||||||
scenarios, err := ret.FetchScenariosListFromDB()
|
scenarios, err := ret.FetchScenariosListFromDB()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ret, errors.Wrapf(err, "get scenario in db: %s", err)
|
return ret, fmt.Errorf("get scenario in db: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
authResp, _, err := ret.apiClient.Auth.AuthenticateWatcher(context.Background(), models.WatcherAuthRequest{
|
authResp, _, err := ret.apiClient.Auth.AuthenticateWatcher(context.Background(), models.WatcherAuthRequest{
|
||||||
|
@ -227,11 +227,11 @@ func NewAPIC(config *csconfig.OnlineApiClientCfg, dbClient *database.Client, con
|
||||||
Scenarios: scenarios,
|
Scenarios: scenarios,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ret, errors.Wrapf(err, "authenticate watcher (%s)", config.Credentials.Login)
|
return ret, fmt.Errorf("authenticate watcher (%s): %w", config.Credentials.Login, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := ret.apiClient.GetClient().Transport.(*apiclient.JWTTransport).Expiration.UnmarshalText([]byte(authResp.Expire)); err != nil {
|
if err := ret.apiClient.GetClient().Transport.(*apiclient.JWTTransport).Expiration.UnmarshalText([]byte(authResp.Expire)); err != nil {
|
||||||
return ret, errors.Wrap(err, "unable to parse jwt expiration")
|
return ret, fmt.Errorf("unable to parse jwt expiration: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ret.apiClient.GetClient().Transport.(*apiclient.JWTTransport).Token = authResp.Token
|
ret.apiClient.GetClient().Transport.(*apiclient.JWTTransport).Token = authResp.Token
|
||||||
|
@ -375,7 +375,7 @@ func (a *apic) CAPIPullIsOld() (bool, error) {
|
||||||
alerts = alerts.Where(alert.CreatedAtGTE(time.Now().UTC().Add(-time.Duration(1*time.Hour + 30*time.Minute)))) //nolint:unconvert
|
alerts = alerts.Where(alert.CreatedAtGTE(time.Now().UTC().Add(-time.Duration(1*time.Hour + 30*time.Minute)))) //nolint:unconvert
|
||||||
count, err := alerts.Count(a.dbClient.CTX)
|
count, err := alerts.Count(a.dbClient.CTX)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, errors.Wrap(err, "while looking for CAPI alert")
|
return false, fmt.Errorf("while looking for CAPI alert: %w", err)
|
||||||
}
|
}
|
||||||
if count > 0 {
|
if count > 0 {
|
||||||
log.Printf("last CAPI pull is newer than 1h30, skip.")
|
log.Printf("last CAPI pull is newer than 1h30, skip.")
|
||||||
|
@ -401,11 +401,11 @@ func (a *apic) HandleDeletedDecisions(deletedDecisions []*models.Decision, delet
|
||||||
|
|
||||||
dbCliRet, _, err := a.dbClient.SoftDeleteDecisionsWithFilter(filter)
|
dbCliRet, _, err := a.dbClient.SoftDeleteDecisionsWithFilter(filter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, errors.Wrap(err, "deleting decisions error")
|
return 0, fmt.Errorf("deleting decisions error: %w", err)
|
||||||
}
|
}
|
||||||
dbCliDel, err := strconv.Atoi(dbCliRet)
|
dbCliDel, err := strconv.Atoi(dbCliRet)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, errors.Wrapf(err, "converting db ret %d", dbCliDel)
|
return 0, fmt.Errorf("converting db ret %d: %w", dbCliDel, err)
|
||||||
}
|
}
|
||||||
updateCounterForDecision(delete_counters, decision.Origin, decision.Scenario, dbCliDel)
|
updateCounterForDecision(delete_counters, decision.Origin, decision.Scenario, dbCliDel)
|
||||||
nbDeleted += dbCliDel
|
nbDeleted += dbCliDel
|
||||||
|
@ -431,11 +431,11 @@ func (a *apic) HandleDeletedDecisionsV3(deletedDecisions []*modelscapi.GetDecisi
|
||||||
|
|
||||||
dbCliRet, _, err := a.dbClient.SoftDeleteDecisionsWithFilter(filter)
|
dbCliRet, _, err := a.dbClient.SoftDeleteDecisionsWithFilter(filter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, errors.Wrap(err, "deleting decisions error")
|
return 0, fmt.Errorf("deleting decisions error: %w", err)
|
||||||
}
|
}
|
||||||
dbCliDel, err := strconv.Atoi(dbCliRet)
|
dbCliDel, err := strconv.Atoi(dbCliRet)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, errors.Wrapf(err, "converting db ret %d", dbCliDel)
|
return 0, fmt.Errorf("converting db ret %d: %w", dbCliDel, err)
|
||||||
}
|
}
|
||||||
updateCounterForDecision(delete_counters, ptr.Of(types.CAPIOrigin), nil, dbCliDel)
|
updateCounterForDecision(delete_counters, ptr.Of(types.CAPIOrigin), nil, dbCliDel)
|
||||||
nbDeleted += dbCliDel
|
nbDeleted += dbCliDel
|
||||||
|
@ -575,7 +575,7 @@ func (a *apic) PullTop(forcePull bool) error {
|
||||||
|
|
||||||
data, _, err := a.apiClient.Decisions.GetStreamV3(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 fmt.Errorf("get stream: %w", err)
|
||||||
}
|
}
|
||||||
a.startup = false
|
a.startup = false
|
||||||
/*to count additions/deletions across lists*/
|
/*to count additions/deletions across lists*/
|
||||||
|
@ -610,12 +610,12 @@ func (a *apic) PullTop(forcePull bool) error {
|
||||||
|
|
||||||
err = a.SaveAlerts(alertsFromCapi, add_counters, delete_counters)
|
err = a.SaveAlerts(alertsFromCapi, add_counters, delete_counters)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "while saving alerts")
|
return fmt.Errorf("while saving alerts: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// update blocklists
|
// update blocklists
|
||||||
if err := a.UpdateBlocklists(data.Links, add_counters); err != nil {
|
if err := a.UpdateBlocklists(data.Links, add_counters); err != nil {
|
||||||
return errors.Wrap(err, "while updating blocklists")
|
return fmt.Errorf("while updating blocklists: %w", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -670,7 +670,7 @@ func (a *apic) SaveAlerts(alertsFromCapi []*models.Alert, add_counters map[strin
|
||||||
}
|
}
|
||||||
alertID, inserted, deleted, err := a.dbClient.UpdateCommunityBlocklist(alertsFromCapi[idx])
|
alertID, inserted, deleted, err := a.dbClient.UpdateCommunityBlocklist(alertsFromCapi[idx])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(err, "while saving alert from %s", *alertsFromCapi[idx].Source.Scope)
|
return fmt.Errorf("while saving alert from %s: %w", *alertsFromCapi[idx].Source.Scope, err)
|
||||||
}
|
}
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
@ -689,7 +689,7 @@ func (a *apic) ShouldForcePullBlocklist(blocklist *modelscapi.BlocklistLink) (bo
|
||||||
log.Debugf("no alert found for %s, force refresh", *blocklist.Name)
|
log.Debugf("no alert found for %s, force refresh", *blocklist.Name)
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
return false, errors.Wrap(err, "while getting alert")
|
return false, fmt.Errorf("while getting alert: %w", err)
|
||||||
}
|
}
|
||||||
decisionQuery := a.dbClient.Ent.Decision.Query()
|
decisionQuery := a.dbClient.Ent.Decision.Query()
|
||||||
decisionQuery.Where(decision.HasOwnerWith(alert.IDEQ(alertInstance.ID)))
|
decisionQuery.Where(decision.HasOwnerWith(alert.IDEQ(alertInstance.ID)))
|
||||||
|
@ -699,7 +699,7 @@ func (a *apic) ShouldForcePullBlocklist(blocklist *modelscapi.BlocklistLink) (bo
|
||||||
log.Debugf("no decision found for %s, force refresh", *blocklist.Name)
|
log.Debugf("no decision found for %s, force refresh", *blocklist.Name)
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
return false, errors.Wrap(err, "while getting decision")
|
return false, fmt.Errorf("while getting decision: %w", err)
|
||||||
}
|
}
|
||||||
if firstDecision == nil || firstDecision.Until == nil || firstDecision.Until.Sub(time.Now().UTC()) < (a.pullInterval+15*time.Minute) {
|
if firstDecision == nil || firstDecision.Until == nil || firstDecision.Until.Sub(time.Now().UTC()) < (a.pullInterval+15*time.Minute) {
|
||||||
log.Debugf("at least one decision found for %s, expire soon, force refresh", *blocklist.Name)
|
log.Debugf("at least one decision found for %s, expire soon, force refresh", *blocklist.Name)
|
||||||
|
@ -719,7 +719,7 @@ func (a *apic) UpdateBlocklists(links *modelscapi.GetDecisionsStreamResponseLink
|
||||||
// we can use the same baseUrl as the urls are absolute and the parse will take care of it
|
// 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, "", "", nil)
|
defaultClient, err := apiclient.NewDefaultClient(a.apiClient.BaseURL, "", "", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "while creating default client")
|
return fmt.Errorf("while creating default client: %w", err)
|
||||||
}
|
}
|
||||||
for _, blocklist := range links.Blocklists {
|
for _, blocklist := range links.Blocklists {
|
||||||
if blocklist.Scope == nil {
|
if blocklist.Scope == nil {
|
||||||
|
@ -732,19 +732,19 @@ func (a *apic) UpdateBlocklists(links *modelscapi.GetDecisionsStreamResponseLink
|
||||||
}
|
}
|
||||||
forcePull, err := a.ShouldForcePullBlocklist(blocklist)
|
forcePull, err := a.ShouldForcePullBlocklist(blocklist)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(err, "while checking if we should force pull blocklist %s", *blocklist.Name)
|
return fmt.Errorf("while checking if we should force pull blocklist %s: %w", *blocklist.Name, err)
|
||||||
}
|
}
|
||||||
blocklistConfigItemName := fmt.Sprintf("blocklist:%s:last_pull", *blocklist.Name)
|
blocklistConfigItemName := fmt.Sprintf("blocklist:%s:last_pull", *blocklist.Name)
|
||||||
var lastPullTimestamp *string
|
var lastPullTimestamp *string
|
||||||
if !forcePull {
|
if !forcePull {
|
||||||
lastPullTimestamp, err = a.dbClient.GetConfigItem(blocklistConfigItemName)
|
lastPullTimestamp, err = a.dbClient.GetConfigItem(blocklistConfigItemName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(err, "while getting last pull timestamp for blocklist %s", *blocklist.Name)
|
return fmt.Errorf("while getting last pull timestamp for blocklist %s: %w", *blocklist.Name, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
decisions, has_changed, err := defaultClient.Decisions.GetDecisionsFromBlocklist(context.Background(), blocklist, lastPullTimestamp)
|
decisions, has_changed, err := defaultClient.Decisions.GetDecisionsFromBlocklist(context.Background(), blocklist, lastPullTimestamp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(err, "while getting decisions from blocklist %s", *blocklist.Name)
|
return fmt.Errorf("while getting decisions from blocklist %s: %w", *blocklist.Name, err)
|
||||||
}
|
}
|
||||||
if !has_changed {
|
if !has_changed {
|
||||||
if lastPullTimestamp == nil {
|
if lastPullTimestamp == nil {
|
||||||
|
@ -756,7 +756,7 @@ func (a *apic) UpdateBlocklists(links *modelscapi.GetDecisionsStreamResponseLink
|
||||||
}
|
}
|
||||||
err = a.dbClient.SetConfigItem(blocklistConfigItemName, time.Now().UTC().Format(http.TimeFormat))
|
err = a.dbClient.SetConfigItem(blocklistConfigItemName, time.Now().UTC().Format(http.TimeFormat))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(err, "while setting last pull timestamp for blocklist %s", *blocklist.Name)
|
return fmt.Errorf("while setting last pull timestamp for blocklist %s: %w", *blocklist.Name, err)
|
||||||
}
|
}
|
||||||
if len(decisions) == 0 {
|
if len(decisions) == 0 {
|
||||||
log.Infof("blocklist %s has no decisions", *blocklist.Name)
|
log.Infof("blocklist %s has no decisions", *blocklist.Name)
|
||||||
|
@ -770,7 +770,7 @@ func (a *apic) UpdateBlocklists(links *modelscapi.GetDecisionsStreamResponseLink
|
||||||
|
|
||||||
err = a.SaveAlerts(alertsFromCapi, add_counters, nil)
|
err = a.SaveAlerts(alertsFromCapi, add_counters, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(err, "while saving alert from blocklist %s", *blocklist.Name)
|
return fmt.Errorf("while saving alert from blocklist %s: %w", *blocklist.Name, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -106,7 +106,7 @@ func NewServer(config *csconfig.LocalApiServerCfg) (*APIServer, error) {
|
||||||
var flushScheduler *gocron.Scheduler
|
var flushScheduler *gocron.Scheduler
|
||||||
dbClient, err := database.NewClient(config.DbConfig)
|
dbClient, err := database.NewClient(config.DbConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &APIServer{}, errors.Wrap(err, "unable to init database client")
|
return &APIServer{}, fmt.Errorf("unable to init database client: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.DbConfig.Flush != nil {
|
if config.DbConfig.Flush != nil {
|
||||||
|
@ -129,7 +129,7 @@ func NewServer(config *csconfig.LocalApiServerCfg) (*APIServer, error) {
|
||||||
|
|
||||||
if config.TrustedProxies != nil && config.UseForwardedForHeaders {
|
if config.TrustedProxies != nil && config.UseForwardedForHeaders {
|
||||||
if err := router.SetTrustedProxies(*config.TrustedProxies); err != nil {
|
if err := router.SetTrustedProxies(*config.TrustedProxies); err != nil {
|
||||||
return &APIServer{}, errors.Wrap(err, "while setting trusted_proxies")
|
return &APIServer{}, fmt.Errorf("while setting trusted_proxies: %w", err)
|
||||||
}
|
}
|
||||||
router.ForwardedByClientIP = true
|
router.ForwardedByClientIP = true
|
||||||
} else {
|
} else {
|
||||||
|
@ -140,7 +140,7 @@ func NewServer(config *csconfig.LocalApiServerCfg) (*APIServer, error) {
|
||||||
clog := log.New()
|
clog := log.New()
|
||||||
|
|
||||||
if err := types.ConfigureLogger(clog); err != nil {
|
if err := types.ConfigureLogger(clog); err != nil {
|
||||||
return nil, errors.Wrap(err, "while configuring gin logger")
|
return nil, fmt.Errorf("while configuring gin logger: %w", err)
|
||||||
}
|
}
|
||||||
if config.LogLevel != nil {
|
if config.LogLevel != nil {
|
||||||
clog.SetLevel(*config.LogLevel)
|
clog.SetLevel(*config.LogLevel)
|
||||||
|
@ -305,7 +305,7 @@ func (s *APIServer) GetTLSConfig() (*tls.Config, error) {
|
||||||
log.Infof("(tls) Client Auth Type set to %s", clientAuthType.String())
|
log.Infof("(tls) Client Auth Type set to %s", clientAuthType.String())
|
||||||
caCert, err = os.ReadFile(s.TLS.CACertPath)
|
caCert, err = os.ReadFile(s.TLS.CACertPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "Error opening cert file")
|
return nil, fmt.Errorf("while opening cert file: %w", err)
|
||||||
}
|
}
|
||||||
caCertPool, err = x509.SystemCertPool()
|
caCertPool, err = x509.SystemCertPool()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -330,7 +330,7 @@ func (s *APIServer) Run(apiReady chan bool) error {
|
||||||
defer trace.CatchPanic("lapi/runServer")
|
defer trace.CatchPanic("lapi/runServer")
|
||||||
tlsCfg, err := s.GetTLSConfig()
|
tlsCfg, err := s.GetTLSConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "while creating TLS config")
|
return fmt.Errorf("while creating TLS config: %w", err)
|
||||||
}
|
}
|
||||||
s.httpServer = &http.Server{
|
s.httpServer = &http.Server{
|
||||||
Addr: s.URL,
|
Addr: s.URL,
|
||||||
|
@ -448,7 +448,7 @@ func (s *APIServer) Shutdown() error {
|
||||||
}
|
}
|
||||||
s.httpServerTomb.Kill(nil)
|
s.httpServerTomb.Kill(nil)
|
||||||
if err := s.httpServerTomb.Wait(); err != nil {
|
if err := s.httpServerTomb.Wait(); err != nil {
|
||||||
return errors.Wrap(err, "while waiting on httpServerTomb")
|
return fmt.Errorf("while waiting on httpServerTomb: %w", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -461,7 +461,7 @@ func (s *APIServer) InitController() error {
|
||||||
|
|
||||||
err := s.controller.Init()
|
err := s.controller.Init()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "controller init")
|
return fmt.Errorf("controller init: %w", err)
|
||||||
}
|
}
|
||||||
if s.TLS != nil {
|
if s.TLS != nil {
|
||||||
var cacheExpiration time.Duration
|
var cacheExpiration time.Duration
|
||||||
|
@ -477,7 +477,7 @@ func (s *APIServer) InitController() error {
|
||||||
"type": "agent",
|
"type": "agent",
|
||||||
}))
|
}))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "while creating TLS auth for agents")
|
return fmt.Errorf("while creating TLS auth for agents: %w", err)
|
||||||
}
|
}
|
||||||
s.controller.HandlerV1.Middlewares.APIKey.TlsAuth, err = v1.NewTLSAuth(s.TLS.AllowedBouncersOU, s.TLS.CRLPath,
|
s.controller.HandlerV1.Middlewares.APIKey.TlsAuth, err = v1.NewTLSAuth(s.TLS.AllowedBouncersOU, s.TLS.CRLPath,
|
||||||
cacheExpiration,
|
cacheExpiration,
|
||||||
|
@ -486,7 +486,7 @@ func (s *APIServer) InitController() error {
|
||||||
"type": "bouncer",
|
"type": "bouncer",
|
||||||
}))
|
}))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "while creating TLS auth for bouncers")
|
return fmt.Errorf("while creating TLS auth for bouncers: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -8,6 +8,9 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
"gopkg.in/tomb.v2"
|
||||||
|
|
||||||
"github.com/crowdsecurity/go-cs-lib/pkg/trace"
|
"github.com/crowdsecurity/go-cs-lib/pkg/trace"
|
||||||
|
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/apiclient"
|
"github.com/crowdsecurity/crowdsec/pkg/apiclient"
|
||||||
|
@ -16,9 +19,6 @@ import (
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/longpollclient"
|
"github.com/crowdsecurity/crowdsec/pkg/longpollclient"
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/models"
|
"github.com/crowdsecurity/crowdsec/pkg/models"
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/types"
|
"github.com/crowdsecurity/crowdsec/pkg/types"
|
||||||
"github.com/pkg/errors"
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
"gopkg.in/tomb.v2"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -103,7 +103,7 @@ func NewPAPI(apic *apic, dbClient *database.Client, consoleConfig *csconfig.Cons
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &Papi{}, errors.Wrap(err, "failed to create PAPI client")
|
return &Papi{}, fmt.Errorf("failed to create PAPI client: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
channels := &OperationChannels{
|
channels := &OperationChannels{
|
||||||
|
@ -231,7 +231,7 @@ func (p *Papi) Pull() error {
|
||||||
if lastTimestampStr == nil {
|
if lastTimestampStr == nil {
|
||||||
binTime, err := lastTimestamp.MarshalText()
|
binTime, err := lastTimestamp.MarshalText()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "failed to marshal last timestamp")
|
return fmt.Errorf("failed to marshal last timestamp: %w", err)
|
||||||
}
|
}
|
||||||
if err := p.DBClient.SetConfigItem(PapiPullKey, string(binTime)); err != nil {
|
if err := p.DBClient.SetConfigItem(PapiPullKey, string(binTime)); err != nil {
|
||||||
p.Logger.Errorf("error setting papi pull last key: %s", err)
|
p.Logger.Errorf("error setting papi pull last key: %s", err)
|
||||||
|
@ -240,7 +240,7 @@ func (p *Papi) Pull() error {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if err := lastTimestamp.UnmarshalText([]byte(*lastTimestampStr)); err != nil {
|
if err := lastTimestamp.UnmarshalText([]byte(*lastTimestampStr)); err != nil {
|
||||||
return errors.Wrap(err, "failed to unmarshal last timestamp")
|
return fmt.Errorf("failed to unmarshal last timestamp: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,7 +251,7 @@ func (p *Papi) Pull() error {
|
||||||
newTime := time.Now().UTC()
|
newTime := time.Now().UTC()
|
||||||
binTime, err := newTime.MarshalText()
|
binTime, err := newTime.MarshalText()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "failed to marshal last timestamp")
|
return fmt.Errorf("failed to marshal last timestamp: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = p.handleEvent(event, false)
|
err = p.handleEvent(event, false)
|
||||||
|
@ -261,7 +261,7 @@ func (p *Papi) Pull() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := p.DBClient.SetConfigItem(PapiPullKey, string(binTime)); err != nil {
|
if err := p.DBClient.SetConfigItem(PapiPullKey, string(binTime)); err != nil {
|
||||||
return errors.Wrap(err, "failed to update last timestamp")
|
return fmt.Errorf("failed to update last timestamp: %w", err)
|
||||||
} else {
|
} else {
|
||||||
logger.Debugf("set last timestamp to %s", newTime)
|
logger.Debugf("set last timestamp to %s", newTime)
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package cwhub
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -11,29 +12,28 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"gopkg.in/yaml.v2"
|
"gopkg.in/yaml.v2"
|
||||||
|
|
||||||
|
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
|
||||||
)
|
)
|
||||||
|
|
||||||
var ErrIndexNotFound = fmt.Errorf("index not found")
|
var ErrIndexNotFound = fmt.Errorf("index not found")
|
||||||
|
|
||||||
func UpdateHubIdx(hub *csconfig.Hub) error {
|
func UpdateHubIdx(hub *csconfig.Hub) error {
|
||||||
|
|
||||||
bidx, err := DownloadHubIdx(hub)
|
bidx, err := DownloadHubIdx(hub)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "failed to download index")
|
return fmt.Errorf("failed to download index: %w", err)
|
||||||
}
|
}
|
||||||
ret, err := LoadPkgIndex(bidx)
|
ret, err := LoadPkgIndex(bidx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !errors.Is(err, ReferenceMissingError) {
|
if !errors.Is(err, ReferenceMissingError) {
|
||||||
return errors.Wrap(err, "failed to read index")
|
return fmt.Errorf("failed to read index: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hubIdx = ret
|
hubIdx = ret
|
||||||
if err, _ := LocalSync(hub); err != nil {
|
if err, _ := LocalSync(hub); err != nil {
|
||||||
return errors.Wrap(err, "failed to sync")
|
return fmt.Errorf("failed to sync: %w", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -42,11 +42,11 @@ func DownloadHubIdx(hub *csconfig.Hub) ([]byte, error) {
|
||||||
log.Debugf("fetching index from branch %s (%s)", HubBranch, fmt.Sprintf(RawFileURLTemplate, HubBranch, HubIndexFile))
|
log.Debugf("fetching index from branch %s (%s)", HubBranch, fmt.Sprintf(RawFileURLTemplate, HubBranch, HubIndexFile))
|
||||||
req, err := http.NewRequest(http.MethodGet, fmt.Sprintf(RawFileURLTemplate, HubBranch, HubIndexFile), nil)
|
req, err := http.NewRequest(http.MethodGet, fmt.Sprintf(RawFileURLTemplate, HubBranch, HubIndexFile), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "failed to build request for hub index")
|
return nil, fmt.Errorf("failed to build request for hub index: %w", err)
|
||||||
}
|
}
|
||||||
resp, err := http.DefaultClient.Do(req)
|
resp, err := http.DefaultClient.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "failed http request for hub index")
|
return nil, fmt.Errorf("failed http request for hub index: %w", err)
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
@ -57,7 +57,7 @@ func DownloadHubIdx(hub *csconfig.Hub) ([]byte, error) {
|
||||||
}
|
}
|
||||||
body, err := io.ReadAll(resp.Body)
|
body, err := io.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "failed to read request answer for hub index")
|
return nil, fmt.Errorf("failed to read request answer for hub index: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
oldContent, err := os.ReadFile(hub.HubIndexFile)
|
oldContent, err := os.ReadFile(hub.HubIndexFile)
|
||||||
|
@ -73,13 +73,13 @@ func DownloadHubIdx(hub *csconfig.Hub) ([]byte, error) {
|
||||||
file, err := os.OpenFile(hub.HubIndexFile, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
|
file, err := os.OpenFile(hub.HubIndexFile, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "while opening hub index file")
|
return nil, fmt.Errorf("while opening hub index file: %w", err)
|
||||||
}
|
}
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
|
|
||||||
wsize, err := file.WriteString(string(body))
|
wsize, err := file.WriteString(string(body))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "while writing hub index file")
|
return nil, fmt.Errorf("while writing hub index file: %w", err)
|
||||||
}
|
}
|
||||||
log.Infof("Wrote new %d bytes index to %s", wsize, hub.HubIndexFile)
|
log.Infof("Wrote new %d bytes index to %s", wsize, hub.HubIndexFile)
|
||||||
return body, nil
|
return body, nil
|
||||||
|
@ -119,19 +119,19 @@ func DownloadLatest(hub *csconfig.Hub, target Item, overwrite bool, updateOnly b
|
||||||
log.Tracef("collection, recurse")
|
log.Tracef("collection, recurse")
|
||||||
hubIdx[ptrtype][p], err = DownloadLatest(hub, val, overwrite, updateOnly)
|
hubIdx[ptrtype][p], err = DownloadLatest(hub, val, overwrite, updateOnly)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return target, errors.Wrap(err, fmt.Sprintf("while downloading %s", val.Name))
|
return target, fmt.Errorf("while downloading %s: %w", val.Name, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
item, err := DownloadItem(hub, val, overwrite)
|
item, err := DownloadItem(hub, val, overwrite)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return target, errors.Wrap(err, fmt.Sprintf("while downloading %s", val.Name))
|
return target, fmt.Errorf("while downloading %s: %w", val.Name, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// We need to enable an item when it has been added to a collection since latest release of the collection.
|
// We need to enable an item when it has been added to a collection since latest release of the collection.
|
||||||
// We check if val.Downloaded is false because maybe the item has been disabled by the user.
|
// We check if val.Downloaded is false because maybe the item has been disabled by the user.
|
||||||
if !item.Installed && !val.Downloaded {
|
if !item.Installed && !val.Downloaded {
|
||||||
if item, err = EnableItem(hub, item); err != nil {
|
if item, err = EnableItem(hub, item); err != nil {
|
||||||
return target, errors.Wrapf(err, "enabling '%s'", item.Name)
|
return target, fmt.Errorf("enabling '%s': %w", item.Name, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hubIdx[ptrtype][p] = item
|
hubIdx[ptrtype][p] = item
|
||||||
|
@ -160,11 +160,11 @@ func DownloadItem(hub *csconfig.Hub, target Item, overwrite bool) (Item, error)
|
||||||
}
|
}
|
||||||
req, err := http.NewRequest(http.MethodGet, fmt.Sprintf(RawFileURLTemplate, HubBranch, target.RemotePath), nil)
|
req, err := http.NewRequest(http.MethodGet, fmt.Sprintf(RawFileURLTemplate, HubBranch, target.RemotePath), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return target, errors.Wrap(err, fmt.Sprintf("while downloading %s", req.URL.String()))
|
return target, fmt.Errorf("while downloading %s: %w", req.URL.String(), err)
|
||||||
}
|
}
|
||||||
resp, err := http.DefaultClient.Do(req)
|
resp, err := http.DefaultClient.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return target, errors.Wrap(err, fmt.Sprintf("while downloading %s", req.URL.String()))
|
return target, fmt.Errorf("while downloading %s: %w", req.URL.String(), err)
|
||||||
}
|
}
|
||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusOK {
|
||||||
return target, fmt.Errorf("bad http code %d for %s", resp.StatusCode, req.URL.String())
|
return target, fmt.Errorf("bad http code %d for %s", resp.StatusCode, req.URL.String())
|
||||||
|
@ -172,11 +172,11 @@ func DownloadItem(hub *csconfig.Hub, target Item, overwrite bool) (Item, error)
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
body, err := io.ReadAll(resp.Body)
|
body, err := io.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return target, errors.Wrap(err, fmt.Sprintf("while reading %s", req.URL.String()))
|
return target, fmt.Errorf("while reading %s: %w", req.URL.String(), err)
|
||||||
}
|
}
|
||||||
h := sha256.New()
|
h := sha256.New()
|
||||||
if _, err := h.Write(body); err != nil {
|
if _, err := h.Write(body); err != nil {
|
||||||
return target, errors.Wrap(err, fmt.Sprintf("while hashing %s", target.Name))
|
return target, fmt.Errorf("while hashing %s: %w", target.Name, err)
|
||||||
}
|
}
|
||||||
meow := fmt.Sprintf("%x", h.Sum(nil))
|
meow := fmt.Sprintf("%x", h.Sum(nil))
|
||||||
if meow != target.Versions[target.Version].Digest {
|
if meow != target.Versions[target.Version].Digest {
|
||||||
|
@ -192,7 +192,7 @@ func DownloadItem(hub *csconfig.Hub, target Item, overwrite bool) (Item, error)
|
||||||
/*ensure that target file is within target dir*/
|
/*ensure that target file is within target dir*/
|
||||||
finalPath, err := filepath.Abs(tdir + "/" + target.RemotePath)
|
finalPath, err := filepath.Abs(tdir + "/" + target.RemotePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return target, errors.Wrapf(err, "Abs error on %s", tdir+"/"+target.RemotePath)
|
return target, fmt.Errorf("filepath.Abs error on %s: %w", tdir+"/"+target.RemotePath, err)
|
||||||
}
|
}
|
||||||
if !strings.HasPrefix(finalPath, tdir) {
|
if !strings.HasPrefix(finalPath, tdir) {
|
||||||
return target, fmt.Errorf("path %s escapes %s, abort", target.RemotePath, tdir)
|
return target, fmt.Errorf("path %s escapes %s, abort", target.RemotePath, tdir)
|
||||||
|
@ -201,7 +201,7 @@ func DownloadItem(hub *csconfig.Hub, target Item, overwrite bool) (Item, error)
|
||||||
if _, err = os.Stat(parent_dir); os.IsNotExist(err) {
|
if _, err = os.Stat(parent_dir); os.IsNotExist(err) {
|
||||||
log.Debugf("%s doesn't exist, create", parent_dir)
|
log.Debugf("%s doesn't exist, create", parent_dir)
|
||||||
if err := os.MkdirAll(parent_dir, os.ModePerm); err != nil {
|
if err := os.MkdirAll(parent_dir, os.ModePerm); err != nil {
|
||||||
return target, errors.Wrap(err, "while creating parent directories")
|
return target, fmt.Errorf("while creating parent directories: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*check actual file*/
|
/*check actual file*/
|
||||||
|
@ -214,19 +214,19 @@ func DownloadItem(hub *csconfig.Hub, target Item, overwrite bool) (Item, error)
|
||||||
|
|
||||||
f, err := os.OpenFile(tdir+"/"+target.RemotePath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
|
f, err := os.OpenFile(tdir+"/"+target.RemotePath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return target, errors.Wrap(err, "while opening file")
|
return target, fmt.Errorf("while opening file: %w", err)
|
||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
_, err = f.WriteString(string(body))
|
_, err = f.WriteString(string(body))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return target, errors.Wrap(err, "while writing file")
|
return target, fmt.Errorf("while writing file: %w", err)
|
||||||
}
|
}
|
||||||
target.Downloaded = true
|
target.Downloaded = true
|
||||||
target.Tainted = false
|
target.Tainted = false
|
||||||
target.UpToDate = true
|
target.UpToDate = true
|
||||||
|
|
||||||
if err = downloadData(dataFolder, overwrite, bytes.NewReader(body)); err != nil {
|
if err = downloadData(dataFolder, overwrite, bytes.NewReader(body)); err != nil {
|
||||||
return target, errors.Wrapf(err, "while downloading data for %s", target.FileName)
|
return target, fmt.Errorf("while downloading data for %s: %w", target.FileName, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
hubIdx[target.Type][target.Name] = target
|
hubIdx[target.Type][target.Name] = target
|
||||||
|
@ -241,11 +241,11 @@ func DownloadDataIfNeeded(hub *csconfig.Hub, target Item, force bool) error {
|
||||||
)
|
)
|
||||||
itemFilePath := fmt.Sprintf("%s/%s/%s/%s", hub.ConfigDir, target.Type, target.Stage, target.FileName)
|
itemFilePath := fmt.Sprintf("%s/%s/%s/%s", hub.ConfigDir, target.Type, target.Stage, target.FileName)
|
||||||
if itemFile, err = os.Open(itemFilePath); err != nil {
|
if itemFile, err = os.Open(itemFilePath); err != nil {
|
||||||
return errors.Wrapf(err, "while opening %s", itemFilePath)
|
return fmt.Errorf("while opening %s: %w", itemFilePath, err)
|
||||||
}
|
}
|
||||||
defer itemFile.Close()
|
defer itemFile.Close()
|
||||||
if err = downloadData(dataFolder, force, itemFile); err != nil {
|
if err = downloadData(dataFolder, force, itemFile); err != nil {
|
||||||
return errors.Wrapf(err, "while downloading data for %s", itemFilePath)
|
return fmt.Errorf("while downloading data for %s: %w", itemFilePath, err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -261,7 +261,7 @@ func downloadData(dataFolder string, force bool, reader io.Reader) error {
|
||||||
if errors.Is(err, io.EOF) {
|
if errors.Is(err, io.EOF) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
return errors.Wrap(err, "while reading file")
|
return fmt.Errorf("while reading file: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
download := false
|
download := false
|
||||||
|
@ -273,7 +273,7 @@ func downloadData(dataFolder string, force bool, reader io.Reader) error {
|
||||||
if download || force {
|
if download || force {
|
||||||
err = GetData(data.Data, dataFolder)
|
err = GetData(data.Data, dataFolder)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "while getting data")
|
return fmt.Errorf("while getting data: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ func TestUpgradeConfigNewScenarioInCollection(t *testing.T) {
|
||||||
require.True(t, hubIdx[COLLECTIONS]["crowdsecurity/test_collection"].UpToDate)
|
require.True(t, hubIdx[COLLECTIONS]["crowdsecurity/test_collection"].UpToDate)
|
||||||
require.False(t, hubIdx[COLLECTIONS]["crowdsecurity/test_collection"].Tainted)
|
require.False(t, hubIdx[COLLECTIONS]["crowdsecurity/test_collection"].Tainted)
|
||||||
|
|
||||||
// This is the sceanrio that gets added in next version of collection
|
// This is the scenario that gets added in next version of collection
|
||||||
require.False(t, hubIdx[SCENARIOS]["crowdsecurity/barfoo_scenario"].Downloaded)
|
require.False(t, hubIdx[SCENARIOS]["crowdsecurity/barfoo_scenario"].Downloaded)
|
||||||
require.False(t, hubIdx[SCENARIOS]["crowdsecurity/barfoo_scenario"].Installed)
|
require.False(t, hubIdx[SCENARIOS]["crowdsecurity/barfoo_scenario"].Installed)
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ func TestUpgradeConfigNewScenarioInCollection(t *testing.T) {
|
||||||
|
|
||||||
// Install a collection, disable a scenario.
|
// Install a collection, disable a scenario.
|
||||||
// Upgrade should install should not enable/download the disabled scenario.
|
// Upgrade should install should not enable/download the disabled scenario.
|
||||||
func TestUpgradeConfigInDisabledSceanarioShouldNotBeInstalled(t *testing.T) {
|
func TestUpgradeConfigInDisabledScenarioShouldNotBeInstalled(t *testing.T) {
|
||||||
cfg := envSetup(t)
|
cfg := envSetup(t)
|
||||||
defer envTearDown(cfg)
|
defer envTearDown(cfg)
|
||||||
|
|
||||||
|
@ -134,7 +134,7 @@ func TestUpgradeConfigNewScenarioIsInstalledWhenReferencedScenarioIsDisabled(t *
|
||||||
|
|
||||||
// collection receives an update. It now adds new scenario "crowdsecurity/barfoo_scenario"
|
// collection receives an update. It now adds new scenario "crowdsecurity/barfoo_scenario"
|
||||||
// we now attempt to upgrade the collection, however it shouldn't install the foobar_scenario
|
// we now attempt to upgrade the collection, however it shouldn't install the foobar_scenario
|
||||||
// we just removed. Nor should it install the newly added sceanrio
|
// we just removed. Nor should it install the newly added scenario
|
||||||
pushUpdateToCollectionInHub()
|
pushUpdateToCollectionInHub()
|
||||||
|
|
||||||
if err := UpdateHubIdx(cfg.Hub); err != nil {
|
if err := UpdateHubIdx(cfg.Hub); err != nil {
|
||||||
|
|
|
@ -5,7 +5,6 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
|
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
|
||||||
|
@ -17,7 +16,7 @@ func purgeItem(hub *csconfig.Hub, target Item) (Item, error) {
|
||||||
|
|
||||||
// disable hub file
|
// disable hub file
|
||||||
if err := os.Remove(hubpath); err != nil {
|
if err := os.Remove(hubpath); err != nil {
|
||||||
return target, errors.Wrap(err, "while removing file")
|
return target, fmt.Errorf("while removing file: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
target.Downloaded = false
|
target.Downloaded = false
|
||||||
|
@ -73,7 +72,7 @@ func DisableItem(hub *csconfig.Hub, target Item, purge bool, force bool) (Item,
|
||||||
if toRemove {
|
if toRemove {
|
||||||
hubIdx[ptrtype][p], err = DisableItem(hub, val, purge, force)
|
hubIdx[ptrtype][p], err = DisableItem(hub, val, purge, force)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return target, errors.Wrap(err, fmt.Sprintf("while disabling %s", p))
|
return target, fmt.Errorf("while disabling %s: %w", p, err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.Infof("%s was not removed because it belongs to another collection", val.Name)
|
log.Infof("%s was not removed because it belongs to another collection", val.Name)
|
||||||
|
@ -98,11 +97,11 @@ func DisableItem(hub *csconfig.Hub, target Item, purge bool, force bool) (Item,
|
||||||
}
|
}
|
||||||
hubpath, err := os.Readlink(syml)
|
hubpath, err := os.Readlink(syml)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return target, errors.Wrap(err, "while reading symlink")
|
return target, fmt.Errorf("while reading symlink: %w", err)
|
||||||
}
|
}
|
||||||
absPath, err := filepath.Abs(hdir + "/" + target.RemotePath)
|
absPath, err := filepath.Abs(hdir + "/" + target.RemotePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return target, errors.Wrap(err, "while abs path")
|
return target, fmt.Errorf("while abs path: %w", err)
|
||||||
}
|
}
|
||||||
if hubpath != absPath {
|
if hubpath != absPath {
|
||||||
log.Warningf("%s (%s) isn't a symlink to %s", target.Name, syml, absPath)
|
log.Warningf("%s (%s) isn't a symlink to %s", target.Name, syml, absPath)
|
||||||
|
@ -111,7 +110,7 @@ func DisableItem(hub *csconfig.Hub, target Item, purge bool, force bool) (Item,
|
||||||
|
|
||||||
//remove the symlink
|
//remove the symlink
|
||||||
if err = os.Remove(syml); err != nil {
|
if err = os.Remove(syml); err != nil {
|
||||||
return target, errors.Wrap(err, "while removing symlink")
|
return target, fmt.Errorf("while removing symlink: %w", err)
|
||||||
}
|
}
|
||||||
log.Infof("Removed symlink [%s] : %s", target.Name, syml)
|
log.Infof("Removed symlink [%s] : %s", target.Name, syml)
|
||||||
}
|
}
|
||||||
|
@ -151,7 +150,7 @@ func EnableItem(hub *csconfig.Hub, target Item) (Item, error) {
|
||||||
if _, err := os.Stat(parent_dir); os.IsNotExist(err) {
|
if _, err := os.Stat(parent_dir); os.IsNotExist(err) {
|
||||||
log.Printf("%s doesn't exist, create", parent_dir)
|
log.Printf("%s doesn't exist, create", parent_dir)
|
||||||
if err := os.MkdirAll(parent_dir, os.ModePerm); err != nil {
|
if err := os.MkdirAll(parent_dir, os.ModePerm); err != nil {
|
||||||
return target, errors.Wrap(err, "while creating directory")
|
return target, fmt.Errorf("while creating directory: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,12 +162,12 @@ func EnableItem(hub *csconfig.Hub, target Item) (Item, error) {
|
||||||
for _, p := range ptr {
|
for _, p := range ptr {
|
||||||
val, ok := hubIdx[ptrtype][p]
|
val, ok := hubIdx[ptrtype][p]
|
||||||
if !ok {
|
if !ok {
|
||||||
return target, fmt.Errorf("required %s %s of %s doesn't exist, abort.", ptrtype, p, target.Name)
|
return target, fmt.Errorf("required %s %s of %s doesn't exist, abort", ptrtype, p, target.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
hubIdx[ptrtype][p], err = EnableItem(hub, val)
|
hubIdx[ptrtype][p], err = EnableItem(hub, val)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return target, errors.Wrap(err, fmt.Sprintf("while installing %s", p))
|
return target, fmt.Errorf("while installing %s: %w", p, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -183,16 +182,16 @@ func EnableItem(hub *csconfig.Hub, target Item) (Item, error) {
|
||||||
//tdir+target.RemotePath
|
//tdir+target.RemotePath
|
||||||
srcPath, err := filepath.Abs(hdir + "/" + target.RemotePath)
|
srcPath, err := filepath.Abs(hdir + "/" + target.RemotePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return target, errors.Wrap(err, "while getting source path")
|
return target, fmt.Errorf("while getting source path: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
dstPath, err := filepath.Abs(parent_dir + "/" + target.FileName)
|
dstPath, err := filepath.Abs(parent_dir + "/" + target.FileName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return target, errors.Wrap(err, "while getting destination path")
|
return target, fmt.Errorf("while getting destination path: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = os.Symlink(srcPath, dstPath); err != nil {
|
if err = os.Symlink(srcPath, dstPath); err != nil {
|
||||||
return target, errors.Wrap(err, fmt.Sprintf("while creating symlink from %s to %s", srcPath, dstPath))
|
return target, fmt.Errorf("while creating symlink from %s to %s: %w", srcPath, dstPath, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("Enabled %s : %s", target.Type, target.Name)
|
log.Printf("Enabled %s : %s", target.Type, target.Name)
|
||||||
|
|
|
@ -131,14 +131,14 @@ func (c *Client) CreateOrUpdateAlert(machineID string, alertItem *models.Alert)
|
||||||
alerts, err := c.Ent.Alert.Query().Where(alert.UUID(alertItem.UUID)).WithDecisions().All(c.CTX)
|
alerts, err := c.Ent.Alert.Query().Where(alert.UUID(alertItem.UUID)).WithDecisions().All(c.CTX)
|
||||||
|
|
||||||
if err != nil && !ent.IsNotFound(err) {
|
if err != nil && !ent.IsNotFound(err) {
|
||||||
return "", errors.Wrap(err, "unable to query alerts for uuid %s")
|
return "", fmt.Errorf("unable to query alerts for uuid %s: %w", alertItem.UUID, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
//alert wasn't found, insert it (expected hotpath)
|
//alert wasn't found, insert it (expected hotpath)
|
||||||
if ent.IsNotFound(err) || len(alerts) == 0 {
|
if ent.IsNotFound(err) || len(alerts) == 0 {
|
||||||
ret, err := c.CreateAlert(machineID, []*models.Alert{alertItem})
|
ret, err := c.CreateAlert(machineID, []*models.Alert{alertItem})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errors.Wrap(err, "unable to create alert")
|
return "", fmt.Errorf("unable to create alert: %w", err)
|
||||||
}
|
}
|
||||||
return ret[0], nil
|
return ret[0], nil
|
||||||
}
|
}
|
||||||
|
@ -256,7 +256,7 @@ func (c *Client) CreateOrUpdateAlert(machineID string, alertItem *models.Alert)
|
||||||
//now that we bulk created missing decisions, let's update the alert
|
//now that we bulk created missing decisions, let's update the alert
|
||||||
err = c.Ent.Alert.Update().Where(alert.UUID(alertItem.UUID)).AddDecisions(decisions...).Exec(c.CTX)
|
err = c.Ent.Alert.Update().Where(alert.UUID(alertItem.UUID)).AddDecisions(decisions...).Exec(c.CTX)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errors.Wrapf(err, "updating alert %s : %s", alertItem.UUID, err)
|
return "", fmt.Errorf("updating alert %s: %w", alertItem.UUID, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return "", nil
|
return "", nil
|
||||||
|
@ -442,7 +442,7 @@ func (c *Client) UpdateCommunityBlocklist(alertItem *models.Alert) (int, int, in
|
||||||
if rollbackErr != nil {
|
if rollbackErr != nil {
|
||||||
log.Errorf("rollback error: %s", rollbackErr)
|
log.Errorf("rollback error: %s", rollbackErr)
|
||||||
}
|
}
|
||||||
return 0, 0, 0, errors.Wrap(err, "while deleting older community blocklist decisions")
|
return 0, 0, 0, fmt.Errorf("while deleting older community blocklist decisions: %w", err)
|
||||||
}
|
}
|
||||||
deleted += deletedDecisions
|
deleted += deletedDecisions
|
||||||
|
|
||||||
|
@ -475,7 +475,7 @@ func (c *Client) UpdateCommunityBlocklist(alertItem *models.Alert) (int, int, in
|
||||||
if rollbackErr != nil {
|
if rollbackErr != nil {
|
||||||
log.Errorf("rollback error: %s", rollbackErr)
|
log.Errorf("rollback error: %s", rollbackErr)
|
||||||
}
|
}
|
||||||
return 0, 0, 0, errors.Wrap(err, "while deleting older community blocklist decisions")
|
return 0, 0, 0, fmt.Errorf("while deleting older community blocklist decisions: %w", err)
|
||||||
}
|
}
|
||||||
deleted += deletedDecisions
|
deleted += deletedDecisions
|
||||||
}
|
}
|
||||||
|
@ -811,7 +811,7 @@ func AlertPredicatesFromFilter(filter map[string][]string) ([]predicate.Alert, e
|
||||||
case "since":
|
case "since":
|
||||||
duration, err := types.ParseDuration(value[0])
|
duration, err := types.ParseDuration(value[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "while parsing duration")
|
return nil, fmt.Errorf("while parsing duration: %w", err)
|
||||||
}
|
}
|
||||||
since := time.Now().UTC().Add(-duration)
|
since := time.Now().UTC().Add(-duration)
|
||||||
if since.IsZero() {
|
if since.IsZero() {
|
||||||
|
@ -821,21 +821,21 @@ func AlertPredicatesFromFilter(filter map[string][]string) ([]predicate.Alert, e
|
||||||
case "created_before":
|
case "created_before":
|
||||||
duration, err := types.ParseDuration(value[0])
|
duration, err := types.ParseDuration(value[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "while parsing duration")
|
return nil, fmt.Errorf("while parsing duration: %w", err)
|
||||||
}
|
}
|
||||||
since := time.Now().UTC().Add(-duration)
|
since := time.Now().UTC().Add(-duration)
|
||||||
if since.IsZero() {
|
if since.IsZero() {
|
||||||
return nil, fmt.Errorf("Empty time now() - %s", since.String())
|
return nil, fmt.Errorf("empty time now() - %s", since.String())
|
||||||
}
|
}
|
||||||
predicates = append(predicates, alert.CreatedAtLTE(since))
|
predicates = append(predicates, alert.CreatedAtLTE(since))
|
||||||
case "until":
|
case "until":
|
||||||
duration, err := types.ParseDuration(value[0])
|
duration, err := types.ParseDuration(value[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "while parsing duration")
|
return nil, fmt.Errorf("while parsing duration: %w", err)
|
||||||
}
|
}
|
||||||
until := time.Now().UTC().Add(-duration)
|
until := time.Now().UTC().Add(-duration)
|
||||||
if until.IsZero() {
|
if until.IsZero() {
|
||||||
return nil, fmt.Errorf("Empty time now() - %s", until.String())
|
return nil, fmt.Errorf("empty time now() - %s", until.String())
|
||||||
}
|
}
|
||||||
predicates = append(predicates, alert.StartedAtLTE(until))
|
predicates = append(predicates, alert.StartedAtLTE(until))
|
||||||
case "decision_type":
|
case "decision_type":
|
||||||
|
@ -966,13 +966,13 @@ func (c *Client) AlertsCountPerScenario(filters map[string][]string) (map[string
|
||||||
query, err := BuildAlertRequestFromFilter(query, filters)
|
query, err := BuildAlertRequestFromFilter(query, filters)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "failed to build alert request")
|
return nil, fmt.Errorf("failed to build alert request: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = query.GroupBy(alert.FieldScenario).Aggregate(ent.Count()).Scan(ctx, &res)
|
err = query.GroupBy(alert.FieldScenario).Aggregate(ent.Count()).Scan(ctx, &res)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "failed to count alerts per scenario")
|
return nil, fmt.Errorf("failed to count alerts per scenario: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
counts := make(map[string]int)
|
counts := make(map[string]int)
|
||||||
|
@ -1270,7 +1270,7 @@ func (c *Client) FlushAlerts(MaxAge string, MaxItems int) error {
|
||||||
totalAlerts, err = c.TotalAlerts()
|
totalAlerts, err = c.TotalAlerts()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Log.Warningf("FlushAlerts (max items count) : %s", err)
|
c.Log.Warningf("FlushAlerts (max items count) : %s", err)
|
||||||
return errors.Wrap(err, "unable to get alerts count")
|
return fmt.Errorf("unable to get alerts count: %w", err)
|
||||||
}
|
}
|
||||||
c.Log.Debugf("FlushAlerts (Total alerts): %d", totalAlerts)
|
c.Log.Debugf("FlushAlerts (Total alerts): %d", totalAlerts)
|
||||||
if MaxAge != "" {
|
if MaxAge != "" {
|
||||||
|
@ -1280,7 +1280,7 @@ func (c *Client) FlushAlerts(MaxAge string, MaxItems int) error {
|
||||||
nbDeleted, err := c.DeleteAlertWithFilter(filter)
|
nbDeleted, err := c.DeleteAlertWithFilter(filter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Log.Warningf("FlushAlerts (max age) : %s", err)
|
c.Log.Warningf("FlushAlerts (max age) : %s", err)
|
||||||
return errors.Wrapf(err, "unable to flush alerts with filter until: %s", MaxAge)
|
return fmt.Errorf("unable to flush alerts with filter until=%s: %w", MaxAge, err)
|
||||||
}
|
}
|
||||||
c.Log.Debugf("FlushAlerts (deleted max age alerts): %d", nbDeleted)
|
c.Log.Debugf("FlushAlerts (deleted max age alerts): %d", nbDeleted)
|
||||||
deletedByAge = nbDeleted
|
deletedByAge = nbDeleted
|
||||||
|
@ -1300,7 +1300,7 @@ func (c *Client) FlushAlerts(MaxAge string, MaxItems int) error {
|
||||||
c.Log.Debugf("FlushAlerts (last alert): %+v", lastAlert)
|
c.Log.Debugf("FlushAlerts (last alert): %+v", lastAlert)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Log.Errorf("FlushAlerts: could not get last alert: %s", err)
|
c.Log.Errorf("FlushAlerts: could not get last alert: %s", err)
|
||||||
return errors.Wrap(err, "could not get last alert")
|
return fmt.Errorf("could not get last alert: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(lastAlert) != 0 {
|
if len(lastAlert) != 0 {
|
||||||
|
@ -1314,7 +1314,7 @@ func (c *Client) FlushAlerts(MaxAge string, MaxItems int) error {
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Log.Errorf("FlushAlerts: Could not delete alerts : %s", err)
|
c.Log.Errorf("FlushAlerts: Could not delete alerts : %s", err)
|
||||||
return errors.Wrap(err, "could not delete alerts")
|
return fmt.Errorf("could not delete alerts: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,7 +108,7 @@ func BuildDecisionRequestWithFilter(query *ent.DecisionQuery, filter map[string]
|
||||||
}
|
}
|
||||||
query, err = applyStartIpEndIpFilter(query, contains, ip_sz, start_ip, start_sfx, end_ip, end_sfx)
|
query, err = applyStartIpEndIpFilter(query, contains, ip_sz, start_ip, start_sfx, end_ip, end_sfx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "fail to apply StartIpEndIpFilter")
|
return nil, fmt.Errorf("fail to apply StartIpEndIpFilter: %w", err)
|
||||||
}
|
}
|
||||||
return query, nil
|
return query, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,19 +2,18 @@ package leakybucket
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/antonmedv/expr"
|
||||||
|
|
||||||
"github.com/mohae/deepcopy"
|
"github.com/mohae/deepcopy"
|
||||||
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/antonmedv/expr"
|
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/types"
|
"github.com/crowdsecurity/crowdsec/pkg/types"
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var serialized map[string]Leaky
|
var serialized map[string]Leaky
|
||||||
|
@ -342,12 +341,12 @@ func PourItemToHolders(parsed types.Event, holders []BucketFactory, buckets *Buc
|
||||||
//we need to either find the existing bucket, or create a new one (if it's the first event to hit it for this partition key)
|
//we need to either find the existing bucket, or create a new one (if it's the first event to hit it for this partition key)
|
||||||
bucket, err := LoadOrStoreBucketFromHolder(buckey, buckets, holders[idx], parsed.ExpectMode)
|
bucket, err := LoadOrStoreBucketFromHolder(buckey, buckets, holders[idx], parsed.ExpectMode)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, errors.Wrap(err, "failed to load or store bucket")
|
return false, fmt.Errorf("failed to load or store bucket: %w", err)
|
||||||
}
|
}
|
||||||
//finally, pour the even into the bucket
|
//finally, pour the even into the bucket
|
||||||
ok, err := PourItemToBucket(bucket, holders[idx], buckets, &parsed)
|
ok, err := PourItemToBucket(bucket, holders[idx], buckets, &parsed)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, errors.Wrap(err, "failed to pour bucket")
|
return false, fmt.Errorf("failed to pour bucket: %w", err)
|
||||||
}
|
}
|
||||||
if ok {
|
if ok {
|
||||||
poured = true
|
poured = true
|
||||||
|
|
Loading…
Reference in a new issue