Skip to content

Commit

Permalink
refactor: Add resource group specific create functions(#542)
Browse files Browse the repository at this point in the history
Signed-off-by: Darren Murray <[email protected]>
  • Loading branch information
dmurray-lacework committed Sep 7, 2021
1 parent 5e27cc8 commit 8a78438
Show file tree
Hide file tree
Showing 13 changed files with 382 additions and 115 deletions.
28 changes: 27 additions & 1 deletion api/resource_groups.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ type ResourceGroupsService struct {
type ResourceGroup interface {
ID() string
ResourceGroupType() ResourceGroupType
ResetResourceGUID()
}

type ResourceGroupType int
Expand Down Expand Up @@ -138,6 +139,26 @@ func (svc *ResourceGroupsService) Create(group ResourceGroupData) (
return
}

// Update updates a single ResourceGroup on the Lacework Server
func (svc *ResourceGroupsService) Update(data ResourceGroup) (
response ResourceGroupResponse,
err error,
) {
if data == nil {
err = errors.New("resource group must not be empty")
return
}
guid := data.ID()
data.ResetResourceGUID()

err = svc.update(guid, data, &response)
if err != nil {
return
}

return
}

func castResourceGroupResponse(data resourceGroupWorkaroundData, response interface{}) error {
isDefault, err := strconv.Atoi(data.IsDefault)
if err != nil {
Expand Down Expand Up @@ -244,8 +265,9 @@ func (svc *ResourceGroupsService) get(guid string, response interface{}) error {

func (svc *ResourceGroupsService) update(guid string, data interface{}, response interface{}) error {
if guid == "" {
return errors.New("specify an intgGuid")
return errors.New("specify a resource group guid")
}

apiPath := fmt.Sprintf(apiV2ResourceGroupsFromGUID, guid)
return svc.client.RequestEncoderDecoder("PATCH", apiPath, data, response)
}
Expand All @@ -259,6 +281,10 @@ func (group ResourceGroupData) ID() string {
return group.ResourceGuid
}

func (group *ResourceGroupData) ResetResourceGUID() {
group.ResourceGuid = ""
}

func (group ResourceGroupData) Status() string {
if group.Enabled == 1 {
return "Enabled"
Expand Down
45 changes: 33 additions & 12 deletions api/resource_groups_aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ var (
AwsResourceGroupAllAccounts = []string{"*"}
)

// GetAwsResourceGroup gets a single Aws ResourceGroup matching the
// GetAws gets a single Aws ResourceGroup matching the
// provided resource guid
func (svc *ResourceGroupsService) GetAwsResourceGroup(guid string) (
func (svc *ResourceGroupsService) GetAws(guid string) (
response AwsResourceGroupResponse,
err error,
) {
Expand All @@ -45,22 +45,35 @@ func (svc *ResourceGroupsService) GetAwsResourceGroup(guid string) (
return setAwsResourceGroupResponse(rawResponse)
}

// UpdateAwsResourceGroup updates a single Aws ResourceGroup on the Lacework Server
func (svc *ResourceGroupsService) UpdateAwsResourceGroup(data ResourceGroup) (
response AwsResourceGroupResponse,
err error,
) {
var rawResponse resourceGroupWorkaroundResponse
err = svc.update(data.ID(), data, &rawResponse)
// UpdateAws updates a single Aws ResourceGroup on the Lacework Server
func (svc *ResourceGroupsService) UpdateAws(data ResourceGroup) (
response AwsResourceGroupResponse, err error) {
if data == nil {
err = errors.New("resource group must not be empty")
return
}
guid := data.ID()
data.ResetResourceGUID()

err = svc.update(guid, data, &response)
if err != nil {
return
}

return setAwsResourceGroupResponse(rawResponse)
return
}

// CreateAws creates a single Aws ResourceGroup on the Lacework Server
func (svc *ResourceGroupsService) CreateAws(data ResourceGroup) (
response AwsResourceGroupResponse,
err error,
) {
err = svc.create(data, &response)
return
}

func setAwsResourceGroupResponse(response resourceGroupWorkaroundResponse) (aws AwsResourceGroupResponse, err error) {
var props AwsResourceGroupProps
var props AwsResourceJsonStringGroupProps

isDefault, err := strconv.Atoi(response.Data.IsDefault)
if err != nil {
Expand Down Expand Up @@ -88,7 +101,7 @@ func setAwsResourceGroupResponse(response resourceGroupWorkaroundResponse) (aws
if err != nil {
return
}
aws.Data.Props = props
aws.Data.Props = AwsResourceGroupProps(props)
return
}

Expand All @@ -107,6 +120,14 @@ type AwsResourceGroupData struct {
}

type AwsResourceGroupProps struct {
Description string `json:"description,omitempty"`
AccountIDs []string `json:"accountIds"`
UpdatedBy string `json:"updatedBy,omitempty"`
LastUpdated int `json:"lastUpdated,omitempty"`
}

// Workaround for props being returned as a json string
type AwsResourceJsonStringGroupProps struct {
Description string `json:"DESCRIPTION,omitempty"`
AccountIDs []string `json:"ACCOUNT_IDS"`
UpdatedBy string `json:"UPDATED_BY,omitempty"`
Expand Down
34 changes: 25 additions & 9 deletions api/resource_groups_aws_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func TestResourceGroupAwsGet(t *testing.T) {
)
assert.Nil(t, err)

response, err := c.V2.ResourceGroups.GetAwsResourceGroup(resourceGUID)
response, err := c.V2.ResourceGroups.GetAws(resourceGUID)
assert.Nil(t, err)
assert.NotNil(t, response)
assert.Equal(t, resourceGUID, response.Data.ResourceGuid)
Expand All @@ -76,14 +76,13 @@ func TestResourceGroupsAwsUpdate(t *testing.T) {

if assert.NotNil(t, r.Body) {
body := httpBodySniffer(r)
assert.Contains(t, body, resourceGUID, "ResourceGUID missing")
assert.Contains(t, body, "group_name", "Resource Group name is missing")
assert.Contains(t, body, "AWS", "wrong Resource Group type")
assert.Contains(t, body, "Updated", "wrong description")
assert.Contains(t, body, "[\"abc123\",\"cba321\"]", "wrong account ids")
}

fmt.Fprintf(w, generateResourceGroupResponse(singleAwsResourceGroup(resourceGUID)))
fmt.Fprintf(w, generateResourceGroupResponse(singleAwsResourceGroupUpdateResponse(resourceGUID)))
})

c, err := api.NewClient("test",
Expand All @@ -95,19 +94,17 @@ func TestResourceGroupsAwsUpdate(t *testing.T) {

resourceGroup := api.NewResourceGroup("group_name",
api.AwsResourceGroup,
api.AwsResourceGroupData{
Props: api.AwsResourceGroupProps{
Description: "Updated",
AccountIDs: []string{"abc123", "cba321"},
},
api.AwsResourceGroupProps{
Description: "Updated",
AccountIDs: []string{"abc123", "cba321"},
},
)
assert.Equal(t, "group_name", resourceGroup.Name, "Aws Resource Group name mismatch")
assert.Equal(t, "AWS", resourceGroup.Type, "a new Aws Resource Group should match its type")
assert.Equal(t, 1, resourceGroup.Enabled, "a new Aws Resource Group should be enabled")
resourceGroup.ResourceGuid = resourceGUID

response, err := c.V2.ResourceGroups.UpdateAwsResourceGroup(resourceGroup)
response, err := c.V2.ResourceGroups.UpdateAws(&resourceGroup)
assert.Nil(t, err)
assert.NotNil(t, response)
assert.Equal(t, resourceGUID, response.Data.ResourceGuid)
Expand All @@ -126,3 +123,22 @@ func singleAwsResourceGroup(id string) string {
}
`
}

func singleAwsResourceGroupUpdateResponse(id string) string {
return `
{
"guid": "` + id + `",
"isDefault": 1,
"props": {
"description":"All Aws Accounts",
"accountIds":["*"],
"updatedBy":null,
"lastUpdated":1586453993470
},
"resourceGuid": "` + id + `",
"resourceName": "group_name",
"resourceType": "AWS",
"enabled": 1
}
`
}
44 changes: 35 additions & 9 deletions api/resource_groups_azure.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ var (
AzureResourceGroupAllSubscriptions = []string{"*"}
)

// GetAzureResourceGroup gets a single Azure ResourceGroup matching the
// GetAzure gets a single Azure ResourceGroup matching the
// provided resource guid
func (svc *ResourceGroupsService) GetAzureResourceGroup(guid string) (
func (svc *ResourceGroupsService) GetAzure(guid string) (
response AzureResourceGroupResponse,
err error,
) {
Expand All @@ -45,22 +45,37 @@ func (svc *ResourceGroupsService) GetAzureResourceGroup(guid string) (
return setAzureResponse(rawResponse)
}

// UpdateAzureResourceGroup updates a single Azure ResourceGroup on the Lacework Server
func (svc *ResourceGroupsService) UpdateAzureResourceGroup(data ResourceGroup) (
// UpdateAzure updates a single Azure ResourceGroup on the Lacework Server
func (svc *ResourceGroupsService) UpdateAzure(data ResourceGroup) (
response AzureResourceGroupResponse,
err error,
) {
var rawResponse resourceGroupWorkaroundResponse
err = svc.update(data.ID(), data, &rawResponse)
if data == nil {
err = errors.New("resource group must not be empty")
return
}
guid := data.ID()
data.ResetResourceGUID()

err = svc.update(guid, data, &response)
if err != nil {
return
}

return setAzureResponse(rawResponse)
return
}

// CreateAzure creates a single Azure ResourceGroup on the Lacework Server
func (svc *ResourceGroupsService) CreateAzure(data ResourceGroup) (
response AzureResourceGroupResponse,
err error,
) {
err = svc.create(data, &response)
return
}

func setAzureResponse(response resourceGroupWorkaroundResponse) (az AzureResourceGroupResponse, err error) {
var props AzureResourceGroupProps
var props AzureResourceJsonStringGroupProps

isDefault, err := strconv.Atoi(response.Data.IsDefault)
if err != nil {
Expand Down Expand Up @@ -88,7 +103,9 @@ func setAzureResponse(response resourceGroupWorkaroundResponse) (az AzureResourc
if err != nil {
return
}
az.Data.Props = props

az.Data.Props = AzureResourceGroupProps(props)

return
}

Expand All @@ -107,6 +124,15 @@ type AzureResourceGroupData struct {
}

type AzureResourceGroupProps struct {
Description string `json:"description,omitempty"`
Tenant string `json:"tenant"`
Subscriptions []string `json:"subscriptions"`
UpdatedBy string `json:"updatedBy,omitempty"`
LastUpdated int `json:"lastUpdated,omitempty"`
}

// Workaround for props being returned as a json string
type AzureResourceJsonStringGroupProps struct {
Description string `json:"DESCRIPTION,omitempty"`
Tenant string `json:"TENANT"`
Subscriptions []string `json:"SUBSCRIPTIONS"`
Expand Down
37 changes: 27 additions & 10 deletions api/resource_groups_azure_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func TestResourceGroupAzureGet(t *testing.T) {
)
assert.Nil(t, err)

response, err := c.V2.ResourceGroups.GetAzureResourceGroup(resourceGUID)
response, err := c.V2.ResourceGroups.GetAzure(resourceGUID)
assert.Nil(t, err)
assert.NotNil(t, response)
assert.Equal(t, resourceGUID, response.Data.ResourceGuid)
Expand All @@ -77,14 +77,13 @@ func TestResourceGroupsAzureUpdate(t *testing.T) {

if assert.NotNil(t, r.Body) {
body := httpBodySniffer(r)
assert.Contains(t, body, resourceGUID, "ResourceGUID missing")
assert.Contains(t, body, "group_name", "Resource Group name is missing")
assert.Contains(t, body, "AZURE", "wrong Resource Group type")
assert.Contains(t, body, "Updated", "wrong description")
assert.Contains(t, body, "[\"abc123\",\"cba321\"]", "wrong subscriptions")
}

fmt.Fprintf(w, generateResourceGroupResponse(singleAzureResourceGroup(resourceGUID)))
fmt.Fprintf(w, generateResourceGroupResponse(singleAzureResourceGroupUpdateResponse(resourceGUID)))
})

c, err := api.NewClient("test",
Expand All @@ -96,20 +95,18 @@ func TestResourceGroupsAzureUpdate(t *testing.T) {

resourceGroup := api.NewResourceGroup("group_name",
api.AzureResourceGroup,
api.AzureResourceGroupData{
Props: api.AzureResourceGroupProps{
Description: "Updated",
Subscriptions: []string{"abc123", "cba321"},
Tenant: "tenant",
},
api.AzureResourceGroupProps{
Description: "Updated",
Subscriptions: []string{"abc123", "cba321"},
Tenant: "tenant",
},
)
assert.Equal(t, "group_name", resourceGroup.Name, "Azure Resource Group name mismatch")
assert.Equal(t, "AZURE", resourceGroup.Type, "a new Azure Resource Group should match its type")
assert.Equal(t, 1, resourceGroup.Enabled, "a new Azure Resource Group should be enabled")
resourceGroup.ResourceGuid = resourceGUID

response, err := c.V2.ResourceGroups.UpdateAzureResourceGroup(resourceGroup)
response, err := c.V2.ResourceGroups.UpdateAzure(&resourceGroup)
assert.Nil(t, err)
assert.NotNil(t, response)
assert.Equal(t, resourceGUID, response.Data.ResourceGuid)
Expand All @@ -128,3 +125,23 @@ func singleAzureResourceGroup(id string) string {
}
`
}

func singleAzureResourceGroupUpdateResponse(id string) string {
return `
{
"guid": "` + id + `",
"isDefault": 1,
"props": {
"description":"All Tenants and Subscriptions",
"subscriptions":["*"],
"tenant":"*",
"updatedBy":null,
"lastUpdated":1586453993470
},
"resourceGuid": "` + id + `",
"resourceName": "group_name",
"resourceType": "AWS",
"enabled": 1
}
`
}
Loading

0 comments on commit 8a78438

Please sign in to comment.