Skip to content

Commit

Permalink
Refactor cyral_repository_conf_analysis
Browse files Browse the repository at this point in the history
  • Loading branch information
wcmjunior committed Apr 2, 2024
1 parent 7fc290f commit 867546f
Show file tree
Hide file tree
Showing 8 changed files with 315 additions and 324 deletions.
5 changes: 5 additions & 0 deletions cyral/internal/repository/confanalysis/constants.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package confanalysis

const (
resourceName = "cyral_repository_conf_analysis"
)
89 changes: 89 additions & 0 deletions cyral/internal/repository/confanalysis/model.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package confanalysis

import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

// TODO: v2 of this API should either return the repository ID
// or something else as an ID. Currently it accepts a `UserConfig`
// for the PUT payload, but returns a `RepositoryConfAnalysisData`.
// This makes the whole API confusing.

type RepositoryConfAnalysisData struct {
UserConfig UserConfig `json:"userConfig"`
}

type UserConfig struct {
AlertOnViolation bool `json:"alertOnViolation"`
BlockOnViolation bool `json:"blockOnViolation"`
CommentAnnotationGroups []string `json:"commentAnnotationGroups,omitempty"`
DisableFilterAnalysis bool `json:"disableFilterAnalysis"`
DisablePreConfiguredAlerts bool `json:"disablePreConfiguredAlerts"`
EnableDataMasking bool `json:"enableDataMasking"`
LogGroups []string `json:"logGroups,omitempty"`
Redact string `json:"redact"`
EnableDatasetRewrites bool `json:"enableDatasetRewrites"`
}

func (r *RepositoryConfAnalysisData) WriteToSchema(d *schema.ResourceData) error {
d.SetId(d.Get("repository_id").(string))
return r.UserConfig.WriteToSchema(d)
}

func (r *UserConfig) WriteToSchema(d *schema.ResourceData) error {
logGroups := make([]interface{}, len(r.LogGroups))
for index, logGroupItem := range r.LogGroups {
logGroups[index] = logGroupItem
}
logGroupsSet := schema.NewSet(schema.HashString, logGroups)

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

d.Set("alert_on_violation", r.AlertOnViolation)
d.Set("block_on_violation", r.BlockOnViolation)
d.Set("comment_annotation_groups", annotationGroupsSet)
d.Set("disable_filter_analysis", r.DisableFilterAnalysis)
d.Set("disable_pre_configured_alerts", r.DisablePreConfiguredAlerts)
d.Set("enable_data_masking", r.EnableDataMasking)
d.Set("log_groups", logGroupsSet)
d.Set("redact", r.Redact)
d.Set("enable_dataset_rewrites", r.EnableDatasetRewrites)

return nil
}

func (r *RepositoryConfAnalysisData) ReadFromSchema(d *schema.ResourceData) error {
return r.UserConfig.ReadFromSchema(d)
}

func (r *UserConfig) ReadFromSchema(d *schema.ResourceData) 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))
}
}

r.AlertOnViolation = d.Get("alert_on_violation").(bool)
r.BlockOnViolation = d.Get("block_on_violation").(bool)
r.DisableFilterAnalysis = d.Get("disable_filter_analysis").(bool)
r.DisablePreConfiguredAlerts = d.Get("disable_pre_configured_alerts").(bool)
r.EnableDataMasking = d.Get("enable_data_masking").(bool)
r.CommentAnnotationGroups = annotationGroups
r.LogGroups = logGroups
r.Redact = d.Get("redact").(string)
r.EnableDatasetRewrites = d.Get("enable_dataset_rewrites").(bool)

return nil
}
193 changes: 193 additions & 0 deletions cyral/internal/repository/confanalysis/resource.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
package confanalysis

