mirror of
https://github.com/bpg/terraform-provider-proxmox.git
synced 2025-06-29 18:21:10 +00:00
feat(cluster): add cluster options resource (#548)
This commit is contained in:
parent
edec5bfd1c
commit
de8b4ec41a
@ -38,7 +38,7 @@ output "proxmox_virtual_environment_hagroups_full" {
|
||||
### Read-Only
|
||||
|
||||
- `comment` (String) The comment associated with this group
|
||||
- `id` (String) The ID of this resource.
|
||||
- `id` (String) The unique identifier of this resource.
|
||||
- `no_failback` (Boolean) A flag that indicates that failing back to a higher priority node is disabled for this HA group.
|
||||
- `nodes` (Map of Number) The member nodes for this group. They are provided as a map, where the keys are the node names and the values represent their priority: integers for known priorities or `null` for unset priorities.
|
||||
- `restricted` (Boolean) A flag that indicates that other nodes may not be used to run resources associated to this HA group.
|
||||
|
@ -27,4 +27,4 @@ output "data_proxmox_virtual_environment_hagroups" {
|
||||
### Read-Only
|
||||
|
||||
- `group_ids` (Set of String) The identifiers of the High Availability groups.
|
||||
- `id` (String) The ID of this resource.
|
||||
- `id` (String) The unique identifier of this resource.
|
||||
|
@ -39,7 +39,7 @@ output "proxmox_virtual_environment_haresources_full" {
|
||||
|
||||
- `comment` (String) The comment associated with this resource.
|
||||
- `group` (String) The identifier of the High Availability group this resource is a member of.
|
||||
- `id` (String) The ID of this resource.
|
||||
- `id` (String) The unique identifier of this resource.
|
||||
- `max_relocate` (Number) The maximal number of relocation attempts.
|
||||
- `max_restart` (Number) The maximal number of restart attempts.
|
||||
- `state` (String) The desired state of the resource.
|
||||
|
@ -39,5 +39,5 @@ output "data_proxmox_virtual_environment_haresources" {
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `id` (String) The ID of this resource.
|
||||
- `id` (String) The unique identifier of this resource.
|
||||
- `resource_ids` (Set of String) The identifiers of the High Availability resources.
|
||||
|
65
docs/resources/virtual_environment_cluster_options.md
Normal file
65
docs/resources/virtual_environment_cluster_options.md
Normal file
@ -0,0 +1,65 @@
|
||||
---
|
||||
layout: page
|
||||
title: proxmox_virtual_environment_cluster_options
|
||||
parent: Resources
|
||||
subcategory: Virtual Environment
|
||||
description: |-
|
||||
Manages Proxmox VE Cluster Datacenter options.
|
||||
---
|
||||
|
||||
# Resource: proxmox_virtual_environment_cluster_options
|
||||
|
||||
Manages Proxmox VE Cluster Datacenter options.
|
||||
|
||||
## Example Usage
|
||||
|
||||
```terraform
|
||||
resource "proxmox_virtual_environment_cluster_options" "options" {
|
||||
language = "en"
|
||||
keyboard = "pl"
|
||||
email_from = "ged@gont.earthsea"
|
||||
bandwidth_limit_migration = 555555
|
||||
bandwidth_limit_default = 666666
|
||||
max_workers = 5
|
||||
migration_cidr = "10.0.0.0/8"
|
||||
migration_type = "secure"
|
||||
}
|
||||
```
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Optional
|
||||
|
||||
- `bandwidth_limit_clone` (Number) Clone I/O bandwidth limit in KiB/s.
|
||||
- `bandwidth_limit_default` (Number) Default I/O bandwidth limit in KiB/s.
|
||||
- `bandwidth_limit_migration` (Number) Migration I/O bandwidth limit in KiB/s.
|
||||
- `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_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`.
|
||||
- `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`.
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `id` (String) The unique identifier of this resource.
|
||||
|
||||
## Import
|
||||
|
||||
Import is supported using the following syntax:
|
||||
|
||||
```shell
|
||||
#!/usr/bin/env sh
|
||||
# Cluster options are global and can be imported using e.g.:
|
||||
terraform import proxmox_virtual_environment_cluster_options.options cluster
|
||||
```
|
@ -46,7 +46,7 @@ resource "proxmox_virtual_environment_hagroup" "example" {
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `id` (String) The ID of this resource.
|
||||
- `id` (String) The unique identifier of this resource.
|
||||
|
||||
## Import
|
||||
|
||||
|
@ -43,7 +43,7 @@ resource "proxmox_virtual_environment_haresource" "example" {
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `id` (String) The ID of this resource.
|
||||
- `id` (String) The unique identifier of this resource.
|
||||
|
||||
## Import
|
||||
|
||||
|
10
example/resource_virtual_environment_cluster_options.tf
Normal file
10
example/resource_virtual_environment_cluster_options.tf
Normal file
@ -0,0 +1,10 @@
|
||||
resource "proxmox_virtual_environment_cluster_options" "options" {
|
||||
language = "en"
|
||||
keyboard = "pl"
|
||||
email_from = "ged@gont.earthsea"
|
||||
bandwidth_limit_migration = 555555
|
||||
bandwidth_limit_default = 666666
|
||||
max_workers = 5
|
||||
migration_cidr = "10.0.0.0/8"
|
||||
migration_type = "secure"
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
#!/usr/bin/env sh
|
||||
# Cluster options are global and can be imported using e.g.:
|
||||
terraform import proxmox_virtual_environment_cluster_options.options cluster
|
@ -0,0 +1,10 @@
|
||||
resource "proxmox_virtual_environment_cluster_options" "options" {
|
||||
language = "en"
|
||||
keyboard = "pl"
|
||||
email_from = "ged@gont.earthsea"
|
||||
bandwidth_limit_migration = 555555
|
||||
bandwidth_limit_default = 666666
|
||||
max_workers = 5
|
||||
migration_cidr = "10.0.0.0/8"
|
||||
migration_type = "secure"
|
||||
}
|
663
internal/cluster/resource_options.go
Normal file
663
internal/cluster/resource_options.go
Normal file
@ -0,0 +1,663 @@
|
||||
/*
|
||||
* 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 cluster
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
|
||||
"github.com/hashicorp/terraform-plugin-framework/diag"
|
||||
"github.com/hashicorp/terraform-plugin-framework/resource"
|
||||
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
|
||||
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||
|
||||
"github.com/bpg/terraform-provider-proxmox/internal/structure"
|
||||
"github.com/bpg/terraform-provider-proxmox/internal/validators"
|
||||
"github.com/bpg/terraform-provider-proxmox/proxmox"
|
||||
"github.com/bpg/terraform-provider-proxmox/proxmox/cluster"
|
||||
)
|
||||
|
||||
var (
|
||||
_ resource.Resource = &clusterOptionsResource{}
|
||||
_ resource.ResourceWithConfigure = &clusterOptionsResource{}
|
||||
_ resource.ResourceWithImportState = &clusterOptionsResource{}
|
||||
)
|
||||
|
||||
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"`
|
||||
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"`
|
||||
EmailFrom types.String `tfsdk:"email_from"`
|
||||
Keyboard types.String `tfsdk:"keyboard"`
|
||||
Language types.String `tfsdk:"language"`
|
||||
MaxWorkers types.Int64 `tfsdk:"max_workers"`
|
||||
}
|
||||
|
||||
func (m *clusterOptionsModel) haData() *string {
|
||||
var haDataParams []string
|
||||
|
||||
if !m.HAShutdownPolicy.IsNull() && m.HAShutdownPolicy.ValueString() != "" {
|
||||
haDataParams = append(haDataParams, fmt.Sprintf("shutdown_policy=%s", m.HAShutdownPolicy.ValueString()))
|
||||
}
|
||||
|
||||
if len(haDataParams) > 0 {
|
||||
haDataValue := strings.Join(haDataParams, ",")
|
||||
|
||||
return &haDataValue
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *clusterOptionsModel) migrationData() *string {
|
||||
var migrationDataParams []string
|
||||
|
||||
if !m.MigrationType.IsNull() && m.MigrationType.ValueString() != "" {
|
||||
migrationDataParams = append(migrationDataParams, fmt.Sprintf("type=%s", m.MigrationType.ValueString()))
|
||||
}
|
||||
|
||||
if !m.MigrationNetwork.IsNull() && m.MigrationNetwork.ValueString() != "" {
|
||||
migrationDataParams = append(migrationDataParams, fmt.Sprintf("network=%s", m.MigrationNetwork.ValueString()))
|
||||
}
|
||||
|
||||
if len(migrationDataParams) > 0 {
|
||||
migrationDataValue := strings.Join(migrationDataParams, ",")
|
||||
|
||||
return &migrationDataValue
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *clusterOptionsModel) crsData() *string {
|
||||
var crsDataParams []string
|
||||
|
||||
if !m.CrsHA.IsNull() && m.CrsHA.ValueString() != "" {
|
||||
crsDataParams = append(crsDataParams, fmt.Sprintf("ha=%s", m.CrsHA.ValueString()))
|
||||
}
|
||||
|
||||
if !m.CrsHARebalanceOnStart.IsNull() {
|
||||
var haRebalanceOnStart string
|
||||
if m.CrsHARebalanceOnStart.ValueBool() {
|
||||
haRebalanceOnStart = "1"
|
||||
} else {
|
||||
haRebalanceOnStart = "0"
|
||||
}
|
||||
|
||||
crsDataParams = append(crsDataParams, fmt.Sprintf("ha-rebalance-on-start=%s", haRebalanceOnStart))
|
||||
}
|
||||
|
||||
if len(crsDataParams) > 0 {
|
||||
crsDataValue := strings.Join(crsDataParams, ",")
|
||||
|
||||
return &crsDataValue
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *clusterOptionsModel) bandwidthData() *string {
|
||||
var bandwidthParams []string
|
||||
|
||||
if !m.BandwidthLimitClone.IsNull() && m.BandwidthLimitClone.ValueInt64() != 0 {
|
||||
bandwidthParams = append(bandwidthParams, fmt.Sprintf("clone=%d", m.BandwidthLimitClone.ValueInt64()))
|
||||
}
|
||||
|
||||
if !m.BandwidthLimitDefault.IsNull() && m.BandwidthLimitDefault.ValueInt64() != 0 {
|
||||
bandwidthParams = append(bandwidthParams, fmt.Sprintf("default=%d", m.BandwidthLimitDefault.ValueInt64()))
|
||||
}
|
||||
|
||||
if !m.BandwidthLimitMigration.IsNull() && m.BandwidthLimitMigration.ValueInt64() != 0 {
|
||||
bandwidthParams = append(bandwidthParams, fmt.Sprintf("migration=%d", m.BandwidthLimitMigration.ValueInt64()))
|
||||
}
|
||||
|
||||
if !m.BandwidthLimitMove.IsNull() && m.BandwidthLimitMove.ValueInt64() != 0 {
|
||||
bandwidthParams = append(bandwidthParams, fmt.Sprintf("move=%d", m.BandwidthLimitMove.ValueInt64()))
|
||||
}
|
||||
|
||||
if !m.BandwidthLimitRestore.IsNull() && m.BandwidthLimitRestore.ValueInt64() != 0 {
|
||||
bandwidthParams = append(bandwidthParams, fmt.Sprintf("restore=%d", m.BandwidthLimitRestore.ValueInt64()))
|
||||
}
|
||||
|
||||
if len(bandwidthParams) > 0 {
|
||||
bandwithDataValue := strings.Join(bandwidthParams, ",")
|
||||
|
||||
return &bandwithDataValue
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *clusterOptionsModel) toOptionsRequestBody() *cluster.OptionsRequestData {
|
||||
body := &cluster.OptionsRequestData{}
|
||||
|
||||
if !m.EmailFrom.IsUnknown() {
|
||||
body.EmailFrom = m.EmailFrom.ValueStringPointer()
|
||||
}
|
||||
|
||||
if !m.Keyboard.IsUnknown() {
|
||||
body.Keyboard = m.Keyboard.ValueStringPointer()
|
||||
}
|
||||
|
||||
if !m.Language.IsUnknown() {
|
||||
body.Language = m.Language.ValueStringPointer()
|
||||
}
|
||||
|
||||
if !m.MaxWorkers.IsUnknown() {
|
||||
body.MaxWorkers = m.MaxWorkers.ValueInt64Pointer()
|
||||
}
|
||||
|
||||
if !m.Console.IsUnknown() {
|
||||
body.Console = m.Console.ValueStringPointer()
|
||||
}
|
||||
|
||||
if !m.HTTPProxy.IsUnknown() {
|
||||
body.HTTPProxy = m.HTTPProxy.ValueStringPointer()
|
||||
}
|
||||
|
||||
if !m.MacPrefix.IsUnknown() {
|
||||
body.MacPrefix = m.MacPrefix.ValueStringPointer()
|
||||
}
|
||||
|
||||
if !m.MacPrefix.IsUnknown() {
|
||||
body.Description = m.Description.ValueStringPointer()
|
||||
}
|
||||
|
||||
body.HASettings = m.haData()
|
||||
body.BandwidthLimit = m.bandwidthData()
|
||||
body.ClusterResourceScheduling = m.crsData()
|
||||
body.Migration = m.migrationData()
|
||||
|
||||
return body
|
||||
}
|
||||
|
||||
func (m *clusterOptionsModel) importFromOptionsAPI(
|
||||
_ context.Context,
|
||||
iface *cluster.OptionsResponseData,
|
||||
) error {
|
||||
m.BandwidthLimitClone = types.Int64Null()
|
||||
m.BandwidthLimitDefault = types.Int64Null()
|
||||
m.BandwidthLimitMigration = types.Int64Null()
|
||||
m.BandwidthLimitMove = types.Int64Null()
|
||||
m.BandwidthLimitRestore = types.Int64Null()
|
||||
|
||||
//nolint:nestif
|
||||
if iface.BandwidthLimit != nil {
|
||||
for _, bandwidth := range strings.Split(*iface.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)
|
||||
}
|
||||
|
||||
if bandwidthName == "clone" {
|
||||
m.BandwidthLimitClone = types.Int64Value(bandwidthLimit)
|
||||
}
|
||||
|
||||
if bandwidthName == "default" {
|
||||
m.BandwidthLimitDefault = types.Int64Value(bandwidthLimit)
|
||||
}
|
||||
|
||||
if bandwidthName == "migration" {
|
||||
m.BandwidthLimitMigration = types.Int64Value(bandwidthLimit)
|
||||
}
|
||||
|
||||
if bandwidthName == "move" {
|
||||
m.BandwidthLimitMove = types.Int64Value(bandwidthLimit)
|
||||
}
|
||||
|
||||
if bandwidthName == "restore" {
|
||||
m.BandwidthLimitRestore = types.Int64Value(bandwidthLimit)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m.EmailFrom = types.StringPointerValue(iface.EmailFrom)
|
||||
m.Keyboard = types.StringPointerValue(iface.Keyboard)
|
||||
m.Language = types.StringPointerValue(iface.Language)
|
||||
|
||||
if iface.MaxWorkers != nil {
|
||||
m.MaxWorkers = types.Int64Value(int64(*iface.MaxWorkers))
|
||||
}
|
||||
|
||||
m.Console = types.StringPointerValue(iface.Console)
|
||||
m.HTTPProxy = types.StringPointerValue(iface.HTTPProxy)
|
||||
m.MacPrefix = types.StringPointerValue(iface.MacPrefix)
|
||||
m.Description = types.StringPointerValue(iface.Description)
|
||||
|
||||
if iface.HASettings != nil {
|
||||
m.HAShutdownPolicy = types.StringPointerValue(iface.HASettings.ShutdownPolicy)
|
||||
} else {
|
||||
m.HAShutdownPolicy = types.StringPointerValue(nil)
|
||||
}
|
||||
|
||||
if iface.Migration != nil {
|
||||
m.MigrationType = types.StringPointerValue(iface.Migration.Type)
|
||||
m.MigrationNetwork = types.StringPointerValue(iface.Migration.Network)
|
||||
} else {
|
||||
m.MigrationType = types.StringPointerValue(nil)
|
||||
m.MigrationNetwork = types.StringPointerValue(nil)
|
||||
}
|
||||
|
||||
if iface.ClusterResourceScheduling != nil {
|
||||
m.CrsHARebalanceOnStart = types.BoolValue(bool(*iface.ClusterResourceScheduling.HaRebalanceOnStart))
|
||||
m.CrsHA = types.StringPointerValue(iface.ClusterResourceScheduling.HA)
|
||||
} else {
|
||||
m.CrsHARebalanceOnStart = types.BoolPointerValue(nil)
|
||||
m.CrsHA = types.StringPointerValue(nil)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewClusterOptionsResource manages cluster options resource.
|
||||
func NewClusterOptionsResource() resource.Resource {
|
||||
return &clusterOptionsResource{}
|
||||
}
|
||||
|
||||
type clusterOptionsResource struct {
|
||||
client proxmox.Client
|
||||
}
|
||||
|
||||
func (r *clusterOptionsResource) Metadata(
|
||||
_ context.Context,
|
||||
req resource.MetadataRequest,
|
||||
resp *resource.MetadataResponse,
|
||||
) {
|
||||
resp.TypeName = req.ProviderTypeName + "_cluster_options"
|
||||
}
|
||||
|
||||
// Schema defines the schema for the resource.
|
||||
func (r *clusterOptionsResource) Schema(
|
||||
_ context.Context,
|
||||
_ resource.SchemaRequest,
|
||||
resp *resource.SchemaResponse,
|
||||
) {
|
||||
resp.Schema = schema.Schema{
|
||||
Description: "Manages Proxmox VE Cluster Datacenter options.",
|
||||
Attributes: map[string]schema.Attribute{
|
||||
"id": structure.IDAttribute(),
|
||||
"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.",
|
||||
MarkdownDescription: "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`.",
|
||||
Optional: true,
|
||||
Computed: 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()},
|
||||
},
|
||||
"console": schema.StringAttribute{
|
||||
Description: "Select the default Console viewer.",
|
||||
MarkdownDescription: "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.",
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Validators: []validator.String{stringvalidator.OneOf([]string{
|
||||
"applet",
|
||||
"vv",
|
||||
"html5",
|
||||
"xtermjs",
|
||||
}...)},
|
||||
},
|
||||
"http_proxy": schema.StringAttribute{
|
||||
Description: "Specify external http proxy which is used for downloads.",
|
||||
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`.",
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Validators: []validator.String{stringvalidator.OneOf([]string{
|
||||
"freeze",
|
||||
"failover",
|
||||
"migrate",
|
||||
"conditional",
|
||||
}...)},
|
||||
},
|
||||
"migration_type": schema.StringAttribute{
|
||||
Description: "Cluster wide migration type.",
|
||||
MarkdownDescription: "Cluster wide migration type. Must be `secure` | `unsecure`.",
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Validators: []validator.String{stringvalidator.OneOf([]string{
|
||||
"secure",
|
||||
"unsecure",
|
||||
}...)},
|
||||
},
|
||||
"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`.",
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Validators: []validator.String{stringvalidator.OneOf([]string{
|
||||
"static",
|
||||
"basic",
|
||||
}...)},
|
||||
},
|
||||
"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,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (r *clusterOptionsResource) Configure(
|
||||
_ context.Context,
|
||||
req resource.ConfigureRequest,
|
||||
resp *resource.ConfigureResponse,
|
||||
) {
|
||||
if req.ProviderData == nil {
|
||||
return
|
||||
}
|
||||
|
||||
client, ok := req.ProviderData.(proxmox.Client)
|
||||
|
||||
if !ok {
|
||||
resp.Diagnostics.AddError(
|
||||
"Unexpected Resource Configure Type",
|
||||
fmt.Sprintf("Expected *proxmox.Client, got: %T. Please report this issue to the provider developers.",
|
||||
req.ProviderData),
|
||||
)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
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) {
|
||||
var plan clusterOptionsModel
|
||||
diags := req.Plan.Get(ctx, &plan)
|
||||
resp.Diagnostics.Append(diags...)
|
||||
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
body := plan.toOptionsRequestBody()
|
||||
|
||||
err := r.client.Cluster().CreateUpdateOptions(ctx, body)
|
||||
if err != nil {
|
||||
resp.Diagnostics.AddError(
|
||||
"Error creating cluster options interface",
|
||||
"Could not create cluster options, unexpected error: "+err.Error(),
|
||||
)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
plan.ID = types.StringValue("cluster")
|
||||
|
||||
r.read(ctx, &plan, &resp.Diagnostics)
|
||||
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
resp.State.Set(ctx, plan)
|
||||
resp.Diagnostics.Append(diags...)
|
||||
}
|
||||
|
||||
func (r *clusterOptionsResource) read(ctx context.Context, model *clusterOptionsModel, diags *diag.Diagnostics) {
|
||||
options, err := r.client.Cluster().GetOptions(ctx)
|
||||
if err != nil {
|
||||
diags.AddError(
|
||||
"Error get cluster options",
|
||||
"Could not get cluster options, unexpected error: "+err.Error(),
|
||||
)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
err = model.importFromOptionsAPI(ctx, options)
|
||||
|
||||
if err != nil {
|
||||
diags.AddError(
|
||||
"Error converting cluster options interface to a model",
|
||||
"Could not import cluster options from API response, unexpected error: "+err.Error(),
|
||||
)
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Read reads a cluster options interface.
|
||||
func (r *clusterOptionsResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
|
||||
// Get current state
|
||||
var state clusterOptionsModel
|
||||
diags := req.State.Get(ctx, &state)
|
||||
resp.Diagnostics.Append(diags...)
|
||||
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
r.read(ctx, &state, &resp.Diagnostics)
|
||||
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
diags = resp.State.Set(ctx, state)
|
||||
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) {
|
||||
var plan, state clusterOptionsModel
|
||||
|
||||
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
|
||||
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
|
||||
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
body := plan.toOptionsRequestBody()
|
||||
|
||||
var toDelete []string
|
||||
|
||||
if !plan.Keyboard.Equal(state.Keyboard) && plan.Keyboard.ValueString() == "" {
|
||||
toDelete = append(toDelete, "keyboard")
|
||||
}
|
||||
|
||||
if (plan.bandwidthData() == nil && state.bandwidthData() != nil) || (*plan.bandwidthData() != *state.bandwidthData() && *plan.bandwidthData() == "") {
|
||||
toDelete = append(toDelete, "bwlimit")
|
||||
}
|
||||
|
||||
if (plan.crsData() == nil && state.crsData() != nil) || (*plan.crsData() != *state.crsData() && *plan.crsData() == "") {
|
||||
toDelete = append(toDelete, "crs")
|
||||
}
|
||||
|
||||
if (plan.haData() == nil && state.haData() != nil) || (*plan.haData() != *state.haData() && *plan.haData() == "") {
|
||||
toDelete = append(toDelete, "ha")
|
||||
}
|
||||
|
||||
if (plan.migrationData() == nil && state.migrationData() != nil) || (*plan.migrationData() != *state.migrationData() && *plan.migrationData() == "") {
|
||||
toDelete = append(toDelete, "migration")
|
||||
}
|
||||
|
||||
if !plan.EmailFrom.Equal(state.EmailFrom) && plan.EmailFrom.ValueString() == "" {
|
||||
toDelete = append(toDelete, "email_from")
|
||||
}
|
||||
|
||||
if !plan.Language.Equal(state.Language) && plan.Language.ValueString() == "" {
|
||||
toDelete = append(toDelete, "language")
|
||||
}
|
||||
|
||||
if !plan.Console.Equal(state.Console) && plan.Console.ValueString() == "" {
|
||||
toDelete = append(toDelete, "console")
|
||||
}
|
||||
|
||||
if !plan.HTTPProxy.Equal(state.HTTPProxy) && plan.HTTPProxy.ValueString() == "" {
|
||||
toDelete = append(toDelete, "http_proxy")
|
||||
}
|
||||
|
||||
if !plan.MacPrefix.Equal(state.MacPrefix) && plan.MacPrefix.ValueString() == "" {
|
||||
toDelete = append(toDelete, "mac_prefix")
|
||||
}
|
||||
|
||||
if !plan.Description.Equal(state.Description) && plan.Description.ValueString() == "" {
|
||||
toDelete = append(toDelete, "description")
|
||||
}
|
||||
|
||||
if !plan.MaxWorkers.Equal(state.MaxWorkers) && plan.MaxWorkers.ValueInt64() == 0 {
|
||||
toDelete = append(toDelete, "max_workers")
|
||||
}
|
||||
|
||||
if len(toDelete) > 0 {
|
||||
d := strings.Join(toDelete, ",")
|
||||
body.Delete = &d
|
||||
}
|
||||
|
||||
err := r.client.Cluster().CreateUpdateOptions(ctx, body)
|
||||
if err != nil {
|
||||
resp.Diagnostics.AddError(
|
||||
"Error updating cluster options interface",
|
||||
"Could not update cluster options, unexpected error: "+err.Error(),
|
||||
)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
r.read(ctx, &plan, &resp.Diagnostics)
|
||||
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
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) {
|
||||
var state clusterOptionsModel
|
||||
diags := req.State.Get(ctx, &state)
|
||||
resp.Diagnostics.Append(diags...)
|
||||
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Imports a cluster options interface.
|
||||
func (r *clusterOptionsResource) ImportState(
|
||||
ctx context.Context,
|
||||
req resource.ImportStateRequest,
|
||||
resp *resource.ImportStateResponse,
|
||||
) {
|
||||
state := clusterOptionsModel{ID: types.StringValue(req.ID)}
|
||||
r.read(ctx, &state, &resp.Diagnostics)
|
||||
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
diags := resp.State.Set(ctx, state)
|
||||
resp.Diagnostics.Append(diags...)
|
||||
}
|
@ -367,6 +367,7 @@ func (p *proxmoxProvider) Resources(_ context.Context) []func() resource.Resourc
|
||||
return []func() resource.Resource{
|
||||
cluster.NewHAGroupResource,
|
||||
cluster.NewHAResourceResource,
|
||||
cluster.NewClusterOptionsResource,
|
||||
network.NewLinuxBridgeResource,
|
||||
network.NewLinuxVLANResource,
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ func IDAttribute(desc ...string) schema.StringAttribute {
|
||||
PlanModifiers: []planmodifier.String{
|
||||
stringplanmodifier.UseStateForUnknown(),
|
||||
},
|
||||
Description: "The unique identifier for the resource.",
|
||||
Description: "The unique identifier of this resource.",
|
||||
}
|
||||
|
||||
if len(desc) > 0 {
|
||||
|
97
internal/test/cluster/cluster_options_test.go
Normal file
97
internal/test/cluster/cluster_options_test.go
Normal file
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* 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 cluster
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/bpg/terraform-provider-proxmox/internal/test"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
|
||||
)
|
||||
|
||||
func TestClusterOptionsResource(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
accProviders := test.AccMuxProviders(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: test.ProviderConfig + `
|
||||
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"),
|
||||
),
|
||||
},
|
||||
// ImportState testing
|
||||
{
|
||||
ResourceName: resourceName,
|
||||
ImportState: true,
|
||||
ImportStateVerify: true,
|
||||
},
|
||||
// Update testing
|
||||
{
|
||||
Config: test.ProviderConfig + `
|
||||
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"),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
28
internal/validators/i18n.go
Normal file
28
internal/validators/i18n.go
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 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 validators
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
|
||||
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
||||
)
|
||||
|
||||
// LanguageValidator returns a new validator for language codes.
|
||||
func LanguageValidator() validator.String {
|
||||
return stringvalidator.OneOf([]string{
|
||||
`ca`, `da`, `de`, `en`, `es`, `eu`, `fa`, `fr`, `he`, `it`, `ja`, `nb`,
|
||||
`nn`, `pl`, `pt_BR`, `ru`, `sl`, `sv`, `tr`, `zh_CN`, `zh_TW`,
|
||||
}...)
|
||||
}
|
||||
|
||||
// KeyboardLayoutValidator returns a new validator for keyboard layouts.
|
||||
func KeyboardLayoutValidator() validator.String {
|
||||
return stringvalidator.OneOf([]string{
|
||||
`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`,
|
||||
}...)
|
||||
}
|
41
proxmox/cluster/options.go
Normal file
41
proxmox/cluster/options.go
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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 cluster
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/bpg/terraform-provider-proxmox/proxmox/api"
|
||||
)
|
||||
|
||||
// GetOptions retrieves the cluster options.
|
||||
func (c *Client) GetOptions(ctx context.Context) (*OptionsResponseData, error) {
|
||||
resBody := &OptionsResponseBody{}
|
||||
|
||||
err := c.DoRequest(ctx, http.MethodGet, c.ExpandPath("options"), nil, resBody)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error reading Cluster options: %w", err)
|
||||
}
|
||||
|
||||
if resBody.Data == nil {
|
||||
return nil, api.ErrNoDataObjectInResponse
|
||||
}
|
||||
|
||||
return resBody.Data, nil
|
||||
}
|
||||
|
||||
// CreateUpdateOptions updates the cluster options.
|
||||
func (c *Client) CreateUpdateOptions(ctx context.Context, data *OptionsRequestData) error {
|
||||
err := c.DoRequest(ctx, http.MethodPut, c.ExpandPath("options"), data, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error updating Cluster resource: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
92
proxmox/cluster/options_types.go
Normal file
92
proxmox/cluster/options_types.go
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* 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 cluster
|
||||
|
||||
import (
|
||||
"github.com/bpg/terraform-provider-proxmox/proxmox/types"
|
||||
)
|
||||
|
||||
type userTagAccess struct {
|
||||
UserAllowList *[]string `json:"user-allow-list,omitempty"`
|
||||
UserAllow *string `json:"user-allow,omitempty"`
|
||||
}
|
||||
type tagStyle struct {
|
||||
Shape *string `json:"shape,omitempty"`
|
||||
CaseSensitive *types.CustomBool `json:"case-sensitive,omitempty"`
|
||||
Ordering *string `json:"ordering,omitempty"`
|
||||
ColorMap *string `json:"color-map,omitempty"`
|
||||
}
|
||||
type crs struct {
|
||||
HaRebalanceOnStart *types.CustomBool `json:"ha-rebalance-on-start,omitempty"`
|
||||
HA *string `json:"ha,omitempty"`
|
||||
}
|
||||
type notify struct {
|
||||
PackageUpdates *string `json:"package-updates,omitempty"`
|
||||
}
|
||||
type migration struct {
|
||||
Network *string `json:"network,omitempty"`
|
||||
Type *string `json:"type,omitempty"`
|
||||
}
|
||||
|
||||
type haSettings struct {
|
||||
ShutdownPolicy *string `json:"shutdown_policy,omitempty"`
|
||||
}
|
||||
type nextID struct {
|
||||
Upper *string `json:"upper,omitempty"`
|
||||
Lower *string `json:"lower,omitempty"`
|
||||
}
|
||||
type webauthn struct {
|
||||
ID *string `json:"id,omitempty"`
|
||||
Origin *string `json:"origin,omitempty"`
|
||||
RP *string `json:"rp,omitempty"`
|
||||
}
|
||||
type optionsBaseData struct {
|
||||
BandwidthLimit *string `json:"bwlimit,omitempty" url:"bwlimit,omitempty"`
|
||||
EmailFrom *string `json:"email_from,omitempty" url:"email_from,omitempty"`
|
||||
Description *string `json:"description,omitempty" url:"description,omitempty"`
|
||||
Console *string `json:"console,omitempty" url:"console,omitempty"`
|
||||
HTTPProxy *string `json:"http_proxy,omitempty" url:"http_proxy,omitempty"`
|
||||
MacPrefix *string `json:"mac_prefix,omitempty" url:"mac_prefix,omitempty"`
|
||||
Keyboard *string `json:"keyboard,omitempty" url:"keyboard,omitempty"`
|
||||
Language *string `json:"language,omitempty" url:"language,omitempty"`
|
||||
}
|
||||
|
||||
// OptionsResponseBody contains the body from a cluster options response.
|
||||
type OptionsResponseBody struct {
|
||||
Data *OptionsResponseData `json:"data,omitempty"`
|
||||
}
|
||||
|
||||
// OptionsResponseData contains the data from a cluster options response.
|
||||
type OptionsResponseData struct {
|
||||
optionsBaseData
|
||||
MaxWorkers *types.CustomInt `json:"max_workers,omitempty"`
|
||||
ClusterResourceScheduling *crs `json:"crs,omitempty"`
|
||||
HASettings *haSettings `json:"ha,omitempty"`
|
||||
TagStyle *tagStyle `json:"tag-style,omitempty"`
|
||||
Migration *migration `json:"migration,omitempty"`
|
||||
Webauthn *webauthn `json:"webauthn,omitempty"`
|
||||
NextID *nextID `json:"next-id,omitempty"`
|
||||
Notify *notify `json:"notify,omitempty"`
|
||||
UserTagAccess *userTagAccess `json:"user-tag-access,omitempty"`
|
||||
RegisteredTags *[]string `json:"registered-tags,omitempty"`
|
||||
}
|
||||
|
||||
// OptionsRequestData contains the body for cluster options request.
|
||||
type OptionsRequestData struct {
|
||||
optionsBaseData
|
||||
MaxWorkers *int64 `json:"max_workers,omitempty" url:"max_workers,omitempty"`
|
||||
Delete *string `json:"delete,omitempty" url:"delete,omitempty"`
|
||||
ClusterResourceScheduling *string `json:"crs,omitempty" url:"crs,omitempty"`
|
||||
HASettings *string `json:"ha,omitempty" url:"ha,omitempty"`
|
||||
TagStyle *string `json:"tag-style,omitempty" url:"tag-style,omitempty"`
|
||||
Migration *string `json:"migration,omitempty" url:"migration,omitempty"`
|
||||
Webauthn *string `json:"webauthn,omitempty" url:"webauthn,omitempty"`
|
||||
NextID *string `json:"next-id,omitempty" url:"next-id,omitempty"`
|
||||
Notify *string `json:"notify,omitempty" url:"notify,omitempty"`
|
||||
UserTagAccess *string `json:"user-tag-access,omitempty" url:"user-tag-access,omitempty"`
|
||||
RegisteredTags *string `json:"registered-tags,omitempty" url:"registered-tags,omitempty"`
|
||||
}
|
@ -1,12 +1,12 @@
|
||||
//go:build tools
|
||||
// +build tools
|
||||
|
||||
/*
|
||||
* 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/.
|
||||
*/
|
||||
|
||||
//go:build tools
|
||||
// +build tools
|
||||
|
||||
package tools
|
||||
|
||||
// Manage tool dependencies via go.mod.
|
||||
@ -37,3 +37,4 @@ import (
|
||||
//go:generate cp ../build/docs-gen/resources/virtual_environment_network_linux_vlan.md ../docs/resources/
|
||||
//go:generate cp ../build/docs-gen/resources/virtual_environment_hagroup.md ../docs/resources/
|
||||
//go:generate cp ../build/docs-gen/resources/virtual_environment_haresource.md ../docs/resources/
|
||||
//go:generate cp ../build/docs-gen/resources/virtual_environment_cluster_options.md ../docs/resources/
|
||||
|
Loading…
Reference in New Issue
Block a user