Skip to content

Commit c7240f6

Browse files
Publish only Computed fields for resources and all fields for data sources to avoid invalid diffs in terraform plan. (#13)
* Publish only COmputed fields for resources and all fields for data sources. Added test for flattenNetInstConfig * After create / Update, do a get and publish all the computed fields again.
1 parent 296bac4 commit c7240f6

27 files changed

+900
-318
lines changed

provider/data_source_edgeapp.go

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import (
1515
)
1616

1717
var EdgeAppDataSourceSchema = &schema.Resource{
18-
ReadContext: readEdgeApp,
18+
ReadContext: readDataSourceEdgeApp,
1919
Schema: zschemas.EdgeAppSchema,
2020
Description: "Schema for data source zedcloud_edgeapp. Must specify id or name",
2121
}
@@ -36,26 +36,31 @@ func getEdgeApp(client *zedcloudapi.Client,
3636
return rspData, nil
3737
}
3838

39-
func flattenEdgeAppConfig(cfg *swagger_models.App) map[string]interface{} {
40-
return map[string]interface{}{
41-
"name": ptrValStr(cfg.Name),
42-
"id": cfg.ID,
43-
"title": ptrValStr(cfg.Title),
44-
"description": cfg.Description,
45-
"cpus": int(cfg.Cpus),
46-
"drives": int(cfg.Drives),
47-
"memory": int(cfg.Memory),
48-
"networks": int(cfg.Networks),
49-
"origin_type": ptrValStr(cfg.OriginType),
50-
"parent_detail": flattenObjectParentDetail(cfg.ParentDetail),
51-
"revision": flattenObjectRevision(cfg.Revision),
52-
"storage": int(cfg.Storage),
53-
"user_defined_version": cfg.UserDefinedVersion,
39+
func flattenEdgeAppConfig(cfg *swagger_models.App, computedOnly bool) map[string]interface{} {
40+
data := map[string]interface{}{
41+
"id": cfg.ID,
42+
"origin_type": ptrValStr(cfg.OriginType),
43+
"parent_detail": flattenObjectParentDetail(cfg.ParentDetail),
44+
"revision": flattenObjectRevision(cfg.Revision),
5445
}
46+
if !computedOnly {
47+
data["name"] = ptrValStr(cfg.Name)
48+
data["title"] = ptrValStr(cfg.Title)
49+
data["description"] = cfg.Description
50+
data["cpus"] = int(cfg.Cpus)
51+
data["drives"] = int(cfg.Drives)
52+
data["memory"] = int(cfg.Memory)
53+
data["networks"] = int(cfg.Networks)
54+
data["storage"] = int(cfg.Storage)
55+
data["user_defined_version"] = cfg.UserDefinedVersion
56+
}
57+
flattenedDataCheckKeys(zschemas.EdgeAppSchema, data, computedOnly)
58+
return data
5559
}
5660

5761
// Read the Resource Group
58-
func readEdgeApp(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
62+
func readEdgeApp(ctx context.Context, d *schema.ResourceData, meta interface{},
63+
resource bool) diag.Diagnostics {
5964
var diags diag.Diagnostics
6065

6166
client := (meta.(Client)).Client
@@ -76,6 +81,10 @@ func readEdgeApp(ctx context.Context, d *schema.ResourceData, meta interface{})
7681
}
7782

7883
// Take the Config and convert it to terraform object
79-
marshalData(d, flattenEdgeAppConfig(cfg))
84+
marshalData(d, flattenEdgeAppConfig(cfg, resource))
8085
return diags
8186
}
87+
88+
func readDataSourceEdgeApp(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
89+
return readEdgeApp(ctx, d, meta, false)
90+
}

provider/data_source_edgeapp_instance.go

Lines changed: 54 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import (
1515
)
1616

1717
var EdgeAppInstanceDataSourceSchema = &schema.Resource{
18-
ReadContext: readAppInst,
18+
ReadContext: readDataSourceAppInst,
1919
Schema: zschemas.AppInstSchema,
2020
Description: "Schema for data source zedcloud_edgeapp_instance. Must specify " +
2121
"id or name",
@@ -282,48 +282,61 @@ func flattenCustomConfig(cfg *swagger_models.CustomConfig) []interface{} {
282282
}}
283283
}
284284

285-
func flattenAppInstance(cfg *swagger_models.AppInstance) map[string]interface{} {
285+
func flattenAppInstance(cfg *swagger_models.AppInstance,
286+
computedOnly bool) map[string]interface{} {
286287
if cfg == nil {
287288
return map[string]interface{}{}
288289
}
289-
activate := false
290-
if cfg.Activate != nil {
291-
activate = *cfg.Activate
292-
}
293290
// Do not publish sensitive fields - crypto_key, encrypted_secrets
294-
return map[string]interface{}{
295-
"activate": activate,
296-
"app_id": ptrValStr(cfg.AppID),
297-
"app_policy_id": cfg.AppPolicyID,
298-
"app_type": ptrValStr(cfg.AppType),
299-
"bundleversion": cfg.Bundleversion,
300-
"cluster_id": cfg.ClusterID,
301-
"collect_stats_ip_addr": cfg.CollectStatsIPAddr,
302-
"custom_config": flattenCustomConfig(cfg.CustomConfig),
303-
"deployment_type": ptrValStr(cfg.DeploymentType),
304-
"description": cfg.Description,
305-
"device_id": ptrValStr(cfg.DeviceID),
306-
"drive": flattenDrives(cfg.Drives),
307-
"id": cfg.ID,
308-
"interface": flattenAppInterfaces(cfg.Interfaces),
309-
"is_secret_updated": cfg.IsSecretUpdated,
310-
"logs": flattenAppInstanceLogs(cfg.Logs),
311-
"name": ptrValStr(cfg.Name),
312-
"project_id": ptrValStr(cfg.ProjectID),
313-
"purge": flattenZedCloudOpsCmd(cfg.Purge),
314-
"refresh": flattenZedCloudOpsCmd(cfg.Refresh),
315-
"remote_console": cfg.RemoteConsole,
316-
"restart": flattenZedCloudOpsCmd(cfg.Restart),
317-
"revision": flattenObjectRevision(cfg.Revision),
318-
"tags": flattenStringMap(cfg.Tags),
319-
"title": ptrValStr(cfg.Title),
320-
"user_defined_version": cfg.UserDefinedVersion,
321-
"vminfo": flattenVM(cfg.Vminfo),
291+
data := map[string]interface{}{
292+
"bundleversion": cfg.Bundleversion,
293+
"cluster_id": cfg.ClusterID,
294+
"id": cfg.ID,
295+
"is_secret_updated": cfg.IsSecretUpdated,
296+
"project_id": ptrValStr(cfg.ProjectID),
297+
"purge": flattenZedCloudOpsCmd(cfg.Purge),
298+
"refresh": flattenZedCloudOpsCmd(cfg.Refresh),
299+
"restart": flattenZedCloudOpsCmd(cfg.Restart),
300+
"revision": flattenObjectRevision(cfg.Revision),
301+
"user_defined_version": cfg.UserDefinedVersion,
302+
"vminfo": flattenVM(cfg.Vminfo),
303+
}
304+
if !computedOnly {
305+
data["activate"] = ptrValBool(cfg.Activate)
306+
data["app_id"] = ptrValStr(cfg.AppID)
307+
data["app_policy_id"] = cfg.AppPolicyID
308+
data["app_type"] = ptrValStr(cfg.AppType)
309+
data["collect_stats_ip_addr"] = cfg.CollectStatsIPAddr
310+
data["custom_config"] = flattenCustomConfig(cfg.CustomConfig)
311+
data["description"] = cfg.Description
312+
data["deployment_type"] = ptrValStr(cfg.DeploymentType)
313+
data["device_id"] = ptrValStr(cfg.DeviceID)
314+
data["drive"] = flattenDrives(cfg.Drives)
315+
data["interface"] = flattenAppInterfaces(cfg.Interfaces)
316+
data["logs"] = flattenAppInstanceLogs(cfg.Logs)
317+
data["name"] = ptrValStr(cfg.Name)
318+
data["remote_console"] = cfg.RemoteConsole
319+
data["tags"] = flattenStringMap(cfg.Tags)
320+
data["title"] = ptrValStr(cfg.Title)
322321
}
322+
flattenedDataCheckKeys(zschemas.AppInstSchema, data, computedOnly)
323+
return data
324+
}
325+
326+
func getAppInstAndPublishData(client *zedcloudapi.Client, d *schema.ResourceData,
327+
name, id string, resource bool) error {
328+
cfg, err := getAppInstance(client, name, id)
329+
if err != nil {
330+
return fmt.Errorf("[ERROR] App Instance %s (id: %s) not found. Err: %s",
331+
name, id, err.Error())
332+
}
333+
marshalData(d, flattenAppInstance(cfg, resource))
334+
return nil
323335
}
324336

325337
// Read the Resource Group
326-
func readAppInst(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
338+
func readAppInst(ctx context.Context, d *schema.ResourceData, meta interface{},
339+
resource bool) diag.Diagnostics {
327340
var diags diag.Diagnostics
328341

329342
client := (meta.(Client)).Client
@@ -337,13 +350,13 @@ func readAppInst(ctx context.Context, d *schema.ResourceData, meta interface{})
337350
if (id == "") && (name == "") {
338351
return diag.Errorf("The arguments \"id\" or \"name\" are required, but no definition was found.")
339352
}
340-
cfg, err := getAppInstance(client, name, id)
353+
err := getAppInstAndPublishData(client, d, name, id, resource)
341354
if err != nil {
342-
return diag.Errorf("[ERROR] App Instance %s (id: %s) not found. Err: %s",
343-
name, id, err.Error())
355+
return diag.Errorf("%s", err.Error())
344356
}
345-
346-
// Take the Config and convert it to terraform object
347-
marshalData(d, flattenAppInstance(cfg))
348357
return diags
349358
}
359+
360+
func readDataSourceAppInst(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
361+
return readAppInst(ctx, d, meta, false)
362+
}

provider/data_source_edgenode.go

Lines changed: 39 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import (
1313
)
1414

1515
var EdgeNodeDataSourceSchema = &schema.Resource{
16-
ReadContext: readEdgeNode,
16+
ReadContext: readDataSourceEdgeNode,
1717
Schema: zschemas.EdgeNodeSchema,
1818
Description: "Schema for data source zedcloud_edgenode. Must specify id or name",
1919
}
@@ -66,7 +66,7 @@ func flattenEDConfigItems(cfgList []*swagger_models.EDConfigItem) map[string]int
6666
return dataMap
6767
}
6868

69-
func flattenDeviceConfig(cfg *swagger_models.DeviceConfig) map[string]interface{} {
69+
func flattenDeviceConfig(cfg *swagger_models.DeviceConfig, computedOnly bool) map[string]interface{} {
7070
eveImageVersion := ""
7171
for _, image := range cfg.BaseImage {
7272
if image.Activate {
@@ -75,36 +75,42 @@ func flattenDeviceConfig(cfg *swagger_models.DeviceConfig) map[string]interface{
7575
}
7676
}
7777

78-
return map[string]interface{}{
79-
"adminstate": ptrValStr(cfg.AdminState),
80-
"asset_id": cfg.AssetID,
81-
"client_ip": cfg.ClientIP,
82-
"cluster_id": cfg.ClusterID,
83-
"config_items": flattenEDConfigItems(cfg.ConfigItem),
84-
"cpu": int(cfg.CPU),
85-
"description": cfg.Description,
86-
"dev_location": flattenGeoLocation(cfg.DevLocation),
87-
"eve_image_version": eveImageVersion,
88-
"id": cfg.ID,
89-
"interface": flattenSysInterfaces(cfg.Interfaces),
90-
"memory": int(cfg.Memory),
91-
"model_id": ptrValStr(cfg.ModelID),
92-
"name": ptrValStr(cfg.Name),
93-
"project_id": ptrValStr(cfg.ProjectID),
94-
"reset_counter": int(cfg.ResetCounter),
95-
"reset_time": cfg.ResetTime,
96-
"revision": flattenObjectRevision(cfg.Revision),
97-
"serialno": cfg.Serialno,
98-
"storage": int(cfg.Storage),
99-
"tags": flattenStringMap(cfg.Tags),
100-
"thread": int(cfg.Storage),
101-
"title": ptrValStr(cfg.Title),
102-
"utype": ptrValStr(cfg.Utype),
78+
data := map[string]interface{}{
79+
"adminstate": ptrValStr(cfg.AdminState),
80+
"cluster_id": cfg.ClusterID,
81+
"cpu": int(cfg.CPU),
82+
"id": cfg.ID,
83+
"memory": int(cfg.Memory),
84+
"model_id": ptrValStr(cfg.ModelID),
85+
"project_id": ptrValStr(cfg.ProjectID),
86+
"reset_counter": int(cfg.ResetCounter),
87+
"reset_time": cfg.ResetTime,
88+
"revision": flattenObjectRevision(cfg.Revision),
89+
"serialno": cfg.Serialno,
90+
"storage": int(cfg.Storage),
91+
"thread": int(cfg.Storage),
92+
"utype": ptrValStr(cfg.Utype),
10393
}
94+
if !computedOnly {
95+
data["asset_id"] = cfg.AssetID
96+
data["client_ip"] = cfg.ClientIP
97+
data["config_items"] = flattenEDConfigItems(cfg.ConfigItem)
98+
data["description"] = cfg.Description
99+
data["dev_location"] = flattenGeoLocation(cfg.DevLocation)
100+
data["eve_image_version"] = eveImageVersion
101+
data["interface"] = flattenSysInterfaces(cfg.Interfaces)
102+
data["name"] = ptrValStr(cfg.Name)
103+
data["project_id"] = ptrValStr(cfg.ProjectID)
104+
data["tags"] = flattenStringMap(cfg.Tags)
105+
data["title"] = ptrValStr(cfg.Title)
106+
}
107+
flattenedDataCheckKeys(zschemas.EdgeNodeSchema, data, computedOnly)
108+
return data
104109
}
105110

106111
// Read the Resource Group
107-
func readEdgeNode(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
112+
func readEdgeNode(ctx context.Context, d *schema.ResourceData,
113+
meta interface{}, resource bool) diag.Diagnostics {
108114
// Warning or errors can be collected in a slice type
109115
var diags diag.Diagnostics
110116

@@ -125,6 +131,10 @@ func readEdgeNode(ctx context.Context, d *schema.ResourceData, meta interface{})
125131
name, id, err.Error())
126132
}
127133
// Take the Config and convert it to terraform object
128-
marshalData(d, flattenDeviceConfig(cfg))
134+
marshalData(d, flattenDeviceConfig(cfg, resource))
129135
return diags
130136
}
137+
138+
func readDataSourceEdgeNode(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
139+
return readEdgeNode(ctx, d, meta, true)
140+
}

provider/data_source_image.go

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import (
1515
)
1616

1717
var ImageDataSourceSchema = &schema.Resource{
18-
ReadContext: readImage,
18+
ReadContext: readDataSourceImage,
1919
Schema: zschemas.ImageSchema,
2020
Description: "Schema for data source zedcloud_image. Must specify id or name",
2121
}
@@ -36,30 +36,34 @@ func getImage(client *zedcloudapi.Client,
3636
return rspData, nil
3737
}
3838

39-
func flattenImageConfig(cfg *swagger_models.ImageConfig) map[string]interface{} {
40-
return map[string]interface{}{
41-
"datastore_id": ptrValStr(cfg.DatastoreID),
42-
"description": cfg.Description,
43-
"id": cfg.ID,
44-
"image_arch": ptrValStr(cfg.ImageArch),
45-
"image_error": cfg.ImageError,
46-
"image_format": ptrValStr(cfg.ImageFormat),
47-
"image_local": cfg.ImageLocal,
48-
"image_rel_url": cfg.ImageRelURL,
49-
"image_sha_256": cfg.ImageSha256,
50-
"image_size_bytes": cfg.ImageSizeBytes,
51-
"image_status": ptrValStr(cfg.ImageStatus),
52-
"image_type": ptrValStr(cfg.ImageType),
53-
"image_version": cfg.ImageVersion,
54-
"name": ptrValStr(cfg.Name),
55-
"origin_type": ptrValStr(cfg.OriginType),
56-
"revision": flattenObjectRevision(cfg.Revision),
57-
"title": ptrValStr(cfg.Title),
39+
func flattenImageConfig(cfg *swagger_models.ImageConfig, computedOnly bool) map[string]interface{} {
40+
data := map[string]interface{}{
41+
"id": cfg.ID,
42+
"image_error": cfg.ImageError,
43+
"image_local": cfg.ImageLocal,
44+
"image_status": ptrValStr(cfg.ImageStatus),
45+
"image_version": cfg.ImageVersion,
46+
"origin_type": ptrValStr(cfg.OriginType),
47+
"revision": flattenObjectRevision(cfg.Revision),
5848
}
49+
if !computedOnly {
50+
data["datastore_id"] = ptrValStr(cfg.DatastoreID)
51+
data["description"] = cfg.Description
52+
data["image_arch"] = ptrValStr(cfg.ImageArch)
53+
data["image_format"] = ptrValStr(cfg.ImageFormat)
54+
data["image_rel_url"] = cfg.ImageRelURL
55+
data["image_sha_256"] = cfg.ImageSha256
56+
data["image_size_bytes"] = cfg.ImageSizeBytes
57+
data["image_type"] = ptrValStr(cfg.ImageType)
58+
data["name"] = ptrValStr(cfg.Name)
59+
data["title"] = ptrValStr(cfg.Title)
60+
}
61+
flattenedDataCheckKeys(zschemas.ImageSchema, data, computedOnly)
62+
return data
5963
}
6064

6165
// Read the Resource Group
62-
func readImage(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
66+
func readImage(ctx context.Context, d *schema.ResourceData, meta interface{}, resource bool) diag.Diagnostics {
6367
var diags diag.Diagnostics
6468

6569
client := (meta.(Client)).Client
@@ -79,7 +83,11 @@ func readImage(ctx context.Context, d *schema.ResourceData, meta interface{}) di
7983
name, id, err.Error())
8084
}
8185

82-
// Take the Config and convert it to terraform object
83-
marshalData(d, flattenImageConfig(cfg))
86+
// For resources, publish only computed fields
87+
marshalData(d, flattenImageConfig(cfg, resource))
8488
return diags
8589
}
90+
91+
func readDataSourceImage(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
92+
return readImage(ctx, d, meta, false)
93+
}

0 commit comments

Comments
 (0)