Skip to content

Commit

Permalink
Refactor remaining resources and data sources (#522)
Browse files Browse the repository at this point in the history
* Refactor cyral_integration_*

* Remove dead code

* Refactor cyral_policy

* Refactor cyral_user_account

* Refactor cyral_policy_rule and fix error in cyral_service_account

* Refactor cyral_role and cyral_rego_policy_instance

* Deprecate cyral_saml_configuration and improve deprecation messages

* Refactor cyral_sidecar_instance, cyral_sidecar_instance_stats and cyral_system_info

* Improve package names;refactor cyral_sidecar_health, cyral_permission

* Fix error handlers to avoid states getting out-of-sync

* Update cyral/internal/regopolicy/schema_loader.go

Co-authored-by: Victor Moraes <[email protected]>

---------

Co-authored-by: Victor Moraes <[email protected]>
  • Loading branch information
wcmjunior and VictorGFM authored Apr 9, 2024
1 parent 37619ab commit 386a9dc
Show file tree
Hide file tree
Showing 130 changed files with 2,365 additions and 1,899 deletions.
4 changes: 2 additions & 2 deletions cyral/core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ func (r *NewFeature) ReadFromSchema(d *schema.ResourceData) error {

### datasource.go

Use the `GetPutDeleteURLFactory` to provide the URL factory to read the data source from the API.
Use the `ReadUpdateDeleteURLFactory` to provide the URL factory to read the data source from the API.

```go
// datasource.go
Expand All @@ -75,7 +75,7 @@ var dsContextHandler = core.DefaultContextHandler{
ResourceName: dataSourceName,
ResourceType: resourcetype.DataSource,
SchemaWriterFactoryGetMethod: func(_ *schema.ResourceData) core.SchemaWriter { return &NewFeature{} },
GetPutDeleteURLFactory: func(d *schema.ResourceData, c *client.Client) string {
ReadUpdateDeleteURLFactory: func(d *schema.ResourceData, c *client.Client) string {
return fmt.Sprintf("https://%s/v1/NewFeature/%s", c.ControlPlane, d.Get("my_id_field").(string))
},
}
Expand Down
30 changes: 19 additions & 11 deletions cyral/core/default_context_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,16 @@ import (
// an `id` field, meaning it will use the
// `IDBasedResponse` struct in such cases.
// 3. `BaseURLFactory` must be provided for resources. It will be used to
// create the POST endpoint and others in case `GetPutDeleteURLFactory`
// create the POST endpoint and others in case `ReadUpdateDeleteURLFactory`
// is not provided.
// 4. `GetPutDeleteURLFactory` must be provided for data sources.
// 5. If `GetPutDeleteURLFactory` is NOT provided (data sources or resources),
// the endpoint to perform GET, PUT and DELETE calls are composed by the
// 4. `ReadUpdateDeleteURLFactory` must be provided for data sources.
// 5. If `ReadUpdateDeleteURLFactory` is NOT provided (data sources or resources),
// the endpoints to perform GET, PUT, PATCH and DELETE calls are composed by the
// `BaseURLFactory` endpoint plus the ID specification as follows:
// - POST: https://<CP>/<apiVersion>/<featureName>
// - GET: https://<CP>/<apiVersion>/<featureName>/<id>
// - PUT: https://<CP>/<apiVersion>/<featureName>/<id>
// - PATCH: https://<CP>/<apiVersion>/<featureName>/<id>
// - DELETE: https://<CP>/<apiVersion>/<featureName>/<id>
type DefaultContextHandler struct {
ResourceName string
Expand All @@ -41,10 +42,13 @@ type DefaultContextHandler struct {
// written in POST operations.
SchemaWriterFactoryPostMethod SchemaWriterFactoryFunc
// BaseURLFactory provides the URL used for POSTs and that
// will also be used to compose the ID URL for GET, PUT and
// DELETE in case `GetPutDeleteURLFactory` is not provided.
BaseURLFactory URLFactoryFunc
GetPutDeleteURLFactory URLFactoryFunc
// will also be used to compose the ID URL for GET, PUT/PATCH and
// DELETE in case `ReadUpdateDeleteURLFactory` is not provided.
BaseURLFactory URLFactoryFunc
ReadUpdateDeleteURLFactory URLFactoryFunc

// Http method for update operations. If not provided, assumes http.MethodPut
UpdateMethod string
}

func DefaultSchemaWriterFactory(d *schema.ResourceData) SchemaWriter {
Expand All @@ -64,8 +68,8 @@ func (dch DefaultContextHandler) defaultOperationHandler(
var url string
if httpMethod == http.MethodPost {
url = dch.BaseURLFactory(d, c)
} else if dch.GetPutDeleteURLFactory != nil {
url = dch.GetPutDeleteURLFactory(d, c)
} else if dch.ReadUpdateDeleteURLFactory != nil {
url = dch.ReadUpdateDeleteURLFactory(d, c)
} else {
url = fmt.Sprintf("%s/%s", dch.BaseURLFactory(d, c), d.Id())
}
Expand Down Expand Up @@ -122,8 +126,12 @@ func (dch DefaultContextHandler) UpdateContext() schema.UpdateContextFunc {

func (dch DefaultContextHandler) UpdateContextCustomErrorHandling(getErrorHandler RequestErrorHandler,
putErrorHandler RequestErrorHandler) schema.UpdateContextFunc {
updateMethod := http.MethodPut
if dch.UpdateMethod != "" {
updateMethod = dch.UpdateMethod
}
return UpdateResource(
dch.defaultOperationHandler(ot.Update, http.MethodPut, dch.SchemaReaderFactory, nil, putErrorHandler),
dch.defaultOperationHandler(ot.Update, updateMethod, dch.SchemaReaderFactory, nil, putErrorHandler),
dch.defaultOperationHandler(ot.Update, http.MethodGet, nil, dch.SchemaWriterFactoryGetMethod, getErrorHandler),
)
}
Expand Down
8 changes: 4 additions & 4 deletions cyral/internal/datalabel/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
)

var getPutDeleteURLFactory = func(d *schema.ResourceData, c *client.Client) string {
var readUpdateDeleteURLFactory = func(d *schema.ResourceData, c *client.Client) string {
return fmt.Sprintf("https://%s/v1/datalabels/%s",
c.ControlPlane,
d.Get("name").(string))
Expand All @@ -27,7 +27,7 @@ func resourceSchema() *schema.Resource {
ResourceType: resourcetype.Resource,
SchemaReaderFactory: func() core.SchemaReader { return &DataLabel{} },
SchemaWriterFactoryGetMethod: func(_ *schema.ResourceData) core.SchemaWriter { return &DataLabel{} },
GetPutDeleteURLFactory: getPutDeleteURLFactory,
ReadUpdateDeleteURLFactory: readUpdateDeleteURLFactory,
}
return &schema.Resource{
Description: "Manages data labels. Data labels are part of the Cyral [Data Map](https://cyral.com/docs/policy/datamap).",
Expand All @@ -36,7 +36,7 @@ func resourceSchema() *schema.Resource {
ResourceName: resourceName,
Type: operationtype.Create,
HttpMethod: http.MethodPut,
URLFactory: getPutDeleteURLFactory,
URLFactory: readUpdateDeleteURLFactory,
SchemaReaderFactory: func() core.SchemaReader { return &DataLabel{} },
SchemaWriterFactory: func(_ *schema.ResourceData) core.SchemaWriter { return &DataLabel{} },
}, readDataLabelConfig,
Expand Down Expand Up @@ -116,7 +116,7 @@ var readDataLabelConfig = core.ResourceOperationConfig{
ResourceName: resourceName,
Type: operationtype.Read,
HttpMethod: http.MethodGet,
URLFactory: getPutDeleteURLFactory,
URLFactory: readUpdateDeleteURLFactory,
SchemaWriterFactory: func(_ *schema.ResourceData) core.SchemaWriter { return &DataLabel{} },
RequestErrorHandler: &core.IgnoreHttpNotFound{ResName: "Data Label"},
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package samlconfiguration
package deprecated

import (
"context"
Expand All @@ -7,7 +7,6 @@ import (
"net/http"

"github.com/cyralinc/terraform-provider-cyral/cyral/client"
"github.com/cyralinc/terraform-provider-cyral/cyral/internal/deprecated"
"github.com/cyralinc/terraform-provider-cyral/cyral/utils"
"github.com/google/uuid"
"github.com/hashicorp/terraform-plugin-log/tflog"
Expand All @@ -21,6 +20,8 @@ var (

func DataSourceSAMLConfiguration() *schema.Resource {
return &schema.Resource{
DeprecationMessage: "This data source has been deprecated. It will be removed in the next major version of " +
"the provider.",
Description: "Parses a SAML metadata URL or a Base64 document into a SAML configuration." +
"\n\nSee also the remaining SAML-related resources and data sources.",
ReadContext: dataSourceSAMLConfigurationRead,
Expand Down Expand Up @@ -182,7 +183,7 @@ func dataSourceSAMLConfigurationRead(ctx context.Context, d *schema.ResourceData
return utils.CreateError("Unable to retrieve saml configuration", fmt.Sprintf("%v", err))
}

response := deprecated.SAMLConfiguration{}
response := SAMLConfiguration{}
if err := json.Unmarshal(body, &response); err != nil {
return utils.CreateError("Unable to unmarshall JSON", fmt.Sprintf("%v", err))
}
Expand All @@ -197,14 +198,14 @@ func dataSourceSAMLConfigurationRead(ctx context.Context, d *schema.ResourceData
return diag.Diagnostics{}
}

func getSAMLMetadataRequestFromSchema(d *schema.ResourceData) deprecated.ParseSAMLMetadataRequest {
return deprecated.ParseSAMLMetadataRequest{
func getSAMLMetadataRequestFromSchema(d *schema.ResourceData) ParseSAMLMetadataRequest {
return ParseSAMLMetadataRequest{
SamlMetadataURL: d.Get("saml_metadata_url").(string),
Base64SamlMetadataDocument: d.Get("base_64_saml_metadata_document").(string),
}
}

func setSAMLConfigurationToSchema(d *schema.ResourceData, data deprecated.SAMLConfiguration) {
func setSAMLConfigurationToSchema(d *schema.ResourceData, data SAMLConfiguration) {
if data.Config != nil {
d.Set("disable_using_jwks_url", data.Config.DisableUsingJWKSUrl)
d.Set("sync_mode", data.Config.SyncMode)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package samlconfiguration_test
package deprecated_test

import (
"fmt"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const CloudFormationDeploymentMethod = "cft-ec2"

func DataSourceSidecarCftTemplate() *schema.Resource {
return &schema.Resource{
DeprecationMessage: "This data source was deprecated. It will be removed in the next major version of " +
DeprecationMessage: "This data source has been deprecated. It will be removed in the next major version of " +
"the provider and no longer works for control planes `v4.13` and later.",
Description: "Retrieves the CloudFormation deployment template for a given sidecar. This data source only " +
"supports sidecars with `cft-ec2` deployment method. For Terraform template, use our " +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ type DeprecatedSidecarInstances struct {

func DataSourceSidecarInstanceIDs() *schema.Resource {
return &schema.Resource{
DeprecationMessage: "This data source was deprecated. It will be removed in the next major version of " +
DeprecationMessage: "This data source has been deprecated. It will be removed in the next major version of " +
"the provider. Use the data source `cyral_sidecar_instance` instead",
Description: "Retrieves the IDs of all the current instances of a given sidecar.",
ReadContext: dataSourceSidecarInstanceIDsRead,
Expand Down
9 changes: 9 additions & 0 deletions cyral/internal/integration/awsiam/constants.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package awsiam

const (
resourceName = "cyral_integration_aws_iam"

AWSIAMIntegrationNameKey = "name"
AWSIAMIntegratioNDescriptionKey = "description"
AWSIAMIntegrationARNsKey = "role_arns"
)
53 changes: 53 additions & 0 deletions cyral/internal/integration/awsiam/model.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package awsiam

import (
"fmt"

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

type AWSIAMIntegrationWrapper struct {
Integration *AWSIAMIntegration `json:"iamIntegration"`
}

type AWSIAMIntegration struct {
ID string `json:"id,omitempty"`
Name string `json:"name"`
Description string `json:"description"`
IAMRoleARNs []string `json:"iamRoleARNs"`
}

func (wrapper AWSIAMIntegrationWrapper) WriteToSchema(d *schema.ResourceData) error {
integration := wrapper.Integration

d.SetId(integration.ID)

if err := d.Set(AWSIAMIntegrationNameKey, integration.Name); err != nil {
return fmt.Errorf("error setting '%s': %w", AWSIAMIntegrationNameKey, err)
}

if err := d.Set(AWSIAMIntegratioNDescriptionKey, integration.Description); err != nil {
return fmt.Errorf("error setting '%s': %w", AWSIAMIntegratioNDescriptionKey, err)
}

if err := d.Set(AWSIAMIntegrationARNsKey, integration.IAMRoleARNs); err != nil {
return fmt.Errorf("error setting '%s': %w", AWSIAMIntegrationARNsKey, err)
}
return nil
}

func (wrapper *AWSIAMIntegrationWrapper) ReadFromSchema(d *schema.ResourceData) error {
wrapper.Integration = &AWSIAMIntegration{}

wrapper.Integration.Name = d.Get(AWSIAMIntegrationNameKey).(string)
wrapper.Integration.Description = d.Get(AWSIAMIntegratioNDescriptionKey).(string)

arns := d.Get(AWSIAMIntegrationARNsKey).([]interface{})
stringARNs := make([]string, 0, len(arns))
for _, arn := range arns {
stringARNs = append(stringARNs, arn.(string))
}

wrapper.Integration.IAMRoleARNs = stringARNs
return nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,59 +10,7 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

const (
AWSIAMIntegrationNameKey = "name"
AWSIAMIntegratioNDescriptionKey = "description"
AWSIAMIntegrationARNsKey = "role_arns"
)

type AWSIAMIntegrationWrapper struct {
Integration *AWSIAMIntegration `json:"iamIntegration"`
}

type AWSIAMIntegration struct {
ID string `json:"id,omitempty"`
Name string `json:"name"`
Description string `json:"description"`
IAMRoleARNs []string `json:"iamRoleARNs"`
}

func (wrapper *AWSIAMIntegrationWrapper) WriteToSchema(d *schema.ResourceData) error {
integration := wrapper.Integration

d.SetId(integration.ID)

if err := d.Set(AWSIAMIntegrationNameKey, integration.Name); err != nil {
return fmt.Errorf("error setting '%s': %w", AWSIAMIntegrationNameKey, err)
}

if err := d.Set(AWSIAMIntegratioNDescriptionKey, integration.Description); err != nil {
return fmt.Errorf("error setting '%s': %w", AWSIAMIntegratioNDescriptionKey, err)
}

if err := d.Set(AWSIAMIntegrationARNsKey, integration.IAMRoleARNs); err != nil {
return fmt.Errorf("error setting '%s': %w", AWSIAMIntegrationARNsKey, err)
}
return nil
}

func (wrapper *AWSIAMIntegrationWrapper) ReadFromSchema(d *schema.ResourceData) error {
wrapper.Integration = &AWSIAMIntegration{}

wrapper.Integration.Name = d.Get(AWSIAMIntegrationNameKey).(string)
wrapper.Integration.Description = d.Get(AWSIAMIntegratioNDescriptionKey).(string)

arns := d.Get(AWSIAMIntegrationARNsKey).([]interface{})
stringARNs := make([]string, 0, len(arns))
for _, arn := range arns {
stringARNs = append(stringARNs, arn.(string))
}

wrapper.Integration.IAMRoleARNs = stringARNs
return nil
}

func ResourceIntegrationAWSIAM() *schema.Resource {
func resourceSchema() *schema.Resource {
contextHandler := core.DefaultContextHandler{
ResourceName: "AWS IAM Integration",
ResourceType: resourcetype.Resource,
Expand Down
24 changes: 24 additions & 0 deletions cyral/internal/integration/awsiam/schema_loader.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package awsiam

import "github.com/cyralinc/terraform-provider-cyral/cyral/core"

type packageSchema struct {
}

func (p *packageSchema) Name() string {
return "integration.awsiam"
}

func (p *packageSchema) Schemas() []*core.SchemaDescriptor {
return []*core.SchemaDescriptor{
{
Name: resourceName,
Type: core.ResourceSchemaType,
Schema: resourceSchema,
},
}
}

func PackageSchema() core.PackageSchema {
return &packageSchema{}
}
9 changes: 9 additions & 0 deletions cyral/internal/integration/confextension/constants.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package confextension

const (
authorizationPurpose = "authorization"
builtinCategory = "builtin"

PagerDutyTemplateType = "pagerduty"
DuoMFATemplateType = "duoMfa"
)
5 changes: 5 additions & 0 deletions cyral/internal/integration/confextension/mfaduo/constants.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package mfaduo

const (
resourceName = "cyral_integration_mfa_duo"
)
Original file line number Diff line number Diff line change
@@ -1,23 +1,18 @@
package mfaduo

import (
"github.com/cyralinc/terraform-provider-cyral/cyral/core"
ce "github.com/cyralinc/terraform-provider-cyral/cyral/internal/integration/confextension"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
)

func ResourceIntegrationMFADuo() *schema.Resource {
func resourceSchema() *schema.Resource {
return &schema.Resource{
Description: "Manages [integration with Duo MFA](https://cyral.com/docs/mfa/duo).",
CreateContext: core.CreateResource(
ce.ConfExtensionIntegrationCreate(ce.DuoMFATemplateType),
ce.ConfExtensionIntegrationRead(ce.DuoMFATemplateType)),
ReadContext: core.ReadResource(ce.ConfExtensionIntegrationRead(ce.DuoMFATemplateType)),
UpdateContext: core.UpdateResource(
ce.ConfExtensionIntegrationUpdate(ce.DuoMFATemplateType),
ce.ConfExtensionIntegrationRead(ce.DuoMFATemplateType)),
DeleteContext: core.DeleteResource(ce.ConfExtensionIntegrationDelete(ce.DuoMFATemplateType)),
Description: "Manages [integration with Duo MFA](https://cyral.com/docs/mfa/duo).",
CreateContext: ce.CreateResource(resourceName, ce.DuoMFATemplateType),
ReadContext: ce.ReadResource(resourceName, ce.DuoMFATemplateType),
UpdateContext: ce.UpdateResource(resourceName, ce.DuoMFATemplateType),
DeleteContext: ce.DeleteResource(resourceName, ce.DuoMFATemplateType),

Schema: map[string]*schema.Schema{
"id": {
Expand Down
Loading

0 comments on commit 386a9dc

Please sign in to comment.