Skip to content

Commit

Permalink
ENG-6346: Add repository conf analysis resource (log settings include…
Browse files Browse the repository at this point in the history
…d) (#108)

Co-authored-by: Wilson de Carvalho <[email protected]>
  • Loading branch information
VictorGFM and wcmjunior authored Sep 25, 2021
1 parent fc5eb7f commit 0486c68
Show file tree
Hide file tree
Showing 6 changed files with 548 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ terraform import cyral_repository.my_resource_name myrepo
- [Resource Policy](./docs/resource_policy.md)
- [Resource Policy Rule](./docs/resource_policy_rule.md)
- [Resource Repository](./docs/resource_repository.md)
- [Resource Repository Analysis Configuration](./docs/resource_repository_conf_analysis.md)
- [Resource Repository Authentication Configuration](./docs/resource_repository_conf_auth.md)
- [Resource Repository Binding](./docs/resource_repository_binding.md)
- [Resource Repository Local Account](./docs/resource_repository_local_account.md)
Expand Down
43 changes: 43 additions & 0 deletions client/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"fmt"

"github.com/aws/aws-sdk-go/aws/endpoints"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
)

// ValidateRepoType checks if a given repository type is valid.
Expand Down Expand Up @@ -75,3 +77,44 @@ func ValidateAWSRegion(param string) error {
}
return nil
}

func ValidateRepositoryConfAnalysisRedact() schema.SchemaValidateFunc {
return validation.StringInSlice([]string{
"all",
"none",
"watched",
}, false)
}

func ValidateRepositoryConfAnalysisCommentAnnotationGroups() schema.SchemaValidateFunc {
return validation.StringInSlice([]string{
"identity",
"client",
"repo",
"sidecar",
}, false)
}

func ValidateRepositoryConfAnalysisLogSettings() schema.SchemaValidateFunc {
return validation.StringInSlice([]string{
"everything",
"dql",
"dml",
"ddl",
"sensitive & dql",
"sensitive & dml",
"sensitive & ddl",
"privileged",
"port-scan",
"auth-failure",
"full-table-scan",
"violations",
"connections",
"sensitive",
"data-classification",
"audit",
"error",
"new-connections",
"closed-connections",
}, false)
}
1 change: 1 addition & 0 deletions cyral/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ func Provider() *schema.Provider {
"cyral_policy": resourcePolicy(),
"cyral_policy_rule": resourcePolicyRule(),
"cyral_repository": resourceRepository(),
"cyral_repository_conf_analysis": resourceRepositoryConfAnalysis(),
"cyral_repository_conf_auth": resourceRepositoryConfAuth(),
"cyral_repository_local_account": resourceRepositoryLocalAccount(),
"cyral_repository_binding": resourceRepositoryBinding(),
Expand Down
233 changes: 233 additions & 0 deletions cyral/resource_cyral_repository_conf_analysis.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
package cyral

import (
"context"
"encoding/json"
"fmt"
"log"
"net/http"

"github.com/cyralinc/terraform-provider-cyral/client"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

type RepositoryConfAnalysisData struct {
Config UserFacingConfig `json:"userConfig"`
}

type UserFacingConfig struct {
Redact string `json:"redact"`
AlertOnViolation bool `json:"alertOnViolation"`
DisablePreConfiguredAlerts bool `json:"disablePreConfiguredAlerts"`
BlockOnViolation bool `json:"blockOnViolation"`
DisableFilterAnalysis bool `json:"disableFilterAnalysis"`
RewriteOnViolation bool `json:"rewriteOnViolation"`
CommentAnnotationGroups []string `json:"commentAnnotationGroups,omitempty"`
LogGroups []string `json:"logGroups,omitempty"`
}

func resourceRepositoryConfAnalysis() *schema.Resource {
return &schema.Resource{
CreateContext: resourceRepositoryConfAnalysisCreate,
ReadContext: resourceRepositoryConfAnalysisRead,
UpdateContext: resourceRepositoryConfAnalysisUpdate,
DeleteContext: resourceRepositoryConfAnalysisDelete,

Schema: map[string]*schema.Schema{
"repository_id": {
Type: schema.TypeString,
Required: true,
},
"redact": {
Type: schema.TypeString,
Optional: true,
Default: "all",
ValidateFunc: client.ValidateRepositoryConfAnalysisRedact(),
},
"alert_on_violation": {
Type: schema.TypeBool,
Optional: true,
Default: true,
},
"disable_pre_configured_alerts": {
Type: schema.TypeBool,
Optional: true,
},
"block_on_violation": {
Type: schema.TypeBool,
Optional: true,
},
"disable_filter_analysis": {
Type: schema.TypeBool,
Optional: true,
},
"rewrite_on_violation": {
Type: schema.TypeBool,
Optional: true,
},
"comment_annotation_groups": {
Type: schema.TypeSet,
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeString,
ValidateFunc: client.ValidateRepositoryConfAnalysisCommentAnnotationGroups(),
},
},
"log_groups": {
Type: schema.TypeSet,
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeString,
ValidateFunc: client.ValidateRepositoryConfAnalysisLogSettings(),
},
},
},
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
}
}

func resourceRepositoryConfAnalysisCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Printf("[DEBUG] Init resourceRepositoryConfAnalysisCreate")
c := m.(*client.Client)

resourceData, err := getConfAnalysisDataFromResource(d)
if err != nil {
return createError("Unable to create conf analysis", fmt.Sprintf("%v", err))
}

url := fmt.Sprintf("https://%s/v1/repos/%s/conf/analysis", c.ControlPlane, d.Get("repository_id"))

