Skip to content

Commit 4876183

Browse files
authored
Merge pull request #1429 from Tinyblargon/lxc-ssh
Feat: new LXC `ssh_public_keys`
2 parents 1c990fd + 202ac03 commit 4876183

File tree

10 files changed

+97
-19
lines changed

10 files changed

+97
-19
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ module github.com/Telmate/terraform-provider-proxmox/v2
33
go 1.24
44

55
require (
6-
github.com/Telmate/proxmox-api-go v0.0.0-20251014200358-2a5959153a7b
6+
github.com/Telmate/proxmox-api-go v0.0.0-20251016192144-4a331a14ad5c
77
github.com/google/uuid v1.6.0
88
github.com/hashicorp/go-cty v1.5.0
99
github.com/hashicorp/terraform-plugin-sdk/v2 v2.37.0

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERo
44
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
55
github.com/ProtonMail/go-crypto v1.2.0 h1:+PhXXn4SPGd+qk76TlEePBfOfivE0zkWFenhGhFLzWs=
66
github.com/ProtonMail/go-crypto v1.2.0/go.mod h1:9whxjD8Rbs29b4XWbB8irEcE8KHMqaR2e7GWU1R+/PE=
7-
github.com/Telmate/proxmox-api-go v0.0.0-20251014200358-2a5959153a7b h1:RQb2k6bWPNdKjhf9I2W9hgD7d6A7S6mDcJtpIC7tf+A=
8-
github.com/Telmate/proxmox-api-go v0.0.0-20251014200358-2a5959153a7b/go.mod h1:HGPbpwiVsrpYYuQAygnnU04ZdGLYc8fdP9qhJIBw2Bg=
7+
github.com/Telmate/proxmox-api-go v0.0.0-20251016192144-4a331a14ad5c h1:ous4SCwB2bwCuY9SmroHCJpT4JVh8eKYhHDp+3ULqSI=
8+
github.com/Telmate/proxmox-api-go v0.0.0-20251016192144-4a331a14ad5c/go.mod h1:HGPbpwiVsrpYYuQAygnnU04ZdGLYc8fdP9qhJIBw2Bg=
99
github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo=
1010
github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
1111
github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec=

proxmox/Internal/resource/guest/clone/schema.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
pveSDK "github.com/Telmate/proxmox-api-go/proxmox"
55
errorMSG "github.com/Telmate/terraform-provider-proxmox/v2/proxmox/Internal/errormsg"
66
"github.com/Telmate/terraform-provider-proxmox/v2/proxmox/Internal/resource/guest/lxc/password"
7+
"github.com/Telmate/terraform-provider-proxmox/v2/proxmox/Internal/resource/guest/lxc/ssh_public_keys"
78
"github.com/Telmate/terraform-provider-proxmox/v2/proxmox/Internal/resource/guest/lxc/template"
89
"github.com/hashicorp/go-cty/cty"
910
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
@@ -29,7 +30,7 @@ func Schema() *schema.Schema {
2930
ForceNew: true,
3031
MaxItems: 1,
3132
MinItems: 1,
32-
ConflictsWith: []string{template.Root, password.Root},
33+
ConflictsWith: []string{template.Root, password.Root, ssh_public_keys.Root},
3334
Elem: &schema.Resource{
3435
Schema: map[string]*schema.Schema{
3536
SchemaID: {

proxmox/Internal/resource/guest/lxc/lxc_tags/terraform.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ import (
66
)
77

88
func Terraform(tags *pveSDK.Tags, d *schema.ResourceData) {
9+
if tags == nil {
10+
d.Set(Root, nil)
11+
return
12+
}
913
tagSet := make([]any, len(*tags))
1014
for i := range *tags {
1115
tagSet[i] = string((*tags)[i])

proxmox/Internal/resource/guest/lxc/password/schema.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,5 @@ func Schema() *schema.Schema {
1111
Type: schema.TypeString,
1212
Sensitive: true,
1313
Optional: true,
14-
WriteOnly: true}
14+
ForceNew: true}
1515
}

proxmox/Internal/resource/guest/lxc/password/sdk.go

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,9 @@ import (
55
)
66

77
func SDK(d *schema.ResourceData) *string {
8-
v, ok := d.GetOk(Root)
9-
if !ok {
8+
v, ok := d.Get(Root).(string)
9+
if !ok || v == "" {
1010
return nil
1111
}
12-
password, ok := v.(string)
13-
if !ok || password == "" {
14-
return nil
15-
}
16-
return &password
12+
return &v
1713
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package ssh_public_keys
2+
3+
import (
4+
"regexp"
5+
"strings"
6+
7+
pveSDK "github.com/Telmate/proxmox-api-go/proxmox"
8+
"github.com/Telmate/terraform-provider-proxmox/v2/proxmox/Internal/resource/guest/lxc/template"
9+
"github.com/hashicorp/go-cty/cty"
10+
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
11+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
12+
)
13+
14+
const (
15+
Root string = "ssh_public_keys"
16+
)
17+
18+
func Schema() *schema.Schema {
19+
return &schema.Schema{
20+
Type: schema.TypeString,
21+
Optional: true,
22+
ForceNew: true,
23+
RequiredWith: []string{template.Root},
24+
DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool {
25+
return trim(old) == trim(new)
26+
},
27+
ValidateDiagFunc: func(i any, p cty.Path) diag.Diagnostics {
28+
v := i.(string)
29+
if v == "" {
30+
return nil
31+
}
32+
rawKeys := strings.Split(v, "\n")
33+
for i := range rawKeys {
34+
err := (&pveSDK.AuthorizedKey{}).Parse([]byte(rawKeys[i]))
35+
if err != nil {
36+
if strings.ReplaceAll(strings.ReplaceAll(rawKeys[i], "\t", ""), " ", "") == "" { // skip empty lines
37+
continue
38+
}
39+
return diag.Diagnostics{{
40+
Severity: diag.Error,
41+
Summary: err.Error()}}
42+
}
43+
}
44+
return nil
45+
}}
46+
}
47+
48+
var regexMultipleSpaces = regexp.MustCompile(`\s+`)
49+
50+
func trim(rawKeys string) string {
51+
return regexMultipleSpaces.ReplaceAllString(strings.TrimSpace(rawKeys), " ")
52+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package ssh_public_keys
2+
3+
import (
4+
"strings"
5+
6+
pveSDK "github.com/Telmate/proxmox-api-go/proxmox"
7+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
8+
)
9+
10+
func SDK(d *schema.ResourceData) []pveSDK.AuthorizedKey {
11+
v := d.Get(Root)
12+
rawKeys := strings.Split(v.(string), "\n")
13+
keys := make([]pveSDK.AuthorizedKey, len(rawKeys))
14+
for i := range rawKeys {
15+
tmpKey := &pveSDK.AuthorizedKey{}
16+
_ = tmpKey.Parse([]byte(rawKeys[i]))
17+
keys[i] = *tmpKey
18+
}
19+
return keys
20+
}

proxmox/Internal/resource/guest/lxc/template/schema.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package template
22

33
import (
4+
"github.com/Telmate/terraform-provider-proxmox/v2/proxmox/Internal/resource/guest/lxc/password"
45
"github.com/hashicorp/go-cty/cty"
56
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
67
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
@@ -15,10 +16,11 @@ const (
1516

1617
func Schema() *schema.Schema {
1718
return &schema.Schema{
18-
Type: schema.TypeList,
19-
Optional: true,
20-
MaxItems: 1,
21-
MinItems: 1,
19+
Type: schema.TypeList,
20+
Optional: true,
21+
MaxItems: 1,
22+
MinItems: 1,
23+
RequiredWith: []string{password.Root},
2224
Elem: &schema.Resource{
2325
Schema: map[string]*schema.Schema{
2426
schemaFile: subSchemaFile(),

proxmox/resource_lxc_new.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"github.com/Telmate/terraform-provider-proxmox/v2/proxmox/Internal/resource/guest/lxc/password"
1919
"github.com/Telmate/terraform-provider-proxmox/v2/proxmox/Internal/resource/guest/lxc/privilege"
2020
"github.com/Telmate/terraform-provider-proxmox/v2/proxmox/Internal/resource/guest/lxc/rootmount"
21+
"github.com/Telmate/terraform-provider-proxmox/v2/proxmox/Internal/resource/guest/lxc/ssh_public_keys"
2122
"github.com/Telmate/terraform-provider-proxmox/v2/proxmox/Internal/resource/guest/lxc/swap"
2223
"github.com/Telmate/terraform-provider-proxmox/v2/proxmox/Internal/resource/guest/lxc/template"
2324
"github.com/Telmate/terraform-provider-proxmox/v2/proxmox/Internal/resource/guest/name"
@@ -45,7 +46,6 @@ func ResourceLxcNew() *schema.Resource {
4546
CustomizeDiff: reboot.CustomizeDiff(),
4647

4748
Schema: map[string]*schema.Schema{
48-
tags.Root: tags.Schema(),
4949
architecture.Root: architecture.Schema(),
5050
clone.Root: clone.Schema(),
5151
cpu.Root: cpu.Schema(),
@@ -70,7 +70,9 @@ func ResourceLxcNew() *schema.Resource {
7070
reboot.RootAutomaticSeverity: reboot.SchemaAutomaticSeverity(),
7171
reboot.RootRequired: reboot.SchemaRequired(),
7272
rootmount.Root: rootmount.Schema(),
73+
ssh_public_keys.Root: ssh_public_keys.Schema(),
7374
swap.Root: swap.Schema(),
75+
tags.Root: tags.Schema(),
7476
template.Root: template.Schema(),
7577
},
7678
Timeouts: resourceTimeouts(),
@@ -132,8 +134,9 @@ func resourceLxcNewCreate(ctx context.Context, d *schema.ResourceData, meta any)
132134
} else {
133135
config.Node = &targetNode
134136
config.CreateOptions = &pveSDK.LxcCreateOptions{
135-
OsTemplate: template.SDK(d),
136-
UserPassword: password.SDK(d)}
137+
OsTemplate: template.SDK(d),
138+
PublicSSHkeys: ssh_public_keys.SDK(d),
139+
UserPassword: password.SDK(d)}
137140
config.Pool = util.Pointer(pool.SDK(d))
138141
vmr, err = config.Create(ctx, client)
139142
if err != nil {

0 commit comments

Comments
 (0)