@@ -6,10 +6,23 @@ import (
66 "fmt"
77 "strconv"
88
9- "github.com/hashicorp /terraform-plugin-framework/types "
9+ "github.com/deploymenttheory /terraform-provider-microsoft365/internal/services/common/convert "
1010 "github.com/hashicorp/terraform-plugin-log/tflog"
1111)
1212
13+ // mapTypeStringToInt converts type strings to integers for API requests
14+ // "Device" = 0, "None" = 1
15+ func mapTypeStringToInt (typeStr string ) int {
16+ switch typeStr {
17+ case "None" :
18+ return 1
19+ case "Device" :
20+ return 0
21+ default :
22+ return 0 // Default to Device
23+ }
24+ }
25+
1326// constructResource constructs a JSON request body for the Autopatch Groups API
1427func constructResource (ctx context.Context , data * AutopatchGroupsResourceModel ) (map [string ]any , error ) {
1528 tflog .Debug (ctx , fmt .Sprintf ("Constructing %s resource from Terraform configuration" , ResourceName ))
@@ -38,7 +51,8 @@ func constructResource(ctx context.Context, data *AutopatchGroupsResourceModel)
3851 groupMap ["id" ] = group .Id .ValueString ()
3952 }
4053 if ! group .Type .IsNull () && ! group .Type .IsUnknown () {
41- groupMap ["type" ] = group .Type .ValueString ()
54+ // Convert string to integer for API (POST uses integers)
55+ groupMap ["type" ] = mapTypeStringToInt (group .Type .ValueString ())
4256 }
4357 globalGroupsAPI = append (globalGroupsAPI , groupMap )
4458 }
@@ -84,7 +98,8 @@ func constructResource(ctx context.Context, data *AutopatchGroupsResourceModel)
8498 userGroupMap ["name" ] = userGroup .Name .ValueString ()
8599 }
86100 if ! userGroup .Type .IsNull () && ! userGroup .Type .IsUnknown () {
87- userGroupMap ["type" ] = userGroup .Type .ValueInt32 ()
101+ // Convert string to integer for API (POST uses integers)
102+ userGroupMap ["type" ] = mapTypeStringToInt (userGroup .Type .ValueString ())
88103 }
89104 userGroupsAPI = append (userGroupsAPI , userGroupMap )
90105 }
@@ -95,66 +110,10 @@ func constructResource(ctx context.Context, data *AutopatchGroupsResourceModel)
95110
96111 // Deployment Group Policy Settings
97112 if group .DeploymentGroupPolicySettings != nil {
98- policyMap := make (map [string ]any )
99-
100- if ! group .DeploymentGroupPolicySettings .AadGroupName .IsNull () && ! group .DeploymentGroupPolicySettings .AadGroupName .IsUnknown () {
101- policyMap ["aadGroupName" ] = group .DeploymentGroupPolicySettings .AadGroupName .ValueString ()
102- }
103- if ! group .DeploymentGroupPolicySettings .IsUpdateSettingsModified .IsNull () && ! group .DeploymentGroupPolicySettings .IsUpdateSettingsModified .IsUnknown () {
104- policyMap ["isUpdateSettingsModified" ] = group .DeploymentGroupPolicySettings .IsUpdateSettingsModified .ValueBool ()
113+ policyMap , err := constructDeploymentGroupPolicySettings (ctx , group .DeploymentGroupPolicySettings )
114+ if err != nil {
115+ return nil , fmt .Errorf ("error constructing deployment group policy settings: %w" , err )
105116 }
106-
107- // Device Configuration Settings
108- if group .DeploymentGroupPolicySettings .DeviceConfigurationSetting != nil {
109- deviceConfigMap := make (map [string ]any )
110-
111- if ! group .DeploymentGroupPolicySettings .DeviceConfigurationSetting .PolicyId .IsNull () && ! group .DeploymentGroupPolicySettings .DeviceConfigurationSetting .PolicyId .IsUnknown () {
112- deviceConfigMap ["policyId" ] = group .DeploymentGroupPolicySettings .DeviceConfigurationSetting .PolicyId .ValueString ()
113- }
114- if ! group .DeploymentGroupPolicySettings .DeviceConfigurationSetting .UpdateBehavior .IsNull () && ! group .DeploymentGroupPolicySettings .DeviceConfigurationSetting .UpdateBehavior .IsUnknown () {
115- deviceConfigMap ["updateBehavior" ] = group .DeploymentGroupPolicySettings .DeviceConfigurationSetting .UpdateBehavior .ValueString ()
116- }
117- if ! group .DeploymentGroupPolicySettings .DeviceConfigurationSetting .NotificationSetting .IsNull () && ! group .DeploymentGroupPolicySettings .DeviceConfigurationSetting .NotificationSetting .IsUnknown () {
118- deviceConfigMap ["notificationSetting" ] = group .DeploymentGroupPolicySettings .DeviceConfigurationSetting .NotificationSetting .ValueString ()
119- }
120-
121- // Quality Deployment Settings
122- if group .DeploymentGroupPolicySettings .DeviceConfigurationSetting .QualityDeploymentSettings != nil {
123- qualityMap := make (map [string ]any )
124- if ! group .DeploymentGroupPolicySettings .DeviceConfigurationSetting .QualityDeploymentSettings .Deadline .IsNull () && ! group .DeploymentGroupPolicySettings .DeviceConfigurationSetting .QualityDeploymentSettings .Deadline .IsUnknown () {
125- qualityMap ["deadline" ] = group .DeploymentGroupPolicySettings .DeviceConfigurationSetting .QualityDeploymentSettings .Deadline .ValueInt32 ()
126- }
127- if ! group .DeploymentGroupPolicySettings .DeviceConfigurationSetting .QualityDeploymentSettings .Deferral .IsNull () && ! group .DeploymentGroupPolicySettings .DeviceConfigurationSetting .QualityDeploymentSettings .Deferral .IsUnknown () {
128- qualityMap ["deferral" ] = group .DeploymentGroupPolicySettings .DeviceConfigurationSetting .QualityDeploymentSettings .Deferral .ValueInt32 ()
129- }
130- if ! group .DeploymentGroupPolicySettings .DeviceConfigurationSetting .QualityDeploymentSettings .GracePeriod .IsNull () && ! group .DeploymentGroupPolicySettings .DeviceConfigurationSetting .QualityDeploymentSettings .GracePeriod .IsUnknown () {
131- qualityMap ["gracePeriod" ] = group .DeploymentGroupPolicySettings .DeviceConfigurationSetting .QualityDeploymentSettings .GracePeriod .ValueInt32 ()
132- }
133- deviceConfigMap ["qualityDeploymentSettings" ] = qualityMap
134- }
135-
136- // Feature Deployment Settings
137- if group .DeploymentGroupPolicySettings .DeviceConfigurationSetting .FeatureDeploymentSettings != nil {
138- featureMap := make (map [string ]any )
139- if ! group .DeploymentGroupPolicySettings .DeviceConfigurationSetting .FeatureDeploymentSettings .Deadline .IsNull () && ! group .DeploymentGroupPolicySettings .DeviceConfigurationSetting .FeatureDeploymentSettings .Deadline .IsUnknown () {
140- featureMap ["deadline" ] = group .DeploymentGroupPolicySettings .DeviceConfigurationSetting .FeatureDeploymentSettings .Deadline .ValueInt32 ()
141- }
142- if ! group .DeploymentGroupPolicySettings .DeviceConfigurationSetting .FeatureDeploymentSettings .Deferral .IsNull () && ! group .DeploymentGroupPolicySettings .DeviceConfigurationSetting .FeatureDeploymentSettings .Deferral .IsUnknown () {
143- featureMap ["deferral" ] = group .DeploymentGroupPolicySettings .DeviceConfigurationSetting .FeatureDeploymentSettings .Deferral .ValueInt32 ()
144- }
145- deviceConfigMap ["featureDeploymentSettings" ] = featureMap
146- }
147-
148- // Add required null fields from API example
149- deviceConfigMap ["updateFrequencyUI" ] = nil
150- deviceConfigMap ["installDays" ] = nil
151- deviceConfigMap ["installTime" ] = nil
152- deviceConfigMap ["activeHourEndTime" ] = nil
153- deviceConfigMap ["activeHourStartTime" ] = nil
154-
155- policyMap ["deviceConfigurationSetting" ] = deviceConfigMap
156- }
157-
158117 groupMap ["deploymentGroupPolicySettings" ] = policyMap
159118 }
160119
@@ -178,21 +137,22 @@ func constructResource(ctx context.Context, data *AutopatchGroupsResourceModel)
178137 requestBody ["enableDriverUpdate" ] = true // Default from API example
179138 }
180139
140+ // Scope Tags - convert from string set to int array for API
181141 if ! data .ScopeTags .IsNull () && ! data .ScopeTags .IsUnknown () {
182- var scopeTags []types. String
183- data . ScopeTags . ElementsAs (ctx , & scopeTags , false )
184-
185- scopeTagsAPI := make ([] int32 , 0 , len ( scopeTags ) )
186- for _ , tag := range scopeTags {
187- if ! tag . IsNull () && ! tag . IsUnknown () {
188- if tagInt , err := strconv . Atoi ( tag . ValueString ()); err == nil {
189- scopeTagsAPI = append ( scopeTagsAPI , int32 ( tagInt ))
190- }
142+ var scopeTagStrings []string
143+ convert . FrameworkToGraphStringSet (ctx , data . ScopeTags , func ( tags [] string ) {
144+ scopeTagStrings = tags
145+ } )
146+
147+ scopeTagsAPI := make ([] int , 0 , len ( scopeTagStrings ))
148+ for _ , tagStr := range scopeTagStrings {
149+ if tagInt , err := strconv . Atoi ( tagStr ); err == nil {
150+ scopeTagsAPI = append ( scopeTagsAPI , tagInt )
191151 }
192152 }
193153 requestBody ["scopeTags" ] = scopeTagsAPI
194154 } else {
195- requestBody ["scopeTags" ] = []int32 {0 } // Default
155+ requestBody ["scopeTags" ] = []int {0 } // Default
196156 }
197157
198158 // Enabled Content Types
@@ -213,3 +173,202 @@ func constructResource(ctx context.Context, data *AutopatchGroupsResourceModel)
213173
214174 return requestBody , nil
215175}
176+
177+ // constructDeploymentGroupPolicySettings constructs the deployment group policy settings
178+ func constructDeploymentGroupPolicySettings (ctx context.Context , settings * DeploymentGroupPolicySettings ) (map [string ]any , error ) {
179+ policyMap := make (map [string ]any )
180+
181+ convert .FrameworkToGraphString (settings .AadGroupName , func (val * string ) {
182+ if val != nil {
183+ policyMap ["aadGroupName" ] = * val
184+ }
185+ })
186+
187+ convert .FrameworkToGraphBool (settings .IsUpdateSettingsModified , func (val * bool ) {
188+ if val != nil {
189+ policyMap ["isUpdateSettingsModified" ] = * val
190+ }
191+ })
192+
193+ // Device Configuration Settings
194+ if settings .DeviceConfigurationSetting != nil {
195+ deviceConfigMap := make (map [string ]any )
196+
197+ convert .FrameworkToGraphString (settings .DeviceConfigurationSetting .PolicyId , func (val * string ) {
198+ if val != nil {
199+ deviceConfigMap ["policyId" ] = * val
200+ }
201+ })
202+
203+ convert .FrameworkToGraphString (settings .DeviceConfigurationSetting .UpdateBehavior , func (val * string ) {
204+ if val != nil {
205+ deviceConfigMap ["updateBehavior" ] = * val
206+ }
207+ })
208+
209+ convert .FrameworkToGraphString (settings .DeviceConfigurationSetting .NotificationSetting , func (val * string ) {
210+ if val != nil {
211+ deviceConfigMap ["notificationSetting" ] = * val
212+ }
213+ })
214+
215+ // Quality Deployment Settings
216+ if settings .DeviceConfigurationSetting .QualityDeploymentSettings != nil {
217+ qualityMap := make (map [string ]any )
218+ convert .FrameworkToGraphInt32 (settings .DeviceConfigurationSetting .QualityDeploymentSettings .Deadline , func (val * int32 ) {
219+ if val != nil {
220+ qualityMap ["deadline" ] = * val
221+ }
222+ })
223+ convert .FrameworkToGraphInt32 (settings .DeviceConfigurationSetting .QualityDeploymentSettings .Deferral , func (val * int32 ) {
224+ if val != nil {
225+ qualityMap ["deferral" ] = * val
226+ }
227+ })
228+ convert .FrameworkToGraphInt32 (settings .DeviceConfigurationSetting .QualityDeploymentSettings .GracePeriod , func (val * int32 ) {
229+ if val != nil {
230+ qualityMap ["gracePeriod" ] = * val
231+ }
232+ })
233+ deviceConfigMap ["qualityDeploymentSettings" ] = qualityMap
234+ }
235+
236+ // Feature Deployment Settings
237+ if settings .DeviceConfigurationSetting .FeatureDeploymentSettings != nil {
238+ featureMap := make (map [string ]any )
239+ convert .FrameworkToGraphInt32 (settings .DeviceConfigurationSetting .FeatureDeploymentSettings .Deadline , func (val * int32 ) {
240+ if val != nil {
241+ featureMap ["deadline" ] = * val
242+ }
243+ })
244+ convert .FrameworkToGraphInt32 (settings .DeviceConfigurationSetting .FeatureDeploymentSettings .Deferral , func (val * int32 ) {
245+ if val != nil {
246+ featureMap ["deferral" ] = * val
247+ }
248+ })
249+ deviceConfigMap ["featureDeploymentSettings" ] = featureMap
250+ }
251+
252+ // Add required null fields from API example
253+ deviceConfigMap ["updateFrequencyUI" ] = nil
254+ deviceConfigMap ["installDays" ] = nil
255+ deviceConfigMap ["installTime" ] = nil
256+ deviceConfigMap ["activeHourEndTime" ] = nil
257+ deviceConfigMap ["activeHourStartTime" ] = nil
258+
259+ policyMap ["deviceConfigurationSetting" ] = deviceConfigMap
260+ }
261+
262+ // DNF Update Cloud Setting
263+ if settings .DnfUpdateCloudSetting != nil {
264+ dnfMap := make (map [string ]any )
265+ convert .FrameworkToGraphString (settings .DnfUpdateCloudSetting .PolicyId , func (val * string ) {
266+ if val != nil {
267+ dnfMap ["policyId" ] = * val
268+ }
269+ })
270+ convert .FrameworkToGraphString (settings .DnfUpdateCloudSetting .ApprovalType , func (val * string ) {
271+ if val != nil {
272+ dnfMap ["approvalType" ] = * val
273+ }
274+ })
275+ convert .FrameworkToGraphInt32 (settings .DnfUpdateCloudSetting .DeploymentDeferralInDays , func (val * int32 ) {
276+ if val != nil {
277+ dnfMap ["deploymentDeferralInDays" ] = * val
278+ } else {
279+ dnfMap ["deploymentDeferralInDays" ] = nil
280+ }
281+ })
282+ policyMap ["dnfUpdateCloudSetting" ] = dnfMap
283+ }
284+
285+ // Office DCv2 Setting
286+ if settings .OfficeDCv2Setting != nil {
287+ officeMap := make (map [string ]any )
288+ convert .FrameworkToGraphString (settings .OfficeDCv2Setting .PolicyId , func (val * string ) {
289+ if val != nil {
290+ officeMap ["policyId" ] = * val
291+ }
292+ })
293+ convert .FrameworkToGraphInt32 (settings .OfficeDCv2Setting .Deadline , func (val * int32 ) {
294+ if val != nil {
295+ officeMap ["deadline" ] = * val
296+ }
297+ })
298+ convert .FrameworkToGraphInt32 (settings .OfficeDCv2Setting .Deferral , func (val * int32 ) {
299+ if val != nil {
300+ officeMap ["deferral" ] = * val
301+ }
302+ })
303+ convert .FrameworkToGraphBool (settings .OfficeDCv2Setting .HideUpdateNotifications , func (val * bool ) {
304+ if val != nil {
305+ officeMap ["hideUpdateNotifications" ] = * val
306+ }
307+ })
308+ convert .FrameworkToGraphString (settings .OfficeDCv2Setting .TargetChannel , func (val * string ) {
309+ if val != nil {
310+ officeMap ["targetChannel" ] = * val
311+ }
312+ })
313+ convert .FrameworkToGraphBool (settings .OfficeDCv2Setting .EnableAutomaticUpdate , func (val * bool ) {
314+ if val != nil {
315+ officeMap ["enableAutomaticUpdate" ] = * val
316+ }
317+ })
318+ convert .FrameworkToGraphBool (settings .OfficeDCv2Setting .HideEnableDisableUpdate , func (val * bool ) {
319+ if val != nil {
320+ officeMap ["hideEnableDisableUpdate" ] = * val
321+ }
322+ })
323+ convert .FrameworkToGraphBool (settings .OfficeDCv2Setting .EnableOfficeMgmt , func (val * bool ) {
324+ if val != nil {
325+ officeMap ["enableOfficeMgmt" ] = * val
326+ }
327+ })
328+ convert .FrameworkToGraphString (settings .OfficeDCv2Setting .UpdatePath , func (val * string ) {
329+ if val != nil {
330+ officeMap ["updatePath" ] = * val
331+ }
332+ })
333+ policyMap ["officeDCv2Setting" ] = officeMap
334+ }
335+
336+ // Edge DCv2 Setting
337+ if settings .EdgeDCv2Setting != nil {
338+ edgeMap := make (map [string ]any )
339+ convert .FrameworkToGraphString (settings .EdgeDCv2Setting .PolicyId , func (val * string ) {
340+ if val != nil {
341+ edgeMap ["policyId" ] = * val
342+ }
343+ })
344+ convert .FrameworkToGraphString (settings .EdgeDCv2Setting .TargetChannel , func (val * string ) {
345+ if val != nil {
346+ edgeMap ["targetChannel" ] = * val
347+ }
348+ })
349+ policyMap ["edgeDCv2Setting" ] = edgeMap
350+ }
351+
352+ // Feature Update Anchor Cloud Setting
353+ if settings .FeatureUpdateAnchorCloudSetting != nil {
354+ featureAnchorMap := make (map [string ]any )
355+ convert .FrameworkToGraphString (settings .FeatureUpdateAnchorCloudSetting .TargetOSVersion , func (val * string ) {
356+ if val != nil {
357+ featureAnchorMap ["targetOSVersion" ] = * val
358+ }
359+ })
360+ convert .FrameworkToGraphBool (settings .FeatureUpdateAnchorCloudSetting .InstallLatestWindows10OnWindows11IneligibleDevice , func (val * bool ) {
361+ if val != nil {
362+ featureAnchorMap ["installLatestWindows10OnWindows11IneligibleDevice" ] = * val
363+ }
364+ })
365+ convert .FrameworkToGraphString (settings .FeatureUpdateAnchorCloudSetting .PolicyId , func (val * string ) {
366+ if val != nil {
367+ featureAnchorMap ["policyId" ] = * val
368+ }
369+ })
370+ policyMap ["featureUpdateAnchorCloudSetting" ] = featureAnchorMap
371+ }
372+
373+ return policyMap , nil
374+ }
0 commit comments