From cd821b077ba1085bb2e4fdb84efc8ee996dd3762 Mon Sep 17 00:00:00 2001 From: Axton Grams Date: Thu, 13 Oct 2022 13:15:36 -0500 Subject: [PATCH] New Data Source: wiz_cloud_accounts (#26) --- docs/data-sources/cloud_accounts.md | 89 ++++ .../host_config_rule_associations.md | 2 +- .../wiz_cloud_accounts/data-source.tf | 19 + .../resource.tf | 2 +- internal/common.go | 7 +- .../provider/data_source_cloud_accounts.go | 418 ++++++++++++++++++ .../data_source_cloud_accounts_test.go | 128 ++++++ .../provider/data_source_organizations.go | 4 +- internal/provider/provider.go | 3 +- internal/vendor/wiz.go | 48 +- 10 files changed, 704 insertions(+), 16 deletions(-) create mode 100644 docs/data-sources/cloud_accounts.md create mode 100644 examples/data-sources/wiz_cloud_accounts/data-source.tf create mode 100644 internal/provider/data_source_cloud_accounts.go create mode 100644 internal/provider/data_source_cloud_accounts_test.go diff --git a/docs/data-sources/cloud_accounts.md b/docs/data-sources/cloud_accounts.md new file mode 100644 index 0000000..1ab9af6 --- /dev/null +++ b/docs/data-sources/cloud_accounts.md @@ -0,0 +1,89 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "wiz_cloud_accounts Data Source - terraform-provider-wiz" +subcategory: "" +description: |- + Query cloud accounts (subscriptions). +--- + +# wiz_cloud_accounts (Data Source) + +Query cloud accounts (subscriptions). + +## Example Usage + +```terraform +# retrieve account by aws account id +data "wiz_cloud_accounts" "accounts_by_id" { + search = [ + "012345678912", + "987654321098", + ] +} + +# retrieve one account by wiz internal identifier +data "wiz_cloud_accounts" "accounts_by_wiz_id" { + ids = [ + "d33a2072-4b95-481b-8153-c0b9089992aa", + ] +} + +# retrieve all ccounts with multiple source connectors +data "wiz_cloud_accounts" "multiple_connectors" { + has_multiple_connector_sources = true +} +``` + + +## Schema + +### Optional + +- `assigned_to_project` (Boolean) QueryQuery cloud accounts by project assignment state. +- `cloud_provider` (List of String) Query cloud accounts of specific cloud provider. + - Allowed values: + - GCP + - AWS + - Azure + - OCI + - Alibaba + - vSphere + - OpenShift + - Kubernetes +- `connector_id` (List of String) Query cloud accounts by specific connector ID. +- `connector_issue_id` (List of String) Query cloud accounts by specific connector issue ID. +- `first` (Number) How many results to return + - Defaults to `500`. +- `has_multiple_connector_sources` (Boolean) QueryQuery cloud accounts by project assignment state. +- `ids` (List of String) Get specific Cloud Accounts by their IDs. +- `project_id` (String) Query cloud accounts of a specific linked project, given its id. +- `search` (List of String) Free text search on cloud account name or tags or external-id. +- `status` (List of String) Query cloud accounts by status. + - Allowed values: + - CONNECTED + - ERROR + - DISABLED + - INITIAL_SCANNING + - PARTIALLY_CONNECTED + - DISCONNECTED + - DISCOVERED + +### Read-Only + +- `cloud_accounts` (Set of Object) The returned cloud accounts. (see [below for nested schema](#nestedatt--cloud_accounts)) +- `id` (String) Internal identifier for the data. + + +### Nested Schema for `cloud_accounts` + +Read-Only: + +- `cloud_provider` (String) +- `external_id` (String) +- `id` (String) +- `linked_project_ids` (List of String) +- `name` (String) +- `source_connector_ids` (List of String) +- `status` (String) + + diff --git a/docs/resources/host_config_rule_associations.md b/docs/resources/host_config_rule_associations.md index 41df950..a0dc55c 100644 --- a/docs/resources/host_config_rule_associations.md +++ b/docs/resources/host_config_rule_associations.md @@ -18,7 +18,7 @@ resource "wiz_host_config_rule_associations" "test" { "2e5bc0d5-835b-4b4c-99cf-b1c6ace90a52", "708ec4a1-1a5c-4cb3-9c52-511229c5bb35", ] - cloud_config_rule_ids = [ + host_config_rule_ids = [ "301e5fd0-6a1a-42a7-99f5-3b0436d55a7f", "a5fbd955-ed78-445a-827a-06d6cbe5aab2", ] diff --git a/examples/data-sources/wiz_cloud_accounts/data-source.tf b/examples/data-sources/wiz_cloud_accounts/data-source.tf new file mode 100644 index 0000000..a574b13 --- /dev/null +++ b/examples/data-sources/wiz_cloud_accounts/data-source.tf @@ -0,0 +1,19 @@ +# retrieve account by aws account id +data "wiz_cloud_accounts" "accounts_by_id" { + search = [ + "012345678912", + "987654321098", + ] +} + +# retrieve one account by wiz internal identifier +data "wiz_cloud_accounts" "accounts_by_wiz_id" { + ids = [ + "d33a2072-4b95-481b-8153-c0b9089992aa", + ] +} + +# retrieve all ccounts with multiple source connectors +data "wiz_cloud_accounts" "multiple_connectors" { + has_multiple_connector_sources = true +} diff --git a/examples/resources/wiz_host_config_rule_associations/resource.tf b/examples/resources/wiz_host_config_rule_associations/resource.tf index 7eac65b..5cea0b4 100644 --- a/examples/resources/wiz_host_config_rule_associations/resource.tf +++ b/examples/resources/wiz_host_config_rule_associations/resource.tf @@ -3,7 +3,7 @@ resource "wiz_host_config_rule_associations" "test" { "2e5bc0d5-835b-4b4c-99cf-b1c6ace90a52", "708ec4a1-1a5c-4cb3-9c52-511229c5bb35", ] - cloud_config_rule_ids = [ + host_config_rule_ids = [ "301e5fd0-6a1a-42a7-99f5-3b0436d55a7f", "a5fbd955-ed78-445a-827a-06d6cbe5aab2", ] diff --git a/internal/common.go b/internal/common.go index 04d11a5..1cba203 100644 --- a/internal/common.go +++ b/internal/common.go @@ -2,9 +2,10 @@ package internal // QueryVariables struct type QueryVariables struct { - ID string `json:"id,omitempty"` - FilterBy FilterBy `json:"filterBy,omitempty"` - First int `json:"first,omitempty"` + ID string `json:"id,omitempty"` + FilterBy interface{} `json:"filterBy,omitempty"` + After string `json:"after,omitempty"` + First int `json:"first,omitempty"` } // FilterBy struct diff --git a/internal/provider/data_source_cloud_accounts.go b/internal/provider/data_source_cloud_accounts.go new file mode 100644 index 0000000..6d5e2e0 --- /dev/null +++ b/internal/provider/data_source_cloud_accounts.go @@ -0,0 +1,418 @@ +package provider + +import ( + "bytes" + "context" + "crypto/sha1" + "encoding/hex" + "fmt" + + "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 dataSourceWizCloudAccounts() *schema.Resource { + return &schema.Resource{ + Description: "Query cloud accounts (subscriptions).", + 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", + }, + "ids": { + Type: schema.TypeList, + Optional: true, + Description: "Get specific Cloud Accounts by their IDs.", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "search": { + Type: schema.TypeList, + Optional: true, + Description: "Free text search on cloud account name or tags or external-id.", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "project_id": { + Type: schema.TypeString, + Optional: true, + Description: "Query cloud accounts of a specific linked project, given its id.", + }, + "cloud_provider": { + Type: schema.TypeList, + Optional: true, + Description: fmt.Sprintf("Query cloud accounts of specific cloud provider.\n - Allowed values: %s", + utils.SliceOfStringToMDUList( + vendor.CloudProvider, + ), + ), + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateDiagFunc: validation.ToDiagFunc( + validation.StringInSlice( + vendor.CloudProvider, + false, + ), + ), + }, + }, + "status": { + Type: schema.TypeList, + Optional: true, + Description: fmt.Sprintf("Query cloud accounts by status.\n - Allowed values: %s", + utils.SliceOfStringToMDUList( + vendor.CloudAccountStatus, + ), + ), + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateDiagFunc: validation.ToDiagFunc( + validation.StringInSlice( + vendor.CloudAccountStatus, + false, + ), + ), + }, + }, + "connector_id": { + Type: schema.TypeList, + Optional: true, + Description: "Query cloud accounts by specific connector ID.", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "connector_issue_id": { + Type: schema.TypeList, + Optional: true, + Description: "Query cloud accounts by specific connector issue ID.", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "assigned_to_project": { + Type: schema.TypeBool, + Optional: true, + Description: "QueryQuery cloud accounts by project assignment state.", + }, + "has_multiple_connector_sources": { + Type: schema.TypeBool, + Optional: true, + Description: "QueryQuery cloud accounts by project assignment state.", + }, + "cloud_accounts": { + Type: schema.TypeSet, + Computed: true, + Description: "The returned cloud accounts.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + Description: "Internal Wiz ID.", + }, + "external_id": { + Type: schema.TypeString, + Computed: true, + Description: "External subscription id from cloud provider (subscriptionId in security graph).", + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: "Display name for this account.", + }, + "cloud_provider": { + Type: schema.TypeString, + Computed: true, + }, + "source_connector_ids": { + Type: schema.TypeList, + Computed: true, + Description: "Connectors detected this cloud account.", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: "Cloud Account connectivity status as affected by configured connectors.", + }, + "linked_project_ids": { + Type: schema.TypeList, + Computed: true, + Description: "Projects list this cloud account is assigned to/", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + }, + }, + }, + }, + ReadContext: dataSourceWizCloudAccountsRead, + } +} + +// ReadCloudAccounts struct +type ReadCloudAccounts struct { + CloudAccounts vendor.CloudAccountConnection `json:"cloudAccounts"` +} + +func dataSourceWizCloudAccountsRead(ctx context.Context, d *schema.ResourceData, m interface{}) (diags diag.Diagnostics) { + tflog.Info(ctx, "dataSourceWizCloudAccountsRead 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("ids") + if b { + identifier.WriteString(utils.PrettyPrint(a)) + } + a, b = d.GetOk("search") + if b { + identifier.WriteString(utils.PrettyPrint(a)) + } + a, b = d.GetOk("project_id") + if b { + identifier.WriteString(utils.PrettyPrint(a)) + } + a, b = d.GetOk("cloud_provider") + if b { + identifier.WriteString(utils.PrettyPrint(a)) + } + a, b = d.GetOk("status") + if b { + identifier.WriteString(utils.PrettyPrint(a)) + } + a, b = d.GetOk("connector_id") + if b { + identifier.WriteString(utils.PrettyPrint(a)) + } + a, b = d.GetOk("connector_issue_id") + if b { + identifier.WriteString(utils.PrettyPrint(a)) + } + a, b = d.GetOk("assigned_to_project") + if b { + identifier.WriteString(utils.PrettyPrint(a)) + } + a, b = d.GetOk("has_multiple_connector_sources") + 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 cloudAccounts( + $filterBy: CloudAccountFilters + $first: Int + $after: String + ) { + cloudAccounts( + filterBy: $filterBy + first: $first + after: $after + ) { + nodes { + id + externalId + name + cloudProvider + sourceConnectors { + id + } + status + linkedProjects { + 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("ids", d.Get("ids").([]interface{})) + if err != nil { + return append(diags, diag.FromErr(err)...) + } + err = d.Set("search", d.Get("search").([]interface{})) + if err != nil { + return append(diags, diag.FromErr(err)...) + } + err = d.Set("project_id", d.Get("project_id").(string)) + 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("status", d.Get("status").([]interface{})) + if err != nil { + return append(diags, diag.FromErr(err)...) + } + err = d.Set("connector_id", d.Get("connector_id").([]interface{})) + if err != nil { + return append(diags, diag.FromErr(err)...) + } + err = d.Set("connector_issue_id", d.Get("connector_issue_id").([]interface{})) + if err != nil { + return append(diags, diag.FromErr(err)...) + } + a, b = d.GetOk("assigned_to_project") + if b { + err = d.Set("assigned_to_project", a.(bool)) + if err != nil { + return append(diags, diag.FromErr(err)...) + } + } + a, b = d.GetOk("has_multiple_connector_sources") + if b { + err = d.Set("has_multiple_connector_sources", d.Get("has_multiple_connector_sources").(bool)) + if err != nil { + return append(diags, diag.FromErr(err)...) + } + } + + // populate the graphql variables + vars := &internal.QueryVariables{} + vars.First = d.Get("first").(int) + filterBy := &vendor.CloudAccountFilters{} + a, b = d.GetOk("ids") + if b { + filterBy.ID = utils.ConvertListToString(a.([]interface{})) + } + a, b = d.GetOk("search") + if b { + filterBy.Search = utils.ConvertListToString(a.([]interface{})) + } + filterBy.ProjectID = d.Get("project_id").(string) + a, b = d.GetOk("cloud_provider") + if b { + filterBy.CloudProvider = utils.ConvertListToString(a.([]interface{})) + } + a, b = d.GetOk("status") + if b { + filterBy.Status = utils.ConvertListToString(a.([]interface{})) + } + a, b = d.GetOk("connector_id") + if b { + filterBy.ConnectorID = utils.ConvertListToString(a.([]interface{})) + } + a, b = d.GetOk("connector_issue_id") + 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)) + vars.FilterBy = filterBy + + // process the request + data := &ReadCloudAccounts{} + requestDiags := client.ProcessRequest(ctx, m, vars, data, query, "cloud_accounts", "read") + diags = append(diags, requestDiags...) + if len(diags) > 0 { + return diags + } + + cloudAccounts := flattenCloudAccounts(ctx, &data.CloudAccounts.Nodes) + if err := d.Set("cloud_accounts", cloudAccounts); err != nil { + return append(diags, diag.FromErr(err)...) + } + + tflog.Debug(ctx, "Finished") + + return diags +} + +func flattenCloudAccounts(ctx context.Context, nodes *[]*vendor.CloudAccount) []interface{} { + tflog.Info(ctx, "flattenCloudAccounts called...") + tflog.Debug(ctx, fmt.Sprintf("Nodes: %s", utils.PrettyPrint(nodes))) + + // walk the slice and construct the map + var output = make([]interface{}, 0, 0) + for _, b := range *nodes { + tflog.Debug(ctx, fmt.Sprintf("b: %T %s", b, utils.PrettyPrint(b))) + accountMap := make(map[string]interface{}) + accountMap["id"] = b.ID + accountMap["external_id"] = b.ExternalID + accountMap["name"] = b.Name + accountMap["cloud_provider"] = b.CloudProvider + accountMap["status"] = b.Status + accountMap["linked_project_ids"] = flattenProjectIDs(ctx, &b.LinkedProjects) + accountMap["source_connector_ids"] = flattenSourceConnectorIDs(ctx, &b.SourceConnectors) + output = append(output, accountMap) + } + + tflog.Debug(ctx, fmt.Sprintf("flattenCloudAccounts output: %s", utils.PrettyPrint(output))) + + return output +} + +func flattenProjectIDs(ctx context.Context, projects *[]*vendor.Project) []interface{} { + tflog.Info(ctx, "flattenProjectIDs called...") + tflog.Debug(ctx, fmt.Sprintf("Projects: %s", utils.PrettyPrint(projects))) + + // walk the slice and construct the list + var output = make([]interface{}, 0, 0) + for _, b := range *projects { + tflog.Debug(ctx, fmt.Sprintf("b: %T %s", b, utils.PrettyPrint(b))) + output = append(output, b.ID) + } + + tflog.Debug(ctx, fmt.Sprintf("flattenProjectIDs output: %s", utils.PrettyPrint(output))) + + return output +} + +func flattenSourceConnectorIDs(ctx context.Context, connectors *[]vendor.Connector) []interface{} { + tflog.Info(ctx, "flattenSourceConnectorIDs called...") + tflog.Debug(ctx, fmt.Sprintf("Projects: %s", utils.PrettyPrint(connectors))) + + // walk the slice and construct the list + var output = make([]interface{}, 0, 0) + for _, b := range *connectors { + tflog.Debug(ctx, fmt.Sprintf("b: %T %s", b, utils.PrettyPrint(b))) + output = append(output, b.ID) + } + + 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 new file mode 100644 index 0000000..aa698e2 --- /dev/null +++ b/internal/provider/data_source_cloud_accounts_test.go @@ -0,0 +1,128 @@ +package provider + +import ( + "context" + "reflect" + "testing" + + "wiz.io/hashicorp/terraform-provider-wiz/internal/vendor" +) + +func TestFlattenCloudAccounts(t *testing.T) { + ctx := context.Background() + expected := []interface{}{ + map[string]interface{}{ + "id": "3bc53af8-6661-4a57-a2ee-69a4f2853bba", + "external_id": "04b1b4a5-755f-41a9-94ab-6e12173c9b3c", + "name": "a6250069-ef06-46ff-bdfe-aea00557f41d", + "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", + }, + "source_connector_ids": []interface{}{ + "7ac2f620-3882-4c35-91f0-7631eef430c6", + "dc303b7d-d03d-47f5-9d40-cf16906fb542", + }, + }, + } + + var cloudAccounts = &[]*vendor.CloudAccount{ + { + ID: "3bc53af8-6661-4a57-a2ee-69a4f2853bba", + ExternalID: "04b1b4a5-755f-41a9-94ab-6e12173c9b3c", + Name: "a6250069-ef06-46ff-bdfe-aea00557f41d", + CloudProvider: "0767b7a3-d540-4b9c-8afd-a018aa7da0fb", + Status: "9b6e7ae9-e0f6-4748-8171-a6b7a8f385ec", + LinkedProjects: []*vendor.Project{ + { + ID: "55e9138d-e48f-4155-a2ac-364eb00005db", + }, + { + ID: "3d9ef88a-84f9-4a84-9a67-e5cdd28ad35f", + }, + }, + SourceConnectors: []vendor.Connector{ + { + ID: "7ac2f620-3882-4c35-91f0-7631eef430c6", + }, + { + ID: "dc303b7d-d03d-47f5-9d40-cf16906fb542", + }, + }, + }, + } + + flattened := flattenCloudAccounts(ctx, cloudAccounts) + + if !reflect.DeepEqual(flattened, expected) { + t.Fatalf( + "Got:\n\n%#v\n\nExpected:\n\n%#v\n", + flattened, + expected, + ) + } +} + +func TestFlattenProjectIDs(t *testing.T) { + ctx := context.Background() + expected := []interface{}{ + "b0a03462-697e-4ef8-af52-0e8122c6eb7f", + "225697ef-8d21-42e1-8195-46d29b285ee6", + "d24f22fb-088d-4586-ba8a-9524260f7427", + } + + var projects = &[]*vendor.Project{ + { + ID: "b0a03462-697e-4ef8-af52-0e8122c6eb7f", + }, + { + ID: "225697ef-8d21-42e1-8195-46d29b285ee6", + }, + { + ID: "d24f22fb-088d-4586-ba8a-9524260f7427", + }, + } + + flattened := flattenProjectIDs(ctx, projects) + + if !reflect.DeepEqual(flattened, expected) { + t.Fatalf( + "Got:\n\n%#v\n\nExpected:\n\n%#v\n", + flattened, + expected, + ) + } +} + +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", + } + + var connectors = &[]vendor.Connector{ + { + ID: "d84b87ad-a38f-4ff1-9ee3-761521fbbaab", + }, + { + ID: "796def2c-70c6-4dc6-85a1-991616a98f4a", + }, + { + ID: "317d6352-69e0-47e0-a280-76dd3e2e9659", + }, + } + + flattened := flattenSourceConnectorIDs(ctx, connectors) + + if !reflect.DeepEqual(flattened, expected) { + t.Fatalf( + "Got:\n\n%#v\n\nExpected:\n\n%#v\n", + flattened, + expected, + ) + } +} diff --git a/internal/provider/data_source_organizations.go b/internal/provider/data_source_organizations.go index 4658ebf..87f6d88 100644 --- a/internal/provider/data_source_organizations.go +++ b/internal/provider/data_source_organizations.go @@ -109,7 +109,9 @@ func dataSourceWizOrganizationsRead(ctx context.Context, d *schema.ResourceData, vars := &internal.QueryVariables{} vars.First = d.Get("first").(int) tflog.Debug(ctx, fmt.Sprintf("search strings (%T) %s", d.Get("search"), d.Get("search").(string))) - vars.FilterBy.Search = append(vars.FilterBy.Search, d.Get("search").(string)) + filterBy := &vendor.CloudOrganizationFilters{} + filterBy.Search = append(filterBy.Search, d.Get("search").(string)) + vars.FilterBy = filterBy // process the request data := &ReadCloudOrganizations{} diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 37d8479..4588a33 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -249,7 +249,8 @@ yLyKQXhw2W2Xs0qLeC1etA+jTGDK4UfLeC0SF7FSi8o5LL21L8IzApar2pR/ }, }, DataSourcesMap: map[string]*schema.Resource{ - "wiz_organizations": dataSourceWizOrganizations(), + "wiz_cloud_accounts": dataSourceWizCloudAccounts(), + "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 1c827c0..7bf3159 100644 --- a/internal/vendor/wiz.go +++ b/internal/vendor/wiz.go @@ -337,15 +337,18 @@ var CloudAccountStatus = []string{ // CloudAccount struct type CloudAccount struct { - CloudProvider string `json:"cloudProvider"` // enum CloudProvider - ContainerCount int `json:"containerCount"` - ExternalID string `json:"externalId"` - ID string `json:"id"` - LinkedProjects []Project `json:"linkedProjects"` - Name string `json:"name"` - ResourceCount int `json:"resourceCount"` - Status string `json:"CloudAccountStatus"` // enum CloudAccountStatus - VirtualMachineCount int `json:"virtualMachineCount"` + CloudProvider string `json:"cloudProvider"` // enum CloudProvider + ContainerCount int `json:"containerCount"` + ExternalID string `json:"externalId"` + FirstScannedAt string `json:"firstScannedAt"` + ID string `json:"id"` + LastScannedAt string `json:"lastScannedAt"` + LinkedProjects []*Project `json:"linkedProjects,omitempty"` + Name string `json:"name"` + ResourceCount int `json:"resourceCount"` + SourceConnectors []Connector `json:"sourceConnectors"` + Status string `json:"status"` // enum CloudAccountStatus + VirtualMachineCount int `json:"virtualMachineCount"` } // ProjectEntrypoint struct @@ -2087,3 +2090,30 @@ type DeleteHostConfigurationRulePayload struct { type UpdateHostConfigurationRulePayload struct { Rule HostConfigurationRule `json:"rule,omitempty"` } + +// CloudAccountFilters struct +type CloudAccountFilters struct { + ID []string `json:"id,omitempty"` + Search []string `json:"search,omitempty"` + ProjectID string `json:"projectId,omitempty"` + CloudProvider []string `json:"cloudProvider,omitempty"` // enum CloudProvider + Status []string `json:"status,omitempty"` // enum CloudAccountStatus + ConnectorID []string `json:"connectorId,omitempty"` + ConnectorIssueID []string `json:"connectorIssueId,omitempty"` + AssignedToProject *bool `json:"assignedToProject,omitempty"` + HasMultipleConnectorSources *bool `json:"hasMultipleConnectorSources"` +} + +// CloudAccountConnection struct +type CloudAccountConnection struct { + Edges []*CloudAccountEdge `json:"edges,omitempty"` + Nodes []*CloudAccount `json:"nodes,omitempty"` + PageInfo PageInfo `json:"pageInfo"` + TotalCount int `json:"totalCount"` +} + +// CloudAccountEdge struct +type CloudAccountEdge struct { + Cursor string `json:"cursor"` + Node CloudAccount `json:"node"` +}