body, err := c.DoRequest(url, http.MethodPut, resourceData.Config)
if err != nil {
return createError("Unable to create conf analysis", fmt.Sprintf("%v", err))
}

response := RepositoryConfAnalysisData{}
if err := json.Unmarshal(body, &response); err != nil {
return createError("Unable to unmarshall JSON", fmt.Sprintf("%v", err))
}

log.Printf("[DEBUG] Response body (unmarshalled): %#v", response)

d.SetId(fmt.Sprintf("%s/ConfAnalysis", d.Get("repository_id")))

log.Printf("[DEBUG] End resourceRepositoryConfAnalysisCreate")

return resourceRepositoryConfAnalysisRead(ctx, d, m)
}

func resourceRepositoryConfAnalysisRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Printf("[DEBUG] Init resourceRepositoryConfAnalysisRead")
c := m.(*client.Client)

url := fmt.Sprintf("https://%s/v1/repos/%s/conf/analysis", c.ControlPlane, d.Get("repository_id"))

body, err := c.DoRequest(url, http.MethodGet, nil)
if err != nil {
return createError(fmt.Sprintf("Unable to read conf analysis. Conf Analysis Id: %s",
d.Id()), fmt.Sprintf("%v", err))
}

response := RepositoryConfAnalysisData{}
if err := json.Unmarshal(body, &response); err != nil {
return createError("Unable to unmarshall JSON", fmt.Sprintf("%v", err))
}

log.Printf("[DEBUG] Response body (unmarshalled): %#v", response)

setConfAnalysisDataToResource(d, response)

log.Printf("[DEBUG] End resourceRepositoryConfAnalysisRead")

return diag.Diagnostics{}
}

func resourceRepositoryConfAnalysisUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Printf("[DEBUG] Init resourceRepositoryConfAnalysisUpdate")
c := m.(*client.Client)

resourceData, err := getConfAnalysisDataFromResource(d)
if err != nil {
return createError("Unable to update conf analysis", fmt.Sprintf("%v", err))
}

url := fmt.Sprintf("https://%s/v1/repos/%s/conf/analysis", c.ControlPlane, d.Get("repository_id"))

if _, err := c.DoRequest(url, http.MethodPut, resourceData.Config); err != nil {
return createError("Unable to update conf analysis", fmt.Sprintf("%v", err))
}

log.Printf("[DEBUG] End resourceRepositoryConfAnalysisUpdate")

return resourceRepositoryConfAnalysisRead(ctx, d, m)
}

func resourceRepositoryConfAnalysisDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Printf("[DEBUG] Init resourceRepositoryConfAnalysisDelete")
c := m.(*client.Client)

url := fmt.Sprintf("https://%s/v1/repos/%s/conf/analysis", c.ControlPlane, d.Get("repository_id"))

if _, err := c.DoRequest(url, http.MethodDelete, nil); err != nil {
return createError("Unable to delete conf analysis", fmt.Sprintf("%v", err))
}

log.Printf("[DEBUG] End resourceRepositoryConfAnalysisDelete")

return diag.Diagnostics{}
}

func getConfAnalysisDataFromResource(d *schema.ResourceData) (RepositoryConfAnalysisData, error) {
var logGroups []string
if logGroupsSet, ok := d.GetOk("log_groups"); ok {
for _, logGroupItem := range logGroupsSet.(*schema.Set).List() {
logGroups = append(logGroups, logGroupItem.(string))
}
}

var annotationGroups []string
if annotationGroupsSet, ok := d.GetOk("comment_annotation_groups"); ok {
for _, annotationGroupItem := range annotationGroupsSet.(*schema.Set).List() {
annotationGroups = append(annotationGroups, annotationGroupItem.(string))
}
}

return RepositoryConfAnalysisData{
Config: UserFacingConfig{
Redact: d.Get("redact").(string),
AlertOnViolation: d.Get("alert_on_violation").(bool),
DisablePreConfiguredAlerts: d.Get("disable_pre_configured_alerts").(bool),
BlockOnViolation: d.Get("block_on_violation").(bool),
DisableFilterAnalysis: d.Get("disable_filter_analysis").(bool),
RewriteOnViolation: d.Get("rewrite_on_violation").(bool),
CommentAnnotationGroups: annotationGroups,
LogGroups: logGroups,
},
}, nil
}

func setConfAnalysisDataToResource(d *schema.ResourceData, resourceData RepositoryConfAnalysisData) {
logGroups := make([]interface{}, len(resourceData.Config.LogGroups))
for index, logGroupItem := range resourceData.Config.LogGroups {
logGroups[index] = logGroupItem
}
logGroupsSet := schema.NewSet(schema.HashString, logGroups)

annotationGroups := make([]interface{}, len(resourceData.Config.CommentAnnotationGroups))
for index, annotationGroupItem := range resourceData.Config.CommentAnnotationGroups {
annotationGroups[index] = annotationGroupItem
}
annotationGroupsSet := schema.NewSet(schema.HashString, annotationGroups)

d.Set("redact", resourceData.Config.Redact)
d.Set("alert_on_violation", resourceData.Config.AlertOnViolation)
d.Set("disable_pre_configured_alerts", resourceData.Config.DisablePreConfiguredAlerts)
d.Set("block_on_violation", resourceData.Config.BlockOnViolation)
d.Set("disable_filter_analysis", resourceData.Config.DisableFilterAnalysis)
d.Set("rewrite_on_violation", resourceData.Config.RewriteOnViolation)
d.Set("comment_annotation_groups", annotationGroupsSet)
d.Set("log_groups", logGroupsSet)
}
Loading

0 comments on commit 0486c68

Please sign in to comment.