Skip to content

Commit

Permalink
ENG-8637: Fix bug where cyral_sidecar_cft_template was crashing (#215)
Browse files Browse the repository at this point in the history
* Fix issue #214

* Add see also note for cft_template data source

* Comment out most changes in splunk integration

* Check if this makes CI build pass

* Run pre-commit

* Add unit tests for integrations_data

* Remove useless constant in unit tests

* Make getValue exported func

* Fix docs

Co-authored-by: Victor Moraes <[email protected]>
  • Loading branch information
Yowgf and VictorGFM authored May 27, 2022
1 parent 98fed13 commit 45ffdc4
Show file tree
Hide file tree
Showing 6 changed files with 153 additions and 41 deletions.
49 changes: 22 additions & 27 deletions cyral/data_source_cyral_sidecar_cft_template.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,6 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

type integrationsData struct {
Id string `json:"id"`
Label string `json:"label"`
Name string `json:"name"`
Type string `json:"type"`
Value string `json:"value"`
}

const CloudFormationDeploymentMethod = "cloudFormation"

func dataSourceSidecarCftTemplate() *schema.Resource {
Expand Down Expand Up @@ -138,57 +130,51 @@ func getSidecarData(c *client.Client, d *schema.ResourceData) (*SidecarData, err
return &response, nil
}

func getLogIntegrations(c *client.Client, d *schema.ResourceData) (*[]integrationsData, error) {
func getLogIntegrations(c *client.Client, d *schema.ResourceData) ([]IntegrationsData, error) {
url := fmt.Sprintf("https://%s/integrations/logging/", removePortFromURL(c.ControlPlane))

body, err := c.DoRequest(url, http.MethodGet, nil)
if err != nil {
return nil, err
}

response := []integrationsData{}
response := []IntegrationsData{}
if err := json.Unmarshal(body, &response); err != nil {
return nil, err
}

return &response, nil
return response, nil
}

func getMetricsIntegrations(c *client.Client, d *schema.ResourceData) (*[]integrationsData, error) {
func getMetricsIntegrations(c *client.Client, d *schema.ResourceData) ([]IntegrationsData, error) {
url := fmt.Sprintf("https://%s/integrations/metrics", removePortFromURL(c.ControlPlane))

body, err := c.DoRequest(url, http.MethodGet, nil)
if err != nil {
return nil, err
}

response := []integrationsData{}
response := []IntegrationsData{}
if err := json.Unmarshal(body, &response); err != nil {
return nil, err
}

return &response, nil
return response, nil
}

func filterIntegrationData(integrations *[]integrationsData, id string) *integrationsData {
for _, it := range *integrations {
func filterIntegrationData(integrations []IntegrationsData, id string) *IntegrationsData {
for _, it := range integrations {
if it.Id == id {
return &it
}
}
return &integrationsData{
Id: "id",
Type: "default",
Value: "default",
Name: "default",
Label: "default",
}
return NewDefaultIntegrationsData()
}

func getTemplateForSidecarProperties(
sidecarData *SidecarData,
logging *[]integrationsData,
metrics *[]integrationsData,
logging []IntegrationsData,
metrics []IntegrationsData,
c *client.Client,
d *schema.ResourceData,
) ([]byte, error) {
Expand All @@ -215,6 +201,15 @@ func getTemplateForSidecarProperties(
}
}

logIntegrationValue, err := logIntegration.GetValue()
if err != nil {
return nil, err
}
metricIntegrationValue, err := metricIntegration.GetValue()
if err != nil {
return nil, err
}

sidecarTemplatePropertiesKV := map[string]string{
"SidecarId": d.Get("sidecar_id").(string),
"KeyName": keyName,
Expand All @@ -227,9 +222,9 @@ func getTemplateForSidecarProperties(
"ELKAddress": "",
"publiclyAccessible": publiclyAccessible,
"logIntegrationType": logIntegration.Type,
"logIntegrationValue": logIntegration.Value,
"logIntegrationValue": logIntegrationValue,
"metricsIntegrationType": metricIntegration.Type,
"metricsIntegrationValue": metricIntegration.Value,
"metricsIntegrationValue": metricIntegrationValue,
}

var url string
Expand Down
56 changes: 56 additions & 0 deletions cyral/integrations_data.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package cyral

import (
"encoding/json"
"errors"
"fmt"
)

const (
integrationTypeSplunk = "splunk"
)

type IntegrationsData struct {
Id string `json:"id"`
Type string `json:"type"`
Name string `json:"name"`
Label string `json:"label"`
Value interface{} `json:"value"`
}

func NewDefaultIntegrationsData() *IntegrationsData {
return &IntegrationsData{
Id: "id",
Type: "default",
Name: "default",
Label: "default",
Value: "default",
}
}

func (isd *IntegrationsData) GetValue() (string, error) {
var err error
defer func() {
if err != nil {
err = fmt.Errorf("unable to get integration value for "+
"type '%s': %w", isd.Type, err)
}
}()
switch isd.Type {
case integrationTypeSplunk:
if value, ok := isd.Value.(SplunkIntegration); ok {
bytesval, jsonErr := json.Marshal(value)
if jsonErr == nil {
return string(bytesval), nil
}
err = fmt.Errorf("error marshalling splunk "+
"integration: %w", jsonErr)
}
default:
if value, ok := isd.Value.(string); ok {
return value, nil
}
err = errors.New("value is not of string type")
}
return "", err
}
54 changes: 54 additions & 0 deletions cyral/integrations_data_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package cyral

import (
"encoding/json"
"testing"

"github.com/stretchr/testify/require"
)

func sampleSplunkIntegrationsData() *IntegrationsData {
return &IntegrationsData{
Id: "id1",
Type: "splunk",
Name: "name1",
Label: "label1",
Value: SplunkIntegration{
Name: "name1",
AccessToken: "accessToken1",
Port: 0,
Host: "host1",
Index: "index1",
UseTLS: false,
CyralActivityLogsEnabled: false,
},
}
}

func TestIntegrationsData_GetValue_Default(t *testing.T) {
integrationsData := NewDefaultIntegrationsData()
expected := NewDefaultIntegrationsData().Value.(string)
actual, err := integrationsData.GetValue()
require.NoError(t, err)
require.Equal(t, expected, actual)
}

func TestIntegrationsData_GetValue_Splunk(t *testing.T) {
splunkIntegrationsData := sampleSplunkIntegrationsData()

expectedBytes, err := json.Marshal(SplunkIntegration{
Name: "name1",
AccessToken: "accessToken1",
Port: 0,
Host: "host1",
Index: "index1",
UseTLS: false,
CyralActivityLogsEnabled: false,
})
require.NoError(t, err)
expected := string(expectedBytes)
actual, err := splunkIntegrationsData.GetValue()
require.NoError(t, err)

require.Equal(t, expected, actual)
}
13 changes: 7 additions & 6 deletions cyral/resource_cyral_integration_splunk.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@ import (
)

type SplunkIntegration struct {
Name string `json:"name"`
AccessToken string `json:"accessToken"`
Port int `json:"hecPort,string"`
Host string `json:"host"`
Index string `json:"index"`
UseTLS bool `json:"useTLS"`
Name string `json:"name"`
AccessToken string `json:"accessToken"`
Port int `json:"hecPort,string"`
Host string `json:"host"`
Index string `json:"index"`
UseTLS bool `json:"useTLS"`
CyralActivityLogsEnabled bool `json:"cyralActivityLogsEnabled"`
}

func (data SplunkIntegration) WriteToSchema(d *schema.ResourceData) {
Expand Down
10 changes: 2 additions & 8 deletions docs/data-sources/sidecar_cft_template.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "cyral_sidecar_cft_template Data Source - cyral"
subcategory: ""
description: |-
Retrieves the CloudFormation deployment template for a given sidecar. This data source only supports sidecars with cloudFormation deployment method. For Terraform template, use our terraform-cyral-sidecar-aws module.
---

# cyral_sidecar_cft_template (Data Source)

Retrieves the CloudFormation deployment template for a given sidecar. This data source only supports sidecars with `cloudFormation` deployment method. For Terraform template, use our `terraform-cyral-sidecar-aws` module.
Expand All @@ -24,6 +16,8 @@ data "cyral_sidecar_cft_template" "some_data_source_name" {
}
```

-> To configure credentials for the parameters `SidecarClientID` and `SidecarClientSecret` of the template, see the [Sidecar Credentials Resource](../resources/sidecar_credentials.md).

<!-- schema generated by tfplugindocs -->

## Schema
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
# {{ .Name | trimspace }} ({{ .Type | trimspace }})

{{ .Description | trimspace }}

## Example Usage

```terraform
data "cyral_sidecar_cft_template" "some_data_source_name" {
sidecar_id = cyral_sidecar.SOME_SIDECAR_RESOURCE_NAME.id
log_integration_id = SOME_CYRAL_INTEGRATION.SOME_INTEGRATION_NAME.id
Expand All @@ -7,3 +14,8 @@ data "cyral_sidecar_cft_template" "some_data_source_name" {
key_name = "some-ec2-key-name"
}
}
```

-> To configure credentials for the parameters `SidecarClientID` and `SidecarClientSecret` of the template, see the [Sidecar Credentials Resource](../resources/sidecar_credentials.md).

{{ .SchemaMarkdown | trimspace }}

0 comments on commit 45ffdc4

Please sign in to comment.