0
0
mirror of https://github.com/bpg/terraform-provider-proxmox.git synced 2025-06-30 02:31:10 +00:00

feat(cluster): Extend the available attributes for the proxmox_virtual_environment_cluster_options resource (#1241)

This commit implements the `next-id` and `notify` PVE API cluster
options.

The `next-id` attribute allows to control the range for the next free
VM ID. It is implemented as object and can be used in the
`proxmox_virtual_environment_cluster_options` resource and can be used
like this:

```terraform
resource "proxmox_virtual_environment_cluster_options" "options" {
  next_id = {
    lower = 200
    upper = 299
  }
}
```

Note that the minimum and maximum values are unfortunately not
documented in the PVE API explorer but can be found in the web UI where
the form fields have validations!

The `notify` PVE API attribute is also an object that has all the PVE
API fields:

```terraform
resource "proxmox_virtual_environment_cluster_options" "options" {
  notify = {
    ha_fencing_mode            = "never"
    ha_fencing_target          = "default-matcher"
    package_updates            = "always"
    package_updates_target     = "default-matcher"
    package_replication        = "always"
    package_replication_target = "default-matcher"
  }
}
```terraform

Note that the "fencing" attribute names have been adjusted to better
reflect their meaning since they are scoped to the Proxmox VE HA fencing
feature [1]. All attributes with the `_target` suffix are names for the
Proxmox VE notifications matchers [2].

[1]: https://pve.proxmox.com/wiki/Fencing
[2]: https://pve.proxmox.com/pve-docs/chapter-notifications.html#notification_matchers

---------

Signed-off-by: Sven Greb <development@svengreb.de>
This commit is contained in:
Sven Greb 2024-04-30 02:08:44 +02:00 committed by GitHub
parent 43bcc84c53
commit 2eb36f4134
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 421 additions and 58 deletions

View File

@ -23,6 +23,18 @@ resource "proxmox_virtual_environment_cluster_options" "options" {
max_workers = 5
migration_cidr = "10.0.0.0/8"
migration_type = "secure"
next_id = {
lower = 100
upper = 999999999
}
notify = {
ha_fencing_mode = "never"
ha_fencing_target = "default-matcher"
package_updates = "always"
package_updates_target = "default-matcher"
package_replication = "always"
package_replication_target = "default-matcher"
}
}
```
@ -49,11 +61,34 @@ resource "proxmox_virtual_environment_cluster_options" "options" {
- `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` (default is `secure`).
- `next_id` (Attributes) The ranges for the next free VM ID auto-selection pool. (see [below for nested schema](#nestedatt--next_id))
- `notify` (Attributes) Cluster-wide notification settings. (see [below for nested schema](#nestedatt--notify))
### Read-Only
- `id` (String) The unique identifier of this resource.
<a id="nestedatt--next_id"></a>
### Nested Schema for `next_id`
Optional:
- `lower` (Number) The minimum number for the next free VM ID. Must be higher or equal to 100
- `upper` (Number) The maximum number for the next free VM ID. Must be less or equal to 999999999
<a id="nestedatt--notify"></a>
### Nested Schema for `notify`
Optional:
- `ha_fencing_mode` (String) Cluster-wide notification settings for the HA fencing mode. Must be `always` | `never`.
- `ha_fencing_target` (String) Cluster-wide notification settings for the HA fencing target.
- `package_updates` (String) Cluster-wide notification settings for package updates. Must be `auto` | `always` | `never`.
- `package_updates_target` (String) Cluster-wide notification settings for the package updates target.
- `replication` (String) Cluster-wide notification settings for replication. Must be `always` | `never`.
- `replication_target` (String) Cluster-wide notification settings for the replication target.
## Import
Import is supported using the following syntax:

View File

@ -7,4 +7,16 @@ resource "proxmox_virtual_environment_cluster_options" "options" {
max_workers = 5
migration_cidr = "10.0.0.0/8"
migration_type = "secure"
next_id = {
lower = 100
upper = 999999999
}
notify = {
ha_fencing_mode = "never"
ha_fencing_target = "default-matcher"
package_updates = "always"
package_updates_target = "default-matcher"
package_replication = "always"
package_replication_target = "default-matcher"
}
}

View File

@ -9,9 +9,11 @@ package fwprovider
import (
"context"
"fmt"
"regexp"
"strconv"
"strings"
"github.com/hashicorp/terraform-plugin-framework-validators/int64validator"
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/resource"
@ -21,11 +23,28 @@ import (
"github.com/bpg/terraform-provider-proxmox/fwprovider/structure"
"github.com/bpg/terraform-provider-proxmox/fwprovider/validators"
"github.com/bpg/terraform-provider-proxmox/proxmox"
"github.com/bpg/terraform-provider-proxmox/proxmox/cluster"
)
const (
// ClusterOptionsNextIDLowerMaximum is the maximum number for the "lower" range for the next VM ID option.
// Note that this value is not documented in the section about the cluster options in the Proxmox VE API explorer but
// [in the sections about QEMU (POST)] as well as [the dedicated Proxmox VE documentations about QEMU/KVM].
//
// [in the sections about QEMU (POST)]: https://pve.proxmox.com/pve-docs/api-viewer/#/nodes/{node}/qemu
// [the dedicated Proxmox VE documentations about QEMU/KVM]: https://pve.proxmox.com/pve-docs/pve-admin-guide.html#_strong_qm_strong_qemu_kvm_virtual_machine_manager
ClusterOptionsNextIDLowerMaximum = 999999999
// ClusterOptionsNextIDLowerMinimum is the minimum number for the "lower" range for the next VM ID option.
// Note that this value is not documented in the section about the cluster options in the Proxmox VE API explorer but
// [in the sections about QEMU (POST)] as well as [the dedicated Proxmox VE documentations about QEMU/KVM].
//
// [in the sections about QEMU (POST)]: https://pve.proxmox.com/pve-docs/api-viewer/#/nodes/{node}/qemu
// [the dedicated Proxmox VE documentations about QEMU/KVM]: https://pve.proxmox.com/pve-docs/pve-admin-guide.html#_strong_qm_strong_qemu_kvm_virtual_machine_manager
ClusterOptionsNextIDLowerMinimum = 100
)
var (
_ resource.Resource = &clusterOptionsResource{}
_ resource.ResourceWithConfigure = &clusterOptionsResource{}
@ -33,25 +52,41 @@ var (
)
type clusterOptionsModel struct {
ID types.String `tfsdk:"id"`
BandwidthLimitClone types.Int64 `tfsdk:"bandwidth_limit_clone"`
BandwidthLimitDefault types.Int64 `tfsdk:"bandwidth_limit_default"`
BandwidthLimitMigration types.Int64 `tfsdk:"bandwidth_limit_migration"`
BandwidthLimitMove types.Int64 `tfsdk:"bandwidth_limit_move"`
BandwidthLimitRestore types.Int64 `tfsdk:"bandwidth_limit_restore"`
Console types.String `tfsdk:"console"`
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"`
ID types.String `tfsdk:"id"`
BandwidthLimitClone types.Int64 `tfsdk:"bandwidth_limit_clone"`
BandwidthLimitDefault types.Int64 `tfsdk:"bandwidth_limit_default"`
BandwidthLimitMigration types.Int64 `tfsdk:"bandwidth_limit_migration"`
BandwidthLimitMove types.Int64 `tfsdk:"bandwidth_limit_move"`
BandwidthLimitRestore types.Int64 `tfsdk:"bandwidth_limit_restore"`
Console types.String `tfsdk:"console"`
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"`
NextID *clusterOptionsNextIDModel `tfsdk:"next_id"`
Notify *clusterOptionsNotifyModel `tfsdk:"notify"`
}
type clusterOptionsNextIDModel struct {
Lower types.Int64 `tfsdk:"lower"`
Upper types.Int64 `tfsdk:"upper"`
}
type clusterOptionsNotifyModel struct {
HAFencingMode types.String `tfsdk:"ha_fencing_mode"`
HAFencingTarget types.String `tfsdk:"ha_fencing_target"`
PackageUpdates types.String `tfsdk:"package_updates"`
PackageUpdatesTarget types.String `tfsdk:"package_updates_target"`
Replication types.String `tfsdk:"replication"`
ReplicationTarget types.String `tfsdk:"replication_target"`
}
// haData returns HA settings parameter string for API, HA settings are
@ -90,6 +125,82 @@ func (m *clusterOptionsModel) migrationData() string {
return ""
}
// nextIDData returns settings for the "next-id" parameter string of the Proxmox VE API, if defined, otherwise an empty
// string is returned.
func (m *clusterOptionsModel) nextIDData() string {
var nextIDDataParams []string
if m.NextID == nil {
return ""
}
if !m.NextID.Lower.IsNull() {
nextIDDataParams = append(nextIDDataParams, fmt.Sprintf("lower=%d", m.NextID.Lower.ValueInt64()))
}
if !m.NextID.Upper.IsNull() {
nextIDDataParams = append(nextIDDataParams, fmt.Sprintf("upper=%d", m.NextID.Upper.ValueInt64()))
}
if len(nextIDDataParams) > 0 {
return strings.Join(nextIDDataParams, ",")
}
return ""
}
// notifyData returns settings for the "notify" parameter string of the Proxmox VE API, if defined, otherwise an empty
// string is returned.
func (m *clusterOptionsModel) notifyData() string {
var notifyDataParams []string
if m.Notify == nil {
return ""
}
if !m.Notify.HAFencingMode.IsNull() {
notifyDataParams = append(notifyDataParams, fmt.Sprintf("fencing=%s", m.Notify.HAFencingMode.ValueString()))
}
if !m.Notify.HAFencingTarget.IsNull() {
notifyDataParams = append(
notifyDataParams,
fmt.Sprintf("target-fencing=%s", m.Notify.HAFencingTarget.ValueString()),
)
}
if !m.Notify.PackageUpdates.IsNull() {
notifyDataParams = append(
notifyDataParams,
fmt.Sprintf("package-updates=%s", m.Notify.PackageUpdates.ValueString()),
)
}
if !m.Notify.PackageUpdatesTarget.IsNull() {
notifyDataParams = append(
notifyDataParams,
fmt.Sprintf("target-package-updates=%s", m.Notify.PackageUpdatesTarget.ValueString()),
)
}
if !m.Notify.Replication.IsNull() {
notifyDataParams = append(notifyDataParams, fmt.Sprintf("replication=%s", m.Notify.Replication.ValueString()))
}
if !m.Notify.ReplicationTarget.IsNull() {
notifyDataParams = append(
notifyDataParams,
fmt.Sprintf("target-replication=%s", m.Notify.ReplicationTarget.ValueString()),
)
}
if len(notifyDataParams) > 0 {
return strings.Join(notifyDataParams, ",")
}
return ""
}
// 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 {
@ -168,6 +279,16 @@ func (m *clusterOptionsModel) toOptionsRequestBody() *cluster.OptionsRequestData
body.MaxWorkers = m.MaxWorkers.ValueInt64Pointer()
}
nextIDData := m.nextIDData()
if nextIDData != "" {
body.NextID = &nextIDData
}
notifyData := m.notifyData()
if notifyData != "" {
body.Notify = &notifyData
}
if !m.Console.IsUnknown() {
body.Console = m.Console.ValueStringPointer()
}
@ -207,10 +328,7 @@ func (m *clusterOptionsModel) toOptionsRequestBody() *cluster.OptionsRequestData
return body
}
func (m *clusterOptionsModel) importFromOptionsAPI(
_ context.Context,
opts *cluster.OptionsResponseData,
) error {
func (m *clusterOptionsModel) importFromOptionsAPI(_ context.Context, opts *cluster.OptionsResponseData) error {
m.BandwidthLimitClone = types.Int64Null()
m.BandwidthLimitDefault = types.Int64Null()
m.BandwidthLimitMigration = types.Int64Null()
@ -285,6 +403,24 @@ func (m *clusterOptionsModel) importFromOptionsAPI(
m.MigrationNetwork = types.StringNull()
}
if opts.NextID != nil {
m.NextID = &clusterOptionsNextIDModel{}
lower := int64(*opts.NextID.Lower)
upper := int64(*opts.NextID.Upper)
m.NextID.Lower = types.Int64PointerValue(&lower)
m.NextID.Upper = types.Int64PointerValue(&upper)
}
if opts.Notify != nil {
m.Notify = &clusterOptionsNotifyModel{}
m.Notify.HAFencingMode = types.StringPointerValue(opts.Notify.HAFencingMode)
m.Notify.HAFencingTarget = types.StringPointerValue(opts.Notify.HAFencingTarget)
m.Notify.PackageUpdates = types.StringPointerValue(opts.Notify.PackageUpdates)
m.Notify.PackageUpdatesTarget = types.StringPointerValue(opts.Notify.PackageUpdatesTarget)
m.Notify.Replication = types.StringPointerValue(opts.Notify.Replication)
m.Notify.ReplicationTarget = types.StringPointerValue(opts.Notify.ReplicationTarget)
}
if opts.ClusterResourceScheduling != nil {
m.CrsHARebalanceOnStart = types.BoolPointerValue(opts.ClusterResourceScheduling.HaRebalanceOnStart.PointerBool())
m.CrsHA = types.StringPointerValue(opts.ClusterResourceScheduling.HA)
@ -414,6 +550,108 @@ func (r *clusterOptionsResource) Schema(
Description: "Cluster wide migration network CIDR.",
Optional: true,
},
"next_id": schema.SingleNestedAttribute{
Attributes: map[string]schema.Attribute{
"lower": schema.Int64Attribute{
Description: "The minimum number for the next free VM ID.",
MarkdownDescription: "The minimum number for the next free VM ID. " +
fmt.Sprintf("Must be higher or equal to %d", ClusterOptionsNextIDLowerMinimum),
Optional: true,
Validators: []validator.Int64{
int64validator.AtLeast(ClusterOptionsNextIDLowerMinimum),
},
},
"upper": schema.Int64Attribute{
Description: "The maximum number for the next free VM ID.",
MarkdownDescription: "The maximum number for the next free VM ID. " +
fmt.Sprintf("Must be less or equal to %d", ClusterOptionsNextIDLowerMaximum),
Optional: true,
Validators: []validator.Int64{
int64validator.AtMost(ClusterOptionsNextIDLowerMaximum),
},
},
},
Description: "The ranges for the next free VM ID auto-selection pool.",
Optional: true,
},
"notify": schema.SingleNestedAttribute{
Attributes: map[string]schema.Attribute{
"ha_fencing_mode": schema.StringAttribute{
Description: "Cluster-wide notification settings for the HA fencing mode.",
MarkdownDescription: "Cluster-wide notification settings for the HA fencing mode. Must be `always` | `never`.",
Optional: true,
Validators: []validator.String{
stringvalidator.OneOf(
[]string{
"always",
"never",
}...,
),
},
},
"ha_fencing_target": schema.StringAttribute{
Description: "Cluster-wide notification settings for the HA fencing target.",
MarkdownDescription: "Cluster-wide notification settings for the HA fencing target.",
Optional: true,
Validators: []validator.String{
stringvalidator.UTF8LengthAtLeast(1),
stringvalidator.RegexMatches(regexp.MustCompile(`^\S|^$`), "must not start with whitespace"),
stringvalidator.RegexMatches(regexp.MustCompile(`\S$|^$`), "must not end with whitespace"),
},
},
"package_updates": schema.StringAttribute{
Description: "Cluster-wide notification settings for package updates.",
MarkdownDescription: "Cluster-wide notification settings for package updates. " +
"Must be `auto` | `always` | `never`. ",
Optional: true,
Validators: []validator.String{
stringvalidator.OneOf(
[]string{
"auto",
"always",
"never",
}...,
),
},
},
"package_updates_target": schema.StringAttribute{
Description: "Cluster-wide notification settings for the package updates target.",
MarkdownDescription: "Cluster-wide notification settings for the package updates target.",
Optional: true,
Validators: []validator.String{
stringvalidator.UTF8LengthAtLeast(1),
stringvalidator.RegexMatches(regexp.MustCompile(`^\S|^$`), "must not start with whitespace"),
stringvalidator.RegexMatches(regexp.MustCompile(`\S$|^$`), "must not end with whitespace"),
},
},
"replication": schema.StringAttribute{
Description: "Cluster-wide notification settings for replication.",
MarkdownDescription: "Cluster-wide notification settings for replication. " +
"Must be `always` | `never`. ",
Optional: true,
Validators: []validator.String{
stringvalidator.OneOf(
[]string{
"always",
"never",
}...,
),
},
},
"replication_target": schema.StringAttribute{
Description: "Cluster-wide notification settings for the replication target.",
MarkdownDescription: "Cluster-wide notification settings for the replication target.",
Optional: true,
Validators: []validator.String{
stringvalidator.UTF8LengthAtLeast(1),
stringvalidator.RegexMatches(regexp.MustCompile(`^\S|^$`), "must not start with whitespace"),
stringvalidator.RegexMatches(regexp.MustCompile(`\S$|^$`), "must not end with whitespace"),
},
},
},
Description: "Cluster-wide notification settings.",
Optional: true,
},
"crs_ha": schema.StringAttribute{
Description: "Cluster resource scheduling setting for HA.",
MarkdownDescription: "Cluster resource scheduling setting for HA. Must be `static` | `basic` (default is `basic`).",
@ -595,6 +833,14 @@ func (r *clusterOptionsResource) Update(
toDelete = append(toDelete, "migration")
}
if plan.nextIDData() != state.nextIDData() && plan.nextIDData() == "" {
toDelete = append(toDelete, "next-id")
}
if plan.notifyData() != state.notifyData() && plan.notifyData() == "" {
toDelete = append(toDelete, "notify")
}
if !plan.EmailFrom.Equal(state.EmailFrom) && plan.EmailFrom.ValueString() == "" {
toDelete = append(toDelete, "email_from")
}
@ -679,6 +925,14 @@ func (r *clusterOptionsResource) Delete(
toDelete = append(toDelete, "migration")
}
if state.nextIDData() != "" {
toDelete = append(toDelete, "next-id")
}
if state.notifyData() != "" {
toDelete = append(toDelete, "notify")
}
if !state.EmailFrom.IsNull() && state.EmailFrom.ValueString() != "" {
toDelete = append(toDelete, "email_from")
}

View File

@ -7,9 +7,12 @@
package tests
import (
"fmt"
"testing"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/bpg/terraform-provider-proxmox/fwprovider"
)
const accTestClusterOptionsName = "proxmox_virtual_environment_cluster_options.test_options"
@ -19,31 +22,34 @@ func TestAccResourceClusterOptions(t *testing.T) {
te := initTestEnvironment(t)
resource.Test(t, resource.TestCase{
ProtoV6ProviderFactories: te.accProviders,
Steps: []resource.TestStep{
// Create and Read testing
{
Config: testAccResourceClusterOptionsCreatedConfig(),
Check: testAccResourceClusterOptionsCreatedCheck(),
},
// ImportState testing
{
ResourceName: accTestClusterOptionsName,
ImportState: true,
ImportStateVerify: true,
},
// Update testing
{
Config: testAccResourceClusterOptionsUpdatedConfig(),
Check: testAccResourceClusterOptionsUpdatedCheck(),
resource.Test(
t, resource.TestCase{
ProtoV6ProviderFactories: te.accProviders,
Steps: []resource.TestStep{
// Create and Read testing
{
Config: testAccResourceClusterOptionsCreatedConfig(),
Check: testAccResourceClusterOptionsCreatedCheck(),
},
// ImportState testing
{
ResourceName: accTestClusterOptionsName,
ImportState: true,
ImportStateVerify: true,
},
// Update testing
{
Config: testAccResourceClusterOptionsUpdatedConfig(),
Check: testAccResourceClusterOptionsUpdatedCheck(),
},
},
},
})
)
}
func testAccResourceClusterOptionsCreatedConfig() string {
return `
return fmt.Sprintf(
`
resource "proxmox_virtual_environment_cluster_options" "test_options" {
bandwidth_limit_default = 666666
bandwidth_limit_migration = 555554
@ -56,9 +62,24 @@ func testAccResourceClusterOptionsCreatedConfig() string {
max_workers = 5
migration_cidr = "10.0.0.0/8"
migration_type = "secure"
bandwidth_limit_restore = 777777
bandwidth_limit_restore = 777777
next_id = {
lower = %d
upper = %d
}
notify = {
ha_fencing_mode = "never"
ha_fencing_target = "default-matcher"
package_updates = "always"
package_updates_target = "default-matcher"
replication = "always"
replication_target = "default-matcher"
}
}
`
`,
fwprovider.ClusterOptionsNextIDLowerMinimum,
fwprovider.ClusterOptionsNextIDLowerMaximum,
)
}
func testAccResourceClusterOptionsCreatedCheck() resource.TestCheckFunc {
@ -76,21 +97,49 @@ func testAccResourceClusterOptionsCreatedCheck() resource.TestCheckFunc {
resource.TestCheckResourceAttr(accTestClusterOptionsName, "max_workers", "5"),
resource.TestCheckResourceAttr(accTestClusterOptionsName, "migration_cidr", "10.0.0.0/8"),
resource.TestCheckResourceAttr(accTestClusterOptionsName, "migration_type", "secure"),
resource.TestCheckResourceAttr(
accTestClusterOptionsName,
"next_id.lower",
fmt.Sprintf("%d", fwprovider.ClusterOptionsNextIDLowerMinimum),
),
resource.TestCheckResourceAttr(
accTestClusterOptionsName,
"next_id.upper",
fmt.Sprintf("%d", fwprovider.ClusterOptionsNextIDLowerMaximum),
),
resource.TestCheckResourceAttr(accTestClusterOptionsName, "notify.ha_fencing_mode", "never"),
resource.TestCheckResourceAttr(accTestClusterOptionsName, "notify.ha_fencing_target", "default-matcher"),
resource.TestCheckResourceAttr(accTestClusterOptionsName, "notify.package_updates", "always"),
resource.TestCheckResourceAttr(accTestClusterOptionsName, "notify.package_updates_target", "default-matcher"),
resource.TestCheckResourceAttr(accTestClusterOptionsName, "notify.replication", "always"),
resource.TestCheckResourceAttr(accTestClusterOptionsName, "notify.replication_target", "default-matcher"),
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"
}
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"
next_id = {
lower = 555
upper = 666
}
notify = {
ha_fencing_mode = "always"
ha_fencing_target = "custom-matcher"
package_updates = "auto"
package_updates_target = "custom-matcher"
replication = "never"
replication_target = "custom-matcher"
}
}
`
}
@ -104,6 +153,14 @@ func testAccResourceClusterOptionsUpdatedCheck() resource.TestCheckFunc {
resource.TestCheckResourceAttr(accTestClusterOptionsName, "max_workers", "6"),
resource.TestCheckResourceAttr(accTestClusterOptionsName, "migration_cidr", "10.0.0.1/8"),
resource.TestCheckResourceAttr(accTestClusterOptionsName, "migration_type", "secure"),
resource.TestCheckResourceAttr(accTestClusterOptionsName, "next_id.lower", "555"),
resource.TestCheckResourceAttr(accTestClusterOptionsName, "next_id.upper", "666"),
resource.TestCheckResourceAttr(accTestClusterOptionsName, "notify.ha_fencing_mode", "always"),
resource.TestCheckResourceAttr(accTestClusterOptionsName, "notify.ha_fencing_target", "custom-matcher"),
resource.TestCheckResourceAttr(accTestClusterOptionsName, "notify.package_updates", "auto"),
resource.TestCheckResourceAttr(accTestClusterOptionsName, "notify.package_updates_target", "custom-matcher"),
resource.TestCheckResourceAttr(accTestClusterOptionsName, "notify.replication", "never"),
resource.TestCheckResourceAttr(accTestClusterOptionsName, "notify.replication_target", "custom-matcher"),
resource.TestCheckNoResourceAttr(accTestClusterOptionsName, "bandwidth_limit_move"),
resource.TestCheckNoResourceAttr(accTestClusterOptionsName, "crs_ha"),
resource.TestCheckNoResourceAttr(accTestClusterOptionsName, "ha_shutdown_policy"),

View File

@ -25,7 +25,12 @@ type crs struct {
HA *string `json:"ha,omitempty"`
}
type notify struct {
PackageUpdates *string `json:"package-updates,omitempty"`
HAFencingMode *string `json:"fencing,omitempty"`
HAFencingTarget *string `json:"target-fencing,omitempty"`
PackageUpdates *string `json:"package-updates,omitempty"`
PackageUpdatesTarget *string `json:"target-package-updates,omitempty"`
Replication *string `json:"replication,omitempty"`
ReplicationTarget *string `json:"target-replication,omitempty"`
}
type migration struct {
Network *string `json:"network,omitempty"`
@ -36,8 +41,8 @@ type haSettings struct {
ShutdownPolicy *string `json:"shutdown_policy,omitempty"`
}
type nextID struct {
Upper *string `json:"upper,omitempty"`
Lower *string `json:"lower,omitempty"`
Upper *types.CustomInt64 `json:"upper,omitempty"`
Lower *types.CustomInt64 `json:"lower,omitempty"`
}
type webauthn struct {
ID *string `json:"id,omitempty"`