diff --git a/.golangci.yml b/.golangci.yml
index 223cf95..4877406 100644
--- a/.golangci.yml
+++ b/.golangci.yml
@@ -24,4 +24,4 @@ linters:
- unconvert
- unparam
- unused
- - vet
\ No newline at end of file
+ - govet
\ No newline at end of file
diff --git a/.goreleaser.yml b/.goreleaser.yml
index 9bb0aa7..37c175a 100644
--- a/.goreleaser.yml
+++ b/.goreleaser.yml
@@ -1,5 +1,8 @@
-# Visit https://goreleaser.com for documentation on how to customize this
-# behavior.
+# Copyright (c) Mondoo, Inc.
+# SPDX-License-Identifier: BUSL-1.1
+
+---
+version: 2
before:
hooks:
# this is just an example and not a requirement for provider building/publishing
@@ -57,4 +60,4 @@ release:
# If you want to manually examine the release before its live, uncomment this line:
# draft: true
changelog:
- skip: true
+ disable: true
diff --git a/docs/data-sources/assets.md b/docs/data-sources/assets.md
new file mode 100644
index 0000000..8b2ab75
--- /dev/null
+++ b/docs/data-sources/assets.md
@@ -0,0 +1,75 @@
+---
+# generated by https://github.com/hashicorp/terraform-plugin-docs
+page_title: "mondoo_assets Data Source - terraform-provider-mondoo"
+subcategory: ""
+description: |-
+ The asset data source allows you to fetch assets from a space.
+---
+
+# mondoo_assets (Data Source)
+
+The asset data source allows you to fetch assets from a space.
+
+## Example Usage
+
+```terraform
+provider "mondoo" {}
+
+data "mondoo_assets" "assets_data" {
+ space_id = "my-space-1234567"
+}
+
+output "asset_mrns" {
+ description = "MRNs of the assets"
+ value = [for asset in data.mondoo_assets.assets_data.assets : asset.mrn]
+}
+
+output "asset_names" {
+ description = "Names of the assets"
+ value = [for asset in data.mondoo_assets.assets_data.assets : asset.name]
+}
+```
+
+
+## Schema
+
+### Optional
+
+- `space_id` (String) The unique identifier of the space.
+- `space_mrn` (String) The unique Mondoo Resource Name (MRN) of the space.
+
+### Read-Only
+
+- `assets` (Attributes List) The list of assets in the space. (see [below for nested schema](#nestedatt--assets))
+
+
+### Nested Schema for `assets`
+
+Read-Only:
+
+- `annotations` (Attributes List) The annotations/tags of the asset. (see [below for nested schema](#nestedatt--assets--annotations))
+- `asset_type` (String) The type of the asset.
+- `id` (String) The unique identifier of the asset.
+- `mrn` (String) The unique Mondoo Resource Name (MRN) of the asset.
+- `name` (String) The name of the asset.
+- `reference_ids` (List of String) The reference IDs of the asset.
+- `score` (Attributes) The overall score of the asset. (see [below for nested schema](#nestedatt--assets--score))
+- `state` (String) The current state of the asset.
+- `updated_at` (String) The timestamp when the asset was last updated.
+
+
+### Nested Schema for `assets.annotations`
+
+Read-Only:
+
+- `key` (String) The key of the annotation.
+- `value` (String) The value of the annotation.
+
+
+
+### Nested Schema for `assets.score`
+
+Read-Only:
+
+- `grade` (String) The grade of the asset.
+- `value` (Number) The score value of the asset.
diff --git a/docs/data-sources/organization.md b/docs/data-sources/organization.md
index 801da32..526a860 100644
--- a/docs/data-sources/organization.md
+++ b/docs/data-sources/organization.md
@@ -16,13 +16,23 @@ Organization data source
provider "mondoo" {}
data "mondoo_organization" "org" {
- id = "reverent-ride-275852"
+ id = "your-org-1234567"
}
output "org_mrn" {
description = "MRN of the organization"
value = data.mondoo_organization.org.mrn
}
+
+output "org_name" {
+ description = "Name of the organization"
+ value = data.mondoo_organization.org.name
+}
+
+output "org_id" {
+ description = "ID of the organization"
+ value = data.mondoo_organization.org.id
+}
```
diff --git a/docs/data-sources/policy.md b/docs/data-sources/policy.md
new file mode 100644
index 0000000..ee366cd
--- /dev/null
+++ b/docs/data-sources/policy.md
@@ -0,0 +1,54 @@
+---
+# generated by https://github.com/hashicorp/terraform-plugin-docs
+page_title: "mondoo_policy Data Source - terraform-provider-mondoo"
+subcategory: ""
+description: |-
+ Data source for policies and querypacks
+---
+
+# mondoo_policy (Data Source)
+
+Data source for policies and querypacks
+
+## Example Usage
+
+```terraform
+data "mondoo_policy" "policy" {
+ space_id = "your-space-1234567"
+ catalog_type = "ALL" # available options: "ALL", "POLICY", "QUERYPACK"
+ assigned_only = true
+}
+
+output "policies_mrn" {
+ value = [for policy in data.mondoo_policy.policy.policies : policy.policy_mrn]
+ description = "The MRN of the policies in the space according to the filter criteria."
+}
+```
+
+
+## Schema
+
+### Optional
+
+- `assigned_only` (Boolean) Only return enabled policies if set to `true`
+- `catalog_type` (String) Catalog type of either `ALL`, `POLICY` or `QUERYPACK`. Defaults to `ALL`
+- `space_id` (String) Space ID
+- `space_mrn` (String) Space MRN
+
+### Read-Only
+
+- `policies` (Attributes List) List of policies (see [below for nested schema](#nestedatt--policies))
+
+
+### Nested Schema for `policies`
+
+Read-Only:
+
+- `action` (String) Policies can be set to `Null`, `IGNORE` or `ACTIVE`
+- `assigned` (Boolean) Determines if a policy is enabled or disabled
+- `created_at` (String) Timestamp of policy creation
+- `is_public` (Boolean) Determines if a policy is public or private
+- `policy_mrn` (String) Unique policy Mondoo Resource Name
+- `policy_name` (String) Policy name
+- `updated_at` (String) Timestamp of policy update
+- `version` (String) Version
diff --git a/docs/data-sources/space.md b/docs/data-sources/space.md
index 64fbced..21fff70 100644
--- a/docs/data-sources/space.md
+++ b/docs/data-sources/space.md
@@ -21,7 +21,7 @@ variable "mondoo_org" {
provider "mondoo" {}
resource "mondoo_space" "test" {
- org_id = var.mondoo_org.value
+ org_id = var.mondoo_org
name = "test-space"
}
@@ -42,6 +42,11 @@ output "space_mrn" {
description = "The MRN of the space"
value = data.mondoo_space.space.mrn
}
+
+output "space_id" {
+ description = "The ID of the space"
+ value = data.mondoo_space.space.id
+}
```
diff --git a/docs/resources/custom_framework.md b/docs/resources/custom_framework.md
new file mode 100644
index 0000000..0830e58
--- /dev/null
+++ b/docs/resources/custom_framework.md
@@ -0,0 +1,54 @@
+---
+# generated by https://github.com/hashicorp/terraform-plugin-docs
+page_title: "mondoo_custom_framework Resource - terraform-provider-mondoo"
+subcategory: ""
+description: |-
+ Set custom Compliance Frameworks for a Mondoo Space.
+---
+
+# mondoo_custom_framework (Resource)
+
+Set custom Compliance Frameworks for a Mondoo Space.
+
+## Example Usage
+
+```terraform
+provider "mondoo" {
+ region = "us"
+}
+
+variable "mondoo_org" {
+ description = "The Mondoo Organization ID"
+ type = string
+ default = "my-org-1234567"
+}
+
+variable "my_custom_framework" {
+ description = "Path to the custom policy file. The file must be in MQL format."
+ type = string
+ default = "framework.mql.yaml"
+}
+
+# Create a new space
+resource "mondoo_space" "my_space" {
+ name = "Custom Framework Space"
+ org_id = var.mondoo_org
+}
+
+resource "mondoo_custom_framework" "compliance_framework_example" {
+ space_id = mondoo_space.my_space.id
+ data_url = var.my_custom_framework
+}
+```
+
+
+## Schema
+
+### Required
+
+- `data_url` (String) URL to the custom Compliance Framework data.
+- `space_id` (String) Mondoo Space Identifier.
+
+### Read-Only
+
+- `mrn` (String) Mondoo Resource Name.
diff --git a/docs/resources/framework_assignment.md b/docs/resources/framework_assignment.md
new file mode 100644
index 0000000..8174833
--- /dev/null
+++ b/docs/resources/framework_assignment.md
@@ -0,0 +1,47 @@
+---
+# generated by https://github.com/hashicorp/terraform-plugin-docs
+page_title: "mondoo_framework_assignment Resource - terraform-provider-mondoo"
+subcategory: ""
+description: |-
+ Set Compliance Frameworks for a Mondoo Space.
+---
+
+# mondoo_framework_assignment (Resource)
+
+Set Compliance Frameworks for a Mondoo Space.
+
+## Example Usage
+
+```terraform
+provider "mondoo" {
+ region = "us"
+}
+
+variable "mondoo_org" {
+ description = "The Mondoo Organization ID"
+ type = string
+ default = "my-org-1234567"
+}
+
+# Create a new space
+resource "mondoo_space" "my_space" {
+ name = "Framework Space"
+ org_id = var.mondoo_org
+}
+
+resource "mondoo_framework_assignment" "compliance_framework_example" {
+ space_id = mondoo_space.my_space.id
+ framework_mrn = ["//policy.api.mondoo.app/frameworks/cis-controls-8",
+ "//policy.api.mondoo.app/frameworks/iso-27001-2022"]
+ enabled = true
+}
+```
+
+
+## Schema
+
+### Required
+
+- `enabled` (Boolean) Enable or disable the Compliance Framework.
+- `framework_mrn` (List of String) Compliance Framework MRN.
+- `space_id` (String) Mondoo Space Identifier.
diff --git a/examples/data-sources/mondoo_assets/data-source.tf b/examples/data-sources/mondoo_assets/data-source.tf
new file mode 100644
index 0000000..36e32c4
--- /dev/null
+++ b/examples/data-sources/mondoo_assets/data-source.tf
@@ -0,0 +1,15 @@
+provider "mondoo" {}
+
+data "mondoo_assets" "assets_data" {
+ space_id = "my-space-1234567"
+}
+
+output "asset_mrns" {
+ description = "MRNs of the assets"
+ value = [for asset in data.mondoo_assets.assets_data.assets : asset.mrn]
+}
+
+output "asset_names" {
+ description = "Names of the assets"
+ value = [for asset in data.mondoo_assets.assets_data.assets : asset.name]
+}
diff --git a/examples/data-sources/mondoo_assets/main.tf b/examples/data-sources/mondoo_assets/main.tf
new file mode 100644
index 0000000..1483327
--- /dev/null
+++ b/examples/data-sources/mondoo_assets/main.tf
@@ -0,0 +1,8 @@
+terraform {
+ required_providers {
+ mondoo = {
+ source = "mondoohq/mondoo"
+ version = ">= 0.4.0"
+ }
+ }
+}
diff --git a/examples/data-sources/mondoo_organization/data-source.tf b/examples/data-sources/mondoo_organization/data-source.tf
index 85b7329..d9f9347 100644
--- a/examples/data-sources/mondoo_organization/data-source.tf
+++ b/examples/data-sources/mondoo_organization/data-source.tf
@@ -1,10 +1,20 @@
provider "mondoo" {}
data "mondoo_organization" "org" {
- id = "reverent-ride-275852"
+ id = "your-org-1234567"
}
output "org_mrn" {
description = "MRN of the organization"
value = data.mondoo_organization.org.mrn
-}
\ No newline at end of file
+}
+
+output "org_name" {
+ description = "Name of the organization"
+ value = data.mondoo_organization.org.name
+}
+
+output "org_id" {
+ description = "ID of the organization"
+ value = data.mondoo_organization.org.id
+}
diff --git a/examples/data-sources/mondoo_policy/data-source.tf b/examples/data-sources/mondoo_policy/data-source.tf
new file mode 100644
index 0000000..17d677a
--- /dev/null
+++ b/examples/data-sources/mondoo_policy/data-source.tf
@@ -0,0 +1,10 @@
+data "mondoo_policy" "policy" {
+ space_id = "your-space-1234567"
+ catalog_type = "ALL" # available options: "ALL", "POLICY", "QUERYPACK"
+ assigned_only = true
+}
+
+output "policies_mrn" {
+ value = [for policy in data.mondoo_policy.policy.policies : policy.policy_mrn]
+ description = "The MRN of the policies in the space according to the filter criteria."
+}
diff --git a/examples/data-sources/mondoo_policy/main.tf b/examples/data-sources/mondoo_policy/main.tf
new file mode 100644
index 0000000..1483327
--- /dev/null
+++ b/examples/data-sources/mondoo_policy/main.tf
@@ -0,0 +1,8 @@
+terraform {
+ required_providers {
+ mondoo = {
+ source = "mondoohq/mondoo"
+ version = ">= 0.4.0"
+ }
+ }
+}
diff --git a/examples/data-sources/mondoo_space/data-source.tf b/examples/data-sources/mondoo_space/data-source.tf
index 82c6244..cfb6976 100644
--- a/examples/data-sources/mondoo_space/data-source.tf
+++ b/examples/data-sources/mondoo_space/data-source.tf
@@ -6,7 +6,7 @@ variable "mondoo_org" {
provider "mondoo" {}
resource "mondoo_space" "test" {
- org_id = var.mondoo_org.value
+ org_id = var.mondoo_org
name = "test-space"
}
@@ -27,3 +27,8 @@ output "space_mrn" {
description = "The MRN of the space"
value = data.mondoo_space.space.mrn
}
+
+output "space_id" {
+ description = "The ID of the space"
+ value = data.mondoo_space.space.id
+}
diff --git a/examples/resources/mondoo_custom_framework/framework.mql.yaml b/examples/resources/mondoo_custom_framework/framework.mql.yaml
new file mode 100644
index 0000000..2638d66
--- /dev/null
+++ b/examples/resources/mondoo_custom_framework/framework.mql.yaml
@@ -0,0 +1,44 @@
+frameworks:
+ - uid: example-framework
+ name: Example Framework
+ version: "1.0"
+ license: open-source
+ tags:
+ example.com/icon: example
+ authors:
+ - name: Example Author
+ groups:
+ - uid: example-group-am
+ title: Asset Management (AM)
+ controls:
+ - uid: example-control-am-01
+ title: Asset Inventory
+ docs:
+ desc: >-
+ A short description
+ evidence:
+ - uid: example-evidence-01
+ - uid: example-control-am-02
+ title: Acceptable Use and Safe Handling of Assets Policy
+ docs:
+ desc: >-
+ A short description
+ evidence:
+ - uid: example-evidence-02
+ - uid: example-group-bcm
+ title: Business Continuity Management (BCM)
+ controls:
+ - uid: example-control-bcm-01
+ title: Top Management Responsibility
+ docs:
+ desc: >-
+ A short description
+ evidence:
+ - uid: example-evidence-03
+ - uid: example-control-bcm-02
+ title: Business Impact Analysis Policies and Instructions
+ docs:
+ desc: >-
+ A short description
+ evidence:
+ - uid: example-evidence-04
diff --git a/examples/resources/mondoo_custom_framework/main.tf b/examples/resources/mondoo_custom_framework/main.tf
new file mode 100644
index 0000000..1483327
--- /dev/null
+++ b/examples/resources/mondoo_custom_framework/main.tf
@@ -0,0 +1,8 @@
+terraform {
+ required_providers {
+ mondoo = {
+ source = "mondoohq/mondoo"
+ version = ">= 0.4.0"
+ }
+ }
+}
diff --git a/examples/resources/mondoo_custom_framework/resource.tf b/examples/resources/mondoo_custom_framework/resource.tf
new file mode 100644
index 0000000..4e12b36
--- /dev/null
+++ b/examples/resources/mondoo_custom_framework/resource.tf
@@ -0,0 +1,26 @@
+provider "mondoo" {
+ region = "us"
+}
+
+variable "mondoo_org" {
+ description = "The Mondoo Organization ID"
+ type = string
+ default = "my-org-1234567"
+}
+
+variable "my_custom_framework" {
+ description = "Path to the custom policy file. The file must be in MQL format."
+ type = string
+ default = "framework.mql.yaml"
+}
+
+# Create a new space
+resource "mondoo_space" "my_space" {
+ name = "Custom Framework Space"
+ org_id = var.mondoo_org
+}
+
+resource "mondoo_custom_framework" "compliance_framework_example" {
+ space_id = mondoo_space.my_space.id
+ data_url = var.my_custom_framework
+}
diff --git a/examples/resources/mondoo_framework_assignment/main.tf b/examples/resources/mondoo_framework_assignment/main.tf
new file mode 100644
index 0000000..1483327
--- /dev/null
+++ b/examples/resources/mondoo_framework_assignment/main.tf
@@ -0,0 +1,8 @@
+terraform {
+ required_providers {
+ mondoo = {
+ source = "mondoohq/mondoo"
+ version = ">= 0.4.0"
+ }
+ }
+}
diff --git a/examples/resources/mondoo_framework_assignment/resource.tf b/examples/resources/mondoo_framework_assignment/resource.tf
new file mode 100644
index 0000000..e6b69b2
--- /dev/null
+++ b/examples/resources/mondoo_framework_assignment/resource.tf
@@ -0,0 +1,22 @@
+provider "mondoo" {
+ region = "us"
+}
+
+variable "mondoo_org" {
+ description = "The Mondoo Organization ID"
+ type = string
+ default = "my-org-1234567"
+}
+
+# Create a new space
+resource "mondoo_space" "my_space" {
+ name = "Framework Space"
+ org_id = var.mondoo_org
+}
+
+resource "mondoo_framework_assignment" "compliance_framework_example" {
+ space_id = mondoo_space.my_space.id
+ framework_mrn = ["//policy.api.mondoo.app/frameworks/cis-controls-8",
+ "//policy.api.mondoo.app/frameworks/iso-27001-2022"]
+ enabled = true
+}
diff --git a/go.mod b/go.mod
index eedbefc..224e154 100644
--- a/go.mod
+++ b/go.mod
@@ -3,14 +3,15 @@ module go.mondoo.com/terraform-provider-mondoo
go 1.22
require (
- github.com/hashicorp/copywrite v0.18.0
+ github.com/hashicorp/copywrite v0.19.0
github.com/hashicorp/terraform-plugin-docs v0.19.4
github.com/hashicorp/terraform-plugin-framework v1.9.0
github.com/hashicorp/terraform-plugin-framework-validators v0.12.0
github.com/hashicorp/terraform-plugin-go v0.23.0
github.com/hashicorp/terraform-plugin-log v0.9.0
github.com/hashicorp/terraform-plugin-testing v1.8.0
- go.mondoo.com/mondoo-go v0.0.0-20240516194133-d6612b90fe7c
+ github.com/stretchr/testify v1.9.0
+ go.mondoo.com/mondoo-go v0.0.0-20240611114249-2c3b9b20e67a
)
require (
@@ -33,6 +34,7 @@ require (
github.com/cli/safeexec v1.0.1 // indirect
github.com/cli/shurcooL-graphql v0.0.4 // indirect
github.com/cloudflare/circl v1.3.8 // indirect
+ github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fatih/color v1.16.0 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/go-jose/go-jose/v3 v3.0.3 // indirect
@@ -89,16 +91,17 @@ require (
github.com/muesli/termenv v0.15.2 // indirect
github.com/oklog/run v1.0.0 // indirect
github.com/oklog/ulid v1.3.1 // indirect
+ github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/posener/complete v1.2.3 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/samber/lo v1.39.0 // indirect
github.com/shopspring/decimal v1.3.1 // indirect
github.com/shurcooL/graphql v0.0.0-20230722043721-ed46e5a46466 // indirect
github.com/spf13/cast v1.5.0 // indirect
- github.com/spf13/cobra v1.8.0 // indirect
+ github.com/spf13/cobra v1.8.1 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/thanhpk/randstr v1.0.6 // indirect
- github.com/thlib/go-timezone-local v0.0.0-20210907160436-ef149e42d28e // indirect
+ github.com/thlib/go-timezone-local v0.0.3 // indirect
github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect
github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
@@ -106,17 +109,17 @@ require (
github.com/yuin/goldmark-meta v1.1.0 // indirect
github.com/zclconf/go-cty v1.14.4 // indirect
go.abhg.dev/goldmark/frontmatter v0.2.0 // indirect
- go.mongodb.org/mongo-driver v1.15.0 // indirect
- golang.org/x/crypto v0.23.0 // indirect
- golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect
- golang.org/x/mod v0.17.0 // indirect
- golang.org/x/net v0.25.0 // indirect
- golang.org/x/oauth2 v0.20.0 // indirect
+ go.mongodb.org/mongo-driver v1.15.1 // indirect
+ golang.org/x/crypto v0.24.0 // indirect
+ golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 // indirect
+ golang.org/x/mod v0.18.0 // indirect
+ golang.org/x/net v0.26.0 // indirect
+ golang.org/x/oauth2 v0.21.0 // indirect
golang.org/x/sync v0.7.0 // indirect
- golang.org/x/sys v0.20.0 // indirect
- golang.org/x/term v0.20.0 // indirect
- golang.org/x/text v0.15.0 // indirect
- golang.org/x/tools v0.21.0 // indirect
+ golang.org/x/sys v0.21.0 // indirect
+ golang.org/x/term v0.21.0 // indirect
+ golang.org/x/text v0.16.0 // indirect
+ golang.org/x/tools v0.22.0 // indirect
google.golang.org/appengine v1.6.8 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de // indirect
google.golang.org/grpc v1.63.2 // indirect
diff --git a/go.sum b/go.sum
index 1508224..29ad497 100644
--- a/go.sum
+++ b/go.sum
@@ -79,7 +79,7 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGX
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
-github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
+github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.17 h1:QeVUsEDNrLBW4tMgZHvxy18sKtr6VI492kBhUfhDJNI=
github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg=
@@ -190,8 +190,8 @@ github.com/hashicorp/cli v1.1.6 h1:CMOV+/LJfL1tXCOKrgAX0uRKnzjj/mpmqNXloRSy2K8=
github.com/hashicorp/cli v1.1.6/go.mod h1:MPon5QYlgjjo0BSoAiN0ESeT5fRzDjVRp+uioJ0piz4=
github.com/hashicorp/consul/api v1.13.0/go.mod h1:ZlVrynguJKcYr54zGaDbaL3fOvKC9m72FhPvA8T35KQ=
github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms=
-github.com/hashicorp/copywrite v0.18.0 h1:6f3aBDyQLBXhD6cdGSnsEM37vCDi3JJrkbR9HPBJf5c=
-github.com/hashicorp/copywrite v0.18.0/go.mod h1:6wvQH+ICDoD2bpjO1RJ6fi+h3aY5NeLEM12oTkEtFoc=
+github.com/hashicorp/copywrite v0.19.0 h1:f9LVxTDBfFYeQmdBpOsZ+HWknXonI8ZwubbO/RwyuCo=
+github.com/hashicorp/copywrite v0.19.0/go.mod h1:6wvQH+ICDoD2bpjO1RJ6fi+h3aY5NeLEM12oTkEtFoc=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
@@ -448,8 +448,8 @@ github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU=
-github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
-github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
+github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
+github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@@ -465,8 +465,8 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/thanhpk/randstr v1.0.6 h1:psAOktJFD4vV9NEVb3qkhRSMvYh4ORRaj1+w/hn4B+o=
github.com/thanhpk/randstr v1.0.6/go.mod h1:M/H2P1eNLZzlDwAzpkkkUvoyNNMbzRGhESZuEQk3r0U=
-github.com/thlib/go-timezone-local v0.0.0-20210907160436-ef149e42d28e h1:BuzhfgfWQbX0dWzYzT1zsORLnHRv3bcRcsaUk0VmXA8=
-github.com/thlib/go-timezone-local v0.0.0-20210907160436-ef149e42d28e/go.mod h1:/Tnicc6m/lsJE0irFMA0LfIwTBo4QP7A8IfyIv4zZKI=
+github.com/thlib/go-timezone-local v0.0.3 h1:ie5XtZWG5lQ4+1MtC5KZ/FeWlOKzW2nPoUnXYUbV/1s=
+github.com/thlib/go-timezone-local v0.0.3/go.mod h1:/Tnicc6m/lsJE0irFMA0LfIwTBo4QP7A8IfyIv4zZKI=
github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI=
github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
@@ -493,10 +493,10 @@ go.abhg.dev/goldmark/frontmatter v0.2.0/go.mod h1:XqrEkZuM57djk7zrlRUB02x8I5J0px
go.etcd.io/etcd/api/v3 v3.5.4/go.mod h1:5GB2vv4A4AOn3yk7MftYGHkUfGtDHnEraIjym4dYz5A=
go.etcd.io/etcd/client/pkg/v3 v3.5.4/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
go.etcd.io/etcd/client/v3 v3.5.4/go.mod h1:ZaRkVgBZC+L+dLCjTcF1hRXpgZXQPOvnA/Ak/gq3kiY=
-go.mondoo.com/mondoo-go v0.0.0-20240516194133-d6612b90fe7c h1:y910hpEdf1rYW/ONzc0NhuTwVDQNJNC9+x1C+xGywAI=
-go.mondoo.com/mondoo-go v0.0.0-20240516194133-d6612b90fe7c/go.mod h1:XY+tOP6vBFJKw5F3WLYEHNQxc+6YmfQ+hEbw3yRy3HI=
-go.mongodb.org/mongo-driver v1.15.0 h1:rJCKC8eEliewXjZGf0ddURtl7tTVy1TK3bfl0gkUSLc=
-go.mongodb.org/mongo-driver v1.15.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c=
+go.mondoo.com/mondoo-go v0.0.0-20240611114249-2c3b9b20e67a h1:+EQW5uXRyUyeiyZnTy2Jc371PTynJm5OruUWt3SqiT4=
+go.mondoo.com/mondoo-go v0.0.0-20240611114249-2c3b9b20e67a/go.mod h1:4032UBD0ph9LyhXq5OQmmxkJv37HdAGi34YLWbhnMDA=
+go.mongodb.org/mongo-driver v1.15.1 h1:l+RvoUOoMXFmADTLfYDm7On9dRm7p4T80/lEQM+r7HU=
+go.mongodb.org/mongo-driver v1.15.1/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
@@ -508,11 +508,11 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
-golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
-golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
+golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI=
+golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
-golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM=
-golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc=
+golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY=
+golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
@@ -523,8 +523,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
-golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
-golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
+golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0=
+golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -546,13 +546,13 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
-golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
-golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
+golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
+golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
-golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo=
-golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
+golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs=
+golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -609,16 +609,16 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
-golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
-golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
+golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
-golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw=
-golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
+golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA=
+golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
@@ -631,8 +631,8 @@ golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
-golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
-golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
+golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
+golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -647,8 +647,8 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
-golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw=
-golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
+golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA=
+golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
diff --git a/internal/provider/assets_data_source.go b/internal/provider/assets_data_source.go
new file mode 100644
index 0000000..35a65b9
--- /dev/null
+++ b/internal/provider/assets_data_source.go
@@ -0,0 +1,243 @@
+package provider
+
+import (
+ "context"
+ "fmt"
+
+ "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
+ "github.com/hashicorp/terraform-plugin-framework/datasource"
+ "github.com/hashicorp/terraform-plugin-framework/datasource/schema"
+ "github.com/hashicorp/terraform-plugin-framework/path"
+ "github.com/hashicorp/terraform-plugin-framework/schema/validator"
+ "github.com/hashicorp/terraform-plugin-framework/types"
+ mondoov1 "go.mondoo.com/mondoo-go"
+)
+
+var _ datasource.DataSource = (*assetsDataSource)(nil)
+
+func NewAssetsDataSource() datasource.DataSource {
+ return &assetsDataSource{}
+}
+
+type assetsDataSource struct {
+ client *ExtendedGqlClient
+}
+
+type assetsDataSourceModel struct {
+ Id types.String `tfsdk:"id"`
+ Mrn types.String `tfsdk:"mrn"`
+ State types.String `tfsdk:"state"`
+ Name types.String `tfsdk:"name"`
+ UpdatedAt types.String `tfsdk:"updated_at"`
+ ReferenceIDs []types.String `tfsdk:"reference_ids"`
+ AssetType types.String `tfsdk:"asset_type"`
+ Annotations []annotationsModel `tfsdk:"annotations"`
+ Score scoreModel `tfsdk:"score"`
+}
+
+type annotationsModel struct {
+ Key string `tfsdk:"key"`
+ Value string `tfsdk:"value"`
+}
+
+type scoreModel struct {
+ Grade types.String `tfsdk:"grade"`
+ Value types.Int64 `tfsdk:"value"`
+}
+
+type spaceAssetDataSourceModel struct {
+ SpaceID types.String `tfsdk:"space_id"`
+ SpaceMrn types.String `tfsdk:"space_mrn"`
+ Assets []assetsDataSourceModel `tfsdk:"assets"`
+}
+
+func (d *assetsDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
+ resp.TypeName = req.ProviderTypeName + "_assets"
+}
+
+func (d *assetsDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
+ resp.Schema = schema.Schema{
+ MarkdownDescription: "The asset data source allows you to fetch assets from a space.",
+ Attributes: map[string]schema.Attribute{
+ "space_id": schema.StringAttribute{
+ MarkdownDescription: "The unique identifier of the space.",
+ Computed: true,
+ Optional: true,
+ Validators: []validator.String{
+ // Validate only this attribute or other_attr is configured.
+ stringvalidator.ExactlyOneOf(path.Expressions{
+ path.MatchRoot("space_mrn"),
+ }...),
+ },
+ },
+ "space_mrn": schema.StringAttribute{
+ MarkdownDescription: "The unique Mondoo Resource Name (MRN) of the space.",
+ Computed: true,
+ Optional: true,
+ Validators: []validator.String{
+ // Validate only this attribute or other_attr is configured.
+ stringvalidator.ExactlyOneOf(path.Expressions{
+ path.MatchRoot("space_id"),
+ }...),
+ },
+ },
+ "assets": schema.ListNestedAttribute{
+ MarkdownDescription: "The list of assets in the space.",
+ Computed: true,
+ NestedObject: schema.NestedAttributeObject{
+ Attributes: map[string]schema.Attribute{
+ "id": schema.StringAttribute{
+ MarkdownDescription: "The unique identifier of the asset.",
+ Computed: true,
+ },
+ "mrn": schema.StringAttribute{
+ MarkdownDescription: "The unique Mondoo Resource Name (MRN) of the asset.",
+ Computed: true,
+ },
+ "state": schema.StringAttribute{
+ MarkdownDescription: "The current state of the asset.",
+ Computed: true,
+ },
+ "name": schema.StringAttribute{
+ MarkdownDescription: "The name of the asset.",
+ Computed: true,
+ },
+ "updated_at": schema.StringAttribute{
+ MarkdownDescription: "The timestamp when the asset was last updated.",
+ Computed: true,
+ },
+ "reference_ids": schema.ListAttribute{
+ MarkdownDescription: "The reference IDs of the asset.",
+ Computed: true,
+ ElementType: types.StringType,
+ },
+ "asset_type": schema.StringAttribute{
+ MarkdownDescription: "The type of the asset.",
+ Computed: true,
+ },
+ "annotations": schema.ListNestedAttribute{
+ MarkdownDescription: "The annotations/tags of the asset.",
+ Computed: true,
+ NestedObject: schema.NestedAttributeObject{
+ Attributes: map[string]schema.Attribute{
+ "key": schema.StringAttribute{
+ MarkdownDescription: "The key of the annotation.",
+ Computed: true,
+ },
+ "value": schema.StringAttribute{
+ MarkdownDescription: "The value of the annotation.",
+ Computed: true,
+ },
+ },
+ },
+ },
+ "score": schema.SingleNestedAttribute{
+ MarkdownDescription: "The overall score of the asset.",
+ Computed: true,
+ Attributes: map[string]schema.Attribute{
+ "grade": schema.StringAttribute{
+ MarkdownDescription: "The grade of the asset.",
+ Computed: true,
+ },
+ "value": schema.Int64Attribute{
+ MarkdownDescription: "The score value of the asset.",
+ Computed: true,
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ }
+}
+
+func (d *assetsDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
+ // Prevent panic if the provider has not been configured.
+ if req.ProviderData == nil {
+ return
+ }
+
+ client, ok := req.ProviderData.(*mondoov1.Client)
+
+ if !ok {
+ resp.Diagnostics.AddError(
+ "Unexpected Data Source Configure Type",
+ fmt.Sprintf("Expected *mondoov1.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData),
+ )
+
+ return
+ }
+
+ d.client = &ExtendedGqlClient{client}
+}
+
+func (d *assetsDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
+ var data spaceAssetDataSourceModel
+
+ // Read Terraform configuration data into the model
+ resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
+
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ spaceMrn := ""
+ if data.SpaceMrn.ValueString() != "" {
+ spaceMrn = data.SpaceMrn.ValueString()
+ } else if data.SpaceID.ValueString() != "" {
+ spaceMrn = spacePrefix + data.SpaceID.ValueString()
+ }
+
+ if spaceMrn == "" {
+ resp.Diagnostics.AddError("Invalid Configuration", "Either `id` or `mrn` must be set")
+ return
+ }
+
+ // Read API call logic
+ assets, err := d.client.GetAssets(ctx, spaceMrn)
+ if err != nil {
+ resp.Diagnostics.AddError("Failed to fetch assets", err.Error())
+ return
+ }
+
+ // Map API response to the model
+ data.Assets = make([]assetsDataSourceModel, len(assets.Edges))
+ for i, asset := range assets.Edges {
+
+ referenceIDs := make([]types.String, len(asset.Node.ReferenceIDs))
+ for j, refID := range asset.Node.ReferenceIDs {
+ referenceIDs[j] = types.StringValue(refID)
+ }
+
+ annotations := make([]annotationsModel, len(asset.Node.Annotations))
+ for j, annotation := range asset.Node.Annotations {
+ annotations[j] = *convertToAnnotationsModel(annotation)
+ }
+
+ data.Assets[i] = assetsDataSourceModel{
+ Id: types.StringValue(asset.Node.Id),
+ Mrn: types.StringValue(asset.Node.Mrn),
+ State: types.StringValue(asset.Node.State),
+ Name: types.StringValue(asset.Node.Name),
+ UpdatedAt: types.StringValue(asset.Node.UpdatedAt),
+ AssetType: types.StringValue(asset.Node.Asset_type),
+ ReferenceIDs: referenceIDs,
+ Annotations: annotations,
+ Score: scoreModel{
+ Grade: types.StringValue(asset.Node.Score.Grade),
+ Value: types.Int64Value(asset.Node.Score.Value),
+ },
+ }
+ }
+
+ // Save data into Terraform state
+ resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
+}
+
+func convertToAnnotationsModel(kv KeyValue) *annotationsModel {
+ return &annotationsModel{
+ Key: kv.Key,
+ Value: kv.Value,
+ }
+}
diff --git a/internal/provider/compliance_framework_resource.go b/internal/provider/compliance_framework_resource.go
new file mode 100644
index 0000000..9b62f56
--- /dev/null
+++ b/internal/provider/compliance_framework_resource.go
@@ -0,0 +1,153 @@
+package provider
+
+import (
+ "context"
+ "fmt"
+
+ "github.com/hashicorp/terraform-plugin-framework/path"
+ "github.com/hashicorp/terraform-plugin-framework/resource"
+ "github.com/hashicorp/terraform-plugin-framework/resource/schema"
+ "github.com/hashicorp/terraform-plugin-framework/types"
+ mondoov1 "go.mondoo.com/mondoo-go"
+)
+
+var _ resource.Resource = (*complianceFrameworkResource)(nil)
+
+func NewComplianceFrameworkResource() resource.Resource {
+ return &complianceFrameworkResource{}
+}
+
+type complianceFrameworkResource struct {
+ client *ExtendedGqlClient
+}
+
+type complianceFrameworkResourceModel struct {
+ // scope
+ SpaceId types.String `tfsdk:"space_id"`
+
+ // resource details
+ FrameworkMrn types.List `tfsdk:"framework_mrn"`
+ Enabled types.Bool `tfsdk:"enabled"`
+}
+
+func (r *complianceFrameworkResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
+ resp.TypeName = req.ProviderTypeName + "_framework_assignment"
+}
+
+func (r *complianceFrameworkResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
+ resp.Schema = schema.Schema{
+ MarkdownDescription: `Set Compliance Frameworks for a Mondoo Space.`,
+ Attributes: map[string]schema.Attribute{
+ "space_id": schema.StringAttribute{
+ MarkdownDescription: "Mondoo Space Identifier.",
+ Required: true,
+ },
+ "framework_mrn": schema.ListAttribute{
+ MarkdownDescription: "Compliance Framework MRN.",
+ Required: true,
+ ElementType: types.StringType,
+ },
+ "enabled": schema.BoolAttribute{
+ MarkdownDescription: "Enable or disable the Compliance Framework.",
+ Required: true,
+ },
+ },
+ }
+}
+
+func (r *complianceFrameworkResource) Configure(ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) {
+ // Prevent panic if the provider has not been configured.
+ if req.ProviderData == nil {
+ return
+ }
+
+ client, ok := req.ProviderData.(*mondoov1.Client)
+
+ if !ok {
+ resp.Diagnostics.AddError(
+ "Unexpected Resource Configure Type",
+ fmt.Sprintf("Expected *http.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData),
+ )
+
+ return
+ }
+
+ r.client = &ExtendedGqlClient{client}
+}
+
+func (r *complianceFrameworkResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
+ var data complianceFrameworkResourceModel
+
+ // Read Terraform plan data into the model
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
+
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ err := r.client.BulkUpdateFramework(ctx, data.FrameworkMrn, data.SpaceId.ValueString(), data.Enabled.ValueBool())
+ if err != nil {
+ resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to create Compliance Framework, got error: %s", err))
+ return
+ }
+
+ // Save data into Terraform state
+ resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
+}
+
+func (r *complianceFrameworkResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
+ var data complianceFrameworkResourceModel
+
+ // Read Terraform prior state data into the model
+ resp.Diagnostics.Append(req.State.Get(ctx, &data)...)
+
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ // Read API call logic
+
+ // Save updated data into Terraform state
+ resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
+}
+
+func (r *complianceFrameworkResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
+ var data complianceFrameworkResourceModel
+
+ // Read Terraform plan data into the model
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
+
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ err := r.client.BulkUpdateFramework(ctx, data.FrameworkMrn, data.SpaceId.ValueString(), data.Enabled.ValueBool())
+ if err != nil {
+ resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to create Compliance Framework, got error: %s", err))
+ return
+ }
+
+ // Save updated data into Terraform state
+ resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
+}
+
+func (r *complianceFrameworkResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
+ var data complianceFrameworkResourceModel
+
+ // Read Terraform prior state data into the model
+ resp.Diagnostics.Append(req.State.Get(ctx, &data)...)
+
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ err := r.client.BulkUpdateFramework(ctx, data.FrameworkMrn, data.SpaceId.ValueString(), false)
+ if err != nil {
+ resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to create Compliance Framework, got error: %s", err))
+ return
+ }
+}
+
+func (r *complianceFrameworkResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
+ resource.ImportStatePassthroughID(ctx, path.Root("mrn"), req, resp)
+}
diff --git a/internal/provider/custom_compliance_framework_resource.go b/internal/provider/custom_compliance_framework_resource.go
new file mode 100644
index 0000000..c803b4d
--- /dev/null
+++ b/internal/provider/custom_compliance_framework_resource.go
@@ -0,0 +1,221 @@
+package provider
+
+import (
+ "context"
+ "fmt"
+ "os"
+
+ "github.com/hashicorp/terraform-plugin-framework/path"
+ "github.com/hashicorp/terraform-plugin-framework/resource"
+ "github.com/hashicorp/terraform-plugin-framework/resource/schema"
+ "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
+ "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
+ "github.com/hashicorp/terraform-plugin-framework/types"
+ mondoov1 "go.mondoo.com/mondoo-go"
+ "gopkg.in/yaml.v2"
+)
+
+var _ resource.Resource = (*customComplianceFrameworkResource)(nil)
+
+func NewCustomComplianceFrameworkResource() resource.Resource {
+ return &customComplianceFrameworkResource{}
+}
+
+type customComplianceFrameworkResource struct {
+ client *ExtendedGqlClient
+}
+
+type customComplianceFrameworkResourceModel struct {
+ // scope
+ SpaceId types.String `tfsdk:"space_id"`
+
+ // resource details
+ Mrn types.String `tfsdk:"mrn"`
+ DataUrl types.String `tfsdk:"data_url"`
+}
+
+func (r *customComplianceFrameworkResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
+ resp.TypeName = req.ProviderTypeName + "_custom_framework"
+}
+
+type Framework struct {
+ UID string `yaml:"uid"`
+ Name string `yaml:"name"`
+}
+
+type Config struct {
+ Frameworks []Framework `yaml:"frameworks"`
+}
+
+func (r *customComplianceFrameworkResource) getFrameworkContent(data customComplianceFrameworkResourceModel) ([]byte, string, error) {
+ var complianceFrameworkData []byte
+ var config Config
+ if !data.DataUrl.IsNull() {
+ // load content from file
+ content, err := os.ReadFile(data.DataUrl.ValueString())
+ if err != nil {
+ return nil, "", err
+ }
+ complianceFrameworkData = content
+
+ // unmarshal the yaml content
+ err = yaml.Unmarshal(content, &config)
+ if err != nil {
+ return nil, "", fmt.Errorf("unable to unmarshal YAML: %w", err)
+ }
+ }
+ return complianceFrameworkData, config.Frameworks[0].UID, nil
+}
+
+func (r *customComplianceFrameworkResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
+ resp.Schema = schema.Schema{
+ MarkdownDescription: `Set custom Compliance Frameworks for a Mondoo Space.`,
+ Attributes: map[string]schema.Attribute{
+ "space_id": schema.StringAttribute{
+ MarkdownDescription: "Mondoo Space Identifier.",
+ Required: true,
+ },
+ "mrn": schema.StringAttribute{
+ MarkdownDescription: "Mondoo Resource Name.",
+ Computed: true,
+ PlanModifiers: []planmodifier.String{
+ stringplanmodifier.UseStateForUnknown(),
+ },
+ },
+ "data_url": schema.StringAttribute{
+ MarkdownDescription: "URL to the custom Compliance Framework data.",
+ Required: true,
+ },
+ },
+ }
+}
+
+func (r *customComplianceFrameworkResource) Configure(ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) {
+ // Prevent panic if the provider has not been configured.
+ if req.ProviderData == nil {
+ return
+ }
+
+ client, ok := req.ProviderData.(*mondoov1.Client)
+
+ if !ok {
+ resp.Diagnostics.AddError(
+ "Unexpected Resource Configure Type",
+ fmt.Sprintf("Expected *http.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData),
+ )
+
+ return
+ }
+
+ r.client = &ExtendedGqlClient{client}
+}
+
+func (r *customComplianceFrameworkResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
+ var data customComplianceFrameworkResourceModel
+
+ // Read Terraform plan data into the model
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
+
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ // Do GraphQL request to API to create the resource.
+ spaceMrn := ""
+ if data.SpaceId.ValueString() != "" {
+ spaceMrn = spacePrefix + data.SpaceId.ValueString()
+ }
+
+ content, uid, err := r.getFrameworkContent(data)
+ if err != nil {
+ resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to get Compliance Framework Content, got error: %s", err))
+ return
+ }
+
+ err = r.client.UploadFramework(ctx, spaceMrn, content)
+ if err != nil {
+ resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to upload Compliance Framework, got error: %s", err))
+ return
+ }
+
+ framework, err := r.client.GetFramework(ctx, spaceMrn, data.SpaceId.ValueString(), uid)
+ if err != nil {
+ resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to get Compliance Framework, got error: %s", err))
+ return
+ }
+
+ data.Mrn = types.StringValue(string(framework.Mrn))
+
+ // Save data into Terraform state
+ resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
+}
+
+func (r *customComplianceFrameworkResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
+ var data customComplianceFrameworkResourceModel
+
+ // Read Terraform prior state data into the model
+ resp.Diagnostics.Append(req.State.Get(ctx, &data)...)
+
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ // Read API call logic
+
+ // Save updated data into Terraform state
+ resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
+}
+
+func (r *customComplianceFrameworkResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
+ var data customComplianceFrameworkResourceModel
+
+ // Read Terraform plan data into the model
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
+
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ // Do GraphQL request to API to create the resource.
+ spaceMrn := ""
+ if data.SpaceId.ValueString() != "" {
+ spaceMrn = spacePrefix + data.SpaceId.ValueString()
+ }
+
+ content, _, err := r.getFrameworkContent(data)
+ if err != nil {
+ resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to get Compliance Framework Content, got error: %s", err))
+ return
+ }
+
+ err = r.client.UploadFramework(ctx, spaceMrn, content)
+ if err != nil {
+ resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to upload Compliance Framework, got error: %s", err))
+ return
+ }
+
+ // Save updated data into Terraform state
+ resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
+}
+
+func (r *customComplianceFrameworkResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
+ var data customComplianceFrameworkResourceModel
+
+ // Read Terraform prior state data into the model
+ resp.Diagnostics.Append(req.State.Get(ctx, &data)...)
+
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ // Do GraphQL request to API to update the resource.
+ err := r.client.DeleteFramework(ctx, data.Mrn.ValueString())
+ if err != nil {
+ resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to delete Compliance Framework, got error: %s", err))
+ return
+ }
+}
+
+func (r *customComplianceFrameworkResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
+ resource.ImportStatePassthroughID(ctx, path.Root("mrn"), req, resp)
+}
diff --git a/internal/provider/gql.go b/internal/provider/gql.go
index 2ab72b2..d87b621 100644
--- a/internal/provider/gql.go
+++ b/internal/provider/gql.go
@@ -8,6 +8,7 @@ import (
"encoding/base64"
"fmt"
+ "github.com/hashicorp/terraform-plugin-framework/types/basetypes"
"github.com/hashicorp/terraform-plugin-log/tflog"
mondoov1 "go.mondoo.com/mondoo-go"
)
@@ -89,9 +90,7 @@ type spacePayload struct {
Id string
Mrn string
Name string
- Organization struct {
- Id string
- }
+ Organization orgPayload
}
func (c *ExtendedGqlClient) GetSpace(ctx context.Context, mrn string) (spacePayload, error) {
@@ -156,6 +155,135 @@ func (c *ExtendedGqlClient) SetCustomPolicy(ctx context.Context, scopeMrn string
return setCustomPolicy.SetCustomPolicyPayload, err
}
+type SpaceReportInput struct {
+ SpaceMrn mondoov1.String
+}
+
+type Policy struct {
+ Mrn mondoov1.String
+ Name mondoov1.String
+ Assigned mondoov1.Boolean
+ Action mondoov1.String
+ Version mondoov1.String
+ IsPublic mondoov1.Boolean
+ CreatedAt mondoov1.String
+ UpdatedAt mondoov1.String
+}
+
+type PolicyNode struct {
+ Policy Policy
+}
+
+type PolicyEdge struct {
+ Cursor mondoov1.String
+ Node PolicyNode
+}
+
+type PolicyReportSummaries struct {
+ TotalCount int
+ Edges []PolicyEdge
+}
+
+type SpaceReport struct {
+ SpaceMrn mondoov1.String
+ PolicyReportSummaries PolicyReportSummaries
+}
+
+type SpaceReportPayload struct {
+ SpaceReport SpaceReport
+}
+
+func (c *ExtendedGqlClient) GetPolicySpaceReport(ctx context.Context, spaceMrn string) (*[]Policy, error) {
+ // Define the query struct according to the provided query
+ var spaceReportQuery struct {
+ Report struct {
+ SpaceReport SpaceReport `graphql:"... on SpaceReport"`
+ } `graphql:"spaceReport(input: $input)"`
+ }
+ // Define the input variable according to the provided query
+ input := mondoov1.SpaceReportInput{
+ SpaceMrn: mondoov1.String(spaceMrn),
+ }
+
+ variables := map[string]interface{}{
+ "input": input,
+ }
+
+ tflog.Trace(ctx, "GetSpaceReportInput", map[string]interface{}{
+ "input": fmt.Sprintf("%+v", input),
+ })
+
+ // Execute the query
+ err := c.Query(ctx, &spaceReportQuery, variables)
+ if err != nil {
+ return nil, err
+ }
+
+ var policies []Policy
+ for _, edges := range spaceReportQuery.Report.SpaceReport.PolicyReportSummaries.Edges {
+ policies = append(policies, edges.Node.Policy)
+ }
+
+ return &policies, nil
+}
+
+type ContentInput struct {
+ ScopeMrn string
+ CatalogType string
+ AssignedOnly bool
+}
+
+type Node struct {
+ Policy Policy `graphql:"... on Policy"`
+}
+
+type Edge struct {
+ Node Node
+}
+
+type Content struct {
+ TotalCount int
+ Edges []Edge
+}
+
+type ContentPayload struct {
+ Content Content
+}
+
+func (c *ExtendedGqlClient) GetPolicies(ctx context.Context, scopeMrn string, catalogType string, assignedOnly bool) (*[]Policy, error) {
+ // Define the query struct according to the provided query
+ var contentQuery struct {
+ Content Content `graphql:"content(input: $input)"`
+ }
+ // Define the input variable according to the provided query
+ input := mondoov1.ContentSearchInput{
+ ScopeMrn: mondoov1.String(scopeMrn),
+ CatalogType: mondoov1.CatalogType(catalogType),
+ AssignedOnly: mondoov1.NewBooleanPtr(mondoov1.Boolean(assignedOnly)),
+ }
+
+ variables := map[string]interface{}{
+ "input": input,
+ }
+
+ tflog.Trace(ctx, "GetContentInput", map[string]interface{}{
+ "input": fmt.Sprintf("%+v", input),
+ })
+
+ // Execute the query
+ err := c.Query(ctx, &contentQuery, variables)
+ if err != nil {
+ return nil, err
+ }
+
+ var policies []Policy
+ for _, edges := range contentQuery.Content.Edges {
+ policies = append(policies, edges.Node.Policy)
+ }
+
+ return &policies, nil
+}
+
func (c *ExtendedGqlClient) AssignPolicy(ctx context.Context, spaceMrn string, action mondoov1.PolicyAction, policyMrns []string) error {
var list *[]mondoov1.String
@@ -470,6 +598,54 @@ func (c *ExtendedGqlClient) TriggerAction(ctx context.Context, integrationMrn st
return q.TriggerAction, nil
}
+type AssetScore struct {
+ Grade string
+ Value int64
+}
+
+type KeyValue struct {
+ Key string
+ Value string
+}
+
+type AssetNode struct {
+ Id string
+ Mrn string
+ State string
+ Name string
+ UpdatedAt string
+ ReferenceIDs []string `graphql:"referenceIDs"`
+ Asset_type string
+ Score AssetScore
+ Annotations []KeyValue
+}
+
+type AssetEdge struct {
+ Cursor string
+ Node AssetNode
+}
+
+type AssetsPayload struct {
+ TotalCount int
+ Edges []AssetEdge
+}
+
+func (c *ExtendedGqlClient) GetAssets(ctx context.Context, spaceMrn string) (AssetsPayload, error) {
+ var q struct {
+ Assets AssetsPayload `graphql:"assets(spaceMrn: $spaceMrn)"`
+ }
+ variables := map[string]interface{}{
+ "spaceMrn": mondoov1.String(spaceMrn),
+ }
+
+ err := c.Query(ctx, &q, variables)
+ if err != nil {
+ return AssetsPayload{}, err
+ }
+
+ return q.Assets, nil
+}
+
func (c *ExtendedGqlClient) SetScimGroupMapping(ctx context.Context, orgMrn string, group string, mappings []mondoov1.ScimGroupMapping) error {
var setScimGroupMappingMutation struct {
SetScimGroupMapping struct {
@@ -485,3 +661,104 @@ func (c *ExtendedGqlClient) SetScimGroupMapping(ctx context.Context, orgMrn stri
return c.Mutate(ctx, &setScimGroupMappingMutation, setScimGroupMappingInput, nil)
}
+
+func (c *ExtendedGqlClient) UploadFramework(ctx context.Context, spaceMrn string, content []byte) error {
+ // Define the mutation struct according to the provided query
+ var uploadMutation struct {
+ UploadFramework bool `graphql:"uploadFramework(input: $input)"`
+ }
+
+ // Define the input variable according to the provided query
+ input := mondoov1.UploadFrameworkInput{
+ SpaceMrn: mondoov1.String(spaceMrn),
+ Dataurl: mondoov1.String(newDataUrl(content)),
+ }
+
+ // Execute the mutation
+ return c.Mutate(ctx, &uploadMutation, input, nil)
+}
+
+type ComplianceFrameworkPayload struct {
+ Mrn mondoov1.String
+ Name mondoov1.String
+ State mondoov1.String
+ ScopeMrn mondoov1.String
+}
+
+func (c *ExtendedGqlClient) GetFramework(ctx context.Context, spaceMrn string, spaceId string, uid string) (*ComplianceFrameworkPayload, error) {
+ // Define the query struct according to the provided query
+ var getFrameworkQuery struct {
+ ComplianceFramework ComplianceFrameworkPayload `graphql:"complianceFramework(input: $input)"`
+ }
+ frameworkMrn := fmt.Sprintf("//policy.api.mondoo.app/spaces/%s/frameworks/%s", spaceId, uid)
+ // Define the input variable according to the provided query
+ input := mondoov1.ComplianceFrameworkInput{
+ ScopeMrn: mondoov1.String(spaceMrn),
+ FrameworkMrn: mondoov1.String(frameworkMrn),
+ }
+
+ variables := map[string]interface{}{
+ "input": input,
+ }
+
+ // Execute the query
+ err := c.Query(ctx, &getFrameworkQuery, variables)
+ if err != nil {
+ return nil, err
+ }
+
+ return &getFrameworkQuery.ComplianceFramework, nil
+}
+
+func (c *ExtendedGqlClient) UpdateFramework(ctx context.Context, frameworkMrn string, scopeMrn string, enabled bool) error {
+ var updateMutation struct {
+ ApplyFramework bool `graphql:"applyFrameworkMutation(input: $input)"`
+ }
+
+ input := mondoov1.ComplianceFrameworkMutationInput{
+ FrameworkMrn: mondoov1.String(frameworkMrn),
+ ScopeMrn: mondoov1.String(scopeMrn),
+ }
+
+ if enabled {
+ input.Action = mondoov1.ComplianceFrameworkMutationActionEnable
+ } else {
+ input.Action = mondoov1.ComplianceFrameworkMutationActionPreview
+ }
+
+ return c.Mutate(ctx, &updateMutation, input, nil)
+}
+
+func (c *ExtendedGqlClient) BulkUpdateFramework(ctx context.Context, frameworkMrns basetypes.ListValue, spaceId string, enabled bool) error {
+ scopeMrn := ""
+ if spaceId != "" {
+ scopeMrn = spacePrefix + spaceId
+ }
+
+ var frameworkList []mondoov1.String
+ listFrameworks, _ := frameworkMrns.ToListValue(ctx)
+ listFrameworks.ElementsAs(ctx, &frameworkList, true)
+
+ for _, mrn := range frameworkList {
+ err := c.UpdateFramework(ctx, string(mrn), scopeMrn, enabled)
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func (c *ExtendedGqlClient) DeleteFramework(ctx context.Context, mrn string) error {
+ // Define the mutation struct according to the provided query
+ var deleteMutation struct {
+ DeleteFramework bool `graphql:"deleteFramework(input: $input)"`
+ }
+
+ // Define the input variable according to the provided query
+ input := mondoov1.DeleteFrameworkInput{
+ Mrn: mondoov1.String(mrn),
+ }
+
+ // Execute the mutation
+ return c.Mutate(ctx, &deleteMutation, input, nil)
+}
diff --git a/internal/provider/integration_aws_resource.go b/internal/provider/integration_aws_resource.go
index 0fec886..4334295 100644
--- a/internal/provider/integration_aws_resource.go
+++ b/internal/provider/integration_aws_resource.go
@@ -7,8 +7,10 @@ import (
"context"
"fmt"
"strings"
+ "regexp"
"github.com/hashicorp/terraform-plugin-framework-validators/objectvalidator"
+ "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
@@ -105,6 +107,9 @@ func (r *integrationAwsResource) Schema(ctx context.Context, req resource.Schema
"name": schema.StringAttribute{
MarkdownDescription: "Name of the integration.",
Required: true,
+ Validators: []validator.String{
+ stringvalidator.LengthAtMost(250),
+ },
},
"credentials": schema.SingleNestedAttribute{
Required: true,
@@ -134,10 +139,22 @@ func (r *integrationAwsResource) Schema(ctx context.Context, req resource.Schema
"access_key": schema.StringAttribute{
Required: true,
Sensitive: true,
+ Validators: []validator.String{
+ stringvalidator.RegexMatches(
+ regexp.MustCompile(`^([A-Z0-9]{20})$`),
+ "must be a 20 character string with uppercase letters and numbers only",
+ ),
+ },
},
"secret_key": schema.StringAttribute{
Required: true,
Sensitive: true,
+ Validators: []validator.String{
+ stringvalidator.RegexMatches(
+ regexp.MustCompile(`^([a-zA-Z0-9+/]{40})$`),
+ "must be a 40 character string with alphanumeric values and + and / only",
+ ),
+ },
},
},
},
diff --git a/internal/provider/integration_azure_resource.go b/internal/provider/integration_azure_resource.go
index ecf61e7..16d6234 100644
--- a/internal/provider/integration_azure_resource.go
+++ b/internal/provider/integration_azure_resource.go
@@ -4,13 +4,16 @@ import (
"context"
"fmt"
"strings"
-
+
"github.com/hashicorp/terraform-plugin-framework/attr"
+ "github.com/hashicorp/terraform-plugin-framework-validators/listvalidator"
+ "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
+ "github.com/hashicorp/terraform-plugin-framework/schema/validator"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
mondoov1 "go.mondoo.com/mondoo-go"
@@ -69,6 +72,9 @@ func (r *integrationAzureResource) Schema(ctx context.Context, req resource.Sche
"name": schema.StringAttribute{
MarkdownDescription: "Name of the integration.",
Required: true,
+ Validators: []validator.String{
+ stringvalidator.LengthAtMost(250),
+ },
},
"client_id": schema.StringAttribute{
MarkdownDescription: "Azure Client ID.",
@@ -86,11 +92,23 @@ func (r *integrationAzureResource) Schema(ctx context.Context, req resource.Sche
MarkdownDescription: "List of Azure subscriptions to scan.",
Optional: true,
ElementType: types.StringType,
+ Validators: []validator.List{
+ // Validate only this attribute or other_attr is configured.
+ listvalidator.ConflictsWith(path.Expressions{
+ path.MatchRoot("subscription_deny_list"),
+ }...),
+ },
},
"subscription_deny_list": schema.ListAttribute{
MarkdownDescription: "List of Azure subscriptions to exclude from scanning.",
Optional: true,
ElementType: types.StringType,
+ Validators: []validator.List{
+ // Validate only this attribute or other_attr is configured.
+ listvalidator.ConflictsWith(path.Expressions{
+ path.MatchRoot("subscription_allow_list"),
+ }...),
+ },
},
"credentials": schema.SingleNestedAttribute{
Required: true,
diff --git a/internal/provider/integration_domain_resource.go b/internal/provider/integration_domain_resource.go
index 5672d9b..bdffd91 100644
--- a/internal/provider/integration_domain_resource.go
+++ b/internal/provider/integration_domain_resource.go
@@ -4,12 +4,15 @@ import (
"context"
"fmt"
"strings"
+ "regexp"
+ "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
+ "github.com/hashicorp/terraform-plugin-framework/schema/validator"
"github.com/hashicorp/terraform-plugin-framework/types"
mondoov1 "go.mondoo.com/mondoo-go"
)
@@ -57,6 +60,12 @@ func (r *integrationDomainResource) Schema(ctx context.Context, req resource.Sch
"host": schema.StringAttribute{
MarkdownDescription: "Domain name or IP address.",
Required: true,
+ Validators: []validator.String{
+ stringvalidator.RegexMatches(
+ regexp.MustCompile(`^((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])$|^([a-z0-9-]+\.)+[a-z]{2,}$`),
+ "must contain only lowercase letters and at least one dot or be an IPv4 address",
+ ),
+ },
},
"https": schema.BoolAttribute{
MarkdownDescription: "Enable HTTPS port.",
diff --git a/internal/provider/integration_gcp_resource.go b/internal/provider/integration_gcp_resource.go
index 9954ea8..98b0a15 100644
--- a/internal/provider/integration_gcp_resource.go
+++ b/internal/provider/integration_gcp_resource.go
@@ -8,11 +8,13 @@ import (
"fmt"
"strings"
+ "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
+ "github.com/hashicorp/terraform-plugin-framework/schema/validator"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
mondoov1 "go.mondoo.com/mondoo-go"
@@ -67,6 +69,9 @@ func (r *integrationGcpResource) Schema(ctx context.Context, req resource.Schema
"name": schema.StringAttribute{
MarkdownDescription: "Name of the integration.",
Required: true,
+ Validators: []validator.String{
+ stringvalidator.LengthAtMost(250),
+ },
},
"project_id": schema.StringAttribute{
MarkdownDescription: "GCP project id",
diff --git a/internal/provider/integration_github_resource.go b/internal/provider/integration_github_resource.go
index 1118c3e..bc2cf68 100644
--- a/internal/provider/integration_github_resource.go
+++ b/internal/provider/integration_github_resource.go
@@ -4,13 +4,17 @@ import (
"context"
"fmt"
"strings"
-
+ "regexp"
+
"github.com/hashicorp/terraform-plugin-framework/attr"
+ "github.com/hashicorp/terraform-plugin-framework-validators/listvalidator"
+ "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
+ "github.com/hashicorp/terraform-plugin-framework/schema/validator"
"github.com/hashicorp/terraform-plugin-framework/types"
mondoov1 "go.mondoo.com/mondoo-go"
)
@@ -103,6 +107,9 @@ func (r *integrationGithubResource) Schema(ctx context.Context, req resource.Sch
"name": schema.StringAttribute{
MarkdownDescription: "Name of the integration.",
Required: true,
+ Validators: []validator.String{
+ stringvalidator.LengthAtMost(250),
+ },
},
"owner": schema.StringAttribute{
MarkdownDescription: "GitHub Owner.",
@@ -116,11 +123,23 @@ func (r *integrationGithubResource) Schema(ctx context.Context, req resource.Sch
MarkdownDescription: "List of GitHub repositories to scan.",
Optional: true,
ElementType: types.StringType,
+ Validators: []validator.List{
+ // Validate only this attribute or other_attr is configured.
+ listvalidator.ConflictsWith(path.Expressions{
+ path.MatchRoot("repository_deny_list"),
+ }...),
+ },
},
"repository_deny_list": schema.ListAttribute{
MarkdownDescription: "List of GitHub repositories to exclude from scanning.",
Optional: true,
ElementType: types.StringType,
+ Validators: []validator.List{
+ // Validate only this attribute or other_attr is configured.
+ listvalidator.ConflictsWith(path.Expressions{
+ path.MatchRoot("repository_allow_list"),
+ }...),
+ },
},
"credentials": schema.SingleNestedAttribute{
Required: true,
@@ -129,6 +148,12 @@ func (r *integrationGithubResource) Schema(ctx context.Context, req resource.Sch
MarkdownDescription: "Token for GitHub integration.",
Required: true,
Sensitive: true,
+ Validators: []validator.String{
+ stringvalidator.RegexMatches(
+ regexp.MustCompile(`^(ghp_[a-zA-Z0-9]{36}|github_pat_[a-zA-Z0-9]{22}_[a-zA-Z0-9]{59})$`),
+ "must be a valid classic GitHub Token with 40 characters in length, with a prefix of ghp_ or a fine-grained GitHub token with 93 characters in length, with a prefix of github_pat_",
+ ),
+ },
},
},
},
diff --git a/internal/provider/integration_ms365_resource.go b/internal/provider/integration_ms365_resource.go
index 0a6643e..2a53eae 100644
--- a/internal/provider/integration_ms365_resource.go
+++ b/internal/provider/integration_ms365_resource.go
@@ -5,11 +5,13 @@ import (
"fmt"
"strings"
+ "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
+ "github.com/hashicorp/terraform-plugin-framework/schema/validator"
"github.com/hashicorp/terraform-plugin-framework/types"
mondoov1 "go.mondoo.com/mondoo-go"
)
@@ -64,6 +66,9 @@ func (r *integrationMs365Resource) Schema(ctx context.Context, req resource.Sche
"name": schema.StringAttribute{
MarkdownDescription: "Name of the integration.",
Required: true,
+ Validators: []validator.String{
+ stringvalidator.LengthAtMost(250),
+ },
},
"client_id": schema.StringAttribute{
MarkdownDescription: "Azure Client ID.",
diff --git a/internal/provider/integration_oci_tenant.go b/internal/provider/integration_oci_tenant.go
index a45a14f..ae40ba1 100644
--- a/internal/provider/integration_oci_tenant.go
+++ b/internal/provider/integration_oci_tenant.go
@@ -7,11 +7,13 @@ import (
"context"
"fmt"
+ "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
+ "github.com/hashicorp/terraform-plugin-framework/schema/validator"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-log/tflog"
mondoov1 "go.mondoo.com/mondoo-go"
@@ -75,6 +77,9 @@ func (r *integrationOciTenantResource) Schema(ctx context.Context, req resource.
"name": schema.StringAttribute{
MarkdownDescription: "Name of the integration.",
Optional: true,
+ Validators: []validator.String{
+ stringvalidator.LengthAtMost(250),
+ },
},
"tenancy": schema.StringAttribute{
MarkdownDescription: "OCI tenancy",
diff --git a/internal/provider/integration_slack_resource.go b/internal/provider/integration_slack_resource.go
index cd637dd..5f8d53e 100644
--- a/internal/provider/integration_slack_resource.go
+++ b/internal/provider/integration_slack_resource.go
@@ -4,11 +4,15 @@ import (
"context"
"fmt"
"strings"
+ "regexp"
+ "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
+ "github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
+ "github.com/hashicorp/terraform-plugin-framework/schema/validator"
"github.com/hashicorp/terraform-plugin-framework/types"
mondoov1 "go.mondoo.com/mondoo-go"
)
@@ -57,11 +61,20 @@ func (r *integrationSlackResource) Schema(ctx context.Context, req resource.Sche
"name": schema.StringAttribute{
MarkdownDescription: "Name of the integration.",
Required: true,
+ Validators: []validator.String{
+ stringvalidator.LengthAtMost(250),
+ },
},
"slack_token": schema.StringAttribute{
Required: true,
Sensitive: true,
Description: "The Slack token to authenticate with the Slack API.",
+ Validators: []validator.String{
+ stringvalidator.RegexMatches(
+ regexp.MustCompile(`^xox[baprs](-[0-9a-zA-Z]{10,48})+$`),
+ "must start with xox and one of the following characters b, a, p, r, s, followed by one or more blocks consisting of a dash and 10-48 alphanumeric characters",
+ ),
+ },
},
},
}
diff --git a/internal/provider/organization_data_source.go b/internal/provider/organization_data_source.go
index deddc08..ff691c8 100644
--- a/internal/provider/organization_data_source.go
+++ b/internal/provider/organization_data_source.go
@@ -6,8 +6,12 @@ package provider
import (
"context"
"fmt"
+
+ "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
+ "github.com/hashicorp/terraform-plugin-framework/path"
+ "github.com/hashicorp/terraform-plugin-framework/schema/validator"
"github.com/hashicorp/terraform-plugin-framework/types"
mondoov1 "go.mondoo.com/mondoo-go"
)
@@ -44,11 +48,23 @@ func (d *OrganizationDataSource) Schema(ctx context.Context, req datasource.Sche
MarkdownDescription: "Organization ID",
Computed: true,
Optional: true,
+ Validators: []validator.String{
+ // Validate only this attribute or other_attr is configured.
+ stringvalidator.ExactlyOneOf(path.Expressions{
+ path.MatchRoot("mrn"),
+ }...),
+ },
},
"mrn": schema.StringAttribute{
MarkdownDescription: "Organization MRN",
Computed: true,
Optional: true,
+ Validators: []validator.String{
+ // Validate only this attribute or other_attr is configured.
+ stringvalidator.ExactlyOneOf(path.Expressions{
+ path.MatchRoot("id"),
+ }...),
+ },
},
"name": schema.StringAttribute{
MarkdownDescription: "Organization name",
@@ -95,6 +111,7 @@ func (d *OrganizationDataSource) Read(ctx context.Context, req datasource.ReadRe
} else if data.OrgID.ValueString() != "" {
orgMrn = orgPrefix + data.OrgID.ValueString()
}
+
if orgMrn == "" {
resp.Diagnostics.AddError("Invalid Configuration", "Either `id` or `mrn` must be set")
return
@@ -106,8 +123,6 @@ func (d *OrganizationDataSource) Read(ctx context.Context, req datasource.ReadRe
return
}
- // For the purposes of this example code, hardcoding a response value to
- // save into the Terraform state.
data.OrgID = types.StringValue(payload.Id)
data.OrgMrn = types.StringValue(payload.Mrn)
data.Name = types.StringValue(payload.Name)
diff --git a/internal/provider/policy_assignment_resource.go b/internal/provider/policy_assignment_resource.go
index f0253ba..46ae153 100644
--- a/internal/provider/policy_assignment_resource.go
+++ b/internal/provider/policy_assignment_resource.go
@@ -6,9 +6,12 @@ package provider
import (
"context"
"fmt"
+
+ "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/listplanmodifier"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault"
+ "github.com/hashicorp/terraform-plugin-framework/schema/validator"
mondoov1 "go.mondoo.com/mondoo-go"
"github.com/hashicorp/terraform-plugin-framework/resource"
@@ -62,6 +65,9 @@ func (r *policyAssignmentResource) Schema(ctx context.Context, req resource.Sche
Default: stringdefault.StaticString("enabled"),
Computed: true,
Optional: true,
+ Validators: []validator.String{
+ stringvalidator.OneOf("enabled", "disabled", "preview"),
+ },
},
},
}
diff --git a/internal/provider/policy_data_source.go b/internal/provider/policy_data_source.go
new file mode 100644
index 0000000..0cf697c
--- /dev/null
+++ b/internal/provider/policy_data_source.go
@@ -0,0 +1,199 @@
+package provider
+
+import (
+ "context"
+ "fmt"
+
+ "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
+ "github.com/hashicorp/terraform-plugin-framework/datasource"
+ "github.com/hashicorp/terraform-plugin-framework/datasource/schema"
+ "github.com/hashicorp/terraform-plugin-framework/path"
+ "github.com/hashicorp/terraform-plugin-framework/schema/validator"
+ "github.com/hashicorp/terraform-plugin-framework/types"
+ mondoov1 "go.mondoo.com/mondoo-go"
+)
+
+var _ datasource.DataSource = (*policyDataSource)(nil)
+
+func NewPolicyDataSource() datasource.DataSource {
+ return &policyDataSource{}
+}
+
+type policyDataSource struct {
+ client *ExtendedGqlClient
+}
+
+type policyModel struct {
+ PolicyMrn types.String `tfsdk:"policy_mrn"`
+ PolicyName types.String `tfsdk:"policy_name"`
+ Assigned types.Bool `tfsdk:"assigned"`
+ Action types.String `tfsdk:"action"`
+ Version types.String `tfsdk:"version"`
+ IsPublic types.Bool `tfsdk:"is_public"`
+ CreatedAt types.String `tfsdk:"created_at"`
+ UpdatedAt types.String `tfsdk:"updated_at"`
+}
+
+type policyDataSourceModel struct {
+ SpaceID types.String `tfsdk:"space_id"`
+ SpaceMrn types.String `tfsdk:"space_mrn"`
+ CatalogType types.String `tfsdk:"catalog_type"`
+ AssignedOnly types.Bool `tfsdk:"assigned_only"`
+ Policies []policyModel `tfsdk:"policies"`
+}
+
+func (d *policyDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
+ resp.TypeName = req.ProviderTypeName + "_policy"
+}
+
+func (d *policyDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
+ resp.Schema = schema.Schema{
+ MarkdownDescription: "Data source for policies and querypacks",
+ Attributes: map[string]schema.Attribute{
+ "space_id": schema.StringAttribute{
+ Computed: true,
+ Optional: true,
+ MarkdownDescription: "Space ID",
+ Validators: []validator.String{
+ // Validate only this attribute or other_attr is configured.
+ stringvalidator.ExactlyOneOf(path.Expressions{
+ path.MatchRoot("space_mrn"),
+ }...),
+ },
+ },
+ "space_mrn": schema.StringAttribute{
+ Computed: true,
+ Optional: true,
+ MarkdownDescription: "Space MRN",
+ Validators: []validator.String{
+ // Validate only this attribute or other_attr is configured.
+ stringvalidator.ExactlyOneOf(path.Expressions{
+ path.MatchRoot("space_id"),
+ }...),
+ },
+ },
+ "catalog_type": schema.StringAttribute{
+ Computed: true,
+ Optional: true,
+ MarkdownDescription: "Catalog type of either `ALL`, `POLICY` or `QUERYPACK`. Defaults to `ALL`",
+ Validators: []validator.String{
+ stringvalidator.OneOf("ALL", "POLICY", "QUERYPACK"),
+ },
+ },
+ "assigned_only": schema.BoolAttribute{
+ Computed: true,
+ Optional: true,
+ MarkdownDescription: "Only return enabled policies if set to `true`",
+ },
+ "policies": schema.ListNestedAttribute{
+ Computed: true,
+ MarkdownDescription: "List of policies",
+ NestedObject: schema.NestedAttributeObject{
+ Attributes: map[string]schema.Attribute{
+ "policy_mrn": schema.StringAttribute{
+ Computed: true,
+ MarkdownDescription: "Unique policy Mondoo Resource Name",
+ },
+ "policy_name": schema.StringAttribute{
+ Computed: true,
+ MarkdownDescription: "Policy name",
+ },
+ "assigned": schema.BoolAttribute{
+ Computed: true,
+ MarkdownDescription: "Determines if a policy is enabled or disabled",
+ },
+ "action": schema.StringAttribute{
+ Computed: true,
+ MarkdownDescription: "Policies can be set to `Null`, `IGNORE` or `ACTIVE`",
+ },
+ "version": schema.StringAttribute{
+ Computed: true,
+ MarkdownDescription: "Version",
+ },
+ "is_public": schema.BoolAttribute{
+ Computed: true,
+ MarkdownDescription: "Determines if a policy is public or private",
+ },
+ "created_at": schema.StringAttribute{
+ Computed: true,
+ MarkdownDescription: "Timestamp of policy creation",
+ },
+ "updated_at": schema.StringAttribute{
+ Computed: true,
+ MarkdownDescription: "Timestamp of policy update",
+ },
+ },
+ },
+ },
+ },
+ }
+}
+
+func (d *policyDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
+ // Prevent panic if the provider has not been configured.
+ if req.ProviderData == nil {
+ return
+ }
+
+ client, ok := req.ProviderData.(*mondoov1.Client)
+
+ if !ok {
+ resp.Diagnostics.AddError(
+ "Unexpected Data Source Configure Type",
+ fmt.Sprintf("Expected *mondoov1.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData),
+ )
+
+ return
+ }
+
+ d.client = &ExtendedGqlClient{client}
+}
+
+func (d *policyDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
+ var data policyDataSourceModel
+
+ // Read Terraform configuration data into the model
+ resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
+
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ // generate space mrn
+ scopeMrn := ""
+ if data.SpaceMrn.ValueString() != "" {
+ scopeMrn = data.SpaceMrn.ValueString()
+ } else if data.SpaceID.ValueString() != "" {
+ scopeMrn = spacePrefix + data.SpaceID.ValueString()
+ }
+
+ if scopeMrn == "" {
+ resp.Diagnostics.AddError("Invalid Configuration", "Either `id` or `mrn` must be set")
+ return
+ }
+
+ // Fetch policies
+ policies, err := d.client.GetPolicies(ctx, scopeMrn, data.CatalogType.ValueString(), data.AssignedOnly.ValueBool())
+ if err != nil {
+ resp.Diagnostics.AddError("Failed to fetch policies", err.Error())
+ return
+ }
+
+ // Convert policies to the model
+ data.Policies = make([]policyModel, len(*policies))
+ for i, policy := range *policies {
+ data.Policies[i] = policyModel{
+ PolicyMrn: types.StringValue(string(policy.Mrn)),
+ PolicyName: types.StringValue(string(policy.Name)),
+ Assigned: types.BoolValue(bool(policy.Assigned)),
+ Action: types.StringValue(string(policy.Action)),
+ Version: types.StringValue(string(policy.Version)),
+ IsPublic: types.BoolValue(bool(policy.IsPublic)),
+ CreatedAt: types.StringValue(string(policy.CreatedAt)),
+ UpdatedAt: types.StringValue(string(policy.UpdatedAt)),
+ }
+ }
+
+ // Save data into Terraform state
+ resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
+}
diff --git a/internal/provider/provider.go b/internal/provider/provider.go
index 98884d8..115a26b 100644
--- a/internal/provider/provider.go
+++ b/internal/provider/provider.go
@@ -170,6 +170,8 @@ func (p *MondooProvider) Resources(ctx context.Context) []func() resource.Resour
NewIntegrationSlackResource,
NewIntegrationMs365Resource,
NewIntegrationGithubResource,
+ NewComplianceFrameworkResource,
+ NewCustomComplianceFrameworkResource,
}
}
@@ -177,6 +179,8 @@ func (p *MondooProvider) DataSources(ctx context.Context) []func() datasource.Da
return []func() datasource.DataSource{
NewOrganizationDataSource,
NewSpaceDataSource,
+ NewPolicyDataSource,
+ NewAssetsDataSource,
}
}
diff --git a/internal/provider/querypack_assignment_resource.go b/internal/provider/querypack_assignment_resource.go
index dcbe9fc..de7f251 100644
--- a/internal/provider/querypack_assignment_resource.go
+++ b/internal/provider/querypack_assignment_resource.go
@@ -6,11 +6,14 @@ package provider
import (
"context"
"fmt"
+ "strings"
+
+ "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/listplanmodifier"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault"
+ "github.com/hashicorp/terraform-plugin-framework/schema/validator"
mondoov1 "go.mondoo.com/mondoo-go"
- "strings"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
@@ -63,6 +66,9 @@ func (r *queryPackAssignmentResource) Schema(ctx context.Context, req resource.S
Default: stringdefault.StaticString("enabled"),
Computed: true,
Optional: true,
+ Validators: []validator.String{
+ stringvalidator.OneOf("enabled", "disabled"),
+ },
},
},
}
diff --git a/internal/provider/space_data_source.go b/internal/provider/space_data_source.go
index 822a21a..b837baf 100644
--- a/internal/provider/space_data_source.go
+++ b/internal/provider/space_data_source.go
@@ -6,8 +6,12 @@ package provider
import (
"context"
"fmt"
+
+ "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
+ "github.com/hashicorp/terraform-plugin-framework/path"
+ "github.com/hashicorp/terraform-plugin-framework/schema/validator"
"github.com/hashicorp/terraform-plugin-framework/types"
mondoov1 "go.mondoo.com/mondoo-go"
)
@@ -44,11 +48,23 @@ func (d *SpaceDataSource) Schema(ctx context.Context, req datasource.SchemaReque
MarkdownDescription: "Space ID",
Computed: true,
Optional: true,
+ Validators: []validator.String{
+ // Validate only this attribute or other_attr is configured.
+ stringvalidator.ExactlyOneOf(path.Expressions{
+ path.MatchRoot("mrn"),
+ }...),
+ },
},
"mrn": schema.StringAttribute{
MarkdownDescription: "Space MRN",
Computed: true,
Optional: true,
+ Validators: []validator.String{
+ // Validate only this attribute or other_attr is configured.
+ stringvalidator.ExactlyOneOf(path.Expressions{
+ path.MatchRoot("id"),
+ }...),
+ },
},
"name": schema.StringAttribute{
MarkdownDescription: "Space name",
@@ -92,9 +108,10 @@ func (d *SpaceDataSource) Read(ctx context.Context, req datasource.ReadRequest,
spaceMrn := ""
if data.SpaceMrn.ValueString() != "" {
spaceMrn = data.SpaceMrn.ValueString()
- } else if data.SpaceMrn.ValueString() != "" {
- spaceMrn = orgPrefix + data.SpaceID.ValueString()
+ } else if data.SpaceID.ValueString() != "" {
+ spaceMrn = spacePrefix + data.SpaceID.ValueString()
}
+
if spaceMrn == "" {
resp.Diagnostics.AddError("Invalid Configuration", "Either `id` or `mrn` must be set")
return
@@ -106,8 +123,6 @@ func (d *SpaceDataSource) Read(ctx context.Context, req datasource.ReadRequest,
return
}
- // For the purposes of this example code, hardcoding a response value to
- // save into the Terraform state.
data.SpaceID = types.StringValue(payload.Id)
data.SpaceMrn = types.StringValue(payload.Mrn)
data.Name = types.StringValue(payload.Name)
diff --git a/internal/provider/space_resource.go b/internal/provider/space_resource.go
index f88eb01..c3ee9f9 100644
--- a/internal/provider/space_resource.go
+++ b/internal/provider/space_resource.go
@@ -6,12 +6,15 @@ package provider
import (
"context"
"fmt"
+ "regexp"
+ "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
+ "github.com/hashicorp/terraform-plugin-framework/schema/validator"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-log/tflog"
mondoov1 "go.mondoo.com/mondoo-go"
@@ -56,6 +59,12 @@ func (r *SpaceResource) Schema(ctx context.Context, req resource.SchemaRequest,
"name": schema.StringAttribute{
MarkdownDescription: "Name of the space.",
Optional: true,
+ Validators: []validator.String{
+ stringvalidator.RegexMatches(
+ regexp.MustCompile(`^([a-zA-Z \-'_]|\d){2,30}$`),
+ "must contain 2 to 30 characters, where each character can be a letter (uppercase or lowercase), a space, a dash, an underscore, or a digit",
+ ),
+ },
},
"id": schema.StringAttribute{
MarkdownDescription: "Id of the space. Must be globally unique.",
@@ -64,6 +73,12 @@ func (r *SpaceResource) Schema(ctx context.Context, req resource.SchemaRequest,
PlanModifiers: []planmodifier.String{
stringplanmodifier.UseStateForUnknown(),
},
+ Validators: []validator.String{
+ stringvalidator.RegexMatches(
+ regexp.MustCompile(`^[a-z]([\d-_]|[a-z]){6,35}[a-z\d]$`),
+ "must contain 6 to 35 digits, dashes, underscores, or lowercase letters, and ending with either a lowercase letter or a digit",
+ ),
+ },
},
"mrn": schema.StringAttribute{
MarkdownDescription: "Mrn of the space.",
@@ -75,6 +90,12 @@ func (r *SpaceResource) Schema(ctx context.Context, req resource.SchemaRequest,
"org_id": schema.StringAttribute{
MarkdownDescription: "Id of the organization.",
Required: true,
+ Validators: []validator.String{
+ stringvalidator.RegexMatches(
+ regexp.MustCompile(`^[a-z]([\d-_]|[a-z]){6,35}[a-z\d]$`),
+ "must contain 6 to 35 digits, dashes, underscores, or lowercase letters, and ending with either a lowercase letter or a digit",
+ ),
+ },
},
},
}