mirror of
https://github.com/bpg/terraform-provider-proxmox.git
synced 2025-06-30 10:33:46 +00:00
fix(cluster): inconsistencies in applying cluster options (#573)
* fix(cluster): inconsistencies in applying cluster options Signed-off-by: Pavel Boldyrev <627562+bpg@users.noreply.github.com> * address review comments Signed-off-by: Pavel Boldyrev <627562+bpg@users.noreply.github.com> --------- Signed-off-by: Pavel Boldyrev <627562+bpg@users.noreply.github.com>
This commit is contained in:
parent
11c09405ea
commit
03f3ed7871
@ -37,18 +37,18 @@ resource "proxmox_virtual_environment_cluster_options" "options" {
|
||||
- `bandwidth_limit_move` (Number) Move I/O bandwidth limit in KiB/s.
|
||||
- `bandwidth_limit_restore` (Number) Restore I/O bandwidth limit in KiB/s.
|
||||
- `console` (String) Select the default Console viewer. Must be `applet` | `vv`| `html5` | `xtermjs`. You can either use the builtin java applet (VNC; deprecated and maps to html5), an external virt-viewer compatible application (SPICE), an HTML5 based vnc viewer (noVNC), or an HTML5 based console client (xtermjs). If the selected viewer is not available (e.g. SPICE not activated for the VM), the fallback is noVNC.
|
||||
- `crs_ha` (String) Cluster resource scheduling setting for HA. Must be `static` | `basic`.
|
||||
- `crs_ha` (String) Cluster resource scheduling setting for HA. Must be `static` | `basic` (default is `basic`).
|
||||
- `crs_ha_rebalance_on_start` (Boolean) Cluster resource scheduling setting for HA rebalance on start.
|
||||
- `description` (String) Datacenter description. Shown in the web-interface datacenter notes panel. This is saved as comment inside the configuration file.
|
||||
- `email_from` (String) email address to send notification from (default is root@$hostname).
|
||||
- `ha_shutdown_policy` (String) Cluster wide HA shutdown policy. Must be `freeze` | `failover` | `migrate` | `conditional`.
|
||||
- `ha_shutdown_policy` (String) Cluster wide HA shutdown policy (). Must be `freeze` | `failover` | `migrate` | `conditional` (default is `conditional`).
|
||||
- `http_proxy` (String) Specify external http proxy which is used for downloads (example: `http://username:password@host:port/`).
|
||||
- `keyboard` (String) Default keyboard layout for vnc server. Must be `de` | `de-ch` | `da` | `en-gb` | `en-us` | `es` | `fi` | `fr` | `fr-be` | `fr-ca` | `fr-ch` | `hu` | `is` | `it` | `ja` | `lt` | `mk` | `nl` | `no` | `pl` | `pt` | `pt-br` | `sv` | `sl` | `tr`.
|
||||
- `language` (String) Default GUI language. Must be `ca` | `da` | `de` | `en` | `es` | `eu` | `fa` | `fr` | `he` | `it` | `ja` | `nb` | `nn` | `pl` | `pt_BR` | `ru` | `sl` | `sv` | `tr` | `zh_CN` | `zh_TW`.
|
||||
- `mac_prefix` (String) Prefix for autogenerated MAC addresses.
|
||||
- `max_workers` (Number) Defines how many workers (per node) are maximal started on actions like 'stopall VMs' or task from the ha-manager.
|
||||
- `migration_cidr` (String) Cluster wide migration network CIDR.
|
||||
- `migration_type` (String) Cluster wide migration type. Must be `secure` | `unsecure`.
|
||||
- `migration_type` (String) Cluster wide migration type. Must be `secure` | `unsecure` (default is `secure`).
|
||||
|
||||
### Read-Only
|
||||
|
||||
|
@ -40,21 +40,23 @@ type clusterOptionsModel struct {
|
||||
BandwidthLimitMove types.Int64 `tfsdk:"bandwidth_limit_move"`
|
||||
BandwidthLimitRestore types.Int64 `tfsdk:"bandwidth_limit_restore"`
|
||||
Console types.String `tfsdk:"console"`
|
||||
HTTPProxy types.String `tfsdk:"http_proxy"`
|
||||
MacPrefix types.String `tfsdk:"mac_prefix"`
|
||||
Description types.String `tfsdk:"description"`
|
||||
HAShutdownPolicy types.String `tfsdk:"ha_shutdown_policy"`
|
||||
MigrationType types.String `tfsdk:"migration_type"`
|
||||
MigrationNetwork types.String `tfsdk:"migration_cidr"`
|
||||
CrsHA types.String `tfsdk:"crs_ha"`
|
||||
CrsHARebalanceOnStart types.Bool `tfsdk:"crs_ha_rebalance_on_start"`
|
||||
Description types.String `tfsdk:"description"`
|
||||
EmailFrom types.String `tfsdk:"email_from"`
|
||||
HAShutdownPolicy types.String `tfsdk:"ha_shutdown_policy"`
|
||||
HTTPProxy types.String `tfsdk:"http_proxy"`
|
||||
Keyboard types.String `tfsdk:"keyboard"`
|
||||
Language types.String `tfsdk:"language"`
|
||||
MacPrefix types.String `tfsdk:"mac_prefix"`
|
||||
MaxWorkers types.Int64 `tfsdk:"max_workers"`
|
||||
MigrationNetwork types.String `tfsdk:"migration_cidr"`
|
||||
MigrationType types.String `tfsdk:"migration_type"`
|
||||
}
|
||||
|
||||
func (m *clusterOptionsModel) haData() *string {
|
||||
// haData returns HA settings parameter string for API, HA settings are
|
||||
// defined, otherwise empty string is returned.
|
||||
func (m *clusterOptionsModel) haData() string {
|
||||
var haDataParams []string
|
||||
|
||||
if !m.HAShutdownPolicy.IsNull() && m.HAShutdownPolicy.ValueString() != "" {
|
||||
@ -62,15 +64,15 @@ func (m *clusterOptionsModel) haData() *string {
|
||||
}
|
||||
|
||||
if len(haDataParams) > 0 {
|
||||
haDataValue := strings.Join(haDataParams, ",")
|
||||
|
||||
return &haDataValue
|
||||
return strings.Join(haDataParams, ",")
|
||||
}
|
||||
|
||||
return nil
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *clusterOptionsModel) migrationData() *string {
|
||||
// migrationData returns migration settings parameter string for API, if any of migration
|
||||
// settings are defined, otherwise empty string is returned.
|
||||
func (m *clusterOptionsModel) migrationData() string {
|
||||
var migrationDataParams []string
|
||||
|
||||
if !m.MigrationType.IsNull() && m.MigrationType.ValueString() != "" {
|
||||
@ -82,15 +84,15 @@ func (m *clusterOptionsModel) migrationData() *string {
|
||||
}
|
||||
|
||||
if len(migrationDataParams) > 0 {
|
||||
migrationDataValue := strings.Join(migrationDataParams, ",")
|
||||
|
||||
return &migrationDataValue
|
||||
return strings.Join(migrationDataParams, ",")
|
||||
}
|
||||
|
||||
return nil
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *clusterOptionsModel) crsData() *string {
|
||||
// crsData returns cluster resource scheduling settings parameter string for API, if any of cluster resource scheduling
|
||||
// settings are defined, otherwise empty string is returned.
|
||||
func (m *clusterOptionsModel) crsData() string {
|
||||
var crsDataParams []string
|
||||
|
||||
if !m.CrsHA.IsNull() && m.CrsHA.ValueString() != "" {
|
||||
@ -109,15 +111,15 @@ func (m *clusterOptionsModel) crsData() *string {
|
||||
}
|
||||
|
||||
if len(crsDataParams) > 0 {
|
||||
crsDataValue := strings.Join(crsDataParams, ",")
|
||||
|
||||
return &crsDataValue
|
||||
return strings.Join(crsDataParams, ",")
|
||||
}
|
||||
|
||||
return nil
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *clusterOptionsModel) bandwidthData() *string {
|
||||
// bandwidthData returns bandwidth limit settings parameter string for API, if any of bandwidth
|
||||
// limit settings are defined, otherwise empty string is returned.
|
||||
func (m *clusterOptionsModel) bandwidthData() string {
|
||||
var bandwidthParams []string
|
||||
|
||||
if !m.BandwidthLimitClone.IsNull() && m.BandwidthLimitClone.ValueInt64() != 0 {
|
||||
@ -141,12 +143,10 @@ func (m *clusterOptionsModel) bandwidthData() *string {
|
||||
}
|
||||
|
||||
if len(bandwidthParams) > 0 {
|
||||
bandwithDataValue := strings.Join(bandwidthParams, ",")
|
||||
|
||||
return &bandwithDataValue
|
||||
return strings.Join(bandwidthParams, ",")
|
||||
}
|
||||
|
||||
return nil
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *clusterOptionsModel) toOptionsRequestBody() *cluster.OptionsRequestData {
|
||||
@ -184,17 +184,32 @@ func (m *clusterOptionsModel) toOptionsRequestBody() *cluster.OptionsRequestData
|
||||
body.Description = m.Description.ValueStringPointer()
|
||||
}
|
||||
|
||||
body.HASettings = m.haData()
|
||||
body.BandwidthLimit = m.bandwidthData()
|
||||
body.ClusterResourceScheduling = m.crsData()
|
||||
body.Migration = m.migrationData()
|
||||
haData := m.haData()
|
||||
if haData != "" {
|
||||
body.HASettings = &haData
|
||||
}
|
||||
|
||||
bandwidthData := m.bandwidthData()
|
||||
if bandwidthData != "" {
|
||||
body.BandwidthLimit = &bandwidthData
|
||||
}
|
||||
|
||||
crsData := m.crsData()
|
||||
if crsData != "" {
|
||||
body.ClusterResourceScheduling = &crsData
|
||||
}
|
||||
|
||||
migrationData := m.migrationData()
|
||||
if migrationData != "" {
|
||||
body.Migration = &migrationData
|
||||
}
|
||||
|
||||
return body
|
||||
}
|
||||
|
||||
func (m *clusterOptionsModel) importFromOptionsAPI(
|
||||
_ context.Context,
|
||||
iface *cluster.OptionsResponseData,
|
||||
opts *cluster.OptionsResponseData,
|
||||
) error {
|
||||
m.BandwidthLimitClone = types.Int64Null()
|
||||
m.BandwidthLimitDefault = types.Int64Null()
|
||||
@ -203,14 +218,14 @@ func (m *clusterOptionsModel) importFromOptionsAPI(
|
||||
m.BandwidthLimitRestore = types.Int64Null()
|
||||
|
||||
//nolint:nestif
|
||||
if iface.BandwidthLimit != nil {
|
||||
for _, bandwidth := range strings.Split(*iface.BandwidthLimit, ",") {
|
||||
if opts.BandwidthLimit != nil {
|
||||
for _, bandwidth := range strings.Split(*opts.BandwidthLimit, ",") {
|
||||
bandwidthData := strings.SplitN(bandwidth, "=", 2)
|
||||
bandwidthName := bandwidthData[0]
|
||||
|
||||
bandwidthLimit, err := strconv.ParseInt(bandwidthData[1], 10, 64)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to parse bandwidth limit: %s", *iface.BandwidthLimit)
|
||||
return fmt.Errorf("failed to parse bandwidth limit: %s", *opts.BandwidthLimit)
|
||||
}
|
||||
|
||||
if bandwidthName == "clone" {
|
||||
@ -235,39 +250,46 @@ func (m *clusterOptionsModel) importFromOptionsAPI(
|
||||
}
|
||||
}
|
||||
|
||||
m.EmailFrom = types.StringPointerValue(iface.EmailFrom)
|
||||
m.Keyboard = types.StringPointerValue(iface.Keyboard)
|
||||
m.Language = types.StringPointerValue(iface.Language)
|
||||
m.EmailFrom = types.StringPointerValue(opts.EmailFrom)
|
||||
m.Keyboard = types.StringPointerValue(opts.Keyboard)
|
||||
m.Language = types.StringPointerValue(opts.Language)
|
||||
|
||||
if iface.MaxWorkers != nil {
|
||||
m.MaxWorkers = types.Int64Value(int64(*iface.MaxWorkers))
|
||||
if opts.MaxWorkers != nil {
|
||||
m.MaxWorkers = types.Int64PointerValue(opts.MaxWorkers.PointerInt64())
|
||||
} else {
|
||||
m.MaxWorkers = types.Int64Null()
|
||||
}
|
||||
|
||||
m.Console = types.StringPointerValue(iface.Console)
|
||||
m.HTTPProxy = types.StringPointerValue(iface.HTTPProxy)
|
||||
m.MacPrefix = types.StringPointerValue(iface.MacPrefix)
|
||||
m.Description = types.StringPointerValue(iface.Description)
|
||||
m.Console = types.StringPointerValue(opts.Console)
|
||||
m.HTTPProxy = types.StringPointerValue(opts.HTTPProxy)
|
||||
m.MacPrefix = types.StringPointerValue(opts.MacPrefix)
|
||||
|
||||
if iface.HASettings != nil {
|
||||
m.HAShutdownPolicy = types.StringPointerValue(iface.HASettings.ShutdownPolicy)
|
||||
if opts.Description != nil && *opts.Description != "" {
|
||||
m.Description = types.StringPointerValue(opts.Description)
|
||||
} else {
|
||||
m.HAShutdownPolicy = types.StringPointerValue(nil)
|
||||
m.Description = types.StringNull()
|
||||
}
|
||||
|
||||
if iface.Migration != nil {
|
||||
m.MigrationType = types.StringPointerValue(iface.Migration.Type)
|
||||
m.MigrationNetwork = types.StringPointerValue(iface.Migration.Network)
|
||||
if opts.HASettings != nil {
|
||||
m.HAShutdownPolicy = types.StringPointerValue(opts.HASettings.ShutdownPolicy)
|
||||
} else {
|
||||
m.MigrationType = types.StringPointerValue(nil)
|
||||
m.MigrationNetwork = types.StringPointerValue(nil)
|
||||
m.HAShutdownPolicy = types.StringNull()
|
||||
}
|
||||
|
||||
if iface.ClusterResourceScheduling != nil {
|
||||
m.CrsHARebalanceOnStart = types.BoolValue(bool(*iface.ClusterResourceScheduling.HaRebalanceOnStart))
|
||||
m.CrsHA = types.StringPointerValue(iface.ClusterResourceScheduling.HA)
|
||||
if opts.Migration != nil {
|
||||
m.MigrationType = types.StringPointerValue(opts.Migration.Type)
|
||||
m.MigrationNetwork = types.StringPointerValue(opts.Migration.Network)
|
||||
} else {
|
||||
m.CrsHARebalanceOnStart = types.BoolPointerValue(nil)
|
||||
m.CrsHA = types.StringPointerValue(nil)
|
||||
m.MigrationType = types.StringNull()
|
||||
m.MigrationNetwork = types.StringNull()
|
||||
}
|
||||
|
||||
if opts.ClusterResourceScheduling != nil {
|
||||
m.CrsHARebalanceOnStart = types.BoolPointerValue(opts.ClusterResourceScheduling.HaRebalanceOnStart.PointerBool())
|
||||
m.CrsHA = types.StringPointerValue(opts.ClusterResourceScheduling.HA)
|
||||
} else {
|
||||
m.CrsHARebalanceOnStart = types.BoolNull()
|
||||
m.CrsHA = types.StringNull()
|
||||
}
|
||||
|
||||
return nil
|
||||
@ -303,7 +325,6 @@ func (r *clusterOptionsResource) Schema(
|
||||
"email_from": schema.StringAttribute{
|
||||
Description: "email address to send notification from (default is root@$hostname).",
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
"keyboard": schema.StringAttribute{
|
||||
Description: "Default keyboard layout for vnc server.",
|
||||
@ -311,24 +332,25 @@ func (r *clusterOptionsResource) Schema(
|
||||
"`de-ch` | `da` | `en-gb` | `en-us` | `es` | `fi` | `fr` | `fr-be` | `fr-ca` " +
|
||||
"| `fr-ch` | `hu` | `is` | `it` | `ja` | `lt` | `mk` | `nl` | `no` | `pl` | " +
|
||||
"`pt` | `pt-br` | `sv` | `sl` | `tr`.",
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Validators: []validator.String{validators.KeyboardLayoutValidator()},
|
||||
Optional: true,
|
||||
Validators: []validator.String{
|
||||
validators.KeyboardLayoutValidator(),
|
||||
},
|
||||
},
|
||||
"max_workers": schema.Int64Attribute{
|
||||
Description: "Defines how many workers (per node) are maximal started on" +
|
||||
" actions like 'stopall VMs' or task from the ha-manager.",
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
"language": schema.StringAttribute{
|
||||
Description: "Default GUI language.",
|
||||
MarkdownDescription: "Default GUI language. Must be `ca` | `da` | `de` " +
|
||||
"| `en` | `es` | `eu` | `fa` | `fr` | `he` | `it` | `ja` | `nb` | " +
|
||||
"`nn` | `pl` | `pt_BR` | `ru` | `sl` | `sv` | `tr` | `zh_CN` | `zh_TW`.",
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Validators: []validator.String{validators.LanguageValidator()},
|
||||
Optional: true,
|
||||
Validators: []validator.String{
|
||||
validators.LanguageValidator(),
|
||||
},
|
||||
},
|
||||
"console": schema.StringAttribute{
|
||||
Description: "Select the default Console viewer.",
|
||||
@ -342,7 +364,6 @@ func (r *clusterOptionsResource) Schema(
|
||||
"(e.g. SPICE not activated for the VM), " +
|
||||
"the fallback is noVNC.",
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Validators: []validator.String{stringvalidator.OneOf([]string{
|
||||
"applet",
|
||||
"vv",
|
||||
@ -355,25 +376,21 @@ func (r *clusterOptionsResource) Schema(
|
||||
MarkdownDescription: "Specify external http proxy which is used for downloads " +
|
||||
"(example: `http://username:password@host:port/`).",
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
"mac_prefix": schema.StringAttribute{
|
||||
Description: "Prefix for autogenerated MAC addresses.",
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
"description": schema.StringAttribute{
|
||||
Description: "Datacenter description. Shown in the web-interface datacenter notes panel. " +
|
||||
"This is saved as comment inside the configuration file.",
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
"ha_shutdown_policy": schema.StringAttribute{
|
||||
Description: "Cluster wide HA shutdown policy.",
|
||||
MarkdownDescription: "Cluster wide HA shutdown policy. " +
|
||||
"Must be `freeze` | `failover` | `migrate` | `conditional`.",
|
||||
MarkdownDescription: "Cluster wide HA shutdown policy (). " +
|
||||
"Must be `freeze` | `failover` | `migrate` | `conditional` (default is `conditional`).",
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Validators: []validator.String{stringvalidator.OneOf([]string{
|
||||
"freeze",
|
||||
"failover",
|
||||
@ -382,10 +399,10 @@ func (r *clusterOptionsResource) Schema(
|
||||
}...)},
|
||||
},
|
||||
"migration_type": schema.StringAttribute{
|
||||
Description: "Cluster wide migration type.",
|
||||
MarkdownDescription: "Cluster wide migration type. Must be `secure` | `unsecure`.",
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "Cluster wide migration type.",
|
||||
MarkdownDescription: "Cluster wide migration type. Must be `secure` | `unsecure` " +
|
||||
"(default is `secure`).",
|
||||
Optional: true,
|
||||
Validators: []validator.String{stringvalidator.OneOf([]string{
|
||||
"secure",
|
||||
"unsecure",
|
||||
@ -394,11 +411,10 @@ func (r *clusterOptionsResource) Schema(
|
||||
"migration_cidr": schema.StringAttribute{
|
||||
Description: "Cluster wide migration network CIDR.",
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
"crs_ha": schema.StringAttribute{
|
||||
Description: "Cluster resource scheduling setting for HA.",
|
||||
MarkdownDescription: "Cluster resource scheduling setting for HA. Must be `static` | `basic`.",
|
||||
MarkdownDescription: "Cluster resource scheduling setting for HA. Must be `static` | `basic` (default is `basic`).",
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Validators: []validator.String{stringvalidator.OneOf([]string{
|
||||
@ -409,32 +425,26 @@ func (r *clusterOptionsResource) Schema(
|
||||
"crs_ha_rebalance_on_start": schema.BoolAttribute{
|
||||
Description: "Cluster resource scheduling setting for HA rebalance on start.",
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
"bandwidth_limit_clone": schema.Int64Attribute{
|
||||
Description: "Clone I/O bandwidth limit in KiB/s.",
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
"bandwidth_limit_default": schema.Int64Attribute{
|
||||
Description: "Default I/O bandwidth limit in KiB/s.",
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
"bandwidth_limit_migration": schema.Int64Attribute{
|
||||
Description: "Migration I/O bandwidth limit in KiB/s.",
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
"bandwidth_limit_move": schema.Int64Attribute{
|
||||
Description: "Move I/O bandwidth limit in KiB/s.",
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
"bandwidth_limit_restore": schema.Int64Attribute{
|
||||
Description: "Restore I/O bandwidth limit in KiB/s.",
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -464,10 +474,12 @@ func (r *clusterOptionsResource) Configure(
|
||||
r.client = client
|
||||
}
|
||||
|
||||
// Create update must-existing cluster options interface.
|
||||
//
|
||||
//nolint:lll
|
||||
func (r *clusterOptionsResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
|
||||
// Create update must-existing cluster options.
|
||||
func (r *clusterOptionsResource) Create(
|
||||
ctx context.Context,
|
||||
req resource.CreateRequest,
|
||||
resp *resource.CreateResponse,
|
||||
) {
|
||||
var plan clusterOptionsModel
|
||||
diags := req.Plan.Get(ctx, &plan)
|
||||
resp.Diagnostics.Append(diags...)
|
||||
@ -481,7 +493,7 @@ func (r *clusterOptionsResource) Create(ctx context.Context, req resource.Create
|
||||
err := r.client.Cluster().CreateUpdateOptions(ctx, body)
|
||||
if err != nil {
|
||||
resp.Diagnostics.AddError(
|
||||
"Error creating cluster options interface",
|
||||
"Error creating cluster options",
|
||||
"Could not create cluster options, unexpected error: "+err.Error(),
|
||||
)
|
||||
|
||||
@ -515,7 +527,7 @@ func (r *clusterOptionsResource) read(ctx context.Context, model *clusterOptions
|
||||
|
||||
if err != nil {
|
||||
diags.AddError(
|
||||
"Error converting cluster options interface to a model",
|
||||
"Error converting cluster options to a model",
|
||||
"Could not import cluster options from API response, unexpected error: "+err.Error(),
|
||||
)
|
||||
|
||||
@ -523,7 +535,7 @@ func (r *clusterOptionsResource) read(ctx context.Context, model *clusterOptions
|
||||
}
|
||||
}
|
||||
|
||||
// Read reads a cluster options interface.
|
||||
// Read reads cluster options.
|
||||
func (r *clusterOptionsResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
|
||||
// Get current state
|
||||
var state clusterOptionsModel
|
||||
@ -544,10 +556,12 @@ func (r *clusterOptionsResource) Read(ctx context.Context, req resource.ReadRequ
|
||||
resp.Diagnostics.Append(diags...)
|
||||
}
|
||||
|
||||
// Update updates a cluster options interface.
|
||||
//
|
||||
//nolint:lll
|
||||
func (r *clusterOptionsResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
|
||||
// Update updates cluster options.
|
||||
func (r *clusterOptionsResource) Update(
|
||||
ctx context.Context,
|
||||
req resource.UpdateRequest,
|
||||
resp *resource.UpdateResponse,
|
||||
) {
|
||||
var plan, state clusterOptionsModel
|
||||
|
||||
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
|
||||
@ -565,19 +579,19 @@ func (r *clusterOptionsResource) Update(ctx context.Context, req resource.Update
|
||||
toDelete = append(toDelete, "keyboard")
|
||||
}
|
||||
|
||||
if (plan.bandwidthData() == nil && state.bandwidthData() != nil) || (*plan.bandwidthData() != *state.bandwidthData() && *plan.bandwidthData() == "") {
|
||||
if plan.bandwidthData() != state.bandwidthData() && plan.bandwidthData() == "" {
|
||||
toDelete = append(toDelete, "bwlimit")
|
||||
}
|
||||
|
||||
if (plan.crsData() == nil && state.crsData() != nil) || (*plan.crsData() != *state.crsData() && *plan.crsData() == "") {
|
||||
if plan.crsData() != state.crsData() && plan.crsData() == "" {
|
||||
toDelete = append(toDelete, "crs")
|
||||
}
|
||||
|
||||
if (plan.haData() == nil && state.haData() != nil) || (*plan.haData() != *state.haData() && *plan.haData() == "") {
|
||||
if plan.haData() != state.haData() && plan.haData() == "" {
|
||||
toDelete = append(toDelete, "ha")
|
||||
}
|
||||
|
||||
if (plan.migrationData() == nil && state.migrationData() != nil) || (*plan.migrationData() != *state.migrationData() && *plan.migrationData() == "") {
|
||||
if plan.migrationData() != state.migrationData() && plan.migrationData() == "" {
|
||||
toDelete = append(toDelete, "migration")
|
||||
}
|
||||
|
||||
@ -617,7 +631,7 @@ func (r *clusterOptionsResource) Update(ctx context.Context, req resource.Update
|
||||
err := r.client.Cluster().CreateUpdateOptions(ctx, body)
|
||||
if err != nil {
|
||||
resp.Diagnostics.AddError(
|
||||
"Error updating cluster options interface",
|
||||
"Error updating cluster options",
|
||||
"Could not update cluster options, unexpected error: "+err.Error(),
|
||||
)
|
||||
|
||||
@ -633,20 +647,83 @@ func (r *clusterOptionsResource) Update(ctx context.Context, req resource.Update
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, plan)...)
|
||||
}
|
||||
|
||||
// Delete deletes a cluster options interface.
|
||||
//
|
||||
//nolint:lll
|
||||
func (r *clusterOptionsResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
|
||||
// Delete deletes cluster options.
|
||||
func (r *clusterOptionsResource) Delete(
|
||||
ctx context.Context,
|
||||
req resource.DeleteRequest,
|
||||
resp *resource.DeleteResponse,
|
||||
) {
|
||||
var state clusterOptionsModel
|
||||
diags := req.State.Get(ctx, &state)
|
||||
resp.Diagnostics.Append(diags...)
|
||||
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
var toDelete []string
|
||||
|
||||
if !state.Keyboard.IsNull() && state.Keyboard.ValueString() != "" {
|
||||
toDelete = append(toDelete, "keyboard")
|
||||
}
|
||||
|
||||
if state.bandwidthData() != "" {
|
||||
toDelete = append(toDelete, "bwlimit")
|
||||
}
|
||||
|
||||
if state.crsData() != "" {
|
||||
toDelete = append(toDelete, "crs")
|
||||
}
|
||||
|
||||
if state.haData() != "" {
|
||||
toDelete = append(toDelete, "ha")
|
||||
}
|
||||
|
||||
if state.migrationData() != "" {
|
||||
toDelete = append(toDelete, "migration")
|
||||
}
|
||||
|
||||
if !state.EmailFrom.IsNull() && state.EmailFrom.ValueString() != "" {
|
||||
toDelete = append(toDelete, "email_from")
|
||||
}
|
||||
|
||||
if !state.Language.IsNull() && state.Language.ValueString() != "" {
|
||||
toDelete = append(toDelete, "language")
|
||||
}
|
||||
|
||||
if !state.Console.IsNull() && state.Console.ValueString() != "" {
|
||||
toDelete = append(toDelete, "console")
|
||||
}
|
||||
|
||||
if !state.HTTPProxy.IsNull() && state.HTTPProxy.ValueString() != "" {
|
||||
toDelete = append(toDelete, "http_proxy")
|
||||
}
|
||||
|
||||
if !state.MacPrefix.IsNull() && state.MacPrefix.ValueString() != "" {
|
||||
toDelete = append(toDelete, "mac_prefix")
|
||||
}
|
||||
|
||||
if !state.Description.IsNull() && state.Description.ValueString() != "" {
|
||||
toDelete = append(toDelete, "description")
|
||||
}
|
||||
|
||||
if !state.MaxWorkers.IsNull() && state.MaxWorkers.ValueInt64() != 0 {
|
||||
toDelete = append(toDelete, "max_workers")
|
||||
}
|
||||
|
||||
if len(toDelete) > 0 {
|
||||
d := strings.Join(toDelete, ",")
|
||||
body := &cluster.OptionsRequestData{
|
||||
Delete: &d,
|
||||
}
|
||||
|
||||
err := r.client.Cluster().CreateUpdateOptions(ctx, body)
|
||||
if err != nil {
|
||||
resp.Diagnostics.AddError(
|
||||
"Error updating cluster options",
|
||||
"Could not update cluster options, unexpected error: "+err.Error(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ImportState a cluster options interface.
|
||||
// ImportState imports cluster options.
|
||||
func (r *clusterOptionsResource) ImportState(
|
||||
ctx context.Context,
|
||||
req resource.ImportStateRequest,
|
||||
|
@ -13,84 +13,102 @@ import (
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
|
||||
)
|
||||
|
||||
func TestClusterOptionsResource(t *testing.T) {
|
||||
const accTestClusterOptionsName = "proxmox_virtual_environment_cluster_options.test_options"
|
||||
|
||||
func TestAccResourceClusterOptions(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
accProviders := testAccMuxProviders(context.Background(), t)
|
||||
|
||||
resourceName := "proxmox_virtual_environment_cluster_options.test_options"
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
ProtoV6ProviderFactories: accProviders,
|
||||
Steps: []resource.TestStep{
|
||||
// Create and Read testing
|
||||
{
|
||||
Config: `
|
||||
resource "proxmox_virtual_environment_cluster_options" "test_options" {
|
||||
language = "en"
|
||||
keyboard = "pl"
|
||||
email_from = "example@example.com"
|
||||
bandwidth_limit_migration = 555554
|
||||
bandwidth_limit_default = 666666
|
||||
max_workers = 5
|
||||
crs_ha = "static"
|
||||
ha_shutdown_policy = "freeze"
|
||||
migration_cidr = "10.0.0.0/8"
|
||||
migration_type = "secure"
|
||||
}
|
||||
`,
|
||||
Check: resource.ComposeAggregateTestCheckFunc(
|
||||
resource.TestCheckResourceAttr(resourceName, "language", "en"),
|
||||
resource.TestCheckResourceAttr(resourceName, "keyboard", "pl"),
|
||||
resource.TestCheckResourceAttr(resourceName, "email_from", "example@example.com"),
|
||||
resource.TestCheckResourceAttr(resourceName, "bandwidth_limit_migration", "555554"),
|
||||
resource.TestCheckResourceAttr(resourceName, "bandwidth_limit_default", "666666"),
|
||||
resource.TestCheckResourceAttr(resourceName, "max_workers", "5"),
|
||||
resource.TestCheckResourceAttr(resourceName, "crs_ha", "static"),
|
||||
resource.TestCheckResourceAttr(resourceName, "ha_shutdown_policy", "freeze"),
|
||||
resource.TestCheckResourceAttr(resourceName, "migration_cidr", "10.0.0.0/8"),
|
||||
resource.TestCheckResourceAttr(resourceName, "migration_type", "secure"),
|
||||
resource.TestCheckResourceAttr(resourceName, "id", "cluster"),
|
||||
resource.TestCheckNoResourceAttr(resourceName, "bandwidth_limit_restore"),
|
||||
resource.TestCheckNoResourceAttr(resourceName, "bandwidth_limit_move"),
|
||||
),
|
||||
Config: testAccResourceClusterOptionsCreatedConfig(),
|
||||
Check: testAccResourceClusterOptionsCreatedCheck(),
|
||||
},
|
||||
// ImportState testing
|
||||
{
|
||||
ResourceName: resourceName,
|
||||
ResourceName: accTestClusterOptionsName,
|
||||
ImportState: true,
|
||||
ImportStateVerify: true,
|
||||
},
|
||||
// Update testing
|
||||
{
|
||||
Config: `
|
||||
resource "proxmox_virtual_environment_cluster_options" "test_options" {
|
||||
language = "en"
|
||||
keyboard = "pl"
|
||||
email_from = "ged@gont.earthsea"
|
||||
bandwidth_limit_migration = 111111
|
||||
bandwidth_limit_default = 666666
|
||||
max_workers = 6
|
||||
migration_cidr = "10.0.0.0/8"
|
||||
migration_type = "secure"
|
||||
}
|
||||
`,
|
||||
Check: resource.ComposeAggregateTestCheckFunc(
|
||||
resource.TestCheckResourceAttr(resourceName, "language", "en"),
|
||||
resource.TestCheckResourceAttr(resourceName, "keyboard", "pl"),
|
||||
resource.TestCheckResourceAttr(resourceName, "email_from", "ged@gont.earthsea"),
|
||||
resource.TestCheckResourceAttr(resourceName, "bandwidth_limit_migration", "111111"),
|
||||
resource.TestCheckResourceAttr(resourceName, "bandwidth_limit_default", "666666"),
|
||||
resource.TestCheckResourceAttr(resourceName, "max_workers", "6"),
|
||||
resource.TestCheckResourceAttr(resourceName, "migration_cidr", "10.0.0.0/8"),
|
||||
resource.TestCheckResourceAttr(resourceName, "migration_type", "secure"),
|
||||
resource.TestCheckResourceAttr(resourceName, "id", "cluster"),
|
||||
resource.TestCheckNoResourceAttr(resourceName, "bandwidth_limit_restore"),
|
||||
resource.TestCheckNoResourceAttr(resourceName, "bandwidth_limit_move"),
|
||||
resource.TestCheckNoResourceAttr(resourceName, "crs_ha"),
|
||||
resource.TestCheckNoResourceAttr(resourceName, "ha_shutdown_policy"),
|
||||
),
|
||||
Config: testAccResourceClusterOptionsUpdatedConfig(),
|
||||
Check: testAccResourceClusterOptionsUpdatedCheck(),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func testAccResourceClusterOptionsCreatedConfig() string {
|
||||
return `
|
||||
resource "proxmox_virtual_environment_cluster_options" "test_options" {
|
||||
bandwidth_limit_default = 666666
|
||||
bandwidth_limit_migration = 555554
|
||||
crs_ha = "static"
|
||||
email_from = "example@example.com"
|
||||
ha_shutdown_policy = "freeze"
|
||||
http_proxy = "http://example.com"
|
||||
keyboard = "pl"
|
||||
language = "en"
|
||||
max_workers = 5
|
||||
migration_cidr = "10.0.0.0/8"
|
||||
migration_type = "secure"
|
||||
bandwidth_limit_restore = 777777
|
||||
}
|
||||
`
|
||||
}
|
||||
|
||||
func testAccResourceClusterOptionsCreatedCheck() resource.TestCheckFunc {
|
||||
return resource.ComposeTestCheckFunc(
|
||||
resource.TestCheckResourceAttr(accTestClusterOptionsName, "bandwidth_limit_default", "666666"),
|
||||
resource.TestCheckResourceAttr(accTestClusterOptionsName, "bandwidth_limit_migration", "555554"),
|
||||
resource.TestCheckResourceAttr(accTestClusterOptionsName, "bandwidth_limit_restore", "777777"),
|
||||
resource.TestCheckResourceAttr(accTestClusterOptionsName, "crs_ha", "static"),
|
||||
resource.TestCheckResourceAttr(accTestClusterOptionsName, "email_from", "example@example.com"),
|
||||
resource.TestCheckResourceAttr(accTestClusterOptionsName, "ha_shutdown_policy", "freeze"),
|
||||
resource.TestCheckResourceAttr(accTestClusterOptionsName, "http_proxy", "http://example.com"),
|
||||
resource.TestCheckResourceAttr(accTestClusterOptionsName, "id", "cluster"),
|
||||
resource.TestCheckResourceAttr(accTestClusterOptionsName, "keyboard", "pl"),
|
||||
resource.TestCheckResourceAttr(accTestClusterOptionsName, "language", "en"),
|
||||
resource.TestCheckResourceAttr(accTestClusterOptionsName, "max_workers", "5"),
|
||||
resource.TestCheckResourceAttr(accTestClusterOptionsName, "migration_cidr", "10.0.0.0/8"),
|
||||
resource.TestCheckResourceAttr(accTestClusterOptionsName, "migration_type", "secure"),
|
||||
resource.TestCheckNoResourceAttr(accTestClusterOptionsName, "bandwidth_limit_move"),
|
||||
)
|
||||
}
|
||||
|
||||
func testAccResourceClusterOptionsUpdatedConfig() string {
|
||||
return `
|
||||
resource "proxmox_virtual_environment_cluster_options" "test_options" {
|
||||
bandwidth_limit_default = 333333
|
||||
bandwidth_limit_migration = 111111
|
||||
email_from = "ged@gont.earthsea"
|
||||
language = "en"
|
||||
max_workers = 6
|
||||
migration_cidr = "10.0.0.1/8"
|
||||
migration_type = "secure"
|
||||
}
|
||||
`
|
||||
}
|
||||
|
||||
func testAccResourceClusterOptionsUpdatedCheck() resource.TestCheckFunc {
|
||||
return resource.ComposeTestCheckFunc(
|
||||
resource.TestCheckResourceAttr(accTestClusterOptionsName, "bandwidth_limit_default", "333333"),
|
||||
resource.TestCheckResourceAttr(accTestClusterOptionsName, "bandwidth_limit_migration", "111111"),
|
||||
resource.TestCheckResourceAttr(accTestClusterOptionsName, "email_from", "ged@gont.earthsea"),
|
||||
resource.TestCheckResourceAttr(accTestClusterOptionsName, "id", "cluster"),
|
||||
resource.TestCheckResourceAttr(accTestClusterOptionsName, "language", "en"),
|
||||
resource.TestCheckResourceAttr(accTestClusterOptionsName, "max_workers", "6"),
|
||||
resource.TestCheckResourceAttr(accTestClusterOptionsName, "migration_cidr", "10.0.0.1/8"),
|
||||
resource.TestCheckResourceAttr(accTestClusterOptionsName, "migration_type", "secure"),
|
||||
resource.TestCheckNoResourceAttr(accTestClusterOptionsName, "bandwidth_limit_move"),
|
||||
resource.TestCheckNoResourceAttr(accTestClusterOptionsName, "crs_ha"),
|
||||
resource.TestCheckNoResourceAttr(accTestClusterOptionsName, "ha_shutdown_policy"),
|
||||
resource.TestCheckNoResourceAttr(accTestClusterOptionsName, "http_proxy"),
|
||||
resource.TestCheckNoResourceAttr(accTestClusterOptionsName, "keyboard"),
|
||||
)
|
||||
}
|
||||
|
@ -114,6 +114,17 @@ func (r *CustomInt) UnmarshalJSON(b []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// PointerInt64 returns a pointer to an int64.
|
||||
func (r *CustomInt) PointerInt64() *int64 {
|
||||
if r == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
i := int64(*r)
|
||||
|
||||
return &i
|
||||
}
|
||||
|
||||
// MarshalJSON converts a boolean to a JSON value.
|
||||
func (r *CustomLineBreakSeparatedList) MarshalJSON() ([]byte, error) {
|
||||
s := strings.Join(*r, "\n")
|
||||
|
Loading…
Reference in New Issue
Block a user