diff --git a/docs/data-sources/cloud_config_rules.md b/docs/data-sources/cloud_config_rules.md
new file mode 100644
index 0000000..4bf8e4c
--- /dev/null
+++ b/docs/data-sources/cloud_config_rules.md
@@ -0,0 +1,138 @@
+---
+# generated by https://github.com/hashicorp/terraform-plugin-docs
+page_title: "wiz_cloud_config_rules Data Source - terraform-provider-wiz"
+subcategory: ""
+description: |-
+ Query cloud configuration rules.
+---
+
+# wiz_cloud_config_rules (Data Source)
+
+Query cloud configuration rules.
+
+## Example Usage
+
+```terraform
+# get aws cloud configuration rules for access keys
+data "wiz_cloud_config_rules" "aws_access_key" {
+ search = "Access key"
+ cloud_provider = [
+ "AWS",
+ ]
+}
+
+# get high and critical aws cloud configuration rules that have remediation
+data "wiz_cloud_config_rules" "aws_critical" {
+ cloud_provider = [
+ "AWS",
+ ]
+ severity = [
+ "CRITICAL",
+ "HIGH",
+ ]
+ has_remediation = true
+}
+```
+
+
+## Schema
+
+### Optional
+
+- `cloud_provider` (List of String) Find CSPM rules related to cloud provider.
+ - Allowed values:
+ - GCP
+ - AWS
+ - Azure
+ - OCI
+ - Alibaba
+ - vSphere
+ - OpenShift
+ - Kubernetes
+- `created_by` (List of String) Search rules by user.
+- `enabled` (Boolean) CSPM Rule enabled status.
+- `first` (Number) How many results to return
+ - Defaults to `500`.
+- `framework_category` (List of String) Search rules by any of securityFramework | securitySubCategory | securityCategory.
+- `function_as_control` (Boolean) Search by function as control.
+- `has_auto_remediation` (Boolean) Rule has auto remediation.
+- `has_remediation` (Boolean) Rule has remediation.
+- `ids` (List of String) GetSearch by IDs.
+- `is_opa_policy` (Boolean) Search by opaPolicy presence.
+- `matcher_type` (List of String) Search rules by target native type.
+ - Allowed values:
+ - CLOUD
+ - TERRAFORM
+ - CLOUD_FORMATION
+ - KUBERNETES
+ - AZURE_RESOURCE_MANAGER
+ - DOCKER_FILE
+- `project` (List of String) Search by project.
+- `risk_equals_all` (List of String)
+- `risk_equals_any` (List of String)
+- `scope_account_ids` (List of String) Find CSPM rules applied on cloud account IDs.
+- `search` (String) Free text search on CSPM name or resource ID.
+- `service_type` (List of String) Find CSPM rules related to the service.
+ - Allowed values:
+ - AWS
+ - Azure
+ - GCP
+ - OCI
+ - Alibaba
+ - AKS
+ - EKS
+ - GKE
+ - Kubernetes
+ - OKE
+- `severity` (List of String) CSPM Rule severity.
+ - Allowed values:
+ - INFORMATIONAL
+ - LOW
+ - MEDIUM
+ - HIGH
+ - CRITICAL
+- `subject_entity_type` (List of String) Find rules by their entity type subject.
+- `target_native_type` (List of String) Search rules by target native type.
+
+### Read-Only
+
+- `cloud_configuration_rules` (Set of Object) The returned cloud configuration rules. (see [below for nested schema](#nestedatt--cloud_configuration_rules))
+- `id` (String) Internal identifier for the data.
+
+
+### Nested Schema for `cloud_configuration_rules`
+
+Read-Only:
+
+- `builtin` (Boolean)
+- `cloud_provider` (String)
+- `control_id` (String)
+- `description` (String)
+- `enabled` (Boolean)
+- `external_references` (Set of Object) (see [below for nested schema](#nestedobjatt--cloud_configuration_rules--external_references))
+- `function_as_control` (Boolean)
+- `graph_id` (String)
+- `has_auto_remediation` (Boolean)
+- `iac_matcher_ids` (List of String)
+- `id` (String)
+- `name` (String)
+- `opa_policy` (String)
+- `remediation_instructions` (String)
+- `scope_accounts` (List of String)
+- `security_sub_category_ids` (List of String)
+- `service_type` (String)
+- `severity` (String)
+- `short_id` (String)
+- `subject_entity_type` (String)
+- `supports_nrt` (Boolean)
+- `target_native_types` (List of String)
+
+
+### Nested Schema for `cloud_configuration_rules.external_references`
+
+Read-Only:
+
+- `id` (String)
+- `name` (String)
+
+
diff --git a/docs/index.md b/docs/index.md
index e421b84..23a0c11 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -6,7 +6,7 @@ description: |-
# terraform-provider-wiz
-The Wiz Terraform provider is designed to work with [Wiz](https://app.wiz.io/).
+The Wiz Terraform provider is designed to work with [Wiz](https://wiz.io/).
The "wiz" provider manages resources typically manually managed in the [Wiz web interface](https://app.wiz.io/). You must configure the provider with the proper credentials before you can use it.
diff --git a/examples/data-sources/wiz_cloud_config_rules/data-source.tf b/examples/data-sources/wiz_cloud_config_rules/data-source.tf
new file mode 100644
index 0000000..b5d88e7
--- /dev/null
+++ b/examples/data-sources/wiz_cloud_config_rules/data-source.tf
@@ -0,0 +1,19 @@
+# get aws cloud configuration rules for access keys
+data "wiz_cloud_config_rules" "aws_access_key" {
+ search = "Access key"
+ cloud_provider = [
+ "AWS",
+ ]
+}
+
+# get high and critical aws cloud configuration rules that have remediation
+data "wiz_cloud_config_rules" "aws_critical" {
+ cloud_provider = [
+ "AWS",
+ ]
+ severity = [
+ "CRITICAL",
+ "HIGH",
+ ]
+ has_remediation = true
+}
diff --git a/internal/provider/data_source_cloud_accounts.go b/internal/provider/data_source_cloud_accounts.go
index 6d5e2e0..b474d3e 100644
--- a/internal/provider/data_source_cloud_accounts.go
+++ b/internal/provider/data_source_cloud_accounts.go
@@ -6,6 +6,7 @@ import (
"crypto/sha1"
"encoding/hex"
"fmt"
+ "sort"
"github.com/hashicorp/terraform-plugin-log/tflog"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
@@ -322,7 +323,10 @@ func dataSourceWizCloudAccountsRead(ctx context.Context, d *schema.ResourceData,
if b {
filterBy.Search = utils.ConvertListToString(a.([]interface{}))
}
- filterBy.ProjectID = d.Get("project_id").(string)
+ a, b = d.GetOk("project_id")
+ if b {
+ filterBy.ProjectID = a.(string)
+ }
a, b = d.GetOk("cloud_provider")
if b {
filterBy.CloudProvider = utils.ConvertListToString(a.([]interface{}))
@@ -339,8 +343,14 @@ func dataSourceWizCloudAccountsRead(ctx context.Context, d *schema.ResourceData,
if b {
filterBy.ConnectorIssueID = utils.ConvertListToString(a.([]interface{}))
}
- filterBy.AssignedToProject = utils.ConvertBoolToPointer(d.Get("assigned_to_project").(bool))
- filterBy.HasMultipleConnectorSources = utils.ConvertBoolToPointer(d.Get("has_multiple_connector_sources").(bool))
+ a, b = d.GetOk("assigned_to_project")
+ if b {
+ filterBy.AssignedToProject = utils.ConvertBoolToPointer(a.(bool))
+ }
+ a, b = d.GetOk("has_multiple_connector_sources")
+ if b {
+ filterBy.HasMultipleConnectorSources = utils.ConvertBoolToPointer(a.(bool))
+ }
vars.FilterBy = filterBy
// process the request
@@ -356,8 +366,6 @@ func dataSourceWizCloudAccountsRead(ctx context.Context, d *schema.ResourceData,
return append(diags, diag.FromErr(err)...)
}
- tflog.Debug(ctx, "Finished")
-
return diags
}
@@ -380,6 +388,11 @@ func flattenCloudAccounts(ctx context.Context, nodes *[]*vendor.CloudAccount) []
output = append(output, accountMap)
}
+ // sort the return slice to avoid unwanted diffs
+ sort.Slice(output, func(i, j int) bool {
+ return output[i].(map[string]interface{})["id"].(string) < output[j].(map[string]interface{})["id"].(string)
+ })
+
tflog.Debug(ctx, fmt.Sprintf("flattenCloudAccounts output: %s", utils.PrettyPrint(output)))
return output
@@ -396,6 +409,11 @@ func flattenProjectIDs(ctx context.Context, projects *[]*vendor.Project) []inter
output = append(output, b.ID)
}
+ // sort the return slice to avoid unwanted diffs
+ sort.Slice(output, func(i, j int) bool {
+ return output[i].(string) < output[j].(string)
+ })
+
tflog.Debug(ctx, fmt.Sprintf("flattenProjectIDs output: %s", utils.PrettyPrint(output)))
return output
@@ -412,6 +430,11 @@ func flattenSourceConnectorIDs(ctx context.Context, connectors *[]vendor.Connect
output = append(output, b.ID)
}
+ // sort the return slice to avoid unwanted diffs
+ sort.Slice(output, func(i, j int) bool {
+ return output[i].(string) < output[j].(string)
+ })
+
tflog.Debug(ctx, fmt.Sprintf("flattenSourceConnectorIDs output: %s", utils.PrettyPrint(output)))
return output
diff --git a/internal/provider/data_source_cloud_accounts_test.go b/internal/provider/data_source_cloud_accounts_test.go
index aa698e2..566adbd 100644
--- a/internal/provider/data_source_cloud_accounts_test.go
+++ b/internal/provider/data_source_cloud_accounts_test.go
@@ -18,8 +18,8 @@ func TestFlattenCloudAccounts(t *testing.T) {
"cloud_provider": "0767b7a3-d540-4b9c-8afd-a018aa7da0fb",
"status": "9b6e7ae9-e0f6-4748-8171-a6b7a8f385ec",
"linked_project_ids": []interface{}{
- "55e9138d-e48f-4155-a2ac-364eb00005db",
"3d9ef88a-84f9-4a84-9a67-e5cdd28ad35f",
+ "55e9138d-e48f-4155-a2ac-364eb00005db",
},
"source_connector_ids": []interface{}{
"7ac2f620-3882-4c35-91f0-7631eef430c6",
@@ -68,8 +68,8 @@ func TestFlattenCloudAccounts(t *testing.T) {
func TestFlattenProjectIDs(t *testing.T) {
ctx := context.Background()
expected := []interface{}{
- "b0a03462-697e-4ef8-af52-0e8122c6eb7f",
"225697ef-8d21-42e1-8195-46d29b285ee6",
+ "b0a03462-697e-4ef8-af52-0e8122c6eb7f",
"d24f22fb-088d-4586-ba8a-9524260f7427",
}
@@ -99,9 +99,9 @@ func TestFlattenProjectIDs(t *testing.T) {
func TestFlattenSourceConnectorIDs(t *testing.T) {
ctx := context.Background()
expected := []interface{}{
- "d84b87ad-a38f-4ff1-9ee3-761521fbbaab",
- "796def2c-70c6-4dc6-85a1-991616a98f4a",
"317d6352-69e0-47e0-a280-76dd3e2e9659",
+ "796def2c-70c6-4dc6-85a1-991616a98f4a",
+ "d84b87ad-a38f-4ff1-9ee3-761521fbbaab",
}
var connectors = &[]vendor.Connector{
diff --git a/internal/provider/data_source_cloud_configuration_rules.go b/internal/provider/data_source_cloud_configuration_rules.go
new file mode 100644
index 0000000..c4c1b02
--- /dev/null
+++ b/internal/provider/data_source_cloud_configuration_rules.go
@@ -0,0 +1,823 @@
+package provider
+
+import (
+ "bytes"
+ "context"
+ "crypto/sha1"
+ "encoding/hex"
+ "fmt"
+ "sort"
+
+ "github.com/hashicorp/terraform-plugin-log/tflog"
+ "github.com/hashicorp/terraform-plugin-sdk/v2/diag"
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
+
+ "wiz.io/hashicorp/terraform-provider-wiz/internal"
+ "wiz.io/hashicorp/terraform-provider-wiz/internal/client"
+ "wiz.io/hashicorp/terraform-provider-wiz/internal/utils"
+ "wiz.io/hashicorp/terraform-provider-wiz/internal/vendor"
+)
+
+func dataSourceWizCloudConfigurationRules() *schema.Resource {
+ return &schema.Resource{
+ Description: "Query cloud configuration rules.",
+ Schema: map[string]*schema.Schema{
+ "id": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "Internal identifier for the data.",
+ },
+ "first": {
+ Type: schema.TypeInt,
+ Optional: true,
+ Default: 500,
+ Description: "How many results to return",
+ },
+ "search": {
+ Type: schema.TypeString,
+ Optional: true,
+ Description: "Free text search on CSPM name or resource ID.",
+ },
+ "scope_account_ids": {
+ Type: schema.TypeList,
+ Optional: true,
+ Description: "Find CSPM rules applied on cloud account IDs.",
+ Elem: &schema.Schema{
+ Type: schema.TypeString,
+ },
+ },
+ "cloud_provider": {
+ Type: schema.TypeList,
+ Optional: true,
+ Description: fmt.Sprintf("Find CSPM rules related to cloud provider.\n - Allowed values: %s",
+ utils.SliceOfStringToMDUList(
+ vendor.CloudProvider,
+ ),
+ ),
+ Elem: &schema.Schema{
+ Type: schema.TypeString,
+ ValidateDiagFunc: validation.ToDiagFunc(
+ validation.StringInSlice(
+ vendor.CloudProvider,
+ false,
+ ),
+ ),
+ },
+ },
+ "service_type": {
+ Type: schema.TypeList,
+ Optional: true,
+ Description: fmt.Sprintf("Find CSPM rules related to the service.\n - Allowed values: %s",
+ utils.SliceOfStringToMDUList(
+ vendor.CloudConfigurationRuleServiceType,
+ ),
+ ),
+ Elem: &schema.Schema{
+ Type: schema.TypeString,
+ ValidateDiagFunc: validation.ToDiagFunc(
+ validation.StringInSlice(
+ vendor.CloudConfigurationRuleServiceType,
+ false,
+ ),
+ ),
+ },
+ },
+ "subject_entity_type": {
+ Type: schema.TypeList,
+ Optional: true,
+ Description: "Find rules by their entity type subject.",
+ Elem: &schema.Schema{
+ Type: schema.TypeString,
+ },
+ },
+ "severity": {
+ Type: schema.TypeList,
+ Optional: true,
+ Description: fmt.Sprintf("CSPM Rule severity.\n - Allowed values: %s",
+ utils.SliceOfStringToMDUList(
+ vendor.Severity,
+ ),
+ ),
+ Elem: &schema.Schema{
+ Type: schema.TypeString,
+ ValidateDiagFunc: validation.ToDiagFunc(
+ validation.StringInSlice(
+ vendor.Severity,
+ false,
+ ),
+ ),
+ },
+ },
+ "enabled": {
+ Type: schema.TypeBool,
+ Optional: true,
+ Description: "CSPM Rule enabled status.",
+ },
+ "has_auto_remediation": {
+ Type: schema.TypeBool,
+ Optional: true,
+ Description: "Rule has auto remediation.",
+ },
+ "has_remediation": {
+ Type: schema.TypeBool,
+ Optional: true,
+ Description: "Rule has remediation.",
+ },
+ "framework_category": {
+ Type: schema.TypeList,
+ Optional: true,
+ Description: "Search rules by any of securityFramework | securitySubCategory | securityCategory.",
+ Elem: &schema.Schema{
+ Type: schema.TypeString,
+ },
+ },
+ "target_native_type": {
+ Type: schema.TypeList,
+ Optional: true,
+ Description: "Search rules by target native type.",
+ Elem: &schema.Schema{
+ Type: schema.TypeString,
+ },
+ },
+ "created_by": {
+ Type: schema.TypeList,
+ Optional: true,
+ Description: "Search rules by user.",
+ Elem: &schema.Schema{
+ Type: schema.TypeString,
+ },
+ },
+ "is_opa_policy": {
+ Type: schema.TypeBool,
+ Optional: true,
+ Description: "Search by opaPolicy presence.",
+ },
+ "project": {
+ Type: schema.TypeList,
+ Optional: true,
+ Description: "Search by project.",
+ Elem: &schema.Schema{
+ Type: schema.TypeString,
+ },
+ },
+ "matcher_type": {
+ Type: schema.TypeList,
+ Optional: true,
+ Description: fmt.Sprintf("Search rules by target native type.\n - Allowed values: %s",
+ utils.SliceOfStringToMDUList(
+ vendor.CloudConfigurationRuleMatcherTypeFilter,
+ ),
+ ),
+ Elem: &schema.Schema{
+ Type: schema.TypeString,
+ ValidateDiagFunc: validation.ToDiagFunc(
+ validation.StringInSlice(
+ vendor.CloudConfigurationRuleMatcherTypeFilter,
+ false,
+ ),
+ ),
+ },
+ },
+ "ids": {
+ Type: schema.TypeList,
+ Optional: true,
+ Description: "GetSearch by IDs.",
+ Elem: &schema.Schema{
+ Type: schema.TypeString,
+ },
+ },
+ "function_as_control": {
+ Type: schema.TypeBool,
+ Optional: true,
+ Description: "Search by function as control.",
+ },
+ "risk_equals_any": {
+ Type: schema.TypeList,
+ Optional: true,
+ Elem: &schema.Schema{
+ Type: schema.TypeString,
+ },
+ },
+ "risk_equals_all": {
+ Type: schema.TypeList,
+ Optional: true,
+ Elem: &schema.Schema{
+ Type: schema.TypeString,
+ },
+ },
+ "cloud_configuration_rules": {
+ Type: schema.TypeSet,
+ Computed: true,
+ Description: "The returned cloud configuration rules.",
+ Elem: &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "id": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "Wiz UUID.",
+ },
+ "name": {
+ Type: schema.TypeString,
+ Computed: true,
+ },
+ "short_id": {
+ Type: schema.TypeString,
+ Computed: true,
+ },
+ "description": {
+ Type: schema.TypeString,
+ Computed: true,
+ },
+ "enabled": {
+ Type: schema.TypeBool,
+ Computed: true,
+ Description: "Rule enabled status.",
+ },
+ "severity": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "Rule severity will outcome to finding severity. This filed initial value is set as the severity of the CSPM rule.",
+ },
+ "external_references": {
+ Type: schema.TypeSet,
+ Computed: true,
+ Elem: &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "id": {
+ Type: schema.TypeString,
+ Computed: true,
+ },
+ "name": {
+ Type: schema.TypeString,
+ Computed: true,
+ },
+ },
+ },
+ },
+ "target_native_types": {
+ Type: schema.TypeList,
+ Optional: true,
+ Description: "The identifier types of the objects targeted by this rule, as seen on the cloud provider service. e.g. 'ec2'.",
+ Elem: &schema.Schema{
+ Type: schema.TypeString,
+ },
+ },
+ "supports_nrt": {
+ Type: schema.TypeBool,
+ Computed: true,
+ Description: "Rule enabled status.",
+ },
+ "subject_entity_type": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The rule subject entity type, as represented on Wiz Security Graph.",
+ },
+ "cloud_provider": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The cloud provider this rule is relevant to.",
+ },
+ "service_type": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The service this rule is relevant to.",
+ },
+ "scope_accounts": {
+ Type: schema.TypeList,
+ Optional: true,
+ Description: "Scope of subscription IDs for automatically asses with this rule on. If set to empty array rule will run on all environment",
+ Elem: &schema.Schema{
+ Type: schema.TypeString,
+ },
+ },
+ "security_sub_category_ids": {
+ Type: schema.TypeList,
+ Optional: true,
+ Elem: &schema.Schema{
+ Type: schema.TypeString,
+ },
+ },
+ "builtin": {
+ Type: schema.TypeBool,
+ Computed: true,
+ Description: "Indication whether the rule is built-in or custom.",
+ },
+ "opa_policy": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "OPA rego policy that this rule runs. Undefined for built-in code based configuration rules.",
+ },
+ "function_as_control": {
+ Type: schema.TypeBool,
+ Computed: true,
+ Description: "Make this rule also function as a control which means findings by this control will also trigger Issues.",
+ },
+ "control_id": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "In case this rule also functions as a control, this property will contain its details.",
+ },
+ "graph_id": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "The vertex id of this rule on the graph.",
+ },
+ "has_auto_remediation": {
+ Type: schema.TypeBool,
+ Computed: true,
+ },
+ "remediation_instructions": {
+ Type: schema.TypeString,
+ Computed: true,
+ },
+ "iac_matcher_ids": {
+ Type: schema.TypeList,
+ Optional: true,
+ Description: "OPA rego policies that this rule runs (Cloud / IaC rules).",
+ Elem: &schema.Schema{
+ Type: schema.TypeString,
+ },
+ },
+ },
+ },
+ },
+ },
+ ReadContext: dataSourceWizCloudConfigurationRuleRead,
+ }
+}
+
+// ReadCloudConfigurationRules struct
+type ReadCloudConfigurationRules struct {
+ CloudConfigurationRules vendor.CloudConfigurationRuleConnection `json:"cloudConfigurationRules"`
+}
+
+func dataSourceWizCloudConfigurationRuleRead(ctx context.Context, d *schema.ResourceData, m interface{}) (diags diag.Diagnostics) {
+ tflog.Info(ctx, "dataSourceWizCloudConfigurationRuleRead called...")
+
+ // generate the id for this resource
+ // id must be deterministic, so the id is based on a hash of the search parameters
+ var identifier bytes.Buffer
+
+ a, b := d.GetOk("first")
+ if b {
+ identifier.WriteString(utils.PrettyPrint(a))
+ }
+ a, b = d.GetOk("search")
+ if b {
+ identifier.WriteString(utils.PrettyPrint(a))
+ }
+ a, b = d.GetOk("scope_account_ids")
+ if b {
+ identifier.WriteString(utils.PrettyPrint(a))
+ }
+ a, b = d.GetOk("service_type")
+ if b {
+ identifier.WriteString(utils.PrettyPrint(a))
+ }
+ a, b = d.GetOk("subject_entity_type")
+ if b {
+ identifier.WriteString(utils.PrettyPrint(a))
+ }
+ a, b = d.GetOk("severity")
+ if b {
+ identifier.WriteString(utils.PrettyPrint(a))
+ }
+ a, b = d.GetOk("enabled")
+ if b {
+ identifier.WriteString(utils.PrettyPrint(a))
+ }
+ a, b = d.GetOk("has_auto_remediation")
+ if b {
+ identifier.WriteString(utils.PrettyPrint(a))
+ }
+ a, b = d.GetOk("has_remediation")
+ if b {
+ identifier.WriteString(utils.PrettyPrint(a))
+ }
+ a, b = d.GetOk("framework_category")
+ if b {
+ identifier.WriteString(utils.PrettyPrint(a))
+ }
+ a, b = d.GetOk("target_native_type")
+ if b {
+ identifier.WriteString(utils.PrettyPrint(a))
+ }
+ a, b = d.GetOk("created_by")
+ if b {
+ identifier.WriteString(utils.PrettyPrint(a))
+ }
+ a, b = d.GetOk("is_opa_policy")
+ if b {
+ identifier.WriteString(utils.PrettyPrint(a))
+ }
+ a, b = d.GetOk("project")
+ if b {
+ identifier.WriteString(utils.PrettyPrint(a))
+ }
+ a, b = d.GetOk("matcher_type")
+ if b {
+ identifier.WriteString(utils.PrettyPrint(a))
+ }
+ a, b = d.GetOk("ids")
+ if b {
+ identifier.WriteString(utils.PrettyPrint(a))
+ }
+ a, b = d.GetOk("function_as_control")
+ if b {
+ identifier.WriteString(utils.PrettyPrint(a))
+ }
+ a, b = d.GetOk("risk_equals_any")
+ if b {
+ identifier.WriteString(utils.PrettyPrint(a))
+ }
+ a, b = d.GetOk("risk_equals_all")
+ if b {
+ identifier.WriteString(utils.PrettyPrint(a))
+ }
+
+ h := sha1.New()
+ h.Write([]byte(identifier.String()))
+ hashID := hex.EncodeToString(h.Sum(nil))
+
+ // Set the id
+ d.SetId(hashID)
+
+ // define the graphql query
+ query := `query cloudConfigurationRules(
+ $filterBy: CloudConfigurationRuleFilters
+ $first: Int
+ $after: String
+ $orderBy: CloudConfigurationRuleOrder
+ ) {
+ cloudConfigurationRules(
+ filterBy: $filterBy
+ first: $first
+ after: $after
+ orderBy: $orderBy
+ ) {
+ nodes {
+ id
+ name
+ shortId
+ description
+ enabled
+ severity
+ externalReferences{
+ id
+ name
+ }
+ targetNativeTypes
+ supportsNRT
+ subjectEntityType
+ cloudProvider
+ serviceType
+ scopeAccounts {
+ id
+ }
+ securitySubCategories {
+ id
+ }
+ builtin
+ opaPolicy
+ functionAsControl
+ control {
+ id
+ }
+ graphId
+ hasAutoRemediation
+ remediationInstructions
+ iacMatchers {
+ id
+ }
+ }
+ pageInfo {
+ hasNextPage
+ endCursor
+ }
+ totalCount
+ }
+ }`
+
+ // set the resource parameters
+ err := d.Set("first", d.Get("first").(int))
+ if err != nil {
+ return append(diags, diag.FromErr(err)...)
+ }
+ err = d.Set("search", d.Get("search").(string))
+ if err != nil {
+ return append(diags, diag.FromErr(err)...)
+ }
+ err = d.Set("scope_account_ids", d.Get("scope_account_ids").([]interface{}))
+ if err != nil {
+ return append(diags, diag.FromErr(err)...)
+ }
+ err = d.Set("cloud_provider", d.Get("cloud_provider").([]interface{}))
+ if err != nil {
+ return append(diags, diag.FromErr(err)...)
+ }
+ err = d.Set("service_type", d.Get("service_type").([]interface{}))
+ if err != nil {
+ return append(diags, diag.FromErr(err)...)
+ }
+ err = d.Set("subject_entity_type", d.Get("subject_entity_type").([]interface{}))
+ if err != nil {
+ return append(diags, diag.FromErr(err)...)
+ }
+ err = d.Set("severity", d.Get("severity").([]interface{}))
+ if err != nil {
+ return append(diags, diag.FromErr(err)...)
+ }
+ a, b = d.GetOk("enabled")
+ if b {
+ err = d.Set("enabled", a.(bool))
+ if err != nil {
+ return append(diags, diag.FromErr(err)...)
+ }
+ }
+ a, b = d.GetOk("has_auto_remediation")
+ if b {
+ err = d.Set("has_auto_remediation", a.(bool))
+ if err != nil {
+ return append(diags, diag.FromErr(err)...)
+ }
+ }
+ a, b = d.GetOk("has_remediation")
+ if b {
+ err = d.Set("has_remediation", a.(bool))
+ if err != nil {
+ return append(diags, diag.FromErr(err)...)
+ }
+ }
+ err = d.Set("framework_category", d.Get("framework_category").([]interface{}))
+ if err != nil {
+ return append(diags, diag.FromErr(err)...)
+ }
+ err = d.Set("target_native_type", d.Get("target_native_type").([]interface{}))
+ if err != nil {
+ return append(diags, diag.FromErr(err)...)
+ }
+ err = d.Set("created_by", d.Get("created_by").([]interface{}))
+ if err != nil {
+ return append(diags, diag.FromErr(err)...)
+ }
+ a, b = d.GetOk("is_opa_policy")
+ if b {
+ err = d.Set("is_opa_policy", a.(bool))
+ if err != nil {
+ return append(diags, diag.FromErr(err)...)
+ }
+ }
+ err = d.Set("project", d.Get("project").([]interface{}))
+ if err != nil {
+ return append(diags, diag.FromErr(err)...)
+ }
+ err = d.Set("matcher_type", d.Get("matcher_type").([]interface{}))
+ if err != nil {
+ return append(diags, diag.FromErr(err)...)
+ }
+ err = d.Set("ids", d.Get("ids").([]interface{}))
+ if err != nil {
+ return append(diags, diag.FromErr(err)...)
+ }
+ a, b = d.GetOk("function_as_control")
+ if b {
+ err = d.Set("function_as_control", a.(bool))
+ if err != nil {
+ return append(diags, diag.FromErr(err)...)
+ }
+ }
+ err = d.Set("risk_equals_any", d.Get("risk_equals_any").([]interface{}))
+ if err != nil {
+ return append(diags, diag.FromErr(err)...)
+ }
+ err = d.Set("risk_equals_all", d.Get("risk_equals_all").([]interface{}))
+ if err != nil {
+ return append(diags, diag.FromErr(err)...)
+ }
+
+ // populate the graphql variables
+ vars := &internal.QueryVariables{}
+ vars.First = d.Get("first").(int)
+ filterBy := &vendor.CloudConfigurationRuleFilters{}
+ a, b = d.GetOk("search")
+ if b {
+ filterBy.Search = a.(string)
+ }
+ a, b = d.GetOk("scope_account_ids")
+ if b {
+ filterBy.ScopeAccountIDs = utils.ConvertListToString(a.([]interface{}))
+ }
+ a, b = d.GetOk("cloud_provider")
+ if b {
+ filterBy.CloudProvider = utils.ConvertListToString(a.([]interface{}))
+ }
+ a, b = d.GetOk("service_type")
+ if b {
+ filterBy.ServiceType = utils.ConvertListToString(a.([]interface{}))
+ }
+ a, b = d.GetOk("subject_entity_type")
+ if b {
+ filterBy.SubjectEntityType = utils.ConvertListToString(a.([]interface{}))
+ }
+ a, b = d.GetOk("severity")
+ if b {
+ filterBy.Severity = utils.ConvertListToString(a.([]interface{}))
+ }
+ a, b = d.GetOk("enabled")
+ if b {
+ filterBy.Enabled = utils.ConvertBoolToPointer(a.(bool))
+ }
+ a, b = d.GetOk("has_auto_remediation")
+ if b {
+ filterBy.HasAutoRemediation = utils.ConvertBoolToPointer(a.(bool))
+ }
+ a, b = d.GetOk("has_remediation")
+ if b {
+ filterBy.HasRemediation = utils.ConvertBoolToPointer(a.(bool))
+ }
+ a, b = d.GetOk("framework_category")
+ if b {
+ filterBy.FrameworkCategory = utils.ConvertListToString(a.([]interface{}))
+ }
+ a, b = d.GetOk("target_native_type")
+ if b {
+ filterBy.TargetNativeType = utils.ConvertListToString(a.([]interface{}))
+ }
+ a, b = d.GetOk("created_by")
+ if b {
+ filterBy.CreatedBy = utils.ConvertListToString(a.([]interface{}))
+ }
+ a, b = d.GetOk("is_opa_policy")
+ if b {
+ filterBy.IsOPAPolicy = utils.ConvertBoolToPointer(a.(bool))
+ }
+ a, b = d.GetOk("project")
+ if b {
+ filterBy.Project = utils.ConvertListToString(a.([]interface{}))
+ }
+ a, b = d.GetOk("matcher_type")
+ if b {
+ filterBy.MatcherType = utils.ConvertListToString(a.([]interface{}))
+ }
+ a, b = d.GetOk("ids")
+ if b {
+ filterBy.ID = utils.ConvertListToString(a.([]interface{}))
+ }
+ a, b = d.GetOk("function_as_control")
+ if b {
+ filterBy.FunctionAsControl = utils.ConvertBoolToPointer(a.(bool))
+ }
+ a, b = d.GetOk("risk_equals_any")
+ if b {
+ filterBy.RiskEqualsAny = utils.ConvertListToString(a.([]interface{}))
+ }
+ a, b = d.GetOk("risk_equals_all")
+ if b {
+ filterBy.RiskEqualsAll = utils.ConvertListToString(a.([]interface{}))
+ }
+
+ vars.FilterBy = filterBy
+
+ // process the request
+ data := &ReadCloudConfigurationRules{}
+ requestDiags := client.ProcessRequest(ctx, m, vars, data, query, "cloud_config_rules", "read")
+ diags = append(diags, requestDiags...)
+ if len(diags) > 0 {
+ return diags
+ }
+
+ cloudConfigurationRules := flattenCloudConfigurationRules(ctx, &data.CloudConfigurationRules.Nodes)
+ if err := d.Set("cloud_configuration_rules", cloudConfigurationRules); err != nil {
+ return append(diags, diag.FromErr(err)...)
+ }
+
+ return diags
+}
+
+func flattenCloudConfigurationRules(ctx context.Context, nodes *[]*vendor.CloudConfigurationRule) []interface{} {
+ tflog.Info(ctx, "flattenCloudConfigurationRules called...")
+ tflog.Debug(ctx, fmt.Sprintf("CloudConfigurationRules: %s", utils.PrettyPrint(nodes)))
+
+ // walk the slice and construct the list
+ var output = make([]interface{}, 0, 0)
+ for _, b := range *nodes {
+ tflog.Debug(ctx, fmt.Sprintf("b: %T %s", b, utils.PrettyPrint(b)))
+ ruleMap := make(map[string]interface{})
+ ruleMap["id"] = b.ID
+ ruleMap["name"] = b.Name
+ ruleMap["short_id"] = b.ShortID
+ ruleMap["description"] = b.Description
+ ruleMap["enabled"] = *b.Enabled
+ ruleMap["severity"] = b.Severity
+ ruleMap["external_references"] = flattenExternalReferences(ctx, &b.ExternalReferences)
+ ruleMap["target_native_types"] = b.TargetNativeTypes
+ ruleMap["supports_nrt"] = *b.SupportsNRT
+ ruleMap["subject_entity_type"] = b.SubjectEntityType
+ ruleMap["cloud_provider"] = b.CloudProvider
+ ruleMap["service_type"] = b.ServiceType
+ ruleMap["scope_accounts"] = flattenScopeAccounts(ctx, &b.ScopeAccounts)
+ ruleMap["security_sub_category_ids"] = flattenSecuritySubCategoryIDs(ctx, &b.SecuritySubCategories)
+ ruleMap["builtin"] = *b.Builtin
+ ruleMap["opa_policy"] = b.OPAPolicy
+ ruleMap["function_as_control"] = *b.FunctionAsControl
+ ruleMap["control_id"] = b.Control.ID
+ ruleMap["graph_id"] = b.GraphID
+ ruleMap["has_auto_remediation"] = *b.HasAutoRemediation
+ ruleMap["remediation_instructions"] = b.RemediationInstructions
+ ruleMap["iac_matcher_ids"] = flattenIACMatcherIDs(ctx, &b.IACMatchers)
+
+ output = append(output, ruleMap)
+ }
+
+ tflog.Debug(ctx, fmt.Sprintf("flattenCloudConfigurationRules output: %s", utils.PrettyPrint(output)))
+
+ return output
+}
+
+func flattenExternalReferences(ctx context.Context, refs *[]*vendor.CloudConfigurationRuleExternalReference) []interface{} {
+ tflog.Info(ctx, "flattenExternalReferences called...")
+ tflog.Debug(ctx, fmt.Sprintf("External References: %s", utils.PrettyPrint(refs)))
+
+ // walk the slice and construct the list
+ var output = make([]interface{}, 0, 0)
+ for _, b := range *refs {
+ tflog.Debug(ctx, fmt.Sprintf("b: %T %s", b, utils.PrettyPrint(b)))
+ refMap := make(map[string]interface{})
+ refMap["id"] = b.ID
+ refMap["name"] = b.Name
+ output = append(output, refMap)
+ }
+
+ // sort the return slice to avoid unwanted diffs
+ sort.Slice(output, func(i, j int) bool {
+ return output[i].(map[string]interface{})["id"].(string) < output[j].(map[string]interface{})["id"].(string)
+ })
+
+ tflog.Debug(ctx, fmt.Sprintf("flattenExternalReferences output: %s", utils.PrettyPrint(output)))
+
+ return output
+}
+
+func flattenScopeAccounts(ctx context.Context, accounts *[]*vendor.CloudAccount) []interface{} {
+ tflog.Info(ctx, "flattenScopeAccounts called...")
+ tflog.Debug(ctx, fmt.Sprintf("ScopeAccounts: %s", utils.PrettyPrint(accounts)))
+
+ // walk the slice and construct the list
+ var output = make([]interface{}, 0, 0)
+ for _, b := range *accounts {
+ tflog.Debug(ctx, fmt.Sprintf("b: %T %s", b, utils.PrettyPrint(b)))
+ output = append(output, b.ID)
+ }
+
+ // sort the return slice to avoid unwanted diffs
+ sort.Slice(output, func(i, j int) bool {
+ return output[i].(string) < output[j].(string)
+ })
+
+ tflog.Debug(ctx, fmt.Sprintf("flattenScopeAccounts output: %s", utils.PrettyPrint(output)))
+
+ return output
+}
+
+func flattenSecuritySubCategoryIDs(ctx context.Context, subCats *[]*vendor.SecuritySubCategory) []interface{} {
+ tflog.Info(ctx, "flattenSecuritySubCategoryIDs called...")
+ tflog.Debug(ctx, fmt.Sprintf("SecuritySubCategories: %s", utils.PrettyPrint(subCats)))
+
+ // walk the slice and construct the list
+ var output = make([]interface{}, 0, 0)
+ for _, b := range *subCats {
+ tflog.Debug(ctx, fmt.Sprintf("b: %T %s", b, utils.PrettyPrint(b)))
+ output = append(output, b.ID)
+ }
+
+ // sort the return slice to avoid unwanted diffs
+ sort.Slice(output, func(i, j int) bool {
+ return output[i].(string) < output[j].(string)
+ })
+
+ tflog.Debug(ctx, fmt.Sprintf("flattenSecuritySubCategoryIDs output: %s", utils.PrettyPrint(output)))
+
+ return output
+}
+
+func flattenIACMatcherIDs(ctx context.Context, matchers *[]*vendor.CloudConfigurationRuleMatcher) []interface{} {
+ tflog.Info(ctx, "flattenIACMatchers called...")
+ tflog.Debug(ctx, fmt.Sprintf("flattenIACMatchers: %s", utils.PrettyPrint(matchers)))
+
+ // walk the slice and construct the list
+ var output = make([]interface{}, 0, 0)
+ for _, b := range *matchers {
+ tflog.Debug(ctx, fmt.Sprintf("b: %T %s", b, utils.PrettyPrint(b)))
+ output = append(output, b.ID)
+ }
+
+ // sort the return slice to avoid unwanted diffs
+ sort.Slice(output, func(i, j int) bool {
+ return output[i].(string) < output[j].(string)
+ })
+
+ tflog.Debug(ctx, fmt.Sprintf("flattenIACMatchers output: %s", utils.PrettyPrint(output)))
+
+ return output
+}
diff --git a/internal/provider/data_source_cloud_configuration_rules_test.go b/internal/provider/data_source_cloud_configuration_rules_test.go
new file mode 100644
index 0000000..5bca7af
--- /dev/null
+++ b/internal/provider/data_source_cloud_configuration_rules_test.go
@@ -0,0 +1,294 @@
+package provider
+
+import (
+ "context"
+ "reflect"
+ "testing"
+
+ "wiz.io/hashicorp/terraform-provider-wiz/internal/utils"
+ "wiz.io/hashicorp/terraform-provider-wiz/internal/vendor"
+)
+
+func TestFlattenCloudConfigurationRules(t *testing.T) {
+ ctx := context.Background()
+ expected := []interface{}{
+ map[string]interface{}{
+ "id": "efc0d7e9-6a84-45f6-869c-529e337db6a8",
+ "name": "1d401010-0e50-4101-93c7-35b7f9226997",
+ "short_id": "ce84a427-7358-4fb8-853e-29fbdd4f3f55",
+ "description": "27669d80-612d-4e25-9c85-369625e2e990",
+ "enabled": false,
+ "severity": "565a7bb8-9f08-4e4f-96e0-da5af64e446a",
+ "target_native_types": []string{
+ "a3f18510-600c-42a0-854a-117e83965f31",
+ "5bcf4cca-8bc1-46bf-8dbc-404486397885",
+ "d88ccf3b-3c58-4209-b2cb-57291512b093",
+ },
+ "supports_nrt": false,
+ "subject_entity_type": "c53b5b06-5565-48e4-9ad7-2ecdb9596681",
+ "cloud_provider": "62c7de2d-d884-4b68-ae8b-f920ed1d60ba",
+ "service_type": "d65d3e25-36ed-45db-bf6b-50dc91c2bfc3",
+ "builtin": false,
+ "opa_policy": "49d5692f-7681-435d-8eb5-e5f22758ffb2",
+ "function_as_control": false,
+ "control_id": "ef708a85-0c78-4a50-b5eb-f44501dc5fc2",
+ "graph_id": "a81dc546-e3e3-4fbc-83c4-0ed5edbfa0c9",
+ "has_auto_remediation": false,
+ "remediation_instructions": "eb3e8071-49dd-4679-90d6-46bdf4387ee8",
+ "external_references": []interface{}{
+ map[string]interface{}{
+ "id": "0bbe2b15-31f1-4786-b2b9-c57704c10fbf",
+ "name": "7afbbec4-76c6-40e2-aeda-24e89f616df0",
+ },
+ map[string]interface{}{
+ "id": "43960b7b-09b3-4db7-90e7-7ad471071ba2",
+ "name": "0bb079f6-d315-4432-9192-d64a30c2cf0f",
+ },
+ map[string]interface{}{
+ "id": "f60d29dd-a16f-4fc0-949b-981b95dcdc16",
+ "name": "8feb5283-1e99-4ba5-b963-1ad631632be3",
+ },
+ },
+ "scope_accounts": []interface{}{
+ "42cecee6-45ec-41d0-8d66-b0571e2b6f62",
+ "868eb547-5b76-4b5e-b9a1-9aecec79846d",
+ "a9caf002-b075-43e9-b1cb-9cce1c809083",
+ },
+ "security_sub_category_ids": []interface{}{
+ "26b40cb3-5730-4097-a61f-c12ed69970bc",
+ "49817d03-5a33-4c52-b7bc-51d800d173de",
+ "83abe403-dc4d-43a1-b5e5-8a6d4b9f5182",
+ },
+ "iac_matcher_ids": []interface{}{
+ "4256c551-a971-4fd6-948c-d883c4964fae",
+ "4d5e2d5c-1157-487b-b9c1-7aa10bc83f83",
+ "56344421-3a12-42da-9c83-8377e3420733",
+ },
+ },
+ }
+
+ var configRules = &[]*vendor.CloudConfigurationRule{
+ {
+ Builtin: utils.ConvertBoolToPointer(false),
+ CloudProvider: "62c7de2d-d884-4b68-ae8b-f920ed1d60ba",
+ Control: &vendor.Control{
+ ID: "ef708a85-0c78-4a50-b5eb-f44501dc5fc2",
+ },
+ CreatedBy: &vendor.User{
+ ID: "7aa9f806-18b2-48fd-83d1-2c151d462ea7",
+ },
+ Description: "27669d80-612d-4e25-9c85-369625e2e990",
+ Enabled: utils.ConvertBoolToPointer(false),
+ ExternalReferences: []*vendor.CloudConfigurationRuleExternalReference{
+ {
+ ID: "0bbe2b15-31f1-4786-b2b9-c57704c10fbf",
+ Name: "7afbbec4-76c6-40e2-aeda-24e89f616df0",
+ },
+ {
+ ID: "f60d29dd-a16f-4fc0-949b-981b95dcdc16",
+ Name: "8feb5283-1e99-4ba5-b963-1ad631632be3",
+ },
+ {
+ ID: "43960b7b-09b3-4db7-90e7-7ad471071ba2",
+ Name: "0bb079f6-d315-4432-9192-d64a30c2cf0f",
+ },
+ },
+ FunctionAsControl: utils.ConvertBoolToPointer(false),
+ GraphID: "a81dc546-e3e3-4fbc-83c4-0ed5edbfa0c9",
+ HasAutoRemediation: utils.ConvertBoolToPointer(false),
+ IACMatchers: []*vendor.CloudConfigurationRuleMatcher{
+ {
+ ID: "4d5e2d5c-1157-487b-b9c1-7aa10bc83f83",
+ },
+ {
+ ID: "4256c551-a971-4fd6-948c-d883c4964fae",
+ },
+ {
+ ID: "56344421-3a12-42da-9c83-8377e3420733",
+ },
+ },
+ ID: "efc0d7e9-6a84-45f6-869c-529e337db6a8",
+ Name: "1d401010-0e50-4101-93c7-35b7f9226997",
+ OPAPolicy: "49d5692f-7681-435d-8eb5-e5f22758ffb2",
+ RemediationInstructions: "eb3e8071-49dd-4679-90d6-46bdf4387ee8",
+ ScopeAccounts: []*vendor.CloudAccount{
+ {
+ ID: "42cecee6-45ec-41d0-8d66-b0571e2b6f62",
+ },
+ {
+ ID: "a9caf002-b075-43e9-b1cb-9cce1c809083",
+ },
+ {
+ ID: "868eb547-5b76-4b5e-b9a1-9aecec79846d",
+ },
+ },
+ SecuritySubCategories: []*vendor.SecuritySubCategory{
+ {
+ ID: "49817d03-5a33-4c52-b7bc-51d800d173de",
+ },
+ {
+ ID: "83abe403-dc4d-43a1-b5e5-8a6d4b9f5182",
+ },
+ {
+ ID: "26b40cb3-5730-4097-a61f-c12ed69970bc",
+ },
+ },
+ ServiceType: "d65d3e25-36ed-45db-bf6b-50dc91c2bfc3",
+ Severity: "565a7bb8-9f08-4e4f-96e0-da5af64e446a",
+ ShortID: "ce84a427-7358-4fb8-853e-29fbdd4f3f55",
+ SubjectEntityType: "c53b5b06-5565-48e4-9ad7-2ecdb9596681",
+ SupportsNRT: utils.ConvertBoolToPointer(false),
+ TargetNativeTypes: []string{
+ "a3f18510-600c-42a0-854a-117e83965f31",
+ "5bcf4cca-8bc1-46bf-8dbc-404486397885",
+ "d88ccf3b-3c58-4209-b2cb-57291512b093",
+ },
+ },
+ }
+
+ flattened := flattenCloudConfigurationRules(ctx, configRules)
+
+ if !reflect.DeepEqual(flattened, expected) {
+ t.Fatalf(
+ "Got:\n\n%#v\n\nExpected:\n\n%#v\n",
+ flattened,
+ expected,
+ )
+ }
+}
+
+func TestFlattenExternalReferences(t *testing.T) {
+ ctx := context.Background()
+ expected := []interface{}{
+ map[string]interface{}{
+ "id": "39475a03-cba0-4aa3-867d-41494b9c4ad7",
+ "name": "7f5fa936-402f-4885-8b79-874ce3db8fb2",
+ },
+ map[string]interface{}{
+ "id": "6362a2a5-a7fc-48fd-9f38-f5a1e9c560d8",
+ "name": "284aab9b-88a5-4e13-a182-212de84989af",
+ },
+ map[string]interface{}{
+ "id": "9c5d545a-bcb2-41ac-89f9-7dcca90483b7",
+ "name": "b9f72ab5-ac09-4f5b-a57f-6691c55bcbdb",
+ },
+ }
+
+ var refs = &[]*vendor.CloudConfigurationRuleExternalReference{
+ {
+ ID: "6362a2a5-a7fc-48fd-9f38-f5a1e9c560d8",
+ Name: "284aab9b-88a5-4e13-a182-212de84989af",
+ },
+ {
+ ID: "9c5d545a-bcb2-41ac-89f9-7dcca90483b7",
+ Name: "b9f72ab5-ac09-4f5b-a57f-6691c55bcbdb",
+ },
+ {
+ ID: "39475a03-cba0-4aa3-867d-41494b9c4ad7",
+ Name: "7f5fa936-402f-4885-8b79-874ce3db8fb2",
+ },
+ }
+
+ flattened := flattenExternalReferences(ctx, refs)
+
+ if !reflect.DeepEqual(flattened, expected) {
+ t.Fatalf(
+ "Got:\n\n%#v\n\nExpected:\n\n%#v\n",
+ flattened,
+ expected,
+ )
+ }
+}
+
+func TestFlattenScopeAccounts(t *testing.T) {
+ ctx := context.Background()
+ expected := []interface{}{
+ "39475a03-cba0-4aa3-867d-41494b9c4ad7",
+ "6362a2a5-a7fc-48fd-9f38-f5a1e9c560d8",
+ "9c5d545a-bcb2-41ac-89f9-7dcca90483b7",
+ }
+
+ var accounts = &[]*vendor.CloudAccount{
+ {
+ ID: "6362a2a5-a7fc-48fd-9f38-f5a1e9c560d8",
+ },
+ {
+ ID: "9c5d545a-bcb2-41ac-89f9-7dcca90483b7",
+ },
+ {
+ ID: "39475a03-cba0-4aa3-867d-41494b9c4ad7",
+ },
+ }
+
+ flattened := flattenScopeAccounts(ctx, accounts)
+
+ if !reflect.DeepEqual(flattened, expected) {
+ t.Fatalf(
+ "Got:\n\n%#v\n\nExpected:\n\n%#v\n",
+ flattened,
+ expected,
+ )
+ }
+}
+
+func TestFlattenSecuritySubCategoryIDs(t *testing.T) {
+ ctx := context.Background()
+ expected := []interface{}{
+ "39475a03-cba0-4aa3-867d-41494b9c4ad7",
+ "6362a2a5-a7fc-48fd-9f38-f5a1e9c560d8",
+ "9c5d545a-bcb2-41ac-89f9-7dcca90483b7",
+ }
+
+ var cats = &[]*vendor.SecuritySubCategory{
+ {
+ ID: "6362a2a5-a7fc-48fd-9f38-f5a1e9c560d8",
+ },
+ {
+ ID: "9c5d545a-bcb2-41ac-89f9-7dcca90483b7",
+ },
+ {
+ ID: "39475a03-cba0-4aa3-867d-41494b9c4ad7",
+ },
+ }
+
+ flattened := flattenSecuritySubCategoryIDs(ctx, cats)
+
+ if !reflect.DeepEqual(flattened, expected) {
+ t.Fatalf(
+ "Got:\n\n%#v\n\nExpected:\n\n%#v\n",
+ flattened,
+ expected,
+ )
+ }
+}
+
+func TestFlattenIACMatcherIDs(t *testing.T) {
+ ctx := context.Background()
+ expected := []interface{}{
+ "39475a03-cba0-4aa3-867d-41494b9c4ad7",
+ "6362a2a5-a7fc-48fd-9f38-f5a1e9c560d8",
+ "9c5d545a-bcb2-41ac-89f9-7dcca90483b7",
+ }
+
+ var matchers = &[]*vendor.CloudConfigurationRuleMatcher{
+ {
+ ID: "6362a2a5-a7fc-48fd-9f38-f5a1e9c560d8",
+ },
+ {
+ ID: "9c5d545a-bcb2-41ac-89f9-7dcca90483b7",
+ },
+ {
+ ID: "39475a03-cba0-4aa3-867d-41494b9c4ad7",
+ },
+ }
+
+ flattened := flattenIACMatcherIDs(ctx, matchers)
+
+ if !reflect.DeepEqual(flattened, expected) {
+ t.Fatalf(
+ "Got:\n\n%#v\n\nExpected:\n\n%#v\n",
+ flattened,
+ expected,
+ )
+ }
+}
diff --git a/internal/provider/provider.go b/internal/provider/provider.go
index 4588a33..6243402 100644
--- a/internal/provider/provider.go
+++ b/internal/provider/provider.go
@@ -249,8 +249,9 @@ yLyKQXhw2W2Xs0qLeC1etA+jTGDK4UfLeC0SF7FSi8o5LL21L8IzApar2pR/
},
},
DataSourcesMap: map[string]*schema.Resource{
- "wiz_cloud_accounts": dataSourceWizCloudAccounts(),
- "wiz_organizations": dataSourceWizOrganizations(),
+ "wiz_cloud_accounts": dataSourceWizCloudAccounts(),
+ "wiz_cloud_config_rules": dataSourceWizCloudConfigurationRules(),
+ "wiz_organizations": dataSourceWizOrganizations(),
},
ResourcesMap: map[string]*schema.Resource{
"wiz_automation_action": resourceWizAutomationAction(),
diff --git a/internal/vendor/wiz.go b/internal/vendor/wiz.go
index 7bf3159..af70605 100644
--- a/internal/vendor/wiz.go
+++ b/internal/vendor/wiz.go
@@ -1149,28 +1149,30 @@ var CloudConfigurationRuleServiceType = []string{
// CloudConfigurationRule struct -- updates
type CloudConfigurationRule struct {
- Builtin *bool `json:"builtin"`
- CloudProvider string `json:"cloudProvider,omitempty"` // enum CloudProvider
- Control *Control `json:"control,omitempty"`
- CreatedBy *User `json:"createdBy,omitempty"`
- Description string `json:"description,omitempty"`
- Enabled *bool `json:"enabled"`
- FunctionAsControl *bool `json:"functionAsControl"`
- GraphID string `json:"graphId"`
- HasAutoRemediation *bool `json:"hasAutoRemediation"`
- IACMatchers []*CloudConfigurationRuleMatcher `json:"iacMatchers,omitempty"`
- ID string `json:"id"`
- Name string `json:"name"`
- OPAPolicy string `json:"opaPolicy,omitempty"`
- RemediationInstructions string `json:"remediationInstructions,omitempty"`
- ScopeAccounts []*CloudAccount `json:"scopeAccounts"` // removed omitempty
- SecuritySubCategories []*SecuritySubCategory `json:"securitySubCategories"`
- ServiceType string `json:"serviceType,omitempty"` // enum CloudConfigurationRuleServiceType
- Severity string `json:"severity"` // enum Severity
- ShortID string `json:"shortId"`
- SupportsNRT *bool `json:"supportsNRT"`
- TargetNativeType string `json:"targetNativeType,omitempty"`
- TargetNativeTypes []string `json:"targetNativeTypes,omitempty"`
+ Builtin *bool `json:"builtin"`
+ CloudProvider string `json:"cloudProvider,omitempty"` // enum CloudProvider
+ Control *Control `json:"control,omitempty"`
+ CreatedBy *User `json:"createdBy,omitempty"`
+ Description string `json:"description,omitempty"`
+ Enabled *bool `json:"enabled"`
+ ExternalReferences []*CloudConfigurationRuleExternalReference `json:"externalReferences,omitempty"`
+ FunctionAsControl *bool `json:"functionAsControl"`
+ GraphID string `json:"graphId"`
+ HasAutoRemediation *bool `json:"hasAutoRemediation"`
+ IACMatchers []*CloudConfigurationRuleMatcher `json:"iacMatchers,omitempty"`
+ ID string `json:"id"`
+ Name string `json:"name"`
+ OPAPolicy string `json:"opaPolicy,omitempty"`
+ RemediationInstructions string `json:"remediationInstructions,omitempty"`
+ ScopeAccounts []*CloudAccount `json:"scopeAccounts"` // removed omitempty
+ SecuritySubCategories []*SecuritySubCategory `json:"securitySubCategories"`
+ ServiceType string `json:"serviceType,omitempty"` // enum CloudConfigurationRuleServiceType
+ Severity string `json:"severity"` // enum Severity
+ ShortID string `json:"shortId"`
+ SubjectEntityType string `json:"subjectEntityType"`
+ SupportsNRT *bool `json:"supportsNRT"`
+ TargetNativeType string `json:"targetNativeType,omitempty"`
+ TargetNativeTypes []string `json:"targetNativeTypes,omitempty"`
}
// SecurityFramework struct -- updates
@@ -1830,7 +1832,7 @@ type CloudConfigurationRuleFilters struct {
CloudProvider []string `json:"cloudProvider,omitempty"` // enum CloudProvider
ServiceType []string `json:"serviceType,omitempty"` // enum CloudConfigurationRuleServiceType
SubjectEntityType []string `json:"subjectEntityType,omitempty"` // enum GraphEntityTypeValue
- Severity string `json:"severity,omitempty"` // enum Severity
+ Severity []string `json:"severity,omitempty"` // enum Severity
Enabled *bool `json:"enabled,omitempty"`
HasAutoRemediation *bool `json:"hasAutoRemediation,omitempty"`
HasRemediation *bool `json:"hasRemediation,omitempty"`
@@ -2117,3 +2119,44 @@ type CloudAccountEdge struct {
Cursor string `json:"cursor"`
Node CloudAccount `json:"node"`
}
+
+// CloudConfigurationRuleOrder struct
+type CloudConfigurationRuleOrder struct {
+ Direction string `json:"direction"` // enum OrderDirection
+ Field string `json:"field"` // enum CloudConfigurationRuleOrderField
+}
+
+// OrderDirection enum
+var OrderDirection = []string{
+ "ASC",
+ "DESC",
+}
+
+// CloudConfigurationRuleOrderField enum
+var CloudConfigurationRuleOrderField = []string{
+ "FAILED_CHECK_COUNT",
+ "SEVERITY",
+ "NAME",
+}
+
+// CloudConfigurationRuleConnection struct
+type CloudConfigurationRuleConnection struct {
+ AnalyticsUpdatedAt string `json:"analyticsUpdatedAt"`
+ Edges []*CloudConfigurationRuleEdge `json:"edges,omitempty"`
+ EnabledAsControlCount int `json:"enabledAsControlCount"`
+ Nodes []*CloudConfigurationRule `json:"nodes,omitempty"`
+ PageInfo PageInfo `json:"pageInfo"`
+ TotalCount int `json:"totalCount"`
+}
+
+// CloudConfigurationRuleEdge struct
+type CloudConfigurationRuleEdge struct {
+ Cursor string `json:"cursor"`
+ Node CloudConfigurationRule `json:"node"`
+}
+
+// CloudConfigurationRuleExternalReference struct
+type CloudConfigurationRuleExternalReference struct {
+ ID string `json:"id"`
+ Name string `json:"name"`
+}
diff --git a/templates/index.md.tmpl b/templates/index.md.tmpl
index ac0316f..da52a97 100644
--- a/templates/index.md.tmpl
+++ b/templates/index.md.tmpl
@@ -6,7 +6,7 @@ description: |-
# {{.ProviderName}}
-The Wiz Terraform provider is designed to work with [Wiz](https://app.wiz.io/).
+The Wiz Terraform provider is designed to work with [Wiz](https://wiz.io/).
The "wiz" provider manages resources typically manually managed in the [Wiz web interface](https://app.wiz.io/). You must configure the provider with the proper credentials before you can use it.