import (
"context"
"fmt"
"net/http"

"github.com/cyralinc/terraform-provider-cyral/cyral/client"
"github.com/cyralinc/terraform-provider-cyral/cyral/core"
"github.com/cyralinc/terraform-provider-cyral/cyral/core/types/operationtype"
"github.com/cyralinc/terraform-provider-cyral/cyral/core/types/resourcetype"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

var urlFactory = func(d *schema.ResourceData, c *client.Client) string {
return fmt.Sprintf("https://%s/v1/repos/%s/conf/analysis",
c.ControlPlane,
d.Get("repository_id"),
)
}

var resourceContextHandler = core.DefaultContextHandler{
ResourceName: resourceName,
ResourceType: resourcetype.Resource,
SchemaReaderFactory: func() core.SchemaReader { return &UserConfig{} },
SchemaWriterFactoryGetMethod: func(_ *schema.ResourceData) core.SchemaWriter { return &RepositoryConfAnalysisData{} },
BaseURLFactory: urlFactory,
IdBasedURLFactory: urlFactory,
}

func resourceSchema() *schema.Resource {
return &schema.Resource{
Description: "Manages Repository Analysis Configuration. This resource allows configuring both " +
"[Log Settings](https://cyral.com/docs/manage-repositories/repo-log-volume) " +
"and [Advanced settings](https://cyral.com/docs/manage-repositories/repo-advanced-settings) " +
"(Logs, Alerts, Analysis and Enforcement) configurations for Data Repositories.",
CreateContext: core.CreateResource(
core.ResourceOperationConfig{
ResourceName: resourceName,
Type: operationtype.Create,
HttpMethod: http.MethodPut,
URLFactory: urlFactory,
SchemaReaderFactory: func() core.SchemaReader { return &UserConfig{} },
SchemaWriterFactory: func(_ *schema.ResourceData) core.SchemaWriter { return &RepositoryConfAnalysisData{} },
},
core.ResourceOperationConfig{
ResourceName: resourceName,
Type: operationtype.Read,
HttpMethod: http.MethodGet,
URLFactory: urlFactory,
SchemaWriterFactory: func(_ *schema.ResourceData) core.SchemaWriter { return &RepositoryConfAnalysisData{} },
RequestErrorHandler: &core.ReadIgnoreHttpNotFound{},
},
),
ReadContext: resourceContextHandler.ReadContext(),
UpdateContext: resourceContextHandler.UpdateContext(),
DeleteContext: resourceContextHandler.DeleteContext(),

SchemaVersion: 1,
StateUpgraders: []schema.StateUpgrader{
{
Version: 0,
Type: repositoryConfAnalysisResourceSchemaV0().
CoreConfigSchema().ImpliedType(),
Upgrade: UpgradeRepositoryConfAnalysisV0,
},
},

Schema: repositoryConfAnalysisResourceSchemaV0().Schema,

Importer: &schema.ResourceImporter{
StateContext: func(
ctx context.Context,
d *schema.ResourceData,
m interface{},
) ([]*schema.ResourceData, error) {
d.Set("repository_id", d.Id())
return []*schema.ResourceData{d}, nil
},
},
}
}

func repositoryConfAnalysisResourceSchemaV0() *schema.Resource {
return &schema.Resource{
Schema: map[string]*schema.Schema{
"id": {
Description: "ID of this resource in Cyral environment",
Type: schema.TypeString,
Computed: true,
},
"repository_id": {
Description: "The ID of an existing data repository resource that will be configured.",
Type: schema.TypeString,
Required: true,
},
"redact": {
Description: "Valid values are: `all`, `none` and `watched`. If set to `all` it will enable the redact of all literal values, `none` will disable it, and `watched` will only redact values from tracked fields set in the Datamap.",
Type: schema.TypeString,
Optional: true,
Default: "all",
ValidateFunc: client.ValidateRepositoryConfAnalysisRedact(),
},
"alert_on_violation": {
Description: "If set to `true` it will enable alert on policy violations.",
Type: schema.TypeBool,
Optional: true,
Default: true,
},
"disable_pre_configured_alerts": {
Description: "If set to `true` it will *disable* preconfigured alerts.",
Type: schema.TypeBool,
Optional: true,
},
"enable_data_masking": {
Description: "If set to `true` it will allow policies to force the masking " +
" of specified data fields in the results of queries. " +
"[Learn more](https://cyral.com/docs/using-cyral/masking/).",
Type: schema.TypeBool,
Optional: true,
},
"block_on_violation": {
Description: "If set to `true` it will enable query blocking in case of a " +
"policy violation.",
Type: schema.TypeBool,
Optional: true,
},
"disable_filter_analysis": {
Description: "If set to `true` it will *disable* filter analysis.",
Type: schema.TypeBool,
Optional: true,
},
"enable_dataset_rewrites": {
Description: "If set to `true` it will enable rewriting queries.",
Type: schema.TypeBool,
Optional: true,
},
"comment_annotation_groups": {
Description: "Valid values are: `identity`, `client`, `repo`, `sidecar`. The " +
"default behavior is to set only the `identity` when this option is " +
"enabled, but you can also opt to add the contents of `client`, `repo`, " +
" `sidecar` logging blocks as query comments. " +
" [Learn more](https://support.cyral.com/support/solutions/articles/44002218978).",
Type: schema.TypeSet,
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeString,
ValidateFunc: client.ValidateRepositoryConfAnalysisCommentAnnotationGroups(),
},
},
"log_groups": {
Description: "Responsible for configuring the Log Settings. Valid values are documented below. The `log_groups` list support the following values: " +
"\n - `everything` - Enables all the Log Settings." +
"\n - `dql` - Enables the `DQLs` setting for `all requests`." +
"\n - `dml` - Enables the `DMLs` setting for `all requests`." +
"\n - `ddl` - Enables the `DDLs` setting for `all requests`." +
"\n - `sensitive & dql` - Enables the `DQLs` setting for `logged fields`." +
"\n - `sensitive & dml` - Enables the `DMLs` setting for `logged fields`." +
"\n - `sensitive & ddl` - Enables the `DDLs` setting for `logged fields`." +
"\n - `privileged` - Enables the `Privileged commands` setting." +
"\n - `port-scan` - Enables the `Port scans` setting." +
"\n - `auth-failure` - Enables the `Authentication failures` setting." +
"\n - `full-table-scan` - Enables the `Full scans` setting." +
"\n - `violations` - Enables the `Policy violations` setting." +
"\n - `connections` - Enables the `Connection activity` setting." +
"\n - `sensitive` - Log all queries manipulating sensitive fields (watches)" +
"\n - `data-classification` - Log all queries whose response was automatically classified as sensitive (credit card numbers, emails and so on)." +
"\n - `audit` - Log `sensitive`, `DQLs`, `DDLs`, `DMLs` and `privileged`." +
"\n - `error` - Log analysis errors." +
"\n - `new-connections` - Log new connections." +
"\n - `closed-connections` - Log closed connections.",
Type: schema.TypeSet,
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeString,
ValidateFunc: client.ValidateRepositoryConfAnalysisLogSettings(),
},
},
},
}
}

// Previously, the ID for cyral_repository_conf_analysis had the format
// {repository_id}/ConfAnalysis. The goal of this state upgrade is to remove
// this suffix `ConfAnalysis`.
func UpgradeRepositoryConfAnalysisV0(
_ context.Context,
rawState map[string]interface{},
_ interface{},
) (map[string]interface{}, error) {
rawState["id"] = rawState["repository_id"]
return rawState, nil
}
Loading

0 comments on commit 867546f

Please sign in to comment.