Skip to content

Commit

Permalink
Merge pull request Telmate#1007 from Tinyblargon/qemu-tags
Browse files Browse the repository at this point in the history
fix: `tags` incorrect diff
  • Loading branch information
Tinyblargon committed May 17, 2024
2 parents 3e88998 + fae6ea0 commit 99bd91b
Show file tree
Hide file tree
Showing 6 changed files with 189 additions and 18 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ go 1.21
toolchain go1.21.0

require (
github.com/Telmate/proxmox-api-go v0.0.0-20240513153448-8ecac06c5879
github.com/Telmate/proxmox-api-go v0.0.0-20240515161628-30cfc1aa4ae4
github.com/google/uuid v1.6.0
github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320
github.com/hashicorp/terraform-plugin-sdk/v2 v2.33.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migc
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
github.com/ProtonMail/go-crypto v1.1.0-alpha.2-proton h1:HKz85FwoXx86kVtTvFke7rgHvq/HoloSUvW5semjFWs=
github.com/ProtonMail/go-crypto v1.1.0-alpha.2-proton/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE=
github.com/Telmate/proxmox-api-go v0.0.0-20240513153448-8ecac06c5879 h1:RHyitzMb2aEtzMgNy80TOnkbvvjZABBWzyhHy+xHMQA=
github.com/Telmate/proxmox-api-go v0.0.0-20240513153448-8ecac06c5879/go.mod h1:bscBzOUx0tJAdVGmQvcnoWPg5eI2eJ6anJKV1ueZ1oU=
github.com/Telmate/proxmox-api-go v0.0.0-20240515161628-30cfc1aa4ae4 h1:UsCuxsMGA0ePmUBYaYNvh1kFxoZ35ARpHCfEw9KZxec=
github.com/Telmate/proxmox-api-go v0.0.0-20240515161628-30cfc1aa4ae4/go.mod h1:bscBzOUx0tJAdVGmQvcnoWPg5eI2eJ6anJKV1ueZ1oU=
github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo=
github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec=
Expand Down
93 changes: 93 additions & 0 deletions proxmox/Internal/pxapi/guest/tags/tags.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package tags

import (
"sort"
"strings"

pxapi "github.com/Telmate/proxmox-api-go/proxmox"
"github.com/hashicorp/go-cty/cty"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

// Returns an unordered list of unique tags
func RemoveDuplicates(tags *[]pxapi.Tag) *[]pxapi.Tag {
if tags == nil || len(*tags) == 0 {
return nil
}
tagMap := make(map[pxapi.Tag]struct{})
for _, tag := range *tags {
tagMap[tag] = struct{}{}
}
uniqueTags := make([]pxapi.Tag, len(tagMap))
var index uint
for tag := range tagMap {
uniqueTags[index] = tag
index++
}
return &uniqueTags
}

func Schema() *schema.Schema {
return &schema.Schema{
Type: schema.TypeString,
Optional: true,
Computed: true,
ValidateDiagFunc: func(i interface{}, path cty.Path) diag.Diagnostics {
v, ok := i.(string)
if !ok {
return diag.Errorf("expected a string, got: %s", i)
}
for _, e := range *Split(v) {
if err := e.Validate(); err != nil {
return diag.Errorf("tag validation failed: %s", err)
}
}
return nil
},
DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool {
return String(sortArray(RemoveDuplicates(Split(old)))) == String(sortArray(RemoveDuplicates(Split(new))))
},
}
}

func sortArray(tags *[]pxapi.Tag) *[]pxapi.Tag {
if tags == nil || len(*tags) == 0 {
return nil
}
sort.SliceStable(*tags, func(i, j int) bool {
return (*tags)[i] < (*tags)[j]
})
return tags
}

func Split(rawTags string) *[]pxapi.Tag {
tags := make([]pxapi.Tag, 0)
if rawTags == "" {
return &tags
}
tagArrays := strings.Split(rawTags, ";")
for _, tag := range tagArrays {
tagSubArrays := strings.Split(tag, ",")
if len(tagSubArrays) > 1 {
tmpTags := make([]pxapi.Tag, len(tagSubArrays))
for i, e := range tagSubArrays {
tmpTags[i] = pxapi.Tag(e)
}
tags = append(tags, tmpTags...)
} else {
tags = append(tags, pxapi.Tag(tag))
}
}
return &tags
}

func String(tags *[]pxapi.Tag) (tagList string) {
if tags == nil || len(*tags) == 0 {
return ""
}
for _, tag := range *tags {
tagList += ";" + string(tag)
}
return tagList[1:]
}
82 changes: 82 additions & 0 deletions proxmox/Internal/pxapi/guest/tags/tags_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package tags

import (
"testing"

pxapi "github.com/Telmate/proxmox-api-go/proxmox"
"github.com/stretchr/testify/require"
)

func Test_RemoveDuplicates(t *testing.T) {
tests := []struct {
name string
input *[]pxapi.Tag
output *[]pxapi.Tag
}{
{name: `nil`},
{name: `empty`, input: &[]pxapi.Tag{}},
{name: `single`, input: &[]pxapi.Tag{"a"}, output: &[]pxapi.Tag{"a"}},
{name: `multiple`, input: &[]pxapi.Tag{"b", "a", "c"}, output: &[]pxapi.Tag{"a", "b", "c"}},
{name: `duplicate`, input: &[]pxapi.Tag{"b", "a", "c", "b", "a"}, output: &[]pxapi.Tag{"a", "b", "c"}},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
require.Equal(t, test.output, sortArray(RemoveDuplicates(test.input)))
})
}
}

