Skip to content

Commit

Permalink
fix(api): omitempty integration responses fields
Browse files Browse the repository at this point in the history
Our API Server returns responses that can change 100%, this behavior is
making us omit a number of fields if they are empty so that we don't
present them to the end user.

There is a current bug that this change is fixing where if you try to
create a new Lacework Integration with the Go client, the request
generated will send the following body and the API Server will through a
500 Internal Server Error (in the k8s logs, Schema validation failure)
```
{
  "NAME": "Azure Activity Log",
  "TYPE": "AZURE_AL_SEQ",
  "ENABLED": 1,
  "STATE": {
    "ok": false,
    "lastUpdatedTime": "",
    "lastSuccessfulTime": ""
  },
  "DATA": {
    "CREDENTIALS": {},
    "TENANT_ID": "ID",
    "QUEUE_URL": "URL"
  }
}
```

We are avoiding adding the `STATE` field if it is empty so that we send
this request body instead:
```
{
  "NAME": "Azure Activity Log",
  "TYPE": "AZURE_AL_SEQ",
  "ENABLED": 1,
  "DATA": {
    "CREDENTIALS": {},
    "TENANT_ID": "ID",
    "QUEUE_URL": "URL"
  }
}
```

Signed-off-by: Salim Afiune Maya <[email protected]>
  • Loading branch information
afiune committed Apr 22, 2020
1 parent 3b03327 commit 44e2314
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 26 deletions.
30 changes: 15 additions & 15 deletions api/integrations.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,31 +161,31 @@ func (svc *IntegrationsService) listByType(iType integrationType, response inter
}

type commonIntegrationData struct {
IntgGuid string `json:"INTG_GUID,omitempty"`
Name string `json:"NAME"`
CreatedOrUpdatedTime string `json:"CREATED_OR_UPDATED_TIME,omitempty"`
CreatedOrUpdatedBy string `json:"CREATED_OR_UPDATED_BY,omitempty"`
Type string `json:"TYPE"`
Enabled int `json:"ENABLED"`
State state `json:"STATE,omitempty"`
IsOrg int `json:"IS_ORG,omitempty"`
TypeName string `json:"TYPE_NAME,omitempty"`
}

func (iData commonIntegrationData) Status() string {
if iData.Enabled == 1 {
IntgGuid string `json:"INTG_GUID,omitempty"`
Name string `json:"NAME"`
CreatedOrUpdatedTime string `json:"CREATED_OR_UPDATED_TIME,omitempty"`
CreatedOrUpdatedBy string `json:"CREATED_OR_UPDATED_BY,omitempty"`
Type string `json:"TYPE"`
Enabled int `json:"ENABLED"`
State *IntegrationState `json:"STATE,omitempty"`
IsOrg int `json:"IS_ORG,omitempty"`
TypeName string `json:"TYPE_NAME,omitempty"`
}

func (c commonIntegrationData) Status() string {
if c.Enabled == 1 {
return "Enabled"
}
return "Disabled"
}

type state struct {
type IntegrationState struct {
Ok bool `json:"ok"`
LastUpdatedTime string `json:"lastUpdatedTime"`
LastSuccessfulTime string `json:"lastSuccessfulTime"`
}

func (s state) String() string {
func (s IntegrationState) String() string {
if s.Ok {
return "Ok"
}
Expand Down
54 changes: 54 additions & 0 deletions api/integrations_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
package api_test

import (
"encoding/json"
"fmt"
"net/http"
"strings"
Expand Down Expand Up @@ -297,6 +298,48 @@ func TestIntegrationsList(t *testing.T) {
}
}

func TestIntegrationsGetWithNoState(t *testing.T) {
var (
intgGUID = "MY_MOCKED_ID"
apiPath = fmt.Sprintf("external/integrations/%s", intgGUID)
fakeServer = lacework.MockServer()
)
fakeServer.MockAPI(apiPath, func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, "GET", r.Method, "Get should be a GET method")
fmt.Fprintf(w, generateIntegrationsResponse(minimalIntegration(intgGUID)))
})
defer fakeServer.Close()

c, err := api.NewClient("test",
api.WithToken("TOKEN"),
api.WithURL(fakeServer.URL()),
)
assert.Nil(t, err)

response, err := c.Integrations.Get(intgGUID)
assert.Nil(t, err)
assert.NotNil(t, response)
assert.True(t, response.Ok)
if assert.Equal(t, 1, len(response.Data)) {
resData := response.Data[0]
assert.Equal(t, intgGUID, resData.IntgGuid)
assert.Equal(t, "minimal_integration", resData.Name)
// @afiune the only rist here is that if the caller tries to access the state
// directly before checking that there is actually an state, the go program
// will panic
assert.Nil(t, resData.State)

// verify the generate json blob from the response
jsonBlob, err := json.Marshal(resData)
if assert.Nil(t, err) {
assert.Equal(t,
"{\"INTG_GUID\":\"MY_MOCKED_ID\",\"NAME\":\"minimal_integration\",\"TYPE\":\"MINIMAL\",\"ENABLED\":0,\"DATA\":{}}",
string(jsonBlob),
"unexpected json blob")
}
}
}

func generateIntegrations(guids []string, iType string) string {
integrations := make([]string, len(guids))
for i, guid := range guids {
Expand Down Expand Up @@ -344,3 +387,14 @@ func singleVanillaIntegration(id string, iType string, data string) string {
}
`
}

func minimalIntegration(id string) string {
return `
{
"INTG_GUID": "` + id + `",
"NAME": "minimal_integration",
"TYPE": "MINIMAL",
"DATA": {}
}
`
}
22 changes: 11 additions & 11 deletions api/vulnerabilities.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ type VulContainerReport struct {

// ScanStatus is a property that will appear when the vulnerability scan finished
// running, this status indicates whether the scan finished successfully or not
ScanStatus string `json:"scan_status"`
ScanStatus string `json:"scan_status,omitempty"`

// @afiune why we can't parse the time?
//LastEvaluationTime time.Time `json:"last_evaluation_time"`
Expand Down Expand Up @@ -252,16 +252,16 @@ type vulContainerPackage struct {
Vulnerabilities []containerVulnerability `json:"vulnerabilities"`

// @afiune maybe these fields are host related information and not container
FixAvailable string `json:"fix_available"`
FixedVersion string `json:"fixed_version"`
HostCount string `json:"host_count"`
Severity string `json:"severity"`
Status string `json:"status"`
CveLink string `json:"cve_link"`
CveScore string `json:"cve_score"`
CvssV3Score string `json:"cvss_v3_score"`
CvssV2Score string `json:"cvss_v2_score"`
FirstSeenTime string `json:"first_seen_time"`
FixAvailable string `json:"fix_available,omitempty"`
FixedVersion string `json:"fixed_version,omitempty"`
HostCount string `json:"host_count,omitempty"`
Severity string `json:"severity,omitempty"`
Status string `json:"status,omitempty"`
CveLink string `json:"cve_link,omitempty"`
CveScore string `json:"cve_score,omitempty"`
CvssV3Score string `json:"cvss_v3_score,omitempty"`
CvssV2Score string `json:"cvss_v2_score,omitempty"`
FirstSeenTime string `json:"first_seen_time,omitempty"`
}

type containerVulnerability struct {
Expand Down

0 comments on commit 44e2314

Please sign in to comment.