From 31457fdc51ef0477e4e28cc830827a9b081db7b1 Mon Sep 17 00:00:00 2001 From: Salim Afiune Maya Date: Mon, 6 Jul 2020 11:38:48 -0600 Subject: [PATCH] feat(api): new Vulnerabilities.ListEvaluations() func This new feature is adding two new functions `ListEvalutions()` and `ListEvaluationsDateRange()` to the `Vulnerabilities` service inside the Go API client, these endpoints wrap the new API endpoint: `/external/vulnerabilities/container/GetEvaluationsForDateRange` The functions will allow users to lists all evaluations in an account. An example: ```go package main import ( "fmt" "log" "github.com/lacework/go-sdk/api" ) func main() { lacework, err := api.NewClient("account") if err != nil { log.Fatal(err) } fmt.Println(lacework.Vulnerabilities.ListEvaluations()) } ``` Contributes to https://github.com/lacework/go-sdk/issues/156 Signed-off-by: Salim Afiune Maya --- api/api.go | 1 + api/events.go | 14 +- api/events_test.go | 4 +- api/vulnerabilities.go | 91 ++++++++ api/vulnerabilities_test.go | 406 +++++++++++++++++++++++++++++++++++- cli/cmd/event.go | 2 +- 6 files changed, 510 insertions(+), 8 deletions(-) diff --git a/api/api.go b/api/api.go index 3e5ca38b5..6786c44e2 100644 --- a/api/api.go +++ b/api/api.go @@ -35,6 +35,7 @@ const ( apiVulnerabilitiesScanStatus = "external/vulnerabilities/container/reqId/%s" apiVulnerabilitiesReportFromID = "external/vulnerabilities/container/imageId/%s" apiVulnerabilitiesReportFromDigest = "external/vulnerabilities/container/imageDigest/%s" + apiVulEvaluationsForDateRange = "external/vulnerabilities/container/GetEvaluationsForDateRange" apiComplianceAwsLatestReport = "external/compliance/aws/GetLatestComplianceReport?AWS_ACCOUNT_ID=%s" apiComplianceGcpLatestReport = "external/compliance/gcp/GetLatestComplianceReport?GCP_ORG_ID=%s&GCP_PROJ_ID=%s" diff --git a/api/events.go b/api/events.go index 88723ee50..5f055e0e6 100644 --- a/api/events.go +++ b/api/events.go @@ -31,17 +31,23 @@ type EventsService struct { client *Client } -// List leverages ListRange and returns a list of events from the last 7 days +// List leverages ListDateRange and returns a list of events from the last 7 days func (svc *EventsService) List() (EventsResponse, error) { var ( now = time.Now().UTC() from = now.AddDate(0, 0, -7) // 7 days from now ) - return svc.ListRange(from, now) + return svc.ListDateRange(from, now) } -// ListRange returns a list of Lacework events during the specified date range +// TODO @afiune (to-be-deprecated) https://github.com/lacework/go-sdk/issues/161 +func (svc *EventsService) ListRange(start, end time.Time) (EventsResponse, error) { + svc.client.log.Warn("ListRange() is DEPRECATED: use ListDateRange() instead") + return svc.ListDateRange(start, end) +} + +// ListDateRange returns a list of Lacework events during the specified date range // // Requirements and specifications: // * The dates format should be: yyyy-MM-ddTHH:mm:ssZ (example 2019-07-11T21:11:00Z) @@ -49,7 +55,7 @@ func (svc *EventsService) List() (EventsResponse, error) { // * The difference between the START_TIME and END_TIME must not be greater than 7 days // * The START_TIME must be less than or equal to three months from current date // * The number of records produced is limited to 5000 -func (svc *EventsService) ListRange(start, end time.Time) ( +func (svc *EventsService) ListDateRange(start, end time.Time) ( response EventsResponse, err error, ) { diff --git a/api/events_test.go b/api/events_test.go index 09d3bbdc0..239fa8d34 100644 --- a/api/events_test.go +++ b/api/events_test.go @@ -58,7 +58,7 @@ func TestEventsListRangeError(t *testing.T) { // a tipical user input error could be that they provide the // date range the other way around, from should be the start // time, and now should be the end time - response, err := c.Events.ListRange(now, from) + response, err := c.Events.ListDateRange(now, from) assert.Empty(t, response) if assert.NotNil(t, err) { assert.Equal(t, @@ -73,7 +73,7 @@ func TestEventsList(t *testing.T) { fakeServer.MockAPI( "external/events/GetEventsForDateRange", func(w http.ResponseWriter, r *http.Request) { - assert.Equal(t, "GET", r.Method, "List or ListRange should be a GET method") + assert.Equal(t, "GET", r.Method, "List or ListDateRange should be a GET method") start, ok := r.URL.Query()["START_TIME"] if assert.True(t, ok, diff --git a/api/vulnerabilities.go b/api/vulnerabilities.go index 1464c4499..81b2ec885 100644 --- a/api/vulnerabilities.go +++ b/api/vulnerabilities.go @@ -19,10 +19,14 @@ package api import ( + "encoding/json" "fmt" + "strconv" "strings" + "time" "github.com/lacework/go-sdk/internal/array" + "github.com/pkg/errors" ) // VulnerabilitiesService is a service that interacts with the vulnerabilities @@ -238,3 +242,90 @@ type containerVulnerability struct { FixVersion string `json:"fix_version"` Metadata map[string]interface{} `json:"metadata"` } + +// ListEvaluations leverages ListEvaluationsDateRange and returns a list of evaluations from the last 7 days +func (svc *VulnerabilitiesService) ListEvaluations() (VulContainerEvaluationsResponse, error) { + var ( + now = time.Now().UTC() + from = now.AddDate(0, 0, -7) // 7 days from now + ) + + return svc.ListEvaluationsDateRange(from, now) +} + +// ListEvaluationsDateRange returns a list of container evaluations during the specified date range +func (svc *VulnerabilitiesService) ListEvaluationsDateRange(start, end time.Time) ( + response VulContainerEvaluationsResponse, + err error, +) { + if start.After(end) { + err = errors.New("data range should have a start time before the end time") + return + } + + apiPath := fmt.Sprintf( + "%s?START_TIME=%s&END_TIME=%s", + apiVulEvaluationsForDateRange, + start.UTC().Format(time.RFC3339), + end.UTC().Format(time.RFC3339), + ) + err = svc.client.RequestDecoder("GET", apiPath, nil, &response) + return +} + +type VulContainerEvaluationsResponse struct { + Data []VulContainerEvaluation `json:"data"` + Ok bool `json:"ok"` + Message string `json:"message"` +} + +// time type to parse the returned 16 digit time in milliseconds +type Json16DigitTime time.Time + +// imeplement Marshal and Unmarshal interfaces +func (j *Json16DigitTime) UnmarshalJSON(b []byte) error { + ms, _ := strconv.Atoi(string(b)) + t := time.Unix(0, int64(ms)*int64(time.Millisecond)) + *j = Json16DigitTime(t) + return nil +} + +func (j Json16DigitTime) MarshalJSON() ([]byte, error) { + return json.Marshal(j) +} + +// A few format functions for printing and manipulating the custom date +func (j Json16DigitTime) ToTime() time.Time { + return time.Time(j) +} +func (j Json16DigitTime) Format(s string) string { + return j.ToTime().Format(s) +} +func (j Json16DigitTime) UTC() time.Time { + return j.ToTime().UTC() +} + +type VulContainerEvaluation struct { + EvalGuid string `json:"eval_guid"` + EvalStatus string `json:"eval_status"` + EvalType string `json:"eval_type"` + ImageCreatedTime Json16DigitTime `json:"image_created_time"` + ImageDigest string `json:"image_digest"` + ImageID string `json:"image_id"` + ImageNamespace string `json:"image_namespace"` + ImageRegistry string `json:"image_registry"` + ImageRepo string `json:"image_repo"` + ImageScanErrorMsg string `json:"image_scan_error_msg"` + ImageScanStatus string `json:"image_scan_status"` + ImageScanTime Json16DigitTime `json:"image_scan_time"` + ImageSize string `json:"image_size"` + ImageTags []string `json:"image_tags"` + NdvContainers string `json:"ndv_containers"` + NumFixes string `json:"num_fixes"` + NumVulnerabilitiesSeverity1 string `json:"num_vulnerabilities_severity_1"` + NumVulnerabilitiesSeverity2 string `json:"num_vulnerabilities_severity_2"` + NumVulnerabilitiesSeverity3 string `json:"num_vulnerabilities_severity_3"` + NumVulnerabilitiesSeverity4 string `json:"num_vulnerabilities_severity_4"` + NumVulnerabilitiesSeverity5 string `json:"num_vulnerabilities_severity_5"` + StartTime Json16DigitTime `json:"start_time"` +} diff --git a/api/vulnerabilities_test.go b/api/vulnerabilities_test.go index f23ec6660..8f251b5bc 100644 --- a/api/vulnerabilities_test.go +++ b/api/vulnerabilities_test.go @@ -22,10 +22,12 @@ import ( "fmt" "net/http" "testing" + "time" + + "github.com/stretchr/testify/assert" "github.com/lacework/go-sdk/api" "github.com/lacework/go-sdk/internal/lacework" - "github.com/stretchr/testify/assert" ) func TestVulnerabilitiesScan(t *testing.T) { @@ -124,6 +126,273 @@ func TestVulnerabilitiesScan404Error(t *testing.T) { } } +func TestVulnerabilitiesScanStatus(t *testing.T) { + expectedStatus := "Scanning" + expectedRequestID := "efd151c8-abcd-1234-5678-13e8cca93584" + fakeServer := lacework.MockServer() + fakeServer.MockAPI("external/vulnerabilities/container/reqId/"+expectedRequestID, + func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, "GET", r.Method, "ScanStatus should be a GET method") + fmt.Fprintf(w, vulScanStatusJsonResponse(expectedStatus)) + }, + ) + defer fakeServer.Close() + + c, err := api.NewClient("test", + api.WithToken("TOKEN"), + api.WithURL(fakeServer.URL()), + ) + assert.Nil(t, err) + + response, err := c.Vulnerabilities.ScanStatus(expectedRequestID) + assert.Nil(t, err) + if assert.NotNil(t, response) { + assert.Equal(t, expectedStatus, response.CheckStatus()) + } +} + +func TestVulnerabilitiesScanStatusError(t *testing.T) { + expectedRequestID := "efd151c8-abcd-1234-5678-13e8cca93584" + fakeServer := lacework.MockServer() + fakeServer.MockAPI("external/vulnerabilities/container/reqId/"+expectedRequestID, + func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, "GET", r.Method, "ScanStatus should be a GET method") + fmt.Fprintf(w, vulScanErrorJsonResponse("something happened")) + }, + ) + defer fakeServer.Close() + + c, err := api.NewClient("test", + api.WithToken("TOKEN"), + api.WithURL(fakeServer.URL()), + ) + assert.Nil(t, err) + + response, err := c.Vulnerabilities.ScanStatus(expectedRequestID) + assert.Nil(t, err) + if assert.NotNil(t, response) { + assert.Equal(t, "there is a problem with the vulnerability scan: something happened", response.CheckStatus()) + } +} + +func TestVulnerabilitiesReportFromID(t *testing.T) { + var ( + imageID = "sha256:01f5882aae5ea55e0dc1b49330b0a83e6be386acd502e6c3ff4b031a227c0dac" + digestID = "sha256:167ec3ad6d0368acc9d64b1d857c0208ac641da83209498d1f3da9f38c9ae9ec" + fakeServer = lacework.MockServer() + ) + fakeServer.MockAPI("external/vulnerabilities/container/imageId/"+imageID, + func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, "GET", r.Method, "ReportFromID should be a GET method") + fmt.Fprintf(w, vulReportJsonResponse(imageID, digestID)) + }, + ) + defer fakeServer.Close() + + c, err := api.NewClient("test", + api.WithToken("TOKEN"), + api.WithURL(fakeServer.URL()), + ) + assert.Nil(t, err) + + response, err := c.Vulnerabilities.ReportFromID(imageID) + assert.Nil(t, err) + var zero int32 = 0 + var uno int32 = 1 + if assert.NotNil(t, response) { + assert.Equal(t, "Success", response.CheckStatus()) + assert.Equal(t, digestID, response.Data.Image.ImageInfo.ImageDigest) + assert.Equal(t, imageID, response.Data.Image.ImageInfo.ImageID) + assert.Equal(t, "test/repo", response.Data.Image.ImageInfo.Repository) + assert.Equal(t, []string{"latest"}, response.Data.Image.ImageInfo.Tags) + assert.Equal(t, uno, response.Data.TotalVulnerabilities) + assert.Equal(t, zero, response.Data.CriticalVulnerabilities) + assert.Equal(t, uno, response.Data.HighVulnerabilities) + assert.Equal(t, zero, response.Data.MediumVulnerabilities) + assert.Equal(t, zero, response.Data.LowVulnerabilities) + assert.Equal(t, zero, response.Data.InfoVulnerabilities) + assert.Equal(t, uno, response.Data.FixableVulnerabilities) + + assert.Equal(t, uno, response.Data.VulFixableCount("High")) + assert.Equal(t, zero, response.Data.VulFixableCount("Info")) + } +} + +func TestVulnerabilitiesReportFromIDNotFound(t *testing.T) { + fakeServer := lacework.MockServer() + defer fakeServer.Close() + + c, err := api.NewClient("test", + api.WithToken("TOKEN"), + api.WithURL(fakeServer.URL()), + ) + assert.Nil(t, err) + + response, err := c.Vulnerabilities.ReportFromID("sha256:01f5882aae5ea55e0dc1b49330b0a83e6be386acd502e6c3ff4b031a227c0dac") + if assert.NotNil(t, err) { + assert.Contains(t, err.Error(), "404 page not found") + } + if assert.NotNil(t, response) { + assert.False(t, response.Ok) + assert.Empty(t, response.Data) + } +} + +func TestVulnerabilitiesReportFromDigest(t *testing.T) { + var ( + imageID = "sha256:01f5882aae5ea55e0dc1b49330b0a83e6be386acd502e6c3ff4b031a227c0dac" + digestID = "sha256:167ec3ad6d0368acc9d64b1d857c0208ac641da83209498d1f3da9f38c9ae9ec" + fakeServer = lacework.MockServer() + ) + fakeServer.MockAPI("external/vulnerabilities/container/imageDigest/"+digestID, + func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, "GET", r.Method, "ReportFromDigest should be a GET method") + fmt.Fprintf(w, vulReportJsonResponse(imageID, digestID)) + }, + ) + defer fakeServer.Close() + + c, err := api.NewClient("test", + api.WithToken("TOKEN"), + api.WithURL(fakeServer.URL()), + ) + assert.Nil(t, err) + + response, err := c.Vulnerabilities.ReportFromDigest(digestID) + assert.Nil(t, err) + var zero int32 = 0 + var uno int32 = 1 + if assert.NotNil(t, response) { + assert.Equal(t, "Success", response.CheckStatus()) + assert.Equal(t, digestID, response.Data.Image.ImageInfo.ImageDigest) + assert.Equal(t, imageID, response.Data.Image.ImageInfo.ImageID) + assert.Equal(t, "test/repo", response.Data.Image.ImageInfo.Repository) + assert.Equal(t, []string{"latest"}, response.Data.Image.ImageInfo.Tags) + assert.Equal(t, uno, response.Data.TotalVulnerabilities) + assert.Equal(t, zero, response.Data.CriticalVulnerabilities) + assert.Equal(t, uno, response.Data.HighVulnerabilities) + assert.Equal(t, zero, response.Data.MediumVulnerabilities) + assert.Equal(t, zero, response.Data.LowVulnerabilities) + assert.Equal(t, zero, response.Data.InfoVulnerabilities) + assert.Equal(t, uno, response.Data.FixableVulnerabilities) + + assert.Equal(t, uno, response.Data.VulFixableCount("High")) + assert.Equal(t, zero, response.Data.VulFixableCount("Info")) + } +} + +func TestVulnerabilitiesListEvaluations(t *testing.T) { + fakeServer := lacework.MockServer() + fakeServer.MockAPI( + "external/vulnerabilities/container/GetEvaluationsForDateRange", + func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, "GET", r.Method, "ListEvaluations or ListEvaluationsDateRange should be a GET method") + + start, ok := r.URL.Query()["START_TIME"] + if assert.True(t, ok, + "START_TIME parameter missing") { + + end, ok := r.URL.Query()["END_TIME"] + if assert.True(t, ok, + "END_TIME parameter missing") { + + // verify that start and end times are 7 days apart + // and that the start time is before the end time + startTime, err := time.Parse(time.RFC3339, start[0]) + assert.Nil(t, err) + endTime, err := time.Parse(time.RFC3339, end[0]) + assert.Nil(t, err) + + assert.True(t, + startTime.Before(endTime), + "the start time should not be after the end time", + ) + assert.True(t, + startTime.AddDate(0, 0, 7).Equal(endTime), + "the data range is not 7 days apart", + ) + fmt.Fprintf(w, vulContainerEvaluationsResponse(startTime.UnixNano())) + } + } + }, + ) + defer fakeServer.Close() + + c, err := api.NewClient("test", + api.WithToken("TOKEN"), + api.WithURL(fakeServer.URL()), + ) + assert.Nil(t, err) + + response, err := c.Vulnerabilities.ListEvaluations() + assert.Nil(t, err) + if assert.NotNil(t, response) { + if assert.Equal(t, 2, len(response.Data)) { + eval := response.Data[0] + assert.Equal(t, "PASSED", eval.EvalStatus) + assert.Equal(t, "EvalBySQL", eval.EvalType) + assert.Equal(t, "492c2f55cf3073e3978138e599bd2074", eval.EvalGuid) + assert.Equal(t, "sha256:4393dcffe989b8785a15c696ae5201b8f82744f7f63743ab470e4ca956dad660", eval.ImageDigest) + assert.Equal(t, "sha256:14a3076d0885a4ab36d52a6834583bc07b6530f7940bff378a67d33c2ee0002b", eval.ImageID) + assert.Equal(t, "2020-06-25T21:01:18Z", eval.ImageCreatedTime.UTC().Format(time.RFC3339)) + assert.Equal(t, "2020-07-01T16:00:30Z", eval.ImageScanTime.ToTime().UTC().Format(time.RFC3339)) + assert.Equal(t, "2020-07-01T16:00:51Z", eval.StartTime.UTC().Format(time.RFC3339)) + assert.Equal(t, "index.docker.io", eval.ImageRegistry) + assert.Equal(t, "techallylw/lacework-cli", eval.ImageRepo) + assert.Equal(t, "Success", eval.ImageScanStatus) + assert.Equal(t, "", eval.ImageNamespace) + assert.Equal(t, "", eval.ImageScanErrorMsg) + assert.Equal(t, "102087642", eval.ImageSize) + assert.Equal(t, []string{"centos-8"}, eval.ImageTags) + assert.Equal(t, "0", eval.NdvContainers) + assert.Equal(t, "2", eval.NumFixes) + assert.Equal(t, "0", eval.NumVulnerabilitiesSeverity1) + assert.Equal(t, "2", eval.NumVulnerabilitiesSeverity2) + assert.Equal(t, "0", eval.NumVulnerabilitiesSeverity3) + assert.Equal(t, "0", eval.NumVulnerabilitiesSeverity4) + assert.Equal(t, "0", eval.NumVulnerabilitiesSeverity5) + + eval = response.Data[1] + assert.Equal(t, "2020-04-17T23:13:43Z", eval.ImageCreatedTime.UTC().Format(time.RFC3339)) + assert.Equal(t, "2020-04-17T23:14:07Z", eval.ImageScanTime.ToTime().UTC().Format(time.RFC3339)) + assert.Equal(t, "2020-07-02T02:19:06Z", eval.StartTime.UTC().Format(time.RFC3339)) + assert.Equal(t, "index.docker.io", eval.ImageRegistry) + assert.Equal(t, "techallylw/lacework-cli", eval.ImageRepo) + assert.Equal(t, "Unsupported", eval.ImageScanStatus) + assert.Equal(t, "Image Distro is not supported.", eval.ImageScanErrorMsg) + assert.Equal(t, []string{"latest"}, eval.ImageTags) + assert.Equal(t, "0", eval.NdvContainers) + assert.Equal(t, "", eval.NumFixes) + assert.Equal(t, "", eval.NumVulnerabilitiesSeverity1) + assert.Equal(t, "", eval.NumVulnerabilitiesSeverity2) + assert.Equal(t, "", eval.NumVulnerabilitiesSeverity3) + assert.Equal(t, "", eval.NumVulnerabilitiesSeverity4) + assert.Equal(t, "", eval.NumVulnerabilitiesSeverity5) + } + } +} + +func TestVulnerabilitiesListEvaluationsDateRangeError(t *testing.T) { + var ( + now = time.Now().UTC() + from = now.AddDate(0, 0, -7) // 7 days from now + c, err = api.NewClient("test", api.WithToken("TOKEN")) + ) + assert.Nil(t, err) + + // a tipical user input error could be that they provide the + // date range the other way around, from should be the start + // time, and now should be the end time + response, err := c.Vulnerabilities.ListEvaluationsDateRange(now, from) + assert.Empty(t, response) + if assert.NotNil(t, err) { + assert.Equal(t, + "data range should have a start time before the end time", + err.Error(), "error message mismatch", + ) + } +} + func vulScanJsonResponse(reqID, status string) string { return ` { @@ -133,6 +402,78 @@ func vulScanJsonResponse(reqID, status string) string { } ` } + +func vulScanStatusJsonResponse(status string) string { + return ` + { + "data": { "scan_status": "` + status + `" }, + "ok": true, + "message": "SUCCESS" + } + ` +} + +func vulReportJsonResponse(id, digest string) string { + return ` + { + "data": { + "image": { + "image_info": { + "image_digest": "` + digest + `", + "image_id": "` + id + `", + "registry": "index.docker.io", + "repository": "test/repo", + "size": 102087642, + "tags": ["latest"] + }, + "image_layers": [ + { + "hash": "sha256:6910e5a164f725142d77994b247ba20040477fbab49a721bdbe8d61cf855ac23", + "created_by": "ADD file:84700c11fcc969ac08ef25f115513d76c7b72a4118c01fbc86ef0a6056fdebeb in / ", + "packages": [ + { + "name": "bind", + "namespace": "centos:8", + "version": "32:9.11.13-3.el8", + "vulnerabilities": [ + { + "name": "CVE-2020-8617", + "description": "description of the vulnerability", + "severity": "high", + "metadata": { + "NVD": { + "CVSSv3": { + "Score": 7.5, + "ExploitabilityScore": 3.9, + "ImpactScore": 3.6, + "Vectors": "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H" + }, + "CVSSv2": { + "Score": 5, + "PublishedDateTime": "2020-05-19T14:15Z", + "Vectors": "AV:N/AC:L/Au:N/C:N/I:N/A:P" + } + } + }, + "fix_version": "32:9.11.13-5.el8_2" + } + ] + } + ] + } + ] + }, + "scan_status": "Success", + "total_vulnerabilities": 1, + "high_vulnerabilities": 1, + "fixable_vulnerabilities": 1 + }, + "ok": true, + "message": "SUCCESS" +} + ` +} + func vulScanErrorJsonResponse(message string) string { return ` { @@ -142,3 +483,66 @@ func vulScanErrorJsonResponse(message string) string { } ` } + +func vulContainerEvaluationsResponse(t int64) string { + return ` +{ + "data": [ + { + "EVAL_GUID": "492c2f55cf3073e3978138e599bd2074", + "EVAL_STATUS": "PASSED", + "EVAL_TYPE": "EvalBySQL", + "IMAGE_CREATED_TIME": 1593118878546, + "IMAGE_DIGEST": "sha256:4393dcffe989b8785a15c696ae5201b8f82744f7f63743ab470e4ca956dad660", + "IMAGE_ID": "sha256:14a3076d0885a4ab36d52a6834583bc07b6530f7940bff378a67d33c2ee0002b", + "IMAGE_NAMESPACE": null, + "IMAGE_REGISTRY": "index.docker.io", + "IMAGE_REPO": "techallylw/lacework-cli", + "IMAGE_SCAN_ERROR_MSG": "", + "IMAGE_SCAN_STATUS": "Success", + "IMAGE_SCAN_TIME": 1593619230613, + "IMAGE_SIZE": "102087642", + "IMAGE_TAGS": [ + "centos-8" + ], + "NDV_CONTAINERS": "0", + "NUM_FIXES": "2", + "NUM_VULNERABILITIES_SEVERITY_1": "0", + "NUM_VULNERABILITIES_SEVERITY_2": "2", + "NUM_VULNERABILITIES_SEVERITY_3": "0", + "NUM_VULNERABILITIES_SEVERITY_4": "0", + "NUM_VULNERABILITIES_SEVERITY_5": "0", + "START_TIME": 1593619251414 + }, + { + "EVAL_GUID": "6c590a95af27068ff7cec5f327044ce9", + "EVAL_STATUS": "PASSED", + "EVAL_TYPE": "EvalBySQL", + "IMAGE_CREATED_TIME": 1587165223000, + "IMAGE_DIGEST": "sha256:412e1e517c9a6bc2dbcd7bcaaaf5bc09d139ab6b1d0d841c23515a1add1a6eb5", + "IMAGE_ID": "sha256:b24f6152db4a18a12a3ba60d298bb3ef5004e8e2c573b91327bf2c7ddc0f4b12", + "IMAGE_NAMESPACE": null, + "IMAGE_REGISTRY": "index.docker.io", + "IMAGE_REPO": "techallylw/lacework-cli", + "IMAGE_SCAN_ERROR_MSG": "Image Distro is not supported.", + "IMAGE_SCAN_STATUS": "Unsupported", + "IMAGE_SCAN_TIME": 1587165247448, + "IMAGE_SIZE": "7341696", + "IMAGE_TAGS": [ + "latest" + ], + "NDV_CONTAINERS": "0", + "NUM_FIXES": null, + "NUM_VULNERABILITIES_SEVERITY_1": null, + "NUM_VULNERABILITIES_SEVERITY_2": null, + "NUM_VULNERABILITIES_SEVERITY_3": null, + "NUM_VULNERABILITIES_SEVERITY_4": null, + "NUM_VULNERABILITIES_SEVERITY_5": null, + "START_TIME": 1593656346316 + } + ], + "message": "SUCCESS", + "ok": true +} +` +} diff --git a/cli/cmd/event.go b/cli/cmd/event.go index 11a2727ad..f04a4363d 100644 --- a/cli/cmd/event.go +++ b/cli/cmd/event.go @@ -76,7 +76,7 @@ time range.`, cli.Log.Infow("requesting list of events from custom time range", "start_time", start, "end_time", end, ) - response, err = cli.LwApi.Events.ListRange(start, end) + response, err = cli.LwApi.Events.ListDateRange(start, end) } else { cli.Log.Info("requesting list of events from the last 7 days") response, err = cli.LwApi.Events.List()