func Test_sort(t *testing.T) {
tests := []struct {
name string
input *[]pxapi.Tag
output *[]pxapi.Tag
}{
{name: `nil`},
{name: `empty`, input: &[]pxapi.Tag{}},
{name: `single`, input: &[]pxapi.Tag{"a"}, output: &[]pxapi.Tag{"a"}},
{name: `multiple`, input: &[]pxapi.Tag{"b", "a", "c"}, output: &[]pxapi.Tag{"a", "b", "c"}},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
require.Equal(t, test.output, sortArray(test.input))
})
}
}

func Test_Split(t *testing.T) {
tests := []struct {
name string
input string
output *[]pxapi.Tag
}{
{name: `empty`, output: &[]pxapi.Tag{}},
{name: `single`, input: "a", output: &[]pxapi.Tag{"a"}},
{name: `multiple ,`, input: "b,a,c", output: &[]pxapi.Tag{"b", "a", "c"}},
{name: `multiple ;`, input: "b;a;c", output: &[]pxapi.Tag{"b", "a", "c"}},
{name: `multiple mixed`, input: "b,a;c,d;e", output: &[]pxapi.Tag{"b", "a", "c", "d", "e"}},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
require.Equal(t, test.output, Split(test.input))
})
}
}

func Test_String(t *testing.T) {
tests := []struct {
name string
input *[]pxapi.Tag
output string
}{
{name: `nil`},
{name: `empty`, input: &[]pxapi.Tag{}},
{name: `single`, input: &[]pxapi.Tag{"a"}, output: "a"},
{name: `multiple`, input: &[]pxapi.Tag{"b", "a", "c"}, output: "b;a;c"},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
require.Equal(t, test.output, String(test.input))
})
}
}
13 changes: 6 additions & 7 deletions proxmox/resource_lxc.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@ import (
"time"

pxapi "github.com/Telmate/proxmox-api-go/proxmox"
"github.com/Telmate/terraform-provider-proxmox/v2/proxmox/Internal/pxapi/guest/tags"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

var lxcResourceDef *schema.Resource

// TODO update tag schema
func resourceLxc() *schema.Resource {
lxcResourceDef = &schema.Resource{
Create: resourceLxcCreate,
Expand Down Expand Up @@ -142,10 +144,7 @@ func resourceLxc() *schema.Resource {
Type: schema.TypeString,
Optional: true,
},
"tags": {
Type: schema.TypeString,
Optional: true,
},
"tags": tags.Schema(),
"memory": {
Type: schema.TypeInt,
Optional: true,
Expand Down Expand Up @@ -488,7 +487,7 @@ func resourceLxcCreate(d *schema.ResourceData, meta interface{}) error {
config.Start = d.Get("start").(bool)
config.Startup = d.Get("startup").(string)
config.Swap = d.Get("swap").(int)
config.Tags = d.Get("tags").(string)
config.Tags = tags.String(tags.RemoveDuplicates(tags.Split(d.Get("tags").(string))))
config.Template = d.Get("template").(bool)
config.Tty = d.Get("tty").(int)
config.Unique = d.Get("unique").(bool)
Expand Down Expand Up @@ -659,7 +658,7 @@ func resourceLxcUpdate(d *schema.ResourceData, meta interface{}) error {
config.Start = d.Get("start").(bool)
config.Startup = d.Get("startup").(string)
config.Swap = d.Get("swap").(int)
config.Tags = d.Get("tags").(string)
config.Tags = tags.String(tags.RemoveDuplicates(tags.Split(d.Get("tags").(string))))
config.Template = d.Get("template").(bool)
config.Tty = d.Get("tty").(int)
config.Unique = d.Get("unique").(bool)
Expand Down Expand Up @@ -884,7 +883,7 @@ func _resourceLxcRead(d *schema.ResourceData, meta interface{}) error {
d.Set("searchdomain", config.SearchDomain)
d.Set("startup", config.Startup)
d.Set("swap", config.Swap)
d.Set("tags", config.Tags)
d.Set("tags", tags.String(tags.Split(config.Tags)))
d.Set("template", config.Template)
d.Set("tty", config.Tty)
d.Set("unique", config.Unique)
Expand Down
13 changes: 5 additions & 8 deletions proxmox/resource_vm_qemu.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"time"

pxapi "github.com/Telmate/proxmox-api-go/proxmox"
"github.com/Telmate/terraform-provider-proxmox/v2/proxmox/Internal/pxapi/guest/tags"
"github.com/google/uuid"
"github.com/hashicorp/go-cty/cty"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
Expand Down Expand Up @@ -215,11 +216,7 @@ func resourceVmQemu() *schema.Resource {
return strings.TrimSpace(old) == strings.TrimSpace(new)
},
},
"tags": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"tags": tags.Schema(),
"args": {
Type: schema.TypeString,
Optional: true,
Expand Down Expand Up @@ -891,7 +888,7 @@ func resourceVmQemuCreate(ctx context.Context, d *schema.ResourceData, meta inte
HaState: d.Get("hastate").(string),
HaGroup: d.Get("hagroup").(string),
QemuOs: d.Get("qemu_os").(string),
Tags: d.Get("tags").(string),
Tags: tags.RemoveDuplicates(tags.Split(d.Get("tags").(string))),
Args: d.Get("args").(string),
QemuNetworks: qemuNetworks,
QemuSerials: qemuSerials,
Expand Down Expand Up @@ -1168,7 +1165,7 @@ func resourceVmQemuUpdate(ctx context.Context, d *schema.ResourceData, meta inte
HaState: d.Get("hastate").(string),
HaGroup: d.Get("hagroup").(string),
QemuOs: d.Get("qemu_os").(string),
Tags: d.Get("tags").(string),
Tags: tags.RemoveDuplicates(tags.Split(d.Get("tags").(string))),
Args: d.Get("args").(string),
QemuNetworks: qemuNetworks,
QemuSerials: qemuSerials,
Expand Down Expand Up @@ -1481,7 +1478,7 @@ func resourceVmQemuRead(ctx context.Context, d *schema.ResourceData, meta interf
d.Set("hastate", vmr.HaState())
d.Set("hagroup", vmr.HaGroup())
d.Set("qemu_os", config.QemuOs)
d.Set("tags", config.Tags)
d.Set("tags", tags.String(config.Tags))
d.Set("args", config.Args)
// Cloud-init.
d.Set("ciuser", config.CIuser)
Expand Down

0 comments on commit 99bd91b

Please sign in to comment.