2020-11-30 09:37:17 +00:00
package main
import (
"context"
2021-12-29 13:08:47 +00:00
"encoding/csv"
2020-11-30 09:37:17 +00:00
"encoding/json"
"fmt"
"net/url"
"os"
2023-01-04 15:50:02 +00:00
"sort"
2020-11-30 09:37:17 +00:00
"strconv"
"strings"
2023-01-31 13:47:44 +00:00
"time"
2020-11-30 09:37:17 +00:00
2022-10-13 10:28:24 +00:00
"github.com/fatih/color"
2020-11-30 09:37:17 +00:00
"github.com/go-openapi/strfmt"
2022-05-19 08:48:08 +00:00
"github.com/pkg/errors"
2020-11-30 09:37:17 +00:00
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"gopkg.in/yaml.v2"
2022-10-07 09:05:35 +00:00
"github.com/crowdsecurity/crowdsec/pkg/apiclient"
"github.com/crowdsecurity/crowdsec/pkg/cwversion"
"github.com/crowdsecurity/crowdsec/pkg/database"
"github.com/crowdsecurity/crowdsec/pkg/models"
2023-01-31 13:47:44 +00:00
"github.com/crowdsecurity/crowdsec/pkg/types"
2020-11-30 09:37:17 +00:00
)
func DecisionsFromAlert ( alert * models . Alert ) string {
ret := ""
var decMap = make ( map [ string ] int )
for _ , decision := range alert . Decisions {
k := * decision . Type
if * decision . Simulated {
k = fmt . Sprintf ( "(simul)%s" , k )
}
v := decMap [ k ]
decMap [ k ] = v + 1
}
for k , v := range decMap {
if len ( ret ) > 0 {
ret += " "
}
ret += fmt . Sprintf ( "%s:%d" , k , v )
}
return ret
}
2023-01-31 13:47:44 +00:00
func DateFromAlert ( alert * models . Alert ) string {
ts , err := time . Parse ( time . RFC3339 , alert . CreatedAt )
if err != nil {
log . Infof ( "while parsing %s with %s : %s" , alert . CreatedAt , time . RFC3339 , err )
return alert . CreatedAt
}
return ts . Format ( time . RFC822 )
}
func SourceFromAlert ( alert * models . Alert ) string {
//more than one item, just number and scope
if len ( alert . Decisions ) > 1 {
return fmt . Sprintf ( "%d %ss (%s)" , len ( alert . Decisions ) , * alert . Decisions [ 0 ] . Scope , * alert . Decisions [ 0 ] . Origin )
}
//fallback on single decision information
if len ( alert . Decisions ) == 1 {
return fmt . Sprintf ( "%s:%s" , * alert . Decisions [ 0 ] . Scope , * alert . Decisions [ 0 ] . Value )
}
//try to compose a human friendly version
if * alert . Source . Value != "" && * alert . Source . Scope != "" {
scope := ""
scope = fmt . Sprintf ( "%s:%s" , * alert . Source . Scope , * alert . Source . Value )
extra := ""
if alert . Source . Cn != "" {
extra = alert . Source . Cn
}
if alert . Source . AsNumber != "" {
extra += fmt . Sprintf ( "/%s" , alert . Source . AsNumber )
}
if alert . Source . AsName != "" {
extra += fmt . Sprintf ( "/%s" , alert . Source . AsName )
}
if extra != "" {
scope += " (" + extra + ")"
}
return scope
}
return ""
}
2020-11-30 09:37:17 +00:00
func AlertsToTable ( alerts * models . GetAlertsResponse , printMachine bool ) error {
if csConfig . Cscli . Output == "raw" {
2021-12-29 13:08:47 +00:00
csvwriter := csv . NewWriter ( os . Stdout )
2022-03-09 15:15:18 +00:00
header := [ ] string { "id" , "scope" , "value" , "reason" , "country" , "as" , "decisions" , "created_at" }
2020-11-30 09:37:17 +00:00
if printMachine {
2022-03-09 15:15:18 +00:00
header = append ( header , "machine" )
}
err := csvwriter . Write ( header )
if err != nil {
return err
2020-11-30 09:37:17 +00:00
}
for _ , alertItem := range * alerts {
2021-12-29 13:08:47 +00:00
row := [ ] string {
fmt . Sprintf ( "%d" , alertItem . ID ) ,
* alertItem . Source . Scope ,
* alertItem . Source . Value ,
* alertItem . Scenario ,
alertItem . Source . Cn ,
2022-11-14 08:55:53 +00:00
alertItem . Source . GetAsNumberName ( ) ,
2021-12-29 13:08:47 +00:00
DecisionsFromAlert ( alertItem ) ,
* alertItem . StartAt ,
}
2020-11-30 09:37:17 +00:00
if printMachine {
2021-12-29 13:08:47 +00:00
row = append ( row , alertItem . MachineID )
}
err := csvwriter . Write ( row )
if err != nil {
return err
2020-11-30 09:37:17 +00:00
}
}
2021-12-29 13:08:47 +00:00
csvwriter . Flush ( )
2020-11-30 09:37:17 +00:00
} else if csConfig . Cscli . Output == "json" {
x , _ := json . MarshalIndent ( alerts , "" , " " )
fmt . Printf ( "%s" , string ( x ) )
} else if csConfig . Cscli . Output == "human" {
if len ( * alerts ) == 0 {
fmt . Println ( "No active alerts" )
return nil
}
2022-10-13 10:28:24 +00:00
alertsTable ( color . Output , alerts , printMachine )
2020-11-30 09:37:17 +00:00
}
return nil
}
func DisplayOneAlert ( alert * models . Alert , withDetail bool ) error {
if csConfig . Cscli . Output == "human" {
fmt . Printf ( "\n################################################################################################\n\n" )
scopeAndValue := * alert . Source . Scope
if * alert . Source . Value != "" {
scopeAndValue += ":" + * alert . Source . Value
}
2023-01-31 13:47:44 +00:00
fmt . Printf ( " - ID : %d\n" , alert . ID )
fmt . Printf ( " - Date : %s\n" , alert . CreatedAt )
fmt . Printf ( " - Machine : %s\n" , alert . MachineID )
fmt . Printf ( " - Simulation : %v\n" , * alert . Simulated )
fmt . Printf ( " - Reason : %s\n" , * alert . Scenario )
2020-11-30 09:37:17 +00:00
fmt . Printf ( " - Events Count : %d\n" , * alert . EventsCount )
2023-01-31 13:47:44 +00:00
fmt . Printf ( " - Scope:Value : %s\n" , scopeAndValue )
fmt . Printf ( " - Country : %s\n" , alert . Source . Cn )
fmt . Printf ( " - AS : %s\n" , alert . Source . AsName )
fmt . Printf ( " - Begin : %s\n" , * alert . StartAt )
fmt . Printf ( " - End : %s\n" , * alert . StopAt )
fmt . Printf ( " - UUID : %s\n\n" , alert . UUID )
2022-10-07 09:05:35 +00:00
2022-10-13 10:28:24 +00:00
alertDecisionsTable ( color . Output , alert )
2020-11-30 09:37:17 +00:00
2023-01-04 15:50:02 +00:00
if len ( alert . Meta ) > 0 {
fmt . Printf ( "\n - Context :\n" )
sort . Slice ( alert . Meta , func ( i , j int ) bool {
return alert . Meta [ i ] . Key < alert . Meta [ j ] . Key
} )
table := newTable ( color . Output )
table . SetRowLines ( false )
table . SetHeaders ( "Key" , "Value" )
for _ , meta := range alert . Meta {
var valSlice [ ] string
if err := json . Unmarshal ( [ ] byte ( meta . Value ) , & valSlice ) ; err != nil {
return fmt . Errorf ( "unknown context value type '%s' : %s" , meta . Value , err )
}
for _ , value := range valSlice {
table . AddRow (
meta . Key ,
value ,
)
}
}
table . Render ( )
}
2020-11-30 09:37:17 +00:00
if withDetail {
fmt . Printf ( "\n - Events :\n" )
for _ , event := range alert . Events {
2022-10-13 10:28:24 +00:00
alertEventTable ( color . Output , event )
2020-11-30 09:37:17 +00:00
}
}
}
return nil
}
func NewAlertsCmd ( ) * cobra . Command {
var cmdAlerts = & cobra . Command {
2021-09-03 10:56:17 +00:00
Use : "alerts [action]" ,
Short : "Manage alerts" ,
Args : cobra . MinimumNArgs ( 1 ) ,
DisableAutoGenTag : true ,
2022-05-19 08:48:08 +00:00
PersistentPreRunE : func ( cmd * cobra . Command , args [ ] string ) error {
2020-11-30 09:37:17 +00:00
var err error
2021-03-24 17:16:17 +00:00
if err := csConfig . LoadAPIClient ( ) ; err != nil {
2022-05-19 08:48:08 +00:00
return errors . Wrap ( err , "loading api client" )
2020-11-30 09:37:17 +00:00
}
apiURL , err := url . Parse ( csConfig . API . Client . Credentials . URL )
if err != nil {
2022-05-19 08:48:08 +00:00
return errors . Wrapf ( err , "parsing api url %s" , apiURL )
2020-11-30 09:37:17 +00:00
}
Client , err = apiclient . NewClient ( & apiclient . Config {
MachineID : csConfig . API . Client . Credentials . Login ,
Password : strfmt . Password ( csConfig . API . Client . Credentials . Password ) ,
UserAgent : fmt . Sprintf ( "crowdsec/%s" , cwversion . VersionStr ( ) ) ,
URL : apiURL ,
VersionPrefix : "v1" ,
} )
if err != nil {
2022-05-19 08:48:08 +00:00
return errors . Wrap ( err , "new api client" )
2020-11-30 09:37:17 +00:00
}
2022-05-19 08:48:08 +00:00
return nil
2020-11-30 09:37:17 +00:00
} ,
}
2023-01-06 22:14:02 +00:00
cmdAlerts . AddCommand ( NewAlertsListCmd ( ) )
cmdAlerts . AddCommand ( NewAlertsInspectCmd ( ) )
cmdAlerts . AddCommand ( NewAlertsFlushCmd ( ) )
cmdAlerts . AddCommand ( NewAlertsDeleteCmd ( ) )
return cmdAlerts
}
func NewAlertsListCmd ( ) * cobra . Command {
2020-11-30 09:37:17 +00:00
var alertListFilter = apiclient . AlertsListOpts {
ScopeEquals : new ( string ) ,
ValueEquals : new ( string ) ,
ScenarioEquals : new ( string ) ,
IPEquals : new ( string ) ,
RangeEquals : new ( string ) ,
Since : new ( string ) ,
Until : new ( string ) ,
TypeEquals : new ( string ) ,
2022-07-28 15:31:53 +00:00
IncludeCAPI : new ( bool ) ,
2023-01-31 13:47:44 +00:00
OriginEquals : new ( string ) ,
2020-11-30 09:37:17 +00:00
}
2023-01-06 22:14:02 +00:00
var limit = new ( int )
2021-01-15 08:48:39 +00:00
contained := new ( bool )
2023-01-06 22:14:02 +00:00
var printMachine bool
2020-11-30 09:37:17 +00:00
var cmdAlertsList = & cobra . Command {
Use : "list [filters]" ,
Short : "List alerts" ,
Example : ` cscli alerts list
cscli alerts list -- ip 1.2 .3 .4
cscli alerts list -- range 1.2 .3 .0 / 24
cscli alerts list - s crowdsecurity / ssh - bf
cscli alerts list -- type ban ` ,
2021-08-31 13:03:47 +00:00
DisableAutoGenTag : true ,
2023-02-20 14:05:42 +00:00
RunE : func ( cmd * cobra . Command , args [ ] string ) error {
2020-11-30 09:37:17 +00:00
var err error
if err := manageCliDecisionAlerts ( alertListFilter . IPEquals , alertListFilter . RangeEquals ,
alertListFilter . ScopeEquals , alertListFilter . ValueEquals ) ; err != nil {
2022-03-10 12:55:25 +00:00
printHelp ( cmd )
2023-02-20 14:05:42 +00:00
return err
2020-11-30 09:37:17 +00:00
}
if limit != nil {
alertListFilter . Limit = limit
}
if * alertListFilter . Until == "" {
alertListFilter . Until = nil
2022-11-07 09:36:50 +00:00
} else if strings . HasSuffix ( * alertListFilter . Until , "d" ) {
2020-11-30 09:37:17 +00:00
/*time.ParseDuration support hours 'h' as bigger unit, let's make the user's life easier*/
2022-11-07 09:36:50 +00:00
realDuration := strings . TrimSuffix ( * alertListFilter . Until , "d" )
days , err := strconv . Atoi ( realDuration )
if err != nil {
printHelp ( cmd )
2023-02-20 14:05:42 +00:00
return fmt . Errorf ( "can't parse duration %s, valid durations format: 1d, 4h, 4h15m" , * alertListFilter . Until )
2020-11-30 09:37:17 +00:00
}
2022-11-07 09:36:50 +00:00
* alertListFilter . Until = fmt . Sprintf ( "%d%s" , days * 24 , "h" )
2020-11-30 09:37:17 +00:00
}
if * alertListFilter . Since == "" {
alertListFilter . Since = nil
2022-11-07 09:36:50 +00:00
} else if strings . HasSuffix ( * alertListFilter . Since , "d" ) {
2020-11-30 09:37:17 +00:00
/*time.ParseDuration support hours 'h' as bigger unit, let's make the user's life easier*/
2022-11-07 09:36:50 +00:00
realDuration := strings . TrimSuffix ( * alertListFilter . Since , "d" )
days , err := strconv . Atoi ( realDuration )
if err != nil {
printHelp ( cmd )
2023-02-20 14:05:42 +00:00
return fmt . Errorf ( "can't parse duration %s, valid durations format: 1d, 4h, 4h15m" , * alertListFilter . Since )
2020-11-30 09:37:17 +00:00
}
2022-11-07 09:36:50 +00:00
* alertListFilter . Since = fmt . Sprintf ( "%d%s" , days * 24 , "h" )
2020-11-30 09:37:17 +00:00
}
2022-07-28 15:31:53 +00:00
if * alertListFilter . IncludeCAPI {
* alertListFilter . Limit = 0
}
2020-11-30 09:37:17 +00:00
if * alertListFilter . TypeEquals == "" {
alertListFilter . TypeEquals = nil
}
if * alertListFilter . ScopeEquals == "" {
alertListFilter . ScopeEquals = nil
}
if * alertListFilter . ValueEquals == "" {
alertListFilter . ValueEquals = nil
}
if * alertListFilter . ScenarioEquals == "" {
alertListFilter . ScenarioEquals = nil
}
if * alertListFilter . IPEquals == "" {
alertListFilter . IPEquals = nil
}
if * alertListFilter . RangeEquals == "" {
alertListFilter . RangeEquals = nil
}
2023-01-31 13:47:44 +00:00
if * alertListFilter . OriginEquals == "" {
alertListFilter . OriginEquals = nil
}
2021-01-15 08:48:39 +00:00
if contained != nil && * contained {
alertListFilter . Contains = new ( bool )
}
2023-01-31 13:47:44 +00:00
2020-11-30 09:37:17 +00:00
alerts , _ , err := Client . Alerts . List ( context . Background ( ) , alertListFilter )
if err != nil {
2023-02-20 14:05:42 +00:00
return fmt . Errorf ( "unable to list alerts: %v" , err )
2020-11-30 09:37:17 +00:00
}
err = AlertsToTable ( alerts , printMachine )
if err != nil {
2023-02-20 14:05:42 +00:00
return fmt . Errorf ( "unable to list alerts: %v" , err )
2020-11-30 09:37:17 +00:00
}
2023-02-20 14:05:42 +00:00
return nil
2020-11-30 09:37:17 +00:00
} ,
}
cmdAlertsList . Flags ( ) . SortFlags = false
2022-07-28 15:31:53 +00:00
cmdAlertsList . Flags ( ) . BoolVarP ( alertListFilter . IncludeCAPI , "all" , "a" , false , "Include decisions from Central API" )
2020-11-30 09:37:17 +00:00
cmdAlertsList . Flags ( ) . StringVar ( alertListFilter . Until , "until" , "" , "restrict to alerts older than until (ie. 4h, 30d)" )
cmdAlertsList . Flags ( ) . StringVar ( alertListFilter . Since , "since" , "" , "restrict to alerts newer than since (ie. 4h, 30d)" )
cmdAlertsList . Flags ( ) . StringVarP ( alertListFilter . IPEquals , "ip" , "i" , "" , "restrict to alerts from this source ip (shorthand for --scope ip --value <IP>)" )
cmdAlertsList . Flags ( ) . StringVarP ( alertListFilter . ScenarioEquals , "scenario" , "s" , "" , "the scenario (ie. crowdsecurity/ssh-bf)" )
cmdAlertsList . Flags ( ) . StringVarP ( alertListFilter . RangeEquals , "range" , "r" , "" , "restrict to alerts from this range (shorthand for --scope range --value <RANGE/X>)" )
cmdAlertsList . Flags ( ) . StringVar ( alertListFilter . TypeEquals , "type" , "" , "restrict to alerts with given decision type (ie. ban, captcha)" )
cmdAlertsList . Flags ( ) . StringVar ( alertListFilter . ScopeEquals , "scope" , "" , "restrict to alerts of this scope (ie. ip,range)" )
cmdAlertsList . Flags ( ) . StringVarP ( alertListFilter . ValueEquals , "value" , "v" , "" , "the value to match for in the specified scope" )
2023-01-31 13:47:44 +00:00
cmdAlertsList . Flags ( ) . StringVar ( alertListFilter . OriginEquals , "origin" , "" , fmt . Sprintf ( "the value to match for the specified origin (%s ...)" , strings . Join ( types . GetOrigins ( ) , "," ) ) )
2021-01-15 08:48:39 +00:00
cmdAlertsList . Flags ( ) . BoolVar ( contained , "contained" , false , "query decisions contained by range" )
2022-03-16 16:29:31 +00:00
cmdAlertsList . Flags ( ) . BoolVarP ( & printMachine , "machine" , "m" , false , "print machines that sent alerts" )
2020-11-30 09:37:17 +00:00
cmdAlertsList . Flags ( ) . IntVarP ( limit , "limit" , "l" , 50 , "limit size of alerts list table (0 to view all alerts)" )
2023-01-06 22:14:02 +00:00
return cmdAlertsList
}
func NewAlertsDeleteCmd ( ) * cobra . Command {
2020-11-30 09:37:17 +00:00
var ActiveDecision * bool
var AlertDeleteAll bool
2022-10-27 07:07:53 +00:00
var delAlertByID string
2023-01-06 22:14:02 +00:00
contained := new ( bool )
2020-11-30 09:37:17 +00:00
var alertDeleteFilter = apiclient . AlertsDeleteOpts {
ScopeEquals : new ( string ) ,
ValueEquals : new ( string ) ,
ScenarioEquals : new ( string ) ,
IPEquals : new ( string ) ,
RangeEquals : new ( string ) ,
}
var cmdAlertsDelete = & cobra . Command {
Use : "delete [filters] [--all]" ,
Short : ` Delete alerts
/ ! \ This command can be use only on the same machine than the local API . ` ,
Example : ` cscli alerts delete -- ip 1.2 .3 .4
cscli alerts delete -- range 1.2 .3 .0 / 24
cscli alerts delete - s crowdsecurity / ssh - bf " ` ,
2021-08-31 13:03:47 +00:00
DisableAutoGenTag : true ,
2022-04-20 13:44:48 +00:00
Aliases : [ ] string { "remove" } ,
2021-08-31 13:03:47 +00:00
Args : cobra . ExactArgs ( 0 ) ,
2023-02-20 14:05:42 +00:00
PreRunE : func ( cmd * cobra . Command , args [ ] string ) error {
2020-11-30 09:37:17 +00:00
if AlertDeleteAll {
2023-02-20 14:05:42 +00:00
return nil
2020-11-30 09:37:17 +00:00
}
if * alertDeleteFilter . ScopeEquals == "" && * alertDeleteFilter . ValueEquals == "" &&
* alertDeleteFilter . ScenarioEquals == "" && * alertDeleteFilter . IPEquals == "" &&
2022-10-27 07:07:53 +00:00
* alertDeleteFilter . RangeEquals == "" && delAlertByID == "" {
2020-11-30 09:37:17 +00:00
_ = cmd . Usage ( )
2023-02-20 14:05:42 +00:00
return fmt . Errorf ( "at least one filter or --all must be specified" )
2020-11-30 09:37:17 +00:00
}
2023-02-20 14:05:42 +00:00
return nil
2020-11-30 09:37:17 +00:00
} ,
2023-02-20 14:05:42 +00:00
RunE : func ( cmd * cobra . Command , args [ ] string ) error {
2020-11-30 09:37:17 +00:00
var err error
if ! AlertDeleteAll {
if err := manageCliDecisionAlerts ( alertDeleteFilter . IPEquals , alertDeleteFilter . RangeEquals ,
alertDeleteFilter . ScopeEquals , alertDeleteFilter . ValueEquals ) ; err != nil {
2022-03-10 12:55:25 +00:00
printHelp ( cmd )
2023-02-20 14:05:42 +00:00
return err
2020-11-30 09:37:17 +00:00
}
if ActiveDecision != nil {
alertDeleteFilter . ActiveDecisionEquals = ActiveDecision
}
if * alertDeleteFilter . ScopeEquals == "" {
alertDeleteFilter . ScopeEquals = nil
}
if * alertDeleteFilter . ValueEquals == "" {
alertDeleteFilter . ValueEquals = nil
}
if * alertDeleteFilter . ScenarioEquals == "" {
alertDeleteFilter . ScenarioEquals = nil
}
if * alertDeleteFilter . IPEquals == "" {
alertDeleteFilter . IPEquals = nil
}
if * alertDeleteFilter . RangeEquals == "" {
alertDeleteFilter . RangeEquals = nil
}
2021-01-15 08:48:39 +00:00
if contained != nil && * contained {
alertDeleteFilter . Contains = new ( bool )
}
2022-10-07 10:40:30 +00:00
limit := 0
alertDeleteFilter . Limit = & limit
2020-11-30 09:37:17 +00:00
} else {
2021-04-27 09:59:18 +00:00
limit := 0
alertDeleteFilter = apiclient . AlertsDeleteOpts { Limit : & limit }
2020-11-30 09:37:17 +00:00
}
2022-10-27 07:07:53 +00:00
var alerts * models . DeleteAlertsResponse
if delAlertByID == "" {
alerts , _ , err = Client . Alerts . Delete ( context . Background ( ) , alertDeleteFilter )
if err != nil {
2023-02-20 14:05:42 +00:00
return fmt . Errorf ( "unable to delete alerts : %v" , err )
2022-10-27 07:07:53 +00:00
}
} else {
alerts , _ , err = Client . Alerts . DeleteOne ( context . Background ( ) , delAlertByID )
if err != nil {
2023-02-20 14:05:42 +00:00
return fmt . Errorf ( "unable to delete alert: %v" , err )
2022-10-27 07:07:53 +00:00
}
2020-11-30 09:37:17 +00:00
}
log . Infof ( "%s alert(s) deleted" , alerts . NbDeleted )
2023-02-20 14:05:42 +00:00
return nil
2020-11-30 09:37:17 +00:00
} ,
}
cmdAlertsDelete . Flags ( ) . SortFlags = false
cmdAlertsDelete . Flags ( ) . StringVar ( alertDeleteFilter . ScopeEquals , "scope" , "" , "the scope (ie. ip,range)" )
cmdAlertsDelete . Flags ( ) . StringVarP ( alertDeleteFilter . ValueEquals , "value" , "v" , "" , "the value to match for in the specified scope" )
cmdAlertsDelete . Flags ( ) . StringVarP ( alertDeleteFilter . ScenarioEquals , "scenario" , "s" , "" , "the scenario (ie. crowdsecurity/ssh-bf)" )
cmdAlertsDelete . Flags ( ) . StringVarP ( alertDeleteFilter . IPEquals , "ip" , "i" , "" , "Source ip (shorthand for --scope ip --value <IP>)" )
cmdAlertsDelete . Flags ( ) . StringVarP ( alertDeleteFilter . RangeEquals , "range" , "r" , "" , "Range source ip (shorthand for --scope range --value <RANGE>)" )
2022-10-27 07:07:53 +00:00
cmdAlertsDelete . Flags ( ) . StringVar ( & delAlertByID , "id" , "" , "alert ID" )
2020-11-30 09:37:17 +00:00
cmdAlertsDelete . Flags ( ) . BoolVarP ( & AlertDeleteAll , "all" , "a" , false , "delete all alerts" )
2021-01-15 08:48:39 +00:00
cmdAlertsDelete . Flags ( ) . BoolVar ( contained , "contained" , false , "query decisions contained by range" )
2023-01-06 22:14:02 +00:00
return cmdAlertsDelete
}
2020-11-30 09:37:17 +00:00
2023-01-06 22:14:02 +00:00
func NewAlertsInspectCmd ( ) * cobra . Command {
2020-11-30 09:37:17 +00:00
var details bool
var cmdAlertsInspect = & cobra . Command {
2021-08-31 13:03:47 +00:00
Use : ` inspect "alert_id" ` ,
Short : ` Show info about an alert ` ,
Example : ` cscli alerts inspect 123 ` ,
DisableAutoGenTag : true ,
2023-02-20 14:05:42 +00:00
RunE : func ( cmd * cobra . Command , args [ ] string ) error {
2020-11-30 09:37:17 +00:00
if len ( args ) == 0 {
2022-03-10 12:55:25 +00:00
printHelp ( cmd )
2023-02-20 14:05:42 +00:00
return fmt . Errorf ( "missing alert_id" )
2020-11-30 09:37:17 +00:00
}
for _ , alertID := range args {
id , err := strconv . Atoi ( alertID )
if err != nil {
2023-02-20 14:05:42 +00:00
return fmt . Errorf ( "bad alert id %s" , alertID )
2020-11-30 09:37:17 +00:00
}
alert , _ , err := Client . Alerts . GetByID ( context . Background ( ) , id )
if err != nil {
2023-02-20 14:05:42 +00:00
return fmt . Errorf ( "can't find alert with id %s: %s" , alertID , err )
2020-11-30 09:37:17 +00:00
}
switch csConfig . Cscli . Output {
case "human" :
if err := DisplayOneAlert ( alert , details ) ; err != nil {
continue
}
case "json" :
data , err := json . MarshalIndent ( alert , "" , " " )
if err != nil {
2023-02-20 14:05:42 +00:00
return fmt . Errorf ( "unable to marshal alert with id %s: %s" , alertID , err )
2020-11-30 09:37:17 +00:00
}
fmt . Printf ( "%s\n" , string ( data ) )
case "raw" :
data , err := yaml . Marshal ( alert )
if err != nil {
2023-02-20 14:05:42 +00:00
return fmt . Errorf ( "unable to marshal alert with id %s: %s" , alertID , err )
2020-11-30 09:37:17 +00:00
}
fmt . Printf ( "%s\n" , string ( data ) )
}
}
2023-02-20 14:05:42 +00:00
return nil
2020-11-30 09:37:17 +00:00
} ,
}
cmdAlertsInspect . Flags ( ) . SortFlags = false
cmdAlertsInspect . Flags ( ) . BoolVarP ( & details , "details" , "d" , false , "show alerts with events" )
2023-01-06 22:14:02 +00:00
return cmdAlertsInspect
}
2020-11-30 09:37:17 +00:00
2023-01-06 22:14:02 +00:00
func NewAlertsFlushCmd ( ) * cobra . Command {
2021-10-26 11:33:45 +00:00
var maxItems int
var maxAge string
var cmdAlertsFlush = & cobra . Command {
Use : ` flush ` ,
Short : ` Flush alerts
/ ! \ This command can be used only on the same machine than the local API ` ,
Example : ` cscli alerts flush --max-items 1000 --max-age 7d ` ,
DisableAutoGenTag : true ,
2023-02-20 14:05:42 +00:00
RunE : func ( cmd * cobra . Command , args [ ] string ) error {
2021-10-26 11:33:45 +00:00
var err error
if err := csConfig . LoadAPIServer ( ) ; err != nil || csConfig . DisableAPI {
2023-02-20 14:05:42 +00:00
return fmt . Errorf ( "local API is disabled, please run this command on the local API machine" )
2021-10-26 11:33:45 +00:00
}
dbClient , err = database . NewClient ( csConfig . DbConfig )
if err != nil {
2023-02-20 14:05:42 +00:00
return fmt . Errorf ( "unable to create new database client: %s" , err )
2021-10-26 11:33:45 +00:00
}
log . Info ( "Flushing alerts. !! This may take a long time !!" )
err = dbClient . FlushAlerts ( maxAge , maxItems )
if err != nil {
2023-02-20 14:05:42 +00:00
return fmt . Errorf ( "unable to flush alerts: %s" , err )
2021-10-26 11:33:45 +00:00
}
log . Info ( "Alerts flushed" )
2023-02-20 14:05:42 +00:00
return nil
2021-10-26 11:33:45 +00:00
} ,
}
cmdAlertsFlush . Flags ( ) . SortFlags = false
cmdAlertsFlush . Flags ( ) . IntVar ( & maxItems , "max-items" , 5000 , "Maximum number of alert items to keep in the database" )
cmdAlertsFlush . Flags ( ) . StringVar ( & maxAge , "max-age" , "7d" , "Maximum age of alert items to keep in the database" )
2023-01-06 22:14:02 +00:00
return cmdAlertsFlush
2020-11-30 09:37:17 +00:00
}