Skip to content

Commit

Permalink
new(func): create and get single GCP integration
Browse files Browse the repository at this point in the history
  • Loading branch information
mjunglw committed Mar 13, 2020
1 parent 02d2da8 commit 052a771
Show file tree
Hide file tree
Showing 3 changed files with 219 additions and 7 deletions.
5 changes: 3 additions & 2 deletions api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ import "fmt"

const (
//apiIntegrationType = "external/integrations/type/%s/"
apiIntegrations = "external/integrations"
apiTokens = "access/tokens"
apiIntegrations = "external/integrations"
apiIntegrationByGUID = "external/integrations/%s"
apiTokens = "access/tokens"
)

// WithApiV2 configures the client to use the API version 2 (/api/v2)
Expand Down
103 changes: 99 additions & 4 deletions api/integrations.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,61 @@ import (
"strings"
)

type integrationType int

const (
// awsCFG - AWS Config integration type
// awsCFG integrationType = iota

// awsCT - AWS CloudTrail integration type
// awsCT

// gcpCFG - GCP Config integration type
gcpCFG integrationType = iota

// gcpAT - GCP Audit Log integration type
// gcpAT

// azureCFG - Azure Config integration type
// azureCFG

// azureAL - Azure Activity Log integration type
// azureAL
)

var integrationTypes = []string{
"AWS_CFG",
"AWS_CT_SQS",
"GCP_CFG",
"GCP_AT_SES",
"AZURE_CFG",
"AZURE_AL_SEQ",
}

func (i integrationType) String() string {
return integrationTypes[i]
}

// gcpResourceLevel determines Project or Organization level integration
type gcpResourceLevel int

const (
// GcpProject level integration with GCP
GcpProject gcpResourceLevel = iota

// GcpOrganization level integration with GCP
GcpOrganization
)

var gcpResourceLevels = []string{
"PROJECT",
"ORGANIZATION",
}

func (g gcpResourceLevel) String() string {
return gcpResourceLevels[g]
}

