Skip to content

Commit 42bdd80

Browse files
author
awlsring
committed
fix: add error if not root on root only field
1 parent d7d7f41 commit 42bdd80

File tree

4 files changed

+94
-20
lines changed

4 files changed

+94
-20
lines changed

internal/service/client.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313

1414
type Proxmox struct {
1515
client *proxmox.DefaultApiService
16+
IsRoot bool
1617
}
1718

1819
type ClientConfig struct {
@@ -54,13 +55,15 @@ func newTokenClient(c ClientConfig, cfg *proxmox.Configuration) (*Proxmox, error
5455
client := proxmox.NewAPIClient(cfg)
5556
return &Proxmox{
5657
client: client.DefaultApi,
58+
IsRoot: false,
5759
}, nil
5860
}
5961

6062
func newBasicAuthClient(c ClientConfig, cfg *proxmox.Configuration) (*Proxmox, error) {
6163
client := proxmox.NewAPIClient(cfg)
6264
p := &Proxmox{
6365
client: client.DefaultApi,
66+
IsRoot: c.Username == "root@pam",
6467
}
6568

6669
ticket, err := p.login(c.Username, c.Password)
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package vms
2+
3+
import (
4+
"context"
5+
6+
vt "github.com/awlsring/terraform-provider-proxmox/proxmox/qemu/vms/types"
7+
"github.com/hashicorp/terraform-plugin-framework/resource"
8+
"github.com/hashicorp/terraform-plugin-log/tflog"
9+
)
10+
11+
func authCreateValidator(ctx context.Context, isRoot bool, model *vt.VirtualMachineResourceModel, resp *resource.ModifyPlanResponse) {
12+
tflog.Debug(ctx, "authCreateValidator")
13+
if isRoot {
14+
tflog.Debug(ctx, "user is root, all allowed")
15+
return
16+
}
17+
if model.CloudInit != nil {
18+
resp.Diagnostics.AddError("Root only property set", "A current bug prevents non-root users from using cloud-init https://lists.proxmox.com/pipermail/pve-devel/2023-March/056155.html")
19+
}
20+
if !model.CPU.Architecture.IsNull() && !model.CPU.Architecture.IsUnknown() {
21+
resp.Diagnostics.AddError("Root only property set", "The field cpu.architecture is only allowed to be set by root users")
22+
}
23+
}
24+
25+
func authUpdateValidator(ctx context.Context, isRoot bool, model *vt.VirtualMachineResourceModel, resp *resource.ModifyPlanResponse) {
26+
tflog.Debug(ctx, "authCreateValidator")
27+
if isRoot {
28+
tflog.Debug(ctx, "user is root, all allowed")
29+
return
30+
}
31+
if model.CloudInit != nil {
32+
resp.Diagnostics.AddError("Root only property set", "A current bug prevents non-root users from using cloud-init https://lists.proxmox.com/pipermail/pve-devel/2023-March/056155.html")
33+
}
34+
}

proxmox/qemu/vms/resource.go

Lines changed: 49 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -29,26 +29,26 @@ type virtualMachineResource struct {
2929
timeouts *VirtualMachineTimeouts
3030
}
3131

32+
type ConfigureMode string
33+
34+
const (
35+
ConfigureModeCreate ConfigureMode = "create"
36+
ConfigureModeUpdate ConfigureMode = "update"
37+
ConfigureModeDelete ConfigureMode = "delete"
38+
)
39+
3240
func (r *virtualMachineResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
3341
resp.TypeName = req.ProviderTypeName + "_virtual_machine"
3442
}
3543

36-
func (r *virtualMachineResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) {
37-
tflog.Debug(ctx, "ModifyPlan virtual machine method")
38-
var plan vt.VirtualMachineResourceModel
39-
diags := req.Plan.Get(ctx, &plan)
40-
if diags.HasError() {
41-
tflog.Debug(ctx, "Plan is delete, skipping")
42-
return
43-
}
44-
45-
var state vt.VirtualMachineResourceModel
46-
diags = req.State.Get(ctx, &state)
47-
if diags.HasError() {
48-
tflog.Debug(ctx, "Plan is create, skipping")
44+
func (r *virtualMachineResource) createPlanModifiers(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse, plan *vt.VirtualMachineResourceModel) {
45+
authCreateValidator(ctx, r.client.IsRoot, plan, resp)
46+
if resp.Diagnostics.HasError() {
4947
return
5048
}
49+
}
5150

51+
func (r *virtualMachineResource) updatePlanModifiers(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse, state *vt.VirtualMachineResourceModel, plan *vt.VirtualMachineResourceModel) {
5252
node := plan.Node.ValueString()
5353
vmId := int(state.ID.ValueInt64())
5454

@@ -61,25 +61,56 @@ func (r *virtualMachineResource) ModifyPlan(ctx context.Context, req resource.Mo
6161
return
6262
}
6363
if status.Status != proxmox.VIRTUALMACHINESTATUS_RUNNING {
64-
powerOffValidator(ctx, r.client, &state, &plan, resp)
64+
powerOffValidator(ctx, r.client, state, plan, resp)
6565
}
6666

67-
changeValidatorDiskSize(ctx, &state, &plan, resp)
68-
changeValidatorDiskStorage(ctx, &state, &plan, resp)
69-
changeValidatorDiskRemoved(ctx, &state, &plan, resp)
67+
authUpdateValidator(ctx, r.client.IsRoot, plan, resp)
68+
69+
changeValidatorDiskSize(ctx, state, plan, resp)
70+
changeValidatorDiskStorage(ctx, state, plan, resp)
71+
changeValidatorDiskRemoved(ctx, state, plan, resp)
7072
// carry over computed values sets to prevent unnecessary diffs
7173
amended := plan
7274
amended.ComputedDisks = state.ComputedDisks
7375
amended.ComputedNetworkInterfaces = state.ComputedNetworkInterfaces
7476
amended.ComputedPCIDevices = state.ComputedPCIDevices
7577

76-
diags = resp.Plan.Set(ctx, &amended)
78+
diags := resp.Plan.Set(ctx, &amended)
7779
resp.Diagnostics.Append(diags...)
7880
if resp.Diagnostics.HasError() {
7981
return
8082
}
8183
}
8284

85+
func (r *virtualMachineResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) {
86+
tflog.Debug(ctx, "ModifyPlan virtual machine method")
87+
configureMode := ConfigureModeUpdate
88+
89+
var plan vt.VirtualMachineResourceModel
90+
diags := req.Plan.Get(ctx, &plan)
91+
if diags.HasError() {
92+
configureMode = ConfigureModeDelete
93+
}
94+
95+
var state vt.VirtualMachineResourceModel
96+
diags = req.State.Get(ctx, &state)
97+
if diags.HasError() {
98+
configureMode = ConfigureModeCreate
99+
}
100+
101+
tflog.Info(ctx, fmt.Sprintf("configureMode '%v'", configureMode))
102+
103+
switch configureMode {
104+
case ConfigureModeCreate:
105+
r.createPlanModifiers(ctx, req, resp, &plan)
106+
return
107+
case ConfigureModeDelete:
108+
return
109+
default:
110+
r.updatePlanModifiers(ctx, req, resp, &state, &plan)
111+
}
112+
}
113+
83114
func (r *virtualMachineResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {
84115
resp.Schema = schemas.ResourceSchema
85116
}

proxmox/qemu/vms/schemas/resource_schema.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,11 @@ var ResourceSchema = schema.Schema{
4545
},
4646
"description": schema.StringAttribute{
4747
Optional: true,
48+
Computed: true,
4849
Description: "The virtual machine description.",
50+
PlanModifiers: []planmodifier.String{
51+
stringplanmodifier.UseStateForUnknown(),
52+
},
4953
},
5054
"tags": schema.SetAttribute{
5155
Optional: true,
@@ -201,10 +205,11 @@ var ResourceSchema = schema.Schema{
201205
"cpu_units": types.Int64Value(100),
202206
}),
203207
},
208+
// requires root, make computed til this can be warned about
204209
Attributes: map[string]schema.Attribute{
205210
"architecture": schema.StringAttribute{
206-
Optional: true,
207211
Computed: true,
212+
Optional: true,
208213
Description: "The CPU architecture.",
209214
Validators: []validator.String{
210215
stringvalidator.OneOf(
@@ -213,7 +218,8 @@ var ResourceSchema = schema.Schema{
213218
),
214219
},
215220
PlanModifiers: []planmodifier.String{
216-
defaults.DefaultString("x86_64"),
221+
stringplanmodifier.RequiresReplace(),
222+
stringplanmodifier.UseStateForUnknown(),
217223
},
218224
},
219225
"cores": schema.Int64Attribute{

0 commit comments

Comments
 (0)