mirror of
https://github.com/bpg/terraform-provider-proxmox.git
synced 2025-06-29 18:21:10 +00:00
* feat(vm): add RNG device support This commit adds support for configuring the Random Number Generator (RNG) device for virtual machines in both the VM resource and datasource. The implementation includes: - New schema and model for RNG configuration - Support for setting RNG source, max_bytes, and period - Updated documentation for RNG configuration - Test cases for RNG configuration - Integration with VM creation, update, and read operations --------- Signed-off-by: Pavel Boldyrev <627562+bpg@users.noreply.github.com>
148 lines
3.9 KiB
Go
148 lines
3.9 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 rng
|
|
|
|
import (
|
|
"context"
|
|
"reflect"
|
|
|
|
"github.com/hashicorp/terraform-plugin-framework/diag"
|
|
"github.com/hashicorp/terraform-plugin-framework/types"
|
|
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
|
|
|
|
"github.com/bpg/terraform-provider-proxmox/fwprovider/attribute"
|
|
"github.com/bpg/terraform-provider-proxmox/proxmox/nodes/vms"
|
|
)
|
|
|
|
// Value represents the type for RNG settings.
|
|
type Value = types.Object
|
|
|
|
// NewValue returns a new Value with the given RNG settings from the PVE API.
|
|
func NewValue(ctx context.Context, config *vms.GetResponseData, diags *diag.Diagnostics) Value {
|
|
rng := Model{}
|
|
|
|
if config.RNGDevice != nil {
|
|
rng.Source = types.StringValue(config.RNGDevice.Source)
|
|
|
|
if config.RNGDevice.MaxBytes != nil {
|
|
rng.MaxBytes = types.Int64Value(int64(*config.RNGDevice.MaxBytes))
|
|
}
|
|
|
|
if config.RNGDevice.Period != nil {
|
|
rng.Period = types.Int64Value(int64(*config.RNGDevice.Period))
|
|
}
|
|
}
|
|
|
|
obj, d := types.ObjectValueFrom(ctx, attributeTypes(), rng)
|
|
diags.Append(d...)
|
|
|
|
return obj
|
|
}
|
|
|
|
// createRNGDevice creates a new CustomRNGDevice from the given Model.
|
|
func createRNGDevice(model Model, setSource bool) *vms.CustomRNGDevice {
|
|
rngDevice := &vms.CustomRNGDevice{}
|
|
|
|
if setSource && !model.Source.IsUnknown() {
|
|
rngDevice.Source = model.Source.ValueString()
|
|
}
|
|
|
|
if !model.MaxBytes.IsUnknown() && model.MaxBytes.ValueInt64() != 0 {
|
|
maxBytes := int(model.MaxBytes.ValueInt64())
|
|
rngDevice.MaxBytes = &maxBytes
|
|
}
|
|
|
|
if !model.Period.IsUnknown() && model.Period.ValueInt64() != 0 {
|
|
period := int(model.Period.ValueInt64())
|
|
rngDevice.Period = &period
|
|
}
|
|
|
|
return rngDevice
|
|
}
|
|
|
|
// FillCreateBody fills the CreateRequestBody with the RNG settings from the Value.
|
|
//
|
|
// In the 'create' context, v is the plan.
|
|
func FillCreateBody(ctx context.Context, planValue Value, body *vms.CreateRequestBody, diags *diag.Diagnostics) {
|
|
var plan Model
|
|
|
|
if planValue.IsNull() || planValue.IsUnknown() {
|
|
return
|
|
}
|
|
|
|
d := planValue.As(ctx, &plan, basetypes.ObjectAsOptions{})
|
|
diags.Append(d...)
|
|
|
|
if d.HasError() {
|
|
return
|
|
}
|
|
|
|
rngDevice := createRNGDevice(plan, true)
|
|
|
|
if !reflect.DeepEqual(rngDevice, &vms.CustomRNGDevice{}) {
|
|
body.RNGDevice = rngDevice
|
|
}
|
|
}
|
|
|
|
// FillUpdateBody fills the UpdateRequestBody with the RNG settings from the Value.
|
|
//
|
|
// In the 'update' context, v is the plan and stateValue is the current state.
|
|
func FillUpdateBody(
|
|
ctx context.Context,
|
|
planValue, stateValue Value,
|
|
updateBody *vms.UpdateRequestBody,
|
|
isClone bool,
|
|
diags *diag.Diagnostics,
|
|
) {
|
|
var plan, state Model
|
|
|
|
if planValue.IsNull() || planValue.IsUnknown() || planValue.Equal(stateValue) {
|
|
return
|
|
}
|
|
|
|
d := planValue.As(ctx, &plan, basetypes.ObjectAsOptions{})
|
|
diags.Append(d...)
|
|
d = stateValue.As(ctx, &state, basetypes.ObjectAsOptions{})
|
|
diags.Append(d...)
|
|
|
|
if diags.HasError() {
|
|
return
|
|
}
|
|
|
|
rngDevice := createRNGDevice(state, true)
|
|
|
|
if !plan.Source.Equal(state.Source) {
|
|
if attribute.ShouldBeRemoved(plan.Source, state.Source, isClone) {
|
|
rngDevice.Source = ""
|
|
} else if attribute.IsDefined(plan.Source) {
|
|
rngDevice.Source = plan.Source.ValueString()
|
|
}
|
|
}
|
|
|
|
if !plan.MaxBytes.Equal(state.MaxBytes) {
|
|
if attribute.ShouldBeRemoved(plan.MaxBytes, state.MaxBytes, isClone) {
|
|
rngDevice.MaxBytes = nil
|
|
} else if attribute.IsDefined(plan.MaxBytes) {
|
|
maxBytes := int(plan.MaxBytes.ValueInt64())
|
|
rngDevice.MaxBytes = &maxBytes
|
|
}
|
|
}
|
|
|
|
if !plan.Period.Equal(state.Period) {
|
|
if attribute.ShouldBeRemoved(plan.Period, state.Period, isClone) {
|
|
rngDevice.Period = nil
|
|
} else if attribute.IsDefined(plan.Period) {
|
|
period := int(plan.Period.ValueInt64())
|
|
rngDevice.Period = &period
|
|
}
|
|
}
|
|
|
|
if !reflect.DeepEqual(rngDevice, &vms.CustomRNGDevice{}) {
|
|
updateBody.RNGDevice = rngDevice
|
|
}
|
|
}
|