// GetIntegrations lists the external integrations available on the server
func (c *Client) GetIntegrations() (response integrationsResponse, err error) {
err = c.RequestDecoder("GET", apiIntegrations, nil, &response)
Expand All @@ -21,6 +76,47 @@ func (c *Client) GetAWSIntegrations() (response awsIntegrationsResponse, err err
return
}

// NewGCPIntegrationData returns an instance of gcpIntegrationData
func NewGCPIntegrationData(name string, idType gcpResourceLevel) gcpIntegrationData {
return gcpIntegrationData{
commonIntegrationData: commonIntegrationData{
Name: name,
Type: gcpCFG.String(),
Enabled: 1,
},
Data: gcpCfg{
IdType: idType.String(),
},
}
}

// CreateGCPConfigIntegration creates a single integration on the server
func (c *Client) CreateGCPConfigIntegration(data gcpIntegrationData) (response gcpIntegrationsResponse, err error) {
err = c.createIntegration(data, &response)
return
}

func (c *Client) createIntegration(data interface{}, response interface{}) error {
body, err := jsonReader(data)
if err != nil {
return err
}

err = c.RequestDecoder("POST", apiIntegrations, body, response)
return err
}

// GetOneGCPConfigIntegration gets a single integration matching the integration guid available on the server
func (c *Client) GetGCPConfigIntegration(intgGuid string) (response gcpIntegrationsResponse, err error) {
err = c.getIntegration(intgGuid, &response)
return
}

func (c *Client) getIntegration(intgGuid string, response interface{}) error {
apiPath := fmt.Sprintf(apiIntegrationByGUID, intgGuid)
return c.RequestDecoder("GET", apiPath, nil, response)
}

type commonIntegrationData struct {
IntgGuid string `json:"INTG_GUID"`
Name string `json:"NAME"`
Expand Down Expand Up @@ -76,10 +172,9 @@ type gcpIntegrationData struct {
}

type gcpCfg struct {
ID string `json:"ID"`
IdType string `json:"ID_TYPE"`
IssueGrouping string `json:"ISSUE_GROUPING"`
Credentials gcpCredentials `json:"CREDENTIALS"`
ID string `json:"ID"`
IdType string `json:"ID_TYPE"`
Credentials gcpCredentials `json:"CREDENTIALS"`
}

type gcpCredentials struct {
Expand Down
118 changes: 117 additions & 1 deletion api/integrations_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,123 @@
package api_test

import "testing"
import (
"fmt"
"net/http"
"testing"

"github.com/lacework/go-sdk/api"
"github.com/stretchr/testify/assert"
)

func TestGetIntegrations(t *testing.T) {
// TODO @afiune implement a mocked Lacework API server
}

func TestCreateGCPConfigIntegration(t *testing.T) {
intgGUID := "12345"

fakeAPI := NewLaceworkServer()
fakeAPI.MockAPI("external/integrations", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, `
{
"data": [
{
"INTG_GUID": "`+intgGUID+`",
"NAME": "integration_name",
"CREATED_OR_UPDATED_TIME": "2020-Mar-10 01:00:00 UTC",
"CREATED_OR_UPDATED_BY": "[email protected]",
"TYPE": "GCP_CFG",
"ENABLED": 1,
"STATE": {
"ok": true,
"lastUpdatedTime": "2020-Mar-10 01:00:00 UTC",
"lastSuccessfulTime": "2020-Mar-10 01:00:00 UTC"
},
"IS_ORG": 0,
"DATA": {
"CREDENTIALS": {
"CLIENT_ID": "xxxxxxxxx",
"CLIENT_EMAIL": "[email protected]",
"PRIVATE_KEY_ID": "xxxxxxxxxxxxxxxx"
},
"ID_TYPE": "PROJECT",
"ID": "xxxxxxxxxx"
},
"TYPE_NAME": "GCP Compliance"
}
],
"ok": true,
"message": "SUCCESS"
}
`)
})
defer fakeAPI.Close()

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

data := api.NewGCPIntegrationData("integration_name", api.GcpProject)
data.Data.ID = "xxxxxxxxxx"
data.Data.Credentials.ClientId = "xxxxxxxxx"
data.Data.Credentials.ClientEmail = "[email protected]"
data.Data.Credentials.PrivateKeyId = "xxxxxxxxxxxxxxxx"

response, err := c.CreateGCPConfigIntegration(data)
assert.Nil(t, err)
assert.NotNil(t, response)
assert.True(t, response.Ok)
assert.Equal(t, 1, len(response.Data))
assert.Equal(t, intgGUID, response.Data[0].IntgGuid)
}

func TestGetGCPConfigIntegration(t *testing.T) {
intgGUID := "12345"
apiPath := fmt.Sprintf("external/integrations/%s", intgGUID)

fakeAPI := NewLaceworkServer()
fakeAPI.MockAPI(apiPath, func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, `
{
"data": [
{
"INTG_GUID": "`+intgGUID+`",
"NAME": "integration_name",
"CREATED_OR_UPDATED_TIME": "2020-Mar-10 01:00:00 UTC",
"CREATED_OR_UPDATED_BY": "[email protected]",
"TYPE": "GCP_CFG",
"ENABLED": 1,
"STATE": {
"ok": true,
"lastUpdatedTime": "2020-Mar-10 01:00:00 UTC",
"lastSuccessfulTime": "2020-Mar-10 01:00:00 UTC"
},
"IS_ORG": 0,
"DATA": {
"CREDENTIALS": {
"CLIENT_ID": "xxxxxxxxx",
"CLIENT_EMAIL": "[email protected]",
"PRIVATE_KEY_ID": "xxxxxxxxxxxxxxxx"
},
"ID_TYPE": "PROJECT",
"ID": "xxxxxxxxxx"
},
"TYPE_NAME": "GCP Compliance"
}
],
"ok": true,
"message": "SUCCESS"
}
`)
})
defer fakeAPI.Close()

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

response, err := c.GetGCPConfigIntegration(intgGUID)
assert.Nil(t, err)
assert.NotNil(t, response)
assert.True(t, response.Ok)
assert.Equal(t, 1, len(response.Data))
assert.Equal(t, intgGUID, response.Data[0].IntgGuid)
}

0 comments on commit 052a771

Please sign in to comment.