diff --git a/cyral/core/default_context_handler.go b/cyral/core/default_context_handler.go index 952c3d10..d7419a02 100644 --- a/cyral/core/default_context_handler.go +++ b/cyral/core/default_context_handler.go @@ -12,13 +12,19 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -// Implementation of a default context handler that can be used by all resources -// which API follows these principles: -// 1. The resource is backed by an ID coming from the API. -// 2. The creation is a POST that returns a JSON with an `id` field, meaning -// it can be used with the `IDBasedResponse` struct. -// 3. The endpoint to perform GET, PUT and DELETE calls are composed by the -// POST endpoint plus the ID specification like the following: +// Implementation of a default context handler that can be used by all resources. +// +// 1. `SchemaWriterFactoryGetMethod“ must be provided. +// 2. In case `SchemaWriterFactoryPostMethod“ is not provided, +// it will assume that a call to POST returns a JSON with +// an `id` field, meaning it will use the +// `IDBasedResponse` struct in such cases. +// 3. `BaseURLFactory` must be provided. It will be used to +// create the POST endpoint and others in case `IdBasedURLFactory` +// is not provided. +// 4. If `IdBasedURLFactory` is NOT provided, the endpoint to +// perform GET, PUT and DELETE calls are composed by the +// `BaseURLFactory` endpoint plus the ID specification as follows: // - POST: https://// // - GET: https:///// // - PUT: https:///// @@ -27,19 +33,25 @@ type DefaultContextHandler struct { ResourceName string ResourceType rt.ResourceType SchemaReaderFactory SchemaReaderFactoryFunc - SchemaWriterFactory SchemaWriterFactoryFunc - BaseURLFactory URLFactoryFunc + // SchemaWriterFactoryGetMethod defines how the schema will be + // written in GET operations. + SchemaWriterFactoryGetMethod SchemaWriterFactoryFunc + // SchemaWriterFactoryPostMethod defines how the schema will be + // written in POST operations. + SchemaWriterFactoryPostMethod SchemaWriterFactoryFunc + // BaseURLFactory provides the base URL used for POSTs and that + // will also be used to compose the ID URL in case the later + // is not provided. + BaseURLFactory URLFactoryFunc + IdBasedURLFactory URLFactoryFunc } -func defaultSchemaWriterFactory(d *schema.ResourceData) SchemaWriter { +func DefaultSchemaWriterFactory(d *schema.ResourceData) SchemaWriter { return &IDBasedResponse{} } -func defaultOperationHandler( - resourceName string, - resourceType rt.ResourceType, +func (dch DefaultContextHandler) defaultOperationHandler( operationType ot.OperationType, - baseURLFactory URLFactoryFunc, httpMethod string, schemaReaderFactory SchemaReaderFactoryFunc, schemaWriterFactory SchemaWriterFactoryFunc, @@ -47,25 +59,29 @@ func defaultOperationHandler( // POST = https://// // GET, PUT and DELETE = https:///// endpoint := func(d *schema.ResourceData, c *client.Client) string { - url := baseURLFactory(d, c) - if d.Id() != "" { - url = fmt.Sprintf("%s/%s", baseURLFactory(d, c), d.Id()) + var url string + if httpMethod == http.MethodPost { + url = dch.BaseURLFactory(d, c) + } else if dch.IdBasedURLFactory != nil { + url = dch.IdBasedURLFactory(d, c) + } else { + url = fmt.Sprintf("%s/%s", dch.BaseURLFactory(d, c), d.Id()) } tflog.Debug(context.Background(), fmt.Sprintf("Returning base URL for %s '%s' operation '%s' and httpMethod %s: %s", - resourceType, resourceName, operationType, httpMethod, url)) + dch.ResourceType, dch.ResourceName, operationType, httpMethod, url)) return url } var errorHandler RequestErrorHandler if httpMethod == http.MethodGet { - errorHandler = &ReadIgnoreHttpNotFound{ResName: resourceName} + errorHandler = &ReadIgnoreHttpNotFound{ResName: dch.ResourceName} } else if httpMethod == http.MethodDelete { - errorHandler = &DeleteIgnoreHttpNotFound{ResName: resourceName} + errorHandler = &DeleteIgnoreHttpNotFound{ResName: dch.ResourceName} } result := ResourceOperationConfig{ - ResourceName: resourceName, + ResourceName: dch.ResourceName, Type: operationType, - ResourceType: resourceType, + ResourceType: dch.ResourceType, HttpMethod: httpMethod, URLFactory: endpoint, SchemaReaderFactory: schemaReaderFactory, @@ -77,9 +93,15 @@ func defaultOperationHandler( } func (dch DefaultContextHandler) CreateContext() schema.CreateContextFunc { + // By default, assumes that if no SchemaWriterFactoryPostMethod is provided, + // the POST api will return an ID + schemaWriterPost := DefaultSchemaWriterFactory + if dch.SchemaWriterFactoryPostMethod != nil { + schemaWriterPost = dch.SchemaWriterFactoryPostMethod + } return CreateResource( - defaultOperationHandler(dch.ResourceName, dch.ResourceType, ot.Create, dch.BaseURLFactory, http.MethodPost, dch.SchemaReaderFactory, nil), - defaultOperationHandler(dch.ResourceName, dch.ResourceType, ot.Create, dch.BaseURLFactory, http.MethodGet, nil, dch.SchemaWriterFactory), + dch.defaultOperationHandler(ot.Create, http.MethodPost, dch.SchemaReaderFactory, schemaWriterPost), + dch.defaultOperationHandler(ot.Create, http.MethodGet, nil, dch.SchemaWriterFactoryGetMethod), ) } @@ -87,16 +109,15 @@ func (dch DefaultContextHandler) ReadContext() schema.ReadContextFunc { return ReadResource(dch.ReadResourceOperationConfig()) } func (dch DefaultContextHandler) ReadResourceOperationConfig() ResourceOperationConfig { - return defaultOperationHandler(dch.ResourceName, dch.ResourceType, ot.Read, dch.BaseURLFactory, http.MethodGet, nil, dch.SchemaWriterFactory) + return dch.defaultOperationHandler(ot.Read, http.MethodGet, nil, dch.SchemaWriterFactoryGetMethod) } func (dch DefaultContextHandler) UpdateContext() schema.UpdateContextFunc { return UpdateResource( - defaultOperationHandler(dch.ResourceName, dch.ResourceType, ot.Update, dch.BaseURLFactory, http.MethodPut, dch.SchemaReaderFactory, nil), - defaultOperationHandler(dch.ResourceName, dch.ResourceType, ot.Update, dch.BaseURLFactory, http.MethodGet, nil, dch.SchemaWriterFactory)) + dch.defaultOperationHandler(ot.Update, http.MethodPut, dch.SchemaReaderFactory, nil), + dch.defaultOperationHandler(ot.Update, http.MethodGet, nil, dch.SchemaWriterFactoryGetMethod)) } func (dch DefaultContextHandler) DeleteContext() schema.DeleteContextFunc { - return DeleteResource(defaultOperationHandler( - dch.ResourceName, dch.ResourceType, ot.Delete, dch.BaseURLFactory, http.MethodDelete, nil, nil)) + return DeleteResource(dch.defaultOperationHandler(ot.Delete, http.MethodDelete, nil, nil)) } diff --git a/cyral/core/resource.go b/cyral/core/resource.go index 7256de2f..8a0e4a59 100644 --- a/cyral/core/resource.go +++ b/cyral/core/resource.go @@ -139,20 +139,10 @@ func handleRequests(operations []ResourceOperationConfig) func(context.Context, ) } - // If a `SchemaWriterFactory` implementation is NOT provided and this is a creation operation, - // use the `defaultSchemaWriterFactory`, assuming the response is a JSON with an `id` field. - /// TODO: Remove this feature after refactoring all resources to use the `DefaultContext`. - var responseDataFunc SchemaWriterFactoryFunc - if body != nil { - if operation.SchemaWriterFactory == nil && operation.Type == operationtype.Create { - responseDataFunc = defaultSchemaWriterFactory - tflog.Debug(ctx, "NewResponseData function set to defaultSchemaWriterFactory.") - } else { - responseDataFunc = operation.SchemaWriterFactory - } - } - if responseDataFunc != nil { - if responseData := responseDataFunc(d); responseData != nil { + if operation.SchemaWriterFactory == nil { + tflog.Debug(ctx, fmt.Sprintf("No SchemaWriterFactory found to %s resource %s", operation.Type, operation.ResourceName)) + } else { + if responseData := operation.SchemaWriterFactory(d); responseData != nil { tflog.Debug(ctx, fmt.Sprintf("NewResponseData function call performed. d: %#v", d)) if err := json.Unmarshal(body, responseData); err != nil { return utils.CreateError("Unable to unmarshall JSON", err.Error()) diff --git a/cyral/internal/datalabel/resource.go b/cyral/internal/datalabel/resource.go index e3953636..332a8c65 100644 --- a/cyral/internal/datalabel/resource.go +++ b/cyral/internal/datalabel/resource.go @@ -17,10 +17,10 @@ import ( func resourceSchema() *schema.Resource { contextHandler := core.DefaultContextHandler{ - ResourceName: resourceName, - ResourceType: resourcetype.Resource, - SchemaReaderFactory: func() core.SchemaReader { return &DataLabel{} }, - SchemaWriterFactory: func(_ *schema.ResourceData) core.SchemaWriter { return &DataLabel{} }, + ResourceName: resourceName, + ResourceType: resourcetype.Resource, + SchemaReaderFactory: func() core.SchemaReader { return &DataLabel{} }, + SchemaWriterFactoryGetMethod: func(_ *schema.ResourceData) core.SchemaWriter { return &DataLabel{} }, BaseURLFactory: func(d *schema.ResourceData, c *client.Client) string { return fmt.Sprintf("https://%s/v1/datalabels", c.ControlPlane) @@ -114,7 +114,7 @@ func resourceSchema() *schema.Resource { } var readDataLabelConfig = core.ResourceOperationConfig{ - ResourceName: "DataLabelResourceRead", + ResourceName: resourceName, Type: operationtype.Read, HttpMethod: http.MethodGet, URLFactory: func(d *schema.ResourceData, c *client.Client) string { diff --git a/cyral/internal/deprecated/resource_cyral_integration_datadog.go b/cyral/internal/deprecated/resource_cyral_integration_datadog.go index ebc3bf19..f1a067ae 100644 --- a/cyral/internal/deprecated/resource_cyral_integration_datadog.go +++ b/cyral/internal/deprecated/resource_cyral_integration_datadog.go @@ -30,10 +30,10 @@ func (data *DatadogIntegration) ReadFromSchema(d *schema.ResourceData) error { func ResourceIntegrationDatadog() *schema.Resource { contextHandler := core.DefaultContextHandler{ - ResourceName: "Datadog Integration", - ResourceType: resourcetype.Resource, - SchemaReaderFactory: func() core.SchemaReader { return &DatadogIntegration{} }, - SchemaWriterFactory: func(_ *schema.ResourceData) core.SchemaWriter { return &DatadogIntegration{} }, + ResourceName: "Datadog Integration", + ResourceType: resourcetype.Resource, + SchemaReaderFactory: func() core.SchemaReader { return &DatadogIntegration{} }, + SchemaWriterFactoryGetMethod: func(_ *schema.ResourceData) core.SchemaWriter { return &DatadogIntegration{} }, BaseURLFactory: func(d *schema.ResourceData, c *client.Client) string { return fmt.Sprintf("https://%s/v1/integrations/datadog", c.ControlPlane) }, diff --git a/cyral/internal/deprecated/resource_cyral_integration_elk.go b/cyral/internal/deprecated/resource_cyral_integration_elk.go index 0293c427..f0031f9a 100644 --- a/cyral/internal/deprecated/resource_cyral_integration_elk.go +++ b/cyral/internal/deprecated/resource_cyral_integration_elk.go @@ -33,10 +33,10 @@ func (data *ELKIntegration) ReadFromSchema(d *schema.ResourceData) error { func ResourceIntegrationELK() *schema.Resource { contextHandler := core.DefaultContextHandler{ - ResourceName: "ELK Integration", - ResourceType: resourcetype.Resource, - SchemaReaderFactory: func() core.SchemaReader { return &ELKIntegration{} }, - SchemaWriterFactory: func(_ *schema.ResourceData) core.SchemaWriter { return &ELKIntegration{} }, + ResourceName: "ELK Integration", + ResourceType: resourcetype.Resource, + SchemaReaderFactory: func() core.SchemaReader { return &ELKIntegration{} }, + SchemaWriterFactoryGetMethod: func(_ *schema.ResourceData) core.SchemaWriter { return &ELKIntegration{} }, BaseURLFactory: func(d *schema.ResourceData, c *client.Client) string { return fmt.Sprintf("https://%s/v1/integrations/elk", c.ControlPlane) }, diff --git a/cyral/internal/deprecated/resource_cyral_integration_logstash.go b/cyral/internal/deprecated/resource_cyral_integration_logstash.go index a4198d0e..88ba38a0 100644 --- a/cyral/internal/deprecated/resource_cyral_integration_logstash.go +++ b/cyral/internal/deprecated/resource_cyral_integration_logstash.go @@ -37,10 +37,10 @@ func (data *LogstashIntegration) ReadFromSchema(d *schema.ResourceData) error { func ResourceIntegrationLogstash() *schema.Resource { contextHandler := core.DefaultContextHandler{ - ResourceName: "Logstash Integration", - ResourceType: resourcetype.Resource, - SchemaReaderFactory: func() core.SchemaReader { return &LogstashIntegration{} }, - SchemaWriterFactory: func(_ *schema.ResourceData) core.SchemaWriter { return &LogstashIntegration{} }, + ResourceName: "Logstash Integration", + ResourceType: resourcetype.Resource, + SchemaReaderFactory: func() core.SchemaReader { return &LogstashIntegration{} }, + SchemaWriterFactoryGetMethod: func(_ *schema.ResourceData) core.SchemaWriter { return &LogstashIntegration{} }, BaseURLFactory: func(d *schema.ResourceData, c *client.Client) string { return fmt.Sprintf("https://%s/v1/integrations/logstash", c.ControlPlane) }, diff --git a/cyral/internal/deprecated/resource_cyral_integration_looker.go b/cyral/internal/deprecated/resource_cyral_integration_looker.go index 34751e29..f67f6cf8 100644 --- a/cyral/internal/deprecated/resource_cyral_integration_looker.go +++ b/cyral/internal/deprecated/resource_cyral_integration_looker.go @@ -31,10 +31,10 @@ func (data *LookerIntegration) ReadFromSchema(d *schema.ResourceData) error { func ResourceIntegrationLooker() *schema.Resource { contextHandler := core.DefaultContextHandler{ - ResourceName: "Looker Integration", - ResourceType: resourcetype.Resource, - SchemaReaderFactory: func() core.SchemaReader { return &LookerIntegration{} }, - SchemaWriterFactory: func(_ *schema.ResourceData) core.SchemaWriter { return &LookerIntegration{} }, + ResourceName: "Looker Integration", + ResourceType: resourcetype.Resource, + SchemaReaderFactory: func() core.SchemaReader { return &LookerIntegration{} }, + SchemaWriterFactoryGetMethod: func(_ *schema.ResourceData) core.SchemaWriter { return &LookerIntegration{} }, BaseURLFactory: func(d *schema.ResourceData, c *client.Client) string { return fmt.Sprintf("https://%s/v1/integrations/looker", c.ControlPlane) }, diff --git a/cyral/internal/deprecated/resource_cyral_integration_splunk.go b/cyral/internal/deprecated/resource_cyral_integration_splunk.go index 8db2ff53..50c41d96 100644 --- a/cyral/internal/deprecated/resource_cyral_integration_splunk.go +++ b/cyral/internal/deprecated/resource_cyral_integration_splunk.go @@ -41,10 +41,10 @@ func (data *SplunkIntegration) ReadFromSchema(d *schema.ResourceData) error { func ResourceIntegrationSplunk() *schema.Resource { contextHandler := core.DefaultContextHandler{ - ResourceName: "Splunk Integration", - ResourceType: resourcetype.Resource, - SchemaReaderFactory: func() core.SchemaReader { return &SplunkIntegration{} }, - SchemaWriterFactory: func(_ *schema.ResourceData) core.SchemaWriter { return &SplunkIntegration{} }, + ResourceName: "Splunk Integration", + ResourceType: resourcetype.Resource, + SchemaReaderFactory: func() core.SchemaReader { return &SplunkIntegration{} }, + SchemaWriterFactoryGetMethod: func(_ *schema.ResourceData) core.SchemaWriter { return &SplunkIntegration{} }, BaseURLFactory: func(d *schema.ResourceData, c *client.Client) string { return fmt.Sprintf("https://%s/v1/integrations/splunk", c.ControlPlane) }, diff --git a/cyral/internal/deprecated/resource_cyral_integration_sumo_logic.go b/cyral/internal/deprecated/resource_cyral_integration_sumo_logic.go index 4a4b1d05..9459bef1 100644 --- a/cyral/internal/deprecated/resource_cyral_integration_sumo_logic.go +++ b/cyral/internal/deprecated/resource_cyral_integration_sumo_logic.go @@ -28,10 +28,10 @@ func (data *SumoLogicIntegration) ReadFromSchema(d *schema.ResourceData) error { func ResourceIntegrationSumoLogic() *schema.Resource { contextHandler := core.DefaultContextHandler{ - ResourceName: "SumoLogic Integration", - ResourceType: resourcetype.Resource, - SchemaReaderFactory: func() core.SchemaReader { return &SumoLogicIntegration{} }, - SchemaWriterFactory: func(_ *schema.ResourceData) core.SchemaWriter { return &SumoLogicIntegration{} }, + ResourceName: "SumoLogic Integration", + ResourceType: resourcetype.Resource, + SchemaReaderFactory: func() core.SchemaReader { return &SumoLogicIntegration{} }, + SchemaWriterFactoryGetMethod: func(_ *schema.ResourceData) core.SchemaWriter { return &SumoLogicIntegration{} }, BaseURLFactory: func(d *schema.ResourceData, c *client.Client) string { return fmt.Sprintf("https://%s/v1/integrations/sumologic", c.ControlPlane) }, diff --git a/cyral/internal/integration/awsiam/resource_cyral_integration_aws_iam.go b/cyral/internal/integration/awsiam/resource_cyral_integration_aws_iam.go index 49b2e5c9..81eaaeed 100644 --- a/cyral/internal/integration/awsiam/resource_cyral_integration_aws_iam.go +++ b/cyral/internal/integration/awsiam/resource_cyral_integration_aws_iam.go @@ -64,10 +64,10 @@ func (wrapper *AWSIAMIntegrationWrapper) ReadFromSchema(d *schema.ResourceData) func ResourceIntegrationAWSIAM() *schema.Resource { contextHandler := core.DefaultContextHandler{ - ResourceName: "AWS IAM Integration", - ResourceType: resourcetype.Resource, - SchemaReaderFactory: func() core.SchemaReader { return &AWSIAMIntegrationWrapper{} }, - SchemaWriterFactory: func(_ *schema.ResourceData) core.SchemaWriter { return &AWSIAMIntegrationWrapper{} }, + ResourceName: "AWS IAM Integration", + ResourceType: resourcetype.Resource, + SchemaReaderFactory: func() core.SchemaReader { return &AWSIAMIntegrationWrapper{} }, + SchemaWriterFactoryGetMethod: func(_ *schema.ResourceData) core.SchemaWriter { return &AWSIAMIntegrationWrapper{} }, BaseURLFactory: func(d *schema.ResourceData, c *client.Client) string { return fmt.Sprintf("https://%s/v1/integrations/aws/iam", c.ControlPlane) }, diff --git a/cyral/internal/integration/confextension/model_integration_confextension.go b/cyral/internal/integration/confextension/model_integration_confextension.go index 8bdc93a1..3fa3e8fa 100644 --- a/cyral/internal/integration/confextension/model_integration_confextension.go +++ b/cyral/internal/integration/confextension/model_integration_confextension.go @@ -102,6 +102,7 @@ func ConfExtensionIntegrationCreate(templateType string) core.ResourceOperationC SchemaReaderFactory: func() core.SchemaReader { return NewIntegrationConfExtension(templateType) }, + SchemaWriterFactory: core.DefaultSchemaWriterFactory, } } diff --git a/cyral/internal/integration/hcvault/resource.go b/cyral/internal/integration/hcvault/resource.go index d717859e..f0fd8b77 100644 --- a/cyral/internal/integration/hcvault/resource.go +++ b/cyral/internal/integration/hcvault/resource.go @@ -10,10 +10,10 @@ import ( ) var resourceContextHandler = core.DefaultContextHandler{ - ResourceName: resourceName, - ResourceType: resourcetype.Resource, - SchemaReaderFactory: func() core.SchemaReader { return &HCVaultIntegration{} }, - SchemaWriterFactory: func(_ *schema.ResourceData) core.SchemaWriter { return &HCVaultIntegration{} }, + ResourceName: resourceName, + ResourceType: resourcetype.Resource, + SchemaReaderFactory: func() core.SchemaReader { return &HCVaultIntegration{} }, + SchemaWriterFactoryGetMethod: func(_ *schema.ResourceData) core.SchemaWriter { return &HCVaultIntegration{} }, BaseURLFactory: func(d *schema.ResourceData, c *client.Client) string { return fmt.Sprintf("https://%s/v1/integrations/secretProviders/hcvault", c.ControlPlane) }, diff --git a/cyral/internal/integration/hcvault/schema_loader.go b/cyral/internal/integration/hcvault/schema_loader.go index 9499b202..159aa501 100644 --- a/cyral/internal/integration/hcvault/schema_loader.go +++ b/cyral/internal/integration/hcvault/schema_loader.go @@ -6,7 +6,7 @@ type packageSchema struct { } func (p *packageSchema) Name() string { - return "HC Vault Integration" + return "hcvault" } func (p *packageSchema) Schemas() []*core.SchemaDescriptor { diff --git a/cyral/internal/integration/logging/resource_cyral_integration_logging.go b/cyral/internal/integration/logging/resource_cyral_integration_logging.go index d03988c5..e860e2d7 100644 --- a/cyral/internal/integration/logging/resource_cyral_integration_logging.go +++ b/cyral/internal/integration/logging/resource_cyral_integration_logging.go @@ -181,6 +181,7 @@ func CreateLoggingIntegration() core.ResourceOperationConfig { return fmt.Sprintf("https://%s/v1/integrations/logging", c.ControlPlane) }, SchemaReaderFactory: func() core.SchemaReader { return &LoggingIntegration{} }, + SchemaWriterFactory: core.DefaultSchemaWriterFactory, } } diff --git a/cyral/internal/integration/slack/resource.go b/cyral/internal/integration/slack/resource.go index fe711b33..9bfb8ff3 100644 --- a/cyral/internal/integration/slack/resource.go +++ b/cyral/internal/integration/slack/resource.go @@ -10,10 +10,10 @@ import ( ) var resourceContextHandler = core.DefaultContextHandler{ - ResourceName: resourceName, - ResourceType: resourcetype.Resource, - SchemaReaderFactory: func() core.SchemaReader { return &SlackAlertsIntegration{} }, - SchemaWriterFactory: func(_ *schema.ResourceData) core.SchemaWriter { return &SlackAlertsIntegration{} }, + ResourceName: resourceName, + ResourceType: resourcetype.Resource, + SchemaReaderFactory: func() core.SchemaReader { return &SlackAlertsIntegration{} }, + SchemaWriterFactoryGetMethod: func(_ *schema.ResourceData) core.SchemaWriter { return &SlackAlertsIntegration{} }, BaseURLFactory: func(d *schema.ResourceData, c *client.Client) string { return fmt.Sprintf("https://%s/v1/integrations/notifications/slack", c.ControlPlane) }, diff --git a/cyral/internal/integration/slack/schema_loader.go b/cyral/internal/integration/slack/schema_loader.go index 458a3e91..c08b2fcb 100644 --- a/cyral/internal/integration/slack/schema_loader.go +++ b/cyral/internal/integration/slack/schema_loader.go @@ -6,7 +6,7 @@ type packageSchema struct { } func (p *packageSchema) Name() string { - return "Slack Integration" + return "slack" } func (p *packageSchema) Schemas() []*core.SchemaDescriptor { diff --git a/cyral/internal/integration/teams/resource.go b/cyral/internal/integration/teams/resource.go index 4d513a66..bd1e6a67 100644 --- a/cyral/internal/integration/teams/resource.go +++ b/cyral/internal/integration/teams/resource.go @@ -12,10 +12,10 @@ import ( ) var resourceContextHandler = core.DefaultContextHandler{ - ResourceName: resourceName, - ResourceType: resourcetype.Resource, - SchemaReaderFactory: func() core.SchemaReader { return &MsTeamsIntegration{} }, - SchemaWriterFactory: func(_ *schema.ResourceData) core.SchemaWriter { return &MsTeamsIntegration{} }, + ResourceName: resourceName, + ResourceType: resourcetype.Resource, + SchemaReaderFactory: func() core.SchemaReader { return &MsTeamsIntegration{} }, + SchemaWriterFactoryGetMethod: func(_ *schema.ResourceData) core.SchemaWriter { return &MsTeamsIntegration{} }, BaseURLFactory: func(d *schema.ResourceData, c *client.Client) string { return fmt.Sprintf("https://%s/v1/integrations/notifications/teams", c.ControlPlane) }, diff --git a/cyral/internal/integration/teams/schema_loader.go b/cyral/internal/integration/teams/schema_loader.go index 75c24700..196bcaf8 100644 --- a/cyral/internal/integration/teams/schema_loader.go +++ b/cyral/internal/integration/teams/schema_loader.go @@ -6,7 +6,7 @@ type packageSchema struct { } func (p *packageSchema) Name() string { - return "Microsoft Teams Integration" + return "teams" } func (p *packageSchema) Schemas() []*core.SchemaDescriptor { diff --git a/cyral/internal/repository/accessgateway/schema_loader.go b/cyral/internal/repository/accessgateway/schema_loader.go index 6c1fdf43..ce0734f9 100644 --- a/cyral/internal/repository/accessgateway/schema_loader.go +++ b/cyral/internal/repository/accessgateway/schema_loader.go @@ -8,7 +8,7 @@ type packageSchema struct { } func (p *packageSchema) Name() string { - return "repository_access_gateway" + return "accessgateway" } func (p *packageSchema) Schemas() []*core.SchemaDescriptor { diff --git a/cyral/internal/repository/binding/constants.go b/cyral/internal/repository/binding/constants.go new file mode 100644 index 00000000..90517f12 --- /dev/null +++ b/cyral/internal/repository/binding/constants.go @@ -0,0 +1,9 @@ +package binding + +const ( + resourceName = "cyral_repository_binding" + + BindingEnabledKey = "enabled" + ListenerBindingKey = "listener_binding" + NodeIndexKey = "node_index" +) diff --git a/cyral/internal/repository/binding/model.go b/cyral/internal/repository/binding/model.go new file mode 100644 index 00000000..0d58d899 --- /dev/null +++ b/cyral/internal/repository/binding/model.go @@ -0,0 +1,97 @@ +package binding + +import ( + "github.com/cyralinc/terraform-provider-cyral/cyral/utils" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +type ListenerBindings []*ListenerBinding + +type Binding struct { + BindingID string `json:"id,omitempty"` + RepoId string `json:"repoId,omitempty"` + Enabled bool `json:"enabled,omitempty"` + ListenerBindings ListenerBindings `json:"listenerBindings,omitempty"` +} + +type ListenerBinding struct { + ListenerID string `json:"listenerId,omitempty"` + NodeIndex uint32 `json:"nodeIndex,omitempty"` +} + +type CreateBindingRequest struct { + SidecarID string `json:"sidecarId,omitempty"` + Binding *Binding `json:"binding,omitempty"` +} + +type CreateBindingResponse struct { + BindingID string `json:"bindingId,omitempty"` +} + +type GetBindingResponse struct { + Binding *Binding `json:"binding,omitempty"` +} + +func (r *CreateBindingResponse) WriteToSchema(d *schema.ResourceData) error { + d.Set(utils.BindingIDKey, r.BindingID) + d.SetId(utils.MarshalComposedID( + []string{ + d.Get(utils.SidecarIDKey).(string), + r.BindingID, + }, "/")) + return nil +} + +func (r *GetBindingResponse) WriteToSchema(d *schema.ResourceData) error { + return r.Binding.WriteToSchema(d) +} + +func (r *Binding) WriteToSchema(d *schema.ResourceData) error { + d.Set(utils.BindingIDKey, r.BindingID) + d.Set(BindingEnabledKey, r.Enabled) + d.Set(utils.RepositoryIDKey, r.RepoId) + d.Set(ListenerBindingKey, r.ListenerBindings.AsInterface()) + return nil +} + +func (r *CreateBindingRequest) ReadFromSchema(d *schema.ResourceData) error { + r.SidecarID = d.Get(utils.SidecarIDKey).(string) + r.Binding = &Binding{} + return r.Binding.ReadFromSchema(d) +} + +func (r *Binding) ReadFromSchema(d *schema.ResourceData) error { + r.BindingID = d.Get(utils.BindingIDKey).(string) + r.Enabled = d.Get(BindingEnabledKey).(bool) + r.RepoId = d.Get(utils.RepositoryIDKey).(string) + r.ListenerBindingsFromInterface(d.Get(ListenerBindingKey).([]interface{})) + return nil +} + +func (r *ListenerBindings) AsInterface() []interface{} { + if r == nil { + return nil + } + listenerBindings := make([]interface{}, len(*r)) + for i, listenerBinding := range *r { + listenerBindings[i] = map[string]interface{}{ + utils.ListenerIDKey: listenerBinding.ListenerID, + NodeIndexKey: listenerBinding.NodeIndex, + } + } + return listenerBindings +} + +func (r *Binding) ListenerBindingsFromInterface(i []interface{}) { + if len(i) == 0 { + return + } + listenerBindings := make([]*ListenerBinding, len(i)) + for index, listenerBinding := range i { + listenerBindings[index] = &ListenerBinding{ + ListenerID: listenerBinding.(map[string]interface{})[utils.ListenerIDKey].(string), + NodeIndex: uint32(listenerBinding.(map[string]interface{})[NodeIndexKey].(int)), + } + } + r.ListenerBindings = listenerBindings +} diff --git a/cyral/internal/repository/binding/resource.go b/cyral/internal/repository/binding/resource.go new file mode 100644 index 00000000..78d1fa8a --- /dev/null +++ b/cyral/internal/repository/binding/resource.go @@ -0,0 +1,102 @@ +package binding + +import ( + "context" + "fmt" + + "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/resourcetype" + "github.com/cyralinc/terraform-provider-cyral/cyral/utils" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func resourceSchema() *schema.Resource { + contextHandler := core.DefaultContextHandler{ + ResourceName: resourceName, + ResourceType: resourcetype.Resource, + SchemaReaderFactory: func() core.SchemaReader { return &CreateBindingRequest{} }, + SchemaWriterFactoryGetMethod: func(_ *schema.ResourceData) core.SchemaWriter { return &GetBindingResponse{} }, + SchemaWriterFactoryPostMethod: func(_ *schema.ResourceData) core.SchemaWriter { return &CreateBindingResponse{} }, + BaseURLFactory: func(d *schema.ResourceData, c *client.Client) string { + return fmt.Sprintf("https://%s/v1/sidecars/%s/bindings", + c.ControlPlane, + d.Get(utils.SidecarIDKey).(string)) + }, + IdBasedURLFactory: func(d *schema.ResourceData, c *client.Client) string { + return fmt.Sprintf("https://%s/v1/sidecars/%s/bindings/%s", + c.ControlPlane, + d.Get(utils.SidecarIDKey).(string), + d.Get(utils.BindingIDKey).(string), + ) + }, + } + return &schema.Resource{ + Description: "Manages [cyral repository to sidecar bindings](https://cyral.com/docs/sidecars/sidecar-assign-repo).", + CreateContext: contextHandler.CreateContext(), + ReadContext: contextHandler.ReadContext(), + UpdateContext: contextHandler.UpdateContext(), + DeleteContext: contextHandler.DeleteContext(), + SchemaVersion: 2, + Schema: map[string]*schema.Schema{ + utils.BindingIDKey: { + Description: "ID of the binding. Computed and assigned to binding at the time of creation.", + Computed: true, + Type: schema.TypeString, + }, + utils.SidecarIDKey: { + Description: "ID of the sidecar that will be bound to the given repository.", + Required: true, + ForceNew: true, + Type: schema.TypeString, + }, + utils.RepositoryIDKey: { + Description: "ID of the repository that will be bound to the sidecar.", + Required: true, + ForceNew: true, + Type: schema.TypeString, + }, + BindingEnabledKey: { + Description: "Enable or disable all listener bindings.", + Type: schema.TypeBool, + Optional: true, + Default: true, + }, + ListenerBindingKey: { + Description: "The configuration for listeners associated with the binding. At least one `listener_binding` is required.", + Type: schema.TypeList, + Required: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + utils.ListenerIDKey: { + Description: "The sidecar listener that this binding is associated with.", + Required: true, + Type: schema.TypeString, + }, + + NodeIndexKey: { + Description: "The index of the repo node that this binding is associated with.", + Optional: true, + Type: schema.TypeInt, + }, + }, + }, + }, + }, + Importer: &schema.ResourceImporter{ + StateContext: func( + ctx context.Context, + d *schema.ResourceData, + m interface{}, + ) ([]*schema.ResourceData, error) { + ids, err := utils.UnMarshalComposedID(d.Id(), "/", 2) + if err != nil { + return nil, err + } + d.Set(utils.SidecarIDKey, ids[0]) + d.Set(utils.BindingIDKey, ids[1]) + return []*schema.ResourceData{d}, nil + }, + }, + } +} diff --git a/cyral/internal/repository/binding/resource_cyral_repository_binding.go b/cyral/internal/repository/binding/resource_cyral_repository_binding.go deleted file mode 100644 index 217702a8..00000000 --- a/cyral/internal/repository/binding/resource_cyral_repository_binding.go +++ /dev/null @@ -1,239 +0,0 @@ -package binding - -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/utils" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" -) - -const ( - BindingEnabledKey = "enabled" - ListenerBindingKey = "listener_binding" - NodeIndexKey = "node_index" -) - -type Binding struct { - BindingID string `json:"id,omitempty"` - RepoId string `json:"repoId,omitempty"` - Enabled bool `json:"enabled,omitempty"` - ListenerBindings []*ListenerBinding `json:"listenerBindings,omitempty"` -} - -type ListenerBinding struct { - ListenerID string `json:"listenerId,omitempty"` - NodeIndex uint32 `json:"nodeIndex,omitempty"` -} - -type CreateBindingRequest struct { - SidecarID string `json:"sidecarId,omitempty"` - Binding *Binding `json:"binding,omitempty"` -} - -type CreateBindingResponse struct { - BindingID string `json:"bindingId,omitempty"` -} - -type GetBindingResponse struct { - Binding *Binding `json:"binding,omitempty"` -} - -func (r *CreateBindingResponse) WriteToSchema(d *schema.ResourceData) error { - d.Set(utils.BindingIDKey, r.BindingID) - d.SetId(utils.MarshalComposedID( - []string{ - d.Get(utils.SidecarIDKey).(string), - r.BindingID, - }, "/")) - return nil -} - -func (r *GetBindingResponse) WriteToSchema(d *schema.ResourceData) error { - return r.Binding.WriteToSchema(d) -} - -func (r *Binding) WriteToSchema(d *schema.ResourceData) error { - d.Set(utils.BindingIDKey, r.BindingID) - d.Set(BindingEnabledKey, r.Enabled) - d.Set(utils.RepositoryIDKey, r.RepoId) - d.Set(ListenerBindingKey, r.ListenerBindingsAsInterface()) - return nil -} - -func (r *CreateBindingRequest) ReadFromSchema(d *schema.ResourceData) error { - r.SidecarID = d.Get(utils.SidecarIDKey).(string) - r.Binding = &Binding{} - return r.Binding.ReadFromSchema(d) -} - -func (r *Binding) ReadFromSchema(d *schema.ResourceData) error { - r.BindingID = d.Get(utils.BindingIDKey).(string) - r.Enabled = d.Get(BindingEnabledKey).(bool) - r.RepoId = d.Get(utils.RepositoryIDKey).(string) - r.ListenerBindingsFromInterface(d.Get(ListenerBindingKey).([]interface{})) - return nil -} - -func (r *Binding) ListenerBindingsAsInterface() []interface{} { - if r.ListenerBindings == nil { - return nil - } - listenerBindings := make([]interface{}, len(r.ListenerBindings)) - for i, listenerBinding := range r.ListenerBindings { - listenerBindings[i] = map[string]interface{}{ - utils.ListenerIDKey: listenerBinding.ListenerID, - NodeIndexKey: listenerBinding.NodeIndex, - } - } - return listenerBindings -} - -func (r *Binding) ListenerBindingsFromInterface(i []interface{}) { - if len(i) == 0 { - return - } - listenerBindings := make([]*ListenerBinding, len(i)) - for index, listenerBinding := range i { - listenerBindings[index] = &ListenerBinding{ - ListenerID: listenerBinding.(map[string]interface{})[utils.ListenerIDKey].(string), - NodeIndex: uint32(listenerBinding.(map[string]interface{})[NodeIndexKey].(int)), - } - } - r.ListenerBindings = listenerBindings -} - -var ReadRepositoryBindingConfig = core.ResourceOperationConfig{ - ResourceName: "RepositoryBindingResourceRead", - Type: operationtype.Read, - HttpMethod: http.MethodGet, - URLFactory: func(d *schema.ResourceData, c *client.Client) string { - return fmt.Sprintf("https://%s/v1/sidecars/%s/bindings/%s", - c.ControlPlane, - d.Get(utils.SidecarIDKey).(string), - d.Get(utils.BindingIDKey).(string), - ) - }, - SchemaWriterFactory: func(_ *schema.ResourceData) core.SchemaWriter { - return &GetBindingResponse{} - }, - RequestErrorHandler: &core.ReadIgnoreHttpNotFound{ResName: "Repository binding"}, -} - -func ResourceRepositoryBinding() *schema.Resource { - return &schema.Resource{ - Description: "Manages [cyral repository to sidecar bindings](https://cyral.com/docs/sidecars/sidecar-assign-repo).", - CreateContext: core.CreateResource( - core.ResourceOperationConfig{ - ResourceName: "RepositoryBindingResourceCreate", - Type: operationtype.Create, - HttpMethod: http.MethodPost, - URLFactory: func(d *schema.ResourceData, c *client.Client) string { - return fmt.Sprintf("https://%s/v1/sidecars/%s/bindings", - c.ControlPlane, - d.Get(utils.SidecarIDKey).(string)) - - }, - SchemaReaderFactory: func() core.SchemaReader { return &CreateBindingRequest{} }, - SchemaWriterFactory: func(_ *schema.ResourceData) core.SchemaWriter { return &CreateBindingResponse{} }, - }, ReadRepositoryBindingConfig, - ), - ReadContext: core.ReadResource(ReadRepositoryBindingConfig), - UpdateContext: core.UpdateResource( - core.ResourceOperationConfig{ - ResourceName: "RepositoryBindingResourceUpdate", - Type: operationtype.Update, - HttpMethod: http.MethodPut, - URLFactory: func(d *schema.ResourceData, c *client.Client) string { - return fmt.Sprintf("https://%s/v1/sidecars/%s/bindings/%s", - c.ControlPlane, - d.Get(utils.SidecarIDKey).(string), - d.Get(utils.BindingIDKey).(string), - ) - - }, - SchemaReaderFactory: func() core.SchemaReader { return &CreateBindingRequest{} }, - }, ReadRepositoryBindingConfig, - ), - DeleteContext: core.DeleteResource( - core.ResourceOperationConfig{ - ResourceName: "RepositoryBindingResourceDelete", - Type: operationtype.Delete, - HttpMethod: http.MethodDelete, - URLFactory: func(d *schema.ResourceData, c *client.Client) string { - return fmt.Sprintf("https://%s/v1/sidecars/%s/bindings/%s", - c.ControlPlane, - d.Get(utils.SidecarIDKey).(string), - d.Get(utils.BindingIDKey).(string), - ) - }, - }, - ), - - SchemaVersion: 2, - Schema: map[string]*schema.Schema{ - utils.BindingIDKey: { - Description: "ID of the binding. Computed and assigned to binding at the time of creation.", - Computed: true, - Type: schema.TypeString, - }, - utils.SidecarIDKey: { - Description: "ID of the sidecar that will be bound to the given repository.", - Required: true, - ForceNew: true, - Type: schema.TypeString, - }, - utils.RepositoryIDKey: { - Description: "ID of the repository that will be bound to the sidecar.", - Required: true, - ForceNew: true, - Type: schema.TypeString, - }, - BindingEnabledKey: { - Description: "Enable or disable all listener bindings.", - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - ListenerBindingKey: { - Description: "The configuration for listeners associated with the binding. At least one `listener_binding` is required.", - Type: schema.TypeList, - Required: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - utils.ListenerIDKey: { - Description: "The sidecar listener that this binding is associated with.", - Required: true, - Type: schema.TypeString, - }, - - NodeIndexKey: { - Description: "The index of the repo node that this binding is associated with.", - Optional: true, - Type: schema.TypeInt, - }, - }, - }, - }, - }, - Importer: &schema.ResourceImporter{ - StateContext: func( - ctx context.Context, - d *schema.ResourceData, - m interface{}, - ) ([]*schema.ResourceData, error) { - ids, err := utils.UnMarshalComposedID(d.Id(), "/", 2) - if err != nil { - return nil, err - } - d.Set(utils.SidecarIDKey, ids[0]) - d.Set(utils.BindingIDKey, ids[1]) - return []*schema.ResourceData{d}, nil - }, - }, - } -} diff --git a/cyral/internal/repository/binding/resource_cyral_repository_binding_test.go b/cyral/internal/repository/binding/resource_test.go similarity index 100% rename from cyral/internal/repository/binding/resource_cyral_repository_binding_test.go rename to cyral/internal/repository/binding/resource_test.go diff --git a/cyral/internal/repository/binding/schema_loader.go b/cyral/internal/repository/binding/schema_loader.go new file mode 100644 index 00000000..6f551f7b --- /dev/null +++ b/cyral/internal/repository/binding/schema_loader.go @@ -0,0 +1,26 @@ +package binding + +import ( + "github.com/cyralinc/terraform-provider-cyral/cyral/core" +) + +type packageSchema struct { +} + +func (p *packageSchema) Name() string { + return "binding" +} + +func (p *packageSchema) Schemas() []*core.SchemaDescriptor { + return []*core.SchemaDescriptor{ + { + Name: resourceName, + Type: core.ResourceSchemaType, + Schema: resourceSchema, + }, + } +} + +func PackageSchema() core.PackageSchema { + return &packageSchema{} +} diff --git a/cyral/internal/repository/data_source.go b/cyral/internal/repository/data_source.go index ee0623ff..d5f5d1c7 100644 --- a/cyral/internal/repository/data_source.go +++ b/cyral/internal/repository/data_source.go @@ -58,10 +58,10 @@ func (resp *GetReposResponse) WriteToSchema(d *schema.ResourceData) error { } var dsContextHandler = core.DefaultContextHandler{ - ResourceName: dataSourceName, - ResourceType: resourcetype.DataSource, - SchemaWriterFactory: func(_ *schema.ResourceData) core.SchemaWriter { return &GetReposResponse{} }, - BaseURLFactory: func(d *schema.ResourceData, c *client.Client) string { + ResourceName: dataSourceName, + ResourceType: resourcetype.DataSource, + SchemaWriterFactoryGetMethod: func(_ *schema.ResourceData) core.SchemaWriter { return &GetReposResponse{} }, + IdBasedURLFactory: func(d *schema.ResourceData, c *client.Client) string { nameFilter := d.Get("name").(string) typeFilter := d.Get("type").(string) urlParams := utils.UrlQuery(map[string]string{ diff --git a/cyral/internal/repository/resource.go b/cyral/internal/repository/resource.go index f100a4b4..37a3ac4c 100644 --- a/cyral/internal/repository/resource.go +++ b/cyral/internal/repository/resource.go @@ -12,10 +12,10 @@ import ( ) var resourceContextHandler = core.DefaultContextHandler{ - ResourceName: resourceName, - ResourceType: resourcetype.Resource, - SchemaReaderFactory: func() core.SchemaReader { return &RepoInfo{} }, - SchemaWriterFactory: func(_ *schema.ResourceData) core.SchemaWriter { return &GetRepoByIDResponse{} }, + ResourceName: resourceName, + ResourceType: resourcetype.Resource, + SchemaReaderFactory: func() core.SchemaReader { return &RepoInfo{} }, + SchemaWriterFactoryGetMethod: func(_ *schema.ResourceData) core.SchemaWriter { return &GetRepoByIDResponse{} }, BaseURLFactory: func(d *schema.ResourceData, c *client.Client) string { return fmt.Sprintf( "https://%s/v1/repos", diff --git a/cyral/internal/repository/useraccount/schema_loader.go b/cyral/internal/repository/useraccount/schema_loader.go index a57e0e8d..86b59280 100644 --- a/cyral/internal/repository/useraccount/schema_loader.go +++ b/cyral/internal/repository/useraccount/schema_loader.go @@ -6,7 +6,7 @@ type packageSchema struct { } func (p *packageSchema) Name() string { - return "User Account" + return "useraccount" } func (p *packageSchema) Schemas() []*core.SchemaDescriptor { diff --git a/cyral/internal/samlcertificate/schema_loader.go b/cyral/internal/samlcertificate/schema_loader.go index 10234985..5535706d 100644 --- a/cyral/internal/samlcertificate/schema_loader.go +++ b/cyral/internal/samlcertificate/schema_loader.go @@ -6,7 +6,7 @@ type packageSchema struct { } func (p *packageSchema) Name() string { - return "SAML Certificate" + return "samlcertificate" } func (p *packageSchema) Schemas() []*core.SchemaDescriptor { diff --git a/cyral/provider/provider.go b/cyral/provider/provider.go index 843e80b4..2f6b564f 100644 --- a/cyral/provider/provider.go +++ b/cyral/provider/provider.go @@ -21,7 +21,6 @@ import ( "github.com/cyralinc/terraform-provider-cyral/cyral/internal/policy" "github.com/cyralinc/terraform-provider-cyral/cyral/internal/policy/rule" "github.com/cyralinc/terraform-provider-cyral/cyral/internal/regopolicy" - "github.com/cyralinc/terraform-provider-cyral/cyral/internal/repository/binding" "github.com/cyralinc/terraform-provider-cyral/cyral/internal/repository/confanalysis" "github.com/cyralinc/terraform-provider-cyral/cyral/internal/repository/confauth" "github.com/cyralinc/terraform-provider-cyral/cyral/internal/repository/network" @@ -164,7 +163,6 @@ func getResourceMap(ps []core.PackageSchema) map[string]*schema.Resource { schemaMap["cyral_policy"] = policy.ResourcePolicy() schemaMap["cyral_policy_rule"] = rule.ResourcePolicyRule() schemaMap["cyral_rego_policy_instance"] = regopolicy.ResourceRegoPolicyInstance() - schemaMap["cyral_repository_binding"] = binding.ResourceRepositoryBinding() schemaMap["cyral_repository_conf_auth"] = confauth.ResourceRepositoryConfAuth() schemaMap["cyral_repository_conf_analysis"] = confanalysis.ResourceRepositoryConfAnalysis() schemaMap["cyral_repository_network_access_policy"] = network.ResourceRepositoryNetworkAccessPolicy() diff --git a/cyral/provider/schema_loader.go b/cyral/provider/schema_loader.go index 8c94c7fa..7516dfb6 100644 --- a/cyral/provider/schema_loader.go +++ b/cyral/provider/schema_loader.go @@ -9,6 +9,7 @@ import ( "github.com/cyralinc/terraform-provider-cyral/cyral/internal/repository" "github.com/cyralinc/terraform-provider-cyral/cyral/internal/repository/accessgateway" "github.com/cyralinc/terraform-provider-cyral/cyral/internal/repository/accessrules" + "github.com/cyralinc/terraform-provider-cyral/cyral/internal/repository/binding" "github.com/cyralinc/terraform-provider-cyral/cyral/internal/repository/datamap" "github.com/cyralinc/terraform-provider-cyral/cyral/internal/repository/useraccount" "github.com/cyralinc/terraform-provider-cyral/cyral/internal/samlcertificate" @@ -19,6 +20,7 @@ func packagesSchemas() []core.PackageSchema { v := []core.PackageSchema{ accessgateway.PackageSchema(), accessrules.PackageSchema(), + binding.PackageSchema(), datalabel.PackageSchema(), datamap.PackageSchema(), hcvault.PackageSchema(),