0
0
mirror of https://github.com/bpg/terraform-provider-proxmox.git synced 2025-06-30 18:42:58 +00:00
terraform-provider-proxmox/utils/maps.go
Pavel Boldyrev 80cafa689f
feat(vm2): add initial support for cdrom (#1370)
feat(vm2): add initial support for `cdrom`

This is a breaking change comparing to v1 - switching the cdrom schema from a nested block to a nested attribute map.

Improvements comparing to v1:
- support for `ide`, `sata`, `scsi` interfaces
- support for multiple cdroms

Signed-off-by: Pavel Boldyrev <627562+bpg@users.noreply.github.com>
2024-06-10 01:28:18 +00:00

111 lines
3.0 KiB
Go

/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package utils
import (
"reflect"
"sort"
)
// OrderedListFromMap generates a list from a map's values. The values are sorted based on the map's keys.
func OrderedListFromMap(inputMap map[string]interface{}) []interface{} {
itemCount := len(inputMap)
keyList := make([]string, itemCount)
i := 0
for key := range inputMap {
keyList[i] = key
i++
}
sort.Strings(keyList)
return OrderedListFromMapByKeyValues(inputMap, keyList)
}
// ListResourcesAttributeValue generates a list of strings from a Terraform resource list (which is list of maps).
// The list is generated by extracting a specific key attribute from each resource. If the attribute is not found in a
// resource, it is skipped.
func ListResourcesAttributeValue(resourceList []interface{}, keyAttr string) []string {
var l []string
for _, resource := range resourceList {
if resource == nil {
continue
}
r := resource.(map[string]interface{})
if value, ok := r[keyAttr].(string); ok {
l = append(l, value)
}
}
return l
}
// MapResourcesByAttribute generates a map of resources from a resource list, using a specified attribute as the key
// and the resource as the value. If the attribute is not found in a resource, it is skipped.
func MapResourcesByAttribute(resourceList []interface{}, keyAttr string) map[string]interface{} {
m := make(map[string]interface{}, len(resourceList))
for _, resource := range resourceList {
if resource == nil {
continue
}
r := resource.(map[string]interface{})
if key, ok := r[keyAttr].(string); ok {
m[key] = r
}
}
return m
}
// OrderedListFromMapByKeyValues generates a list from a map's values.
// The values are sorted based on the provided key list. If a key is not found in the map, it is skipped.
func OrderedListFromMapByKeyValues(inputMap map[string]interface{}, keyList []string) []interface{} {
orderedList := make([]interface{}, len(keyList))
for i, k := range keyList {
val, ok := inputMap[k]
if ok {
orderedList[i] = val
}
}
return orderedList
}
// MapDiff compares the difference between two maps and returns the elements that are in the plan but not
// in the state (toCreate), the elements that are in the plan and in the state but are different (toUpdate),
// and the elements that are in the state but not in the plan (toDelete).
// The keyFunc is used to extract a unique key from each element to compare them.
func MapDiff[T any](plan map[string]T, state map[string]T) (map[string]T, map[string]T, map[string]T) {
toCreate := map[string]T{}
toUpdate := map[string]T{}
toDelete := map[string]T{}
for key, p := range plan {
s, ok := state[key]
if !ok {
toCreate[key] = p
} else if !reflect.DeepEqual(p, s) {
toUpdate[key] = p
}
}
for key, s := range state {
_, ok := plan[key]
if !ok {
toDelete[key] = s
}
}
return toCreate, toUpdate, toDelete
}