From 8f75c78d222f3fa00d24cf41e8d1e712f6600122 Mon Sep 17 00:00:00 2001 From: Salim Afiune Maya Date: Thu, 23 Apr 2020 14:14:36 -0600 Subject: [PATCH] feat(cli): new event show command Adding a new `show` sub-command to the `event` command that will show the details of a specific event. Example: Human readable output ``` $ lacework event show 5 EVENT ID | TYPE | ACTOR | MODEL | START TIME | END TIME -----------+----------------------------------+---------------+------------------+----------------------+----------------------- 5 | CloudStorageIAMPermissionChanged | GcpAuditTrail | GcpAuditTrailCep | 2020-04-17T19:00:00Z | 2020-04-17T20:00:00Z ``` Example: Machine/JSON format ``` $ lacework event show 5 --json { "end_time": "2020-04-17T20:00:00Z", "entity_map": { "resource": [ { "name": "gcs_bucket.location", "value": "us" }, { "name": "gcs_bucket.project_id", "value": "gcr-jenkins-sandbox-1234" }, { "name": "gcs_bucket.bucket_name", "value": "us.artifacts.gcr-jenkins-sandbox-1234.appspot.com" } ] }, "event_actor": "GcpAuditTrail", "event_id": "5", "event_model": "GcpAuditTrailCep", "event_type": "CloudStorageIAMPermissionChanged", "start_time": "2020-04-17T19:00:00Z" } ``` Closes https://github.com/lacework/go-sdk/issues/68 Signed-off-by: Salim Afiune Maya --- cli/cmd/event.go | 68 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 64 insertions(+), 4 deletions(-) diff --git a/cli/cmd/event.go b/cli/cmd/event.go index 176e12300..f90d3891d 100644 --- a/cli/cmd/event.go +++ b/cli/cmd/event.go @@ -52,11 +52,13 @@ var ( return errors.Wrap(err, "unable to generate api client") } + cli.Log.Info("requesting list of events") response, err := lacework.Events.List() if err != nil { return errors.Wrap(err, "unable to get events") } + cli.Log.Debugw("events", "raw", response) // Sort the events from the response by severity sort.Slice(response.Events, func(i, j int) bool { return response.Events[i].Severity < response.Events[j].Severity @@ -74,19 +76,48 @@ var ( // eventShowCmd represents the show sub-command inside the event command eventShowCmd = &cobra.Command{ Use: "show ", - Short: "Create an external integrations", + Short: "Show details about an specific event", Args: cobra.ExactArgs(1), - RunE: func(_ *cobra.Command, _ []string) error { + RunE: func(_ *cobra.Command, args []string) error { + lacework, err := api.NewClient(cli.Account, + api.WithLogLevel(cli.LogLevel), + api.WithApiKeys(cli.KeyID, cli.Secret), + ) + if err != nil { + return errors.Wrap(err, "unable to generate api client") + } + + cli.Log.Infow("requesting event details", "event_id", args[0]) + response, err := lacework.Events.Details(args[0]) + if err != nil { + return errors.Wrap(err, "unable to get event details") + } + + cli.Log.Debugw("event details", + "event_id", args[0], + "raw", response, + ) + if len(response.Events) == 0 { + return errors.Errorf("there are no details about the event '%s'", args[0]) + } + + // @afiune why do we have an array of events when we ask for details + // about a single event? Let us use the first one for now + if cli.JSONOutput() { + return cli.OutputJSON(response.Events[0]) + } + + cli.OutputHuman(eventDetailsToTableReport(response.Events[0])) return nil }, } ) func init() { - // add the integration command + // add the event command rootCmd.AddCommand(eventCmd) - // add sub-commands to the integration command + // add sub-commands to the event command eventCmd.AddCommand(eventListCmd) eventCmd.AddCommand(eventShowCmd) } @@ -124,3 +155,32 @@ func eventsToTable(events []api.Event) [][]string { } return out } + +func eventDetailsToTableReport(details api.EventDetails) string { + var ( + eventDetailsReport = &strings.Builder{} + table = tablewriter.NewWriter(eventDetailsReport) + ) + + table.SetHeader([]string{ + "Event ID", + "Type", + "Actor", + "Model", + "Start Time", + "End Time", + }) + table.SetBorder(false) + // TODO @afiune how do we add/display the EntityMap field + table.Append([]string{ + details.EventID, + details.EventType, + details.EventActor, + details.EventModel, + details.StartTime.UTC().Format(time.RFC3339), + details.EndTime.UTC().Format(time.RFC3339), + }) + table.Render() + + return eventDetailsReport.String() +}