diff --git a/docs/data-sources/mdm_software_update_enforcement.md b/docs/data-sources/mdm_software_update_enforcement.md index fb88bd2..37cf59d 100644 --- a/docs/data-sources/mdm_software_update_enforcement.md +++ b/docs/data-sources/mdm_software_update_enforcement.md @@ -29,4 +29,5 @@ The data source `zentral_mdm_software_update_enforcement` allows details of a MD - `local_time` (String) The local time value that specifies when to force install the software update. - `max_os_version` (String) The maximum (excluded) target OS version to update the device to by the appropriate time. - `os_version` (String) The target OS version to update the device to by the appropriate time. +- `platforms` (Set of String) The platforms this software update enforcement is scoped to. - `tag_ids` (Set of Number) The `ID`s of the tags used to scope the software update enforcement. diff --git a/docs/resources/mdm_software_update_enforcement.md b/docs/resources/mdm_software_update_enforcement.md index b922b35..5c349ce 100644 --- a/docs/resources/mdm_software_update_enforcement.md +++ b/docs/resources/mdm_software_update_enforcement.md @@ -18,6 +18,7 @@ The resource `zentral_mdm_software_update_enforcement` manages MDM software upda ### Required - `name` (String) Name of the software update enforcement. +- `platforms` (Set of String) Restrict the software update enforcement to some platforms. ### Optional diff --git a/go.mod b/go.mod index 37bd0f3..244205a 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/hashicorp/terraform-plugin-go v0.19.1 github.com/hashicorp/terraform-plugin-log v0.9.0 github.com/hashicorp/terraform-plugin-sdk/v2 v2.30.0 - github.com/zentralopensource/goztl v0.1.43 + github.com/zentralopensource/goztl v0.1.44 ) require ( diff --git a/go.sum b/go.sum index a0196a2..f6ebfeb 100644 --- a/go.sum +++ b/go.sum @@ -180,8 +180,8 @@ github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zclconf/go-cty v1.14.1 h1:t9fyA35fwjjUMcmL5hLER+e/rEPqrbCK1/OSE4SI9KA= github.com/zclconf/go-cty v1.14.1/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= -github.com/zentralopensource/goztl v0.1.43 h1:nSPa1McCxDgKhPJDjcWV5Oao3ZZmn4za4EbHpdkYcjI= -github.com/zentralopensource/goztl v0.1.43/go.mod h1:pO0e3V3dmiRByUcsaMnaJGdEaPl30xMzTqLD2mK9yrM= +github.com/zentralopensource/goztl v0.1.44 h1:LBCToI5IW/zGrVzOApD5JAJuj/4pNWbg+nlzmjoF7mU= +github.com/zentralopensource/goztl v0.1.44/go.mod h1:pO0e3V3dmiRByUcsaMnaJGdEaPl30xMzTqLD2mK9yrM= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= diff --git a/internal/provider/mdm_blueprint_data_source_test.go b/internal/provider/mdm_blueprint_data_source_test.go index 83c11a1..5a129de 100644 --- a/internal/provider/mdm_blueprint_data_source_test.go +++ b/internal/provider/mdm_blueprint_data_source_test.go @@ -15,6 +15,7 @@ func TestAccMDMBlueprintDataSource(t *testing.T) { c2ResourceName := "zentral_mdm_blueprint.check2" fc2ResourceName := "zentral_mdm_filevault_config.check2" rpc2ResourceName := "zentral_mdm_recovery_password_config.check2" + sue2ResourceName := "zentral_mdm_software_update_enforcement.check2" ds1ResourceName := "data.zentral_mdm_blueprint.check1_by_name" ds2ResourceName := "data.zentral_mdm_blueprint.check2_by_id" @@ -42,6 +43,8 @@ func TestAccMDMBlueprintDataSource(t *testing.T) { ds1ResourceName, "filevault_config_id"), resource.TestCheckNoResourceAttr( ds1ResourceName, "recovery_password_config_id"), + resource.TestCheckResourceAttr( + ds1ResourceName, "software_update_enforcement_ids.#", "0"), // Read by ID resource.TestCheckResourceAttrPair( ds2ResourceName, "id", c2ResourceName, "id"), @@ -59,6 +62,10 @@ func TestAccMDMBlueprintDataSource(t *testing.T) { ds2ResourceName, "filevault_config_id", fc2ResourceName, "id"), resource.TestCheckResourceAttrPair( ds2ResourceName, "recovery_password_config_id", rpc2ResourceName, "id"), + resource.TestCheckResourceAttr( + ds2ResourceName, "software_update_enforcement_ids.#", "1"), + resource.TestCheckTypeSetElemAttrPair( + ds2ResourceName, "software_update_enforcement_ids.*", sue2ResourceName, "id"), ), }, }, @@ -80,14 +87,21 @@ resource "zentral_mdm_recovery_password_config" "check2" { name = %[2]q } +resource "zentral_mdm_software_update_enforcement" "check2" { + name = %[1]q + platforms = ["macOS"] + max_os_version = "15" +} + resource "zentral_mdm_blueprint" "check2" { - name = %[2]q - inventory_interval = 77777 - collect_apps = "MANAGED_ONLY" - collect_certificates = "ALL" - collect_profiles = "MANAGED_ONLY" - filevault_config_id = zentral_mdm_filevault_config.check2.id - recovery_password_config_id = zentral_mdm_recovery_password_config.check2.id + name = %[2]q + inventory_interval = 77777 + collect_apps = "MANAGED_ONLY" + collect_certificates = "ALL" + collect_profiles = "MANAGED_ONLY" + filevault_config_id = zentral_mdm_filevault_config.check2.id + recovery_password_config_id = zentral_mdm_recovery_password_config.check2.id + software_update_enforcement_ids = [zentral_mdm_software_update_enforcement.check2.id] } data "zentral_mdm_blueprint" "check1_by_name" { diff --git a/internal/provider/mdm_blueprint_resource_test.go b/internal/provider/mdm_blueprint_resource_test.go index 16f50d2..3a79f53 100644 --- a/internal/provider/mdm_blueprint_resource_test.go +++ b/internal/provider/mdm_blueprint_resource_test.go @@ -103,6 +103,7 @@ resource "zentral_mdm_recovery_password_config" "test" { resource "zentral_mdm_software_update_enforcement" "test" { name = %[1]q + platforms = ["macOS"] max_os_version = "15" } diff --git a/internal/provider/mdm_software_update_enforcement.go b/internal/provider/mdm_software_update_enforcement.go index b3dfbc4..738b107 100644 --- a/internal/provider/mdm_software_update_enforcement.go +++ b/internal/provider/mdm_software_update_enforcement.go @@ -10,6 +10,7 @@ type mdmSoftwareUpdateEnforcement struct { ID types.Int64 `tfsdk:"id"` Name types.String `tfsdk:"name"` DetailsURL types.String `tfsdk:"details_url"` + Platforms types.Set `tfsdk:"platforms"` TagIDs types.Set `tfsdk:"tag_ids"` OSVersion types.String `tfsdk:"os_version"` BuildVersion types.String `tfsdk:"build_version"` @@ -20,6 +21,11 @@ type mdmSoftwareUpdateEnforcement struct { } func mdmSoftwareUpdateEnforcementForState(msue *goztl.MDMSoftwareUpdateEnforcement) mdmSoftwareUpdateEnforcement { + platforms := make([]attr.Value, 0) + for _, platform := range msue.Platforms { + platforms = append(platforms, types.StringValue(platform)) + } + tagIDs := make([]attr.Value, 0) for _, tagID := range msue.TagIDs { tagIDs = append(tagIDs, types.Int64Value(int64(tagID))) @@ -50,6 +56,7 @@ func mdmSoftwareUpdateEnforcementForState(msue *goztl.MDMSoftwareUpdateEnforceme ID: types.Int64Value(int64(msue.ID)), Name: types.StringValue(msue.Name), DetailsURL: types.StringValue(msue.DetailsURL), + Platforms: types.SetValueMust(types.StringType, platforms), TagIDs: types.SetValueMust(types.Int64Type, tagIDs), OSVersion: types.StringValue(msue.OSVersion), BuildVersion: types.StringValue(msue.BuildVersion), @@ -61,6 +68,11 @@ func mdmSoftwareUpdateEnforcementForState(msue *goztl.MDMSoftwareUpdateEnforceme } func mdmSoftwareUpdateEnforcementRequestWithState(data mdmSoftwareUpdateEnforcement) *goztl.MDMSoftwareUpdateEnforcementRequest { + platforms := make([]string, 0) + for _, platform := range data.Platforms.Elements() { // nil if null or unknown → no iterations + platforms = append(platforms, platform.(types.String).ValueString()) + } + tagIDs := make([]int, 0) for _, tagID := range data.TagIDs.Elements() { // nil if null or unknown → no iterations tagIDs = append(tagIDs, int(tagID.(types.Int64).ValueInt64())) @@ -92,6 +104,7 @@ func mdmSoftwareUpdateEnforcementRequestWithState(data mdmSoftwareUpdateEnforcem return &goztl.MDMSoftwareUpdateEnforcementRequest{ Name: data.Name.ValueString(), DetailsURL: data.DetailsURL.ValueString(), + Platforms: platforms, TagIDs: tagIDs, OSVersion: data.OSVersion.ValueString(), BuildVersion: data.BuildVersion.ValueString(), diff --git a/internal/provider/mdm_software_update_enforcement_data_source.go b/internal/provider/mdm_software_update_enforcement_data_source.go index d42fb72..a2eb4ba 100644 --- a/internal/provider/mdm_software_update_enforcement_data_source.go +++ b/internal/provider/mdm_software_update_enforcement_data_source.go @@ -47,6 +47,12 @@ func (d *MDMSoftwareUpdateEnforcementDataSource) Schema(ctx context.Context, req MarkdownDescription: "The URL of a web page that shows details that the organization provides about the enforced update.", Computed: true, }, + "platforms": schema.SetAttribute{ + Description: "The platforms this software update enforcement is scoped to.", + MarkdownDescription: "The platforms this software update enforcement is scoped to.", + ElementType: types.StringType, + Computed: true, + }, "tag_ids": schema.SetAttribute{ Description: "The IDs of the tags used to scope the software update enforcement.", MarkdownDescription: "The `ID`s of the tags used to scope the software update enforcement.", diff --git a/internal/provider/mdm_software_update_enforcement_data_source_test.go b/internal/provider/mdm_software_update_enforcement_data_source_test.go index 6ef1c44..967d709 100644 --- a/internal/provider/mdm_software_update_enforcement_data_source_test.go +++ b/internal/provider/mdm_software_update_enforcement_data_source_test.go @@ -29,6 +29,12 @@ func TestAccMDMSoftwareUpdateEnforcementDataSource(t *testing.T) { ds1ResourceName, "id", c1ResourceName, "id"), resource.TestCheckResourceAttr( ds1ResourceName, "details_url", ""), + resource.TestCheckResourceAttr( + ds1ResourceName, "platforms.#", "2"), + resource.TestCheckTypeSetElemAttr( + ds1ResourceName, "platforms.*", "iOS"), + resource.TestCheckTypeSetElemAttr( + ds1ResourceName, "platforms.*", "iPadOS"), resource.TestCheckResourceAttr( ds1ResourceName, "tag_ids.#", "0"), resource.TestCheckResourceAttr( @@ -48,6 +54,10 @@ func TestAccMDMSoftwareUpdateEnforcementDataSource(t *testing.T) { ds2ResourceName, "id", c2ResourceName, "id"), resource.TestCheckResourceAttr( ds2ResourceName, "details_url", "https://www.example.com"), + resource.TestCheckResourceAttr( + ds2ResourceName, "platforms.#", "1"), + resource.TestCheckTypeSetElemAttr( + ds2ResourceName, "platforms.*", "macOS"), resource.TestCheckResourceAttr( ds2ResourceName, "tag_ids.#", "1"), resource.TestCheckTypeSetElemAttrPair( @@ -74,6 +84,7 @@ func testAccMDMSoftwareUpdateEnforcementDataSourceConfig(c1Name string, c2Name s return fmt.Sprintf(` resource "zentral_mdm_software_update_enforcement" "check1" { name = %[1]q + platforms = ["iPadOS", "iOS"] max_os_version = "15" delay_days = 3 local_time = "04:05:06" @@ -86,6 +97,7 @@ resource "zentral_tag" "check2" { resource "zentral_mdm_software_update_enforcement" "check2" { name = %[2]q details_url = "https://www.example.com" + platforms = ["macOS"] tag_ids = [zentral_tag.check2.id] os_version = "14.1" build_version = "23B74" diff --git a/internal/provider/mdm_software_update_enforcement_resource.go b/internal/provider/mdm_software_update_enforcement_resource.go index 31ddff4..26dc0fb 100644 --- a/internal/provider/mdm_software_update_enforcement_resource.go +++ b/internal/provider/mdm_software_update_enforcement_resource.go @@ -5,6 +5,8 @@ import ( "fmt" "github.com/hashicorp/terraform-plugin-framework-validators/int64validator" + "github.com/hashicorp/terraform-plugin-framework-validators/setvalidator" + "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/resource/schema" "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64planmodifier" @@ -59,6 +61,16 @@ func (r *MDMSoftwareUpdateEnforcementResource) Schema(ctx context.Context, req r Computed: true, Default: stringdefault.StaticString(""), }, + "platforms": schema.SetAttribute{ + Description: "Restrict the software update enforcement to some platforms.", + MarkdownDescription: "Restrict the software update enforcement to some platforms.", + ElementType: types.StringType, + Required: true, + Validators: []validator.Set{ + setvalidator.ValueStringsAre(stringvalidator.OneOf([]string{"macOS", "iOS", "iPadOS", "tvOS"}...)), + setvalidator.SizeAtLeast(1), + }, + }, "tag_ids": schema.SetAttribute{ Description: "The IDs of the tags used to scope the software update enforcement.", MarkdownDescription: "The `ID`s of the tags used to scope the software update enforcement.", diff --git a/internal/provider/mdm_software_update_enforcement_resource_test.go b/internal/provider/mdm_software_update_enforcement_resource_test.go index 8e3ea94..4d928bd 100644 --- a/internal/provider/mdm_software_update_enforcement_resource_test.go +++ b/internal/provider/mdm_software_update_enforcement_resource_test.go @@ -26,6 +26,10 @@ func TestAccMDMSoftwareUpdateEnforcementResource(t *testing.T) { resourceName, "name", firstName), resource.TestCheckResourceAttr( resourceName, "details_url", ""), + resource.TestCheckResourceAttr( + resourceName, "platforms.#", "1"), + resource.TestCheckTypeSetElemAttr( + resourceName, "platforms.*", "iOS"), resource.TestCheckResourceAttr( resourceName, "tag_ids.#", "0"), resource.TestCheckResourceAttr( @@ -56,6 +60,10 @@ func TestAccMDMSoftwareUpdateEnforcementResource(t *testing.T) { resourceName, "name", secondName), resource.TestCheckResourceAttr( resourceName, "details_url", "https://www.example.com"), + resource.TestCheckResourceAttr( + resourceName, "platforms.#", "1"), + resource.TestCheckTypeSetElemAttr( + resourceName, "platforms.*", "macOS"), resource.TestCheckResourceAttr( resourceName, "tag_ids.#", "1"), resource.TestCheckTypeSetElemAttrPair( @@ -88,6 +96,7 @@ func testAccMDMSoftwareUpdateEnforcementResourceConfigLatest(name string) string return fmt.Sprintf(` resource "zentral_mdm_software_update_enforcement" "test" { name = %[1]q + platforms = ["iOS"] max_os_version = "15" } `, name) @@ -102,6 +111,7 @@ resource "zentral_tag" "test" { resource "zentral_mdm_software_update_enforcement" "test" { name = %[1]q details_url = "https://www.example.com" + platforms = ["macOS"] tag_ids = [zentral_tag.test.id] os_version = "14.1" build_version = "23B74"