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

feat: Add firewall resources (#246)

* refactoring existing cluster / firewall API for better composition

* add basic security groups API
fix linter errors

* add rules API

* fix after renaming resourceVirtualEnvironmentClusterIPSet

* fix linter errors

* make linter happy

* even more refactoring

* tidy up datasources

* in refactoring spree

* update examples

* fix firewall resource/datasource & client error handling

* add ipset(s) datasource

* update docs

* add security group resource with rules

* docs

* fix security group update, TODO: rule update

* fix after rebase

* add rule update, extract common rule schema, refactor group

* fix linter  errors

* bump linter for ci

* make alias and ipset reusable

* make security group reusable

* refactor datasources

* add security group datasources

* fix linter errors

* update docs

TODO: documentation for group datasources

* add sg docs, update doc index

* minor cleanup

* fix examples & tests

* stub for firewall-level options and rules

* extract firewall interface

* add firewall options and rules on the cluster level

TODO: issues with rule list management

* refactor all resources format AGAIN, now more flat, without complex subresources

* sort out hierarchy of APIs and remove duplication in API wrappers

* bring back security group

* finally, working rules

* restore cluster firewall option

* add containers support

* add options

* move rules back under security group, update docs

* fix vm_id / container_id attrs

* add examples

* cleanup

* more cleanup


Release-As: 0.17.0-rc1
This commit is contained in:
Pavel Boldyrev 2023-04-02 18:01:10 -04:00 committed by GitHub
parent 960af3ab89
commit 98e1cff7fe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
209 changed files with 7301 additions and 3905 deletions

View File

@ -1,4 +1,4 @@
# v1.50.1
# v1.51.2
run:
deadline: 5m
issues:
@ -47,35 +47,31 @@ linters:
enable-all: true
disable:
# deprecated
- gocyclo
- interfacer
- scopelint
- maligned
- golint
- deadcode
- gocyclo
- golint
- ifshort
- varcheck
- interfacer
- maligned
- rowserrcheck
- scopelint
- structcheck
- varcheck
- wastedassign
# require massive refactoring
- cyclop
- forcetypeassert
- govet
- funlen
- gocognit
- cyclop
#
- containedctx
- decorder
- execinquery
- govet
# others
- exhaustivestruct
- exhaustruct
- gci
- gochecknoinits
- godot
- godox
- goerr113
- goheader
- gomnd
- gomodguard
- grouper
- ireturn
- maintidx

View File

@ -1,12 +1,11 @@
GEM
remote: https://rubygems.org/
specs:
activesupport (6.1.7.3)
activesupport (7.0.4.2)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 1.6, < 2)
minitest (>= 5.1)
tzinfo (~> 2.0)
zeitwerk (~> 2.3)
addressable (2.8.1)
public_suffix (>= 2.0.2, < 6.0)
coffee-script (2.4.1)
@ -14,7 +13,7 @@ GEM
execjs
coffee-script-source (1.11.1)
colorator (1.1.0)
commonmarker (0.23.7)
commonmarker (0.23.8)
concurrent-ruby (1.2.2)
dnsruby (1.61.9)
simpleidn (~> 0.1)
@ -199,7 +198,7 @@ GEM
gemoji (~> 3.0)
html-pipeline (~> 2.2)
jekyll (>= 3.0, < 5.0)
just-the-docs (0.4.0)
just-the-docs (0.4.1)
jekyll (>= 3.8.5)
jekyll-seo-tag (>= 2.0)
rake (>= 12.3.1)
@ -212,18 +211,14 @@ GEM
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
mercenary (0.3.6)
mini_portile2 (2.8.1)
minima (2.5.1)
jekyll (>= 3.5, < 5.0)
jekyll-feed (~> 0.9)
jekyll-seo-tag (~> 2.1)
minitest (5.18.0)
nokogiri (1.14.0-arm64-darwin)
racc (~> 1.4)
nokogiri (1.14.0-x64-mingw32)
racc (~> 1.4)
nokogiri (1.14.0-x86_64-darwin)
racc (~> 1.4)
nokogiri (1.14.0-x86_64-linux)
nokogiri (1.14.2)
mini_portile2 (~> 2.8.0)
racc (~> 1.4)
octokit (4.25.1)
faraday (>= 1, < 3)
@ -262,10 +257,8 @@ GEM
unf (0.1.4)
unf_ext
unf_ext (0.0.8.2)
unf_ext (0.0.8.2-x64-mingw32)
unicode-display_width (1.8.0)
webrick (1.7.0)
zeitwerk (2.6.7)
webrick (1.8.1)
PLATFORMS
arm64-darwin-22
@ -284,4 +277,4 @@ DEPENDENCIES
webrick (~> 1.7)
BUNDLED WITH
2.4.5
2.4.10

View File

@ -1,29 +0,0 @@
---
layout: page
title: proxmox_virtual_environment_cluster_alias
permalink: /data-sources/virtual_environment_cluster_alias
nav_order: 1
parent: Data Sources
subcategory: Virtual Environment
---
# Data Source: proxmox_virtual_environment_cluster_alias
Retrieves information about a specific alias.
## Example Usage
```terraform
data "proxmox_virtual_environment_cluster_alias" "local_network" {
name = "local_network"
}
```
## Argument Reference
* `name` - (Required) Alias name.
## Attribute Reference
* `cidr` - (Required) Network/IP specification in CIDR format.
* `comment` - (Optional) Alias comment.

View File

@ -1,26 +0,0 @@
---
layout: page
title: proxmox_virtual_environment_cluster_aliases
permalink: /data-sources/virtual_environment_cluster_aliases
nav_order: 2
parent: Data Sources
subcategory: Virtual Environment
---
# Data Source: proxmox_virtual_environment_cluster_aliases
Retrieves the identifiers for all the available aliases.
## Example Usage
```terraform
data "proxmox_virtual_environment_cluster_aliases" "available_aliases" {}
```
## Argument Reference
There are no arguments available for this data source.
## Attribute Reference
- `alias_ids` - The pool identifiers.

View File

@ -2,7 +2,7 @@
layout: page
title: proxmox_virtual_environment_datastores
permalink: /data-sources/virtual_environment_datastores
nav_order: 3
nav_order: 7
parent: Data Sources
subcategory: Virtual Environment
---

View File

@ -2,7 +2,7 @@
layout: page
title: proxmox_virtual_environment_dns
permalink: /data-sources/virtual_environment_dns
nav_order: 4
nav_order: 8
parent: Data Sources
subcategory: Virtual Environment
---

View File

@ -2,7 +2,7 @@
layout: page
title: proxmox_virtual_environment_group
permalink: /data-sources/virtual_environment_group
nav_order: 5
nav_order: 9
parent: Data Sources
subcategory: Virtual Environment
---

View File

@ -2,7 +2,7 @@
layout: page
title: proxmox_virtual_environment_groups
permalink: /data-sources/virtual_environment_groups
nav_order: 6
nav_order: 10
parent: Data Sources
subcategory: Virtual Environment
---

View File

@ -2,7 +2,7 @@
layout: page
title: proxmox_virtual_environment_hosts
permalink: /data-sources/virtual_environment_hosts
nav_order: 7
nav_order: 11
parent: Data Sources
subcategory: Virtual Environment
---

View File

@ -2,7 +2,7 @@
layout: page
title: proxmox_virtual_environment_nodes
permalink: /data-sources/virtual_environment_nodes
nav_order: 8
nav_order: 12
parent: Data Sources
subcategory: Virtual Environment
---

View File

@ -2,7 +2,7 @@
layout: page
title: proxmox_virtual_environment_pool
permalink: /data-sources/virtual_environment_pool
nav_order: 9
nav_order: 13
parent: Data Sources
subcategory: Virtual Environment
---

View File

@ -2,7 +2,7 @@
layout: page
title: proxmox_virtual_environment_pools
permalink: /data-sources/virtual_environment_pools
nav_order: 10
nav_order: 14
parent: Data Sources
subcategory: Virtual Environment
---

View File

@ -2,7 +2,7 @@
layout: page
title: proxmox_virtual_environment_role
permalink: /data-sources/virtual_environment_role
nav_order: 11
nav_order: 15
parent: Data Sources
subcategory: Virtual Environment
---

View File

@ -2,7 +2,7 @@
layout: page
title: proxmox_virtual_environment_roles
permalink: /data-sources/virtual_environment_roles
nav_order: 12
nav_order: 16
parent: Data Sources
subcategory: Virtual Environment
---

View File

@ -2,7 +2,7 @@
layout: page
title: proxmox_virtual_environment_time
permalink: /data-sources/virtual_environment_time
nav_order: 13
nav_order: 17
parent: Data Sources
subcategory: Virtual Environment
---

View File

@ -2,7 +2,7 @@
layout: page
title: proxmox_virtual_environment_user
permalink: /data-sources/virtual_environment_user
nav_order: 14
nav_order: 18
parent: Data Sources
subcategory: Virtual Environment
---

View File

@ -2,7 +2,7 @@
layout: page
title: proxmox_virtual_environment_users
permalink: /data-sources/virtual_environment_users
nav_order: 15
nav_order: 19
parent: Data Sources
subcategory: Virtual Environment
---

View File

@ -2,7 +2,7 @@
layout: page
title: proxmox_virtual_environment_version
permalink: /data-sources/virtual_environment_version
nav_order: 16
nav_order: 20
parent: Data Sources
subcategory: Virtual Environment
---

View File

@ -2,7 +2,7 @@
layout: page
title: proxmox_virtual_environment_vm
permalink: /data-sources/virtual_environment_vm
nav_order: 17
nav_order: 21
parent: Data Sources
subcategory: Virtual Environment
---

View File

@ -2,7 +2,7 @@
layout: page
title: proxmox_virtual_environment_vms
permalink: /data-sources/virtual_environment_vms
nav_order: 18
nav_order: 22
parent: Data Sources
subcategory: Virtual Environment
---

View File

@ -1,39 +0,0 @@
---
layout: page
title: proxmox_virtual_environment_cluster_alias
permalink: /resources/virtual_environment_cluster_alias
nav_order: 2
parent: Resources
subcategory: Virtual Environment
---
# Resource: proxmox_virtual_environment_cluster_alias
Aliases are used to see what devices or group of devices are affected by a rule.
We can create aliases to identify an IP address or a network.
## Example Usage
```terraform
resource "proxmox_virtual_environment_cluster_alias" "local_network" {
name = "local_network"
cidr = "192.168.0.0/23"
comment = "Managed by Terraform"
}
resource "proxmox_virtual_environment_cluster_alias" "ubuntu_vm" {
name = "ubuntu"
cidr = "192.168.0.1"
comment = "Managed by Terraform"
}
```
## Argument Reference
- `name` - (Required) Alias name.
- `cidr` - (Required) Network/IP specification in CIDR format.
- `comment` - (Optional) Alias comment.
## Attribute Reference
There are no attribute references available for this resource.

View File

@ -0,0 +1,45 @@
---
layout: page
title: proxmox_virtual_environment_cluster_firewall
permalink: /resources/virtual_environment_cluster_firewall
nav_order: 2
parent: Resources
subcategory: Virtual Environment
---
# Resource: proxmox_virtual_environment_cluster_firewall
Manages firewall options on the cluster level.
## Example Usage
```terraform
resource "proxmox_virtual_environment_cluster_firewall" "example" {
enabled = false
ebtables = false
input_policy = "DROP"
output_policy = "ACCEPT"
log_ratelimit {
enabled = false
burst = 10
rate = "5/second"
}
}
```
## Argument Reference
- `enabled` - (Optional) Enable or disable the firewall cluster wide.
- `ebtables` - (Optional) Enable ebtables rules cluster wide.
- `input_policy` - (Optional) The default input policy (`ACCEPT`, `DROP`, `REJECT`).
- `output_policy` - (Optional) The default output policy (`ACCEPT`, `DROP`, `REJECT`).
- `log_ratelimit` - (Optional) The log rate limit.
- `enabled` - (Optional) Enable or disable the log rate limit.
- `burst` - (Optional) Initial burst of packages which will always get
logged before the rate is applied (defaults to `5`).
- `rate` - (Optional) Frequency with which the burst bucket gets refilled (defaults to `1/second`).
## Attribute Reference
There are no additional attributes available for this resource.

View File

@ -0,0 +1,87 @@
---
layout: page
title: proxmox_virtual_environment_cluster_firewall_security_group
permalink: /resources/virtual_environment_cluster_firewall_security_group
nav_order: 3
parent: Resources
subcategory: Virtual Environment
---
# Resource: proxmox_virtual_environment_cluster_firewall_security_group
A security group is a collection of rules, defined at cluster level, which can
be used in all VMs' rules. For example, you can define a group named “webserver”
with rules to open the http and https ports.
## Example Usage
```terraform
resource "proxmox_virtual_environment_cluster_firewall_security_group" "webserver" {
name = "webserver"
comment = "Managed by Terraform"
rule {
type = "in"
action = "ACCEPT"
comment = "Allow HTTP"
dest = "192.168.1.5"
dport = "80"
proto = "tcp"
log = "info"
}
rule {
type = "in"
action = "ACCEPT"
comment = "Allow HTTPS"
dest = "192.168.1.5"
dport = "443"
proto = "tcp"
log = "info"
}
}
```
## Argument Reference
- `name` - (Required) Security group name.
- `comment` - (Optional) Security group comment.
- `rule` - (Optional) Firewall rule block (multiple blocks supported).
- `action` - (Required) Rule action (`ACCEPT`, `DROP`, `REJECT`).
- `type` - (Required) Rule type (`in`, `out`).
- `comment` - (Optional) Rule comment.
- `dest` - (Optional) Restrict packet destination address. This can refer to
a single IP address, an IP set ('+ipsetname') or an IP alias definition.
You can also specify an address range like `20.34.101.207-201.3.9.99`, or
a list of IP addresses and networks (entries are separated by comma).
Please do not mix IPv4 and IPv6 addresses inside such lists.
- `dport` - (Optional) Restrict TCP/UDP destination port. You can use
service names or simple numbers (0-65535), as defined in '/etc/services'.
Port ranges can be specified with '\d+:\d+', for example `80:85`, and
you can use comma separated list to match several ports or ranges.
- `enable` - (Optional) Enable this rule. Defaults to `true`.
- `iface` - (Optional) Network interface name. You have to use network
configuration key names for VMs and containers ('net\d+'). Host related
rules can use arbitrary strings.
- `log` - (Optional) Log level for this rule (`emerg`, `alert`, `crit`,
`err`, `warning`, `notice`, `info`, `debug`, `nolog`).
- `macro`- (Optional) Macro name. Use predefined standard macro.
- `proto` - (Optional) Restrict packet protocol. You can use protocol names
or simple numbers (0-255), as defined in '/etc/protocols'.
- `source` - (Optional) Restrict packet source address. This can refer
to a single IP address, an IP set ('+ipsetname') or an IP alias
definition. You can also specify an address range like
`20.34.101.207-201.3.9.99`, or a list of IP addresses and networks (
entries are separated by comma). Please do not mix IPv4 and IPv6 addresses
inside such lists.
- `sport` - (Optional) Restrict TCP/UDP source port. You can use
service names or simple numbers (0-65535), as defined in '/etc/services'.
Port ranges can be specified with '\d+:\d+', for example `80:85`, and
you can use comma separated list to match several ports or ranges.
## Attribute Reference
- `rule`
- `pos` - Position of the rule in the list.
There are no attribute references available for this resource.

View File

@ -0,0 +1,48 @@
---
layout: page
title: proxmox_virtual_environment_cluster_firewall_alias
permalink: /resources/virtual_environment_cluster_firewall_alias
nav_order: 7
parent: Resources
subcategory: Virtual Environment
---
# Resource: proxmox_virtual_environment_cluster_firewall_alias
Aliases are used to see what devices or group of devices are affected by a rule.
We can create aliases to identify an IP address or a network. Aliases can be
created on the cluster level, on VM / Container level.
## Example Usage
```terraform
resource "proxmox_virtual_environment_cluster_firewall_alias" "local_network" {
depends_on = [proxmox_virtual_environment_vm.example]
node_name = proxmox_virtual_environment_vm.example.node_name
vm_id = proxmox_virtual_environment_vm.example.vm_id
name = "local_network"
cidr = "192.168.0.0/23"
comment = "Managed by Terraform"
}
resource "proxmox_virtual_environment_cluster_firewall_alias" "ubuntu_vm" {
name = "ubuntu"
cidr = "192.168.0.1"
comment = "Managed by Terraform"
}
```
## Argument Reference
- `node_name` - (Optional) Node name. Leave empty for cluster level aliases.
- `vm_id` - (Optional) VM ID. Leave empty for cluster level aliases.
- `container_id` - (Optional) Container ID. Leave empty for cluster level aliases.
- `name` - (Required) Alias name.
- `cidr` - (Required) Network/IP specification in CIDR format.
- `comment` - (Optional) Alias comment.
## Attribute Reference
There are no attribute references available for this resource.

View File

@ -1,20 +1,26 @@
---
layout: page
title: proxmox_virtual_environment_cluster_ipset
permalink: /resources/virtual_environment_cluster_ipset
nav_order: 3
title: proxmox_virtual_environment_cluster_firewall_ipset
permalink: /resources/virtual_environment_cluster_firewall_ipset
nav_order: 8
parent: Resources
subcategory: Virtual Environment
---
# Resource: proxmox_virtual_environment_cluster_ipset
# Resource: proxmox_virtual_environment_cluster_firewall_ipset
An IPSet allows us to group multiple IP addresses, IP subnets and aliases.
An IPSet allows us to group multiple IP addresses, IP subnets and aliases. Aliases can be
created on the cluster level, on VM / Container level.
## Example Usage
```terraform
resource "proxmox_virtual_environment_cluster_ipset" "ipset" {
resource "proxmox_virtual_environment_cluster_firewall_ipset" "ipset" {
depends_on = [proxmox_virtual_environment_vm.example]
node_name = proxmox_virtual_environment_vm.example.node_name
vm_id = proxmox_virtual_environment_vm.example.vm_id
name = "local_network"
comment = "Managed by Terraform"
@ -38,8 +44,11 @@ resource "proxmox_virtual_environment_cluster_ipset" "ipset" {
## Argument Reference
- `name` - (Required) Alias name.
- `comment` - (Optional) Alias comment.
- `node_name` - (Optional) Node name. Leave empty for cluster level aliases.
- `vm_id` - (Optional) VM ID. Leave empty for cluster level aliases.
- `container_id` - (Optional) Container ID. Leave empty for cluster level aliases.
- `name` - (Required) IPSet name.
- `comment` - (Optional) IPSet comment.
- `cidr` - (Optional) IP/CIDR block (multiple blocks supported).
- `name` - Network/IP specification in CIDR format.
- `comment` - (Optional) Arbitrary string annotation.

View File

@ -0,0 +1,59 @@
---
layout: page
title: proxmox_virtual_environment_firewall_options
permalink: /resources/virtual_environment_firewall_options
nav_order: 9
parent: Resources
subcategory: Virtual Environment
---
# Resource: proxmox_virtual_environment_firewall_options
Manages firewall options on VM / Container level.
## Example Usage
```terraform
resource "proxmox_virtual_environment_firewall_options" "example" {
enabled = false
dhcp = true
enabled = false
ipfilter = true
log_level_in = "info"
log_level_out = "info"
macfilter = false
ndp = true
input_policy = "ACCEPT
output_policy = "ACCEPT"
radv = true
}
```
## Argument Reference
- `node_name` - (Required) Node name.
- `vm_id` - (Optional) VM ID. Leave empty for cluster level aliases.
- `container_id` - (Optional) Container ID. Leave empty for cluster level aliases.
- `dhcp` - (Optional)Enable DHCP.
- `enabled` - (Optional) Enable or disable the firewall.
- `ipfilter` - (Optional) Enable default IP filters. This is equivalent to
adding an empty ipfilter-net<id> ipset for every interface. Such ipsets
implicitly contain sane default restrictions such as restricting IPv6 link
local addresses to the one derived from the interface's MAC address. For
containers the configured IP addresses will be implicitly added.
- `log_level_in` - (Optional) Log level for incoming
packets (`emerg`, `alert`, `crit`, `err`, `warning`, `notice`, `info`, `debug`, `nolog`).
- `log_level_out` - (Optional) Log level for outgoing
packets (`emerg`, `alert`, `crit`, `err`, `warning`, `notice`, `info`, `debug`, `nolog`).
- `macfilter` - (Optional) Enable/disable MAC address filter.
- `ndp` - (Optional) Enable NDP (Neighbor Discovery Protocol).
- `input_policy` - (Optional) The default input
policy (`ACCEPT`, `DROP`, `REJECT`).
- `output_policy` - (Optional) The default output
policy (`ACCEPT`, `DROP`, `REJECT`).
- `radv` - (Optional) Enable Router Advertisement.
## Attribute Reference
There are no additional attributes available for this resource.

View File

@ -0,0 +1,90 @@
---
layout: page
title: proxmox_virtual_environment_firewall_rules
permalink: /resources/virtual_environment_firewall_rules
nav_order: 10
parent: Resources
subcategory: Virtual Environment
---
# Resource: proxmox_virtual_environment_firewall_rules
A security group is a collection of rules, defined at cluster level, which can
be used in all VMs' rules. For example, you can define a group named “webserver”
with rules to open the http and https ports. Rules can be created on the cluster
level, on VM / Container level.
## Example Usage
```terraform
resource "proxmox_virtual_environment_firewall_rules" "inbound" {
depends_on = [proxmox_virtual_environment_vm.example]
node_name = proxmox_virtual_environment_vm.example.node_name
vm_id = proxmox_virtual_environment_vm.example.vm_id
rule {
type = "in"
action = "ACCEPT"
comment = "Allow HTTP"
dest = "192.168.1.5"
dport = "80"
proto = "tcp"
log = "info"
}
rule {
type = "in"
action = "ACCEPT"
comment = "Allow HTTPS"
dest = "192.168.1.5"
dport = "443"
proto = "tcp"
log = "info"
}
}
```
## Argument Reference
- `node_name` - (Optional) Node name. Leave empty for cluster level aliases.
- `vm_id` - (Optional) VM ID. Leave empty for cluster level aliases.
- `container_id` - (Optional) Container ID. Leave empty for cluster level aliases.
- `rule` - (Optional) Firewall rule block (multiple blocks supported).
- `action` - (Required) Rule action (`ACCEPT`, `DROP`, `REJECT`).
- `type` - (Required) Rule type (`in`, `out`).
- `comment` - (Optional) Rule comment.
- `dest` - (Optional) Restrict packet destination address. This can refer to
a single IP address, an IP set ('+ipsetname') or an IP alias definition.
You can also specify an address range like `20.34.101.207-201.3.9.99`, or
a list of IP addresses and networks (entries are separated by comma).
Please do not mix IPv4 and IPv6 addresses inside such lists.
- `dport` - (Optional) Restrict TCP/UDP destination port. You can use
service names or simple numbers (0-65535), as defined in '/etc/services'.
Port ranges can be specified with '\d+:\d+', for example `80:85`, and
you can use comma separated list to match several ports or ranges.
- `enable` - (Optional) Enable this rule. Defaults to `true`.
- `iface` - (Optional) Network interface name. You have to use network
configuration key names for VMs and containers ('net\d+'). Host related
rules can use arbitrary strings.
- `log` - (Optional) Log level for this rule (`emerg`, `alert`, `crit`,
`err`, `warning`, `notice`, `info`, `debug`, `nolog`).
- `macro`- (Optional) Macro name. Use predefined standard macro.
- `proto` - (Optional) Restrict packet protocol. You can use protocol names
or simple numbers (0-255), as defined in '/etc/protocols'.
- `source` - (Optional) Restrict packet source address. This can refer
to a single IP address, an IP set ('+ipsetname') or an IP alias
definition. You can also specify an address range like
`20.34.101.207-201.3.9.99`, or a list of IP addresses and networks (
entries
are separated by comma). Please do not mix IPv4 and IPv6 addresses inside
such lists.
- `sport` - (Optional) Restrict TCP/UDP source port. You can use
service names or simple numbers (0-65535), as defined in '/etc/services'.
Port ranges can be specified with '\d+:\d+', for example `80:85`, and
you can use comma separated list to match several ports or ranges.
## Attribute Reference
- `rule`
- `pos` - Position of the rule in the list.

View File

@ -2,7 +2,7 @@
layout: page
title: proxmox_virtual_environment_group
permalink: /resources/virtual_environment_group
nav_order: 7
nav_order: 11
parent: Resources
subcategory: Virtual Environment
---

View File

@ -2,7 +2,7 @@
layout: page
title: proxmox_virtual_environment_hosts
permalink: /resources/virtual_environment_hosts
nav_order: 8
nav_order: 12
parent: Resources
subcategory: Virtual Environment
---

View File

@ -2,7 +2,7 @@
layout: page
title: proxmox_virtual_environment_pool
permalink: /resources/virtual_environment_pool
nav_order: 9
nav_order: 14
parent: Resources
subcategory: Virtual Environment
---

View File

@ -2,7 +2,7 @@
layout: page
title: proxmox_virtual_environment_role
permalink: /resources/virtual_environment_role
nav_order: 10
nav_order: 14
parent: Resources
subcategory: Virtual Environment
---

View File

@ -2,7 +2,7 @@
layout: page
title: proxmox_virtual_environment_time
permalink: /resources/virtual_environment_time
nav_order: 11
nav_order: 15
parent: Resources
subcategory: Virtual Environment
---

View File

@ -2,7 +2,7 @@
layout: page
title: proxmox_virtual_environment_user
permalink: /resources/virtual_environment_user
nav_order: 12
nav_order: 16
parent: Resources
subcategory: Virtual Environment
---

View File

@ -2,7 +2,7 @@
layout: page
title: proxmox_virtual_environment_vm
permalink: /resources/virtual_environment_vm
nav_order: 13
nav_order: 17
parent: Resources
subcategory: Virtual Environment
---

View File

@ -1,9 +0,0 @@
data "proxmox_virtual_environment_cluster_alias" "example" {
depends_on = [proxmox_virtual_environment_cluster_alias.example]
name = proxmox_virtual_environment_cluster_alias.example.name
}
output "data_proxmox_virtual_environment_cluster_alias_example_cidr" {
value = proxmox_virtual_environment_cluster_alias.example.cidr
}

View File

@ -1,9 +0,0 @@
data "proxmox_virtual_environment_cluster_aliases" "example" {
depends_on = [proxmox_virtual_environment_cluster_alias.example]
}
output "data_proxmox_virtual_environment_cluster_aliases" {
value = {
"alias_ids" = data.proxmox_virtual_environment_cluster_aliases.example.alias_ids
}
}

View File

@ -1,13 +0,0 @@
resource "proxmox_virtual_environment_cluster_alias" "example" {
name = "example"
cidr = "192.168.0.0/23"
comment = "Managed by Terraform"
}
output "proxmox_virtual_environment_cluster_alias_example_name" {
value = proxmox_virtual_environment_cluster_alias.example.name
}
output "proxmox_virtual_environment_cluster_alias_example_cidr" {
value = proxmox_virtual_environment_cluster_alias.example.cidr
}

View File

@ -0,0 +1,28 @@
resource "proxmox_virtual_environment_cluster_firewall_security_group" "example" {
name = "example-sg"
comment = "Managed by Terraform"
rule {
type = "in"
action = "ACCEPT"
comment = "Allow FTP"
dest = "192.168.1.5"
dport = "21"
proto = "tcp"
log = "info"
}
rule {
type = "in"
action = "DROP"
comment = "Allow SSH"
dest = "192.168.1.5"
dport = "22"
proto = "udp"
log = "info"
}
}
output "resource_proxmox_virtual_environment_cluster_firewall_security_group_example" {
value = proxmox_virtual_environment_cluster_firewall_security_group.example
}

View File

@ -1,25 +0,0 @@
resource "proxmox_virtual_environment_cluster_ipset" "example" {
name = "local_network"
comment = "Managed by Terraform"
cidr {
name = "192.168.0.0/23"
comment = "Local network 1"
}
cidr {
name = "192.168.0.1"
comment = "Server 1"
nomatch = true
}
cidr {
name = "192.168.2.1"
comment = "Server 1"
}
}
output "resource_proxmox_virtual_environment_cluster_ipset" {
value = proxmox_virtual_environment_cluster_ipset.example.name
}

View File

@ -0,0 +1,39 @@
resource "proxmox_virtual_environment_firewall_alias" "cluster_alias" {
name = "cluster-alias"
cidr = "192.168.0.0/23"
comment = "Managed by Terraform"
}
resource "proxmox_virtual_environment_firewall_alias" "vm_alias" {
depends_on = [proxmox_virtual_environment_vm.example]
node_name = proxmox_virtual_environment_vm.example.node_name
vm_id = proxmox_virtual_environment_vm.example.vm_id
name = "vm-alias"
cidr = "192.168.1.0/23"
comment = "Managed by Terraform"
}
resource "proxmox_virtual_environment_firewall_alias" "container_alias" {
depends_on = [proxmox_virtual_environment_container.example]
node_name = proxmox_virtual_environment_container.example.node_name
container_id = proxmox_virtual_environment_container.example.vm_id
name = "container-alias"
cidr = "192.168.2.0/23"
comment = "Managed by Terraform"
}
output "resource_proxmox_virtual_environment_firewall_alias_cluster" {
value = proxmox_virtual_environment_firewall_alias.cluster_alias
}
output "resource_proxmox_virtual_environment_firewall_alias_vm" {
value = proxmox_virtual_environment_firewall_alias.vm_alias
}
output "resource_proxmox_virtual_environment_firewall_alias_container" {
value = proxmox_virtual_environment_firewall_alias.container_alias
}

View File

@ -0,0 +1,70 @@
resource "proxmox_virtual_environment_firewall_ipset" "cluster_ipset" {
name = "cluster-ipset"
comment = "Managed by Terraform"
cidr {
name = "192.168.0.1"
comment = "Server 1"
nomatch = true
}
cidr {
name = "192.168.0.2"
comment = "Server 2"
}
}
resource "proxmox_virtual_environment_firewall_ipset" "vm_ipset" {
depends_on = [proxmox_virtual_environment_vm.example]
node_name = proxmox_virtual_environment_vm.example.node_name
vm_id = proxmox_virtual_environment_vm.example.vm_id
name = "vm-ipset"
comment = "Managed by Terraform"
cidr {
name = "192.168.1.1"
comment = "Server 1"
nomatch = true
}
cidr {
name = "192.168.1.2"
comment = "Server 2"
}
}
resource "proxmox_virtual_environment_firewall_ipset" "container_ipset" {
depends_on = [proxmox_virtual_environment_container.example]
node_name = proxmox_virtual_environment_container.example.node_name
container_id = proxmox_virtual_environment_container.example.vm_id
name = "container-ipset"
comment = "Managed by Terraform"
cidr {
name = "192.168.2.1"
comment = "Server 1"
nomatch = true
}
cidr {
name = "192.168.2.2"
comment = "Server 2"
}
}
output "resource_proxmox_virtual_environment_firewall_ipset_cluster" {
value = proxmox_virtual_environment_firewall_ipset.cluster_ipset
}
output "resource_proxmox_virtual_environment_firewall_ipset_vm" {
value = proxmox_virtual_environment_firewall_ipset.vm_ipset
}
output "resource_proxmox_virtual_environment_firewall_ipset_container" {
value = proxmox_virtual_environment_firewall_ipset.container_ipset
}

View File

@ -0,0 +1,62 @@
resource "proxmox_virtual_environment_cluster_firewall" "cluster_options" {
enabled = false
ebtables = false
input_policy = "ACCEPT"
output_policy = "REJECT"
log_ratelimit {
enabled = false
burst = 20
rate = "5/second"
}
}
resource "proxmox_virtual_environment_firewall_options" "vm_options" {
depends_on = [proxmox_virtual_environment_vm.example]
node_name = proxmox_virtual_environment_vm.example.node_name
vm_id = proxmox_virtual_environment_vm.example.vm_id
dhcp = true
enabled = false
ipfilter = true
log_level_in = "info"
log_level_out = "info"
macfilter = false
ndp = true
input_policy = "REJECT"
output_policy = "REJECT"
radv = true
}
resource "proxmox_virtual_environment_firewall_options" "container_options" {
depends_on = [proxmox_virtual_environment_container.example]
node_name = proxmox_virtual_environment_container.example.node_name
container_id = proxmox_virtual_environment_container.example.vm_id
dhcp = false
enabled = false
ipfilter = false
log_level_in = "alert"
log_level_out = "alert"
macfilter = true
ndp = false
input_policy = "ACCEPT"
output_policy = "DROP"
radv = false
}
output "resource_proxmox_virtual_environment_firewall_options_cluster" {
value = proxmox_virtual_environment_cluster_firewall.cluster_options
}
output "resource_proxmox_virtual_environment_firewall_options_vm" {
value = proxmox_virtual_environment_firewall_options.vm_options
}
output "resource_proxmox_virtual_environment_firewall_options_container" {
value = proxmox_virtual_environment_firewall_options.container_options
}

View File

@ -0,0 +1,84 @@
resource "proxmox_virtual_environment_firewall_rules" "cluster_rules" {
rule {
type = "in"
action = "ACCEPT"
comment = "Allow FTP"
dest = "192.168.0.5"
dport = "21"
proto = "tcp"
log = "info"
}
rule {
type = "out"
action = "DROP"
comment = "Allow SSH"
dest = "192.168.0.5"
dport = "22"
proto = "tcp"
}
}
resource "proxmox_virtual_environment_firewall_rules" "vm_rules" {
depends_on = [proxmox_virtual_environment_vm.example]
node_name = proxmox_virtual_environment_vm.example.node_name
vm_id = proxmox_virtual_environment_vm.example.vm_id
rule {
type = "in"
action = "ACCEPT"
comment = "Allow FTP"
dest = "192.168.1.5"
dport = "21"
proto = "tcp"
log = "info"
}
rule {
type = "out"
action = "DROP"
comment = "Allow SSH"
dest = "192.168.1.5"
dport = "22"
proto = "tcp"
}
}
resource "proxmox_virtual_environment_firewall_rules" "container_rules" {
depends_on = [proxmox_virtual_environment_container.example]
node_name = proxmox_virtual_environment_container.example.node_name
container_id = proxmox_virtual_environment_container.example.vm_id
rule {
type = "in"
action = "ACCEPT"
comment = "Allow FTP"
dest = "192.168.2.5"
dport = "21"
proto = "tcp"
log = "info"
}
rule {
type = "out"
action = "DROP"
comment = "Allow SSH"
dest = "192.168.2.5"
dport = "22"
proto = "tcp"
}
}
output "resource_proxmox_virtual_environment_firewall_rules_cluster" {
value = proxmox_virtual_environment_firewall_rules.cluster_rules
}
output "resource_proxmox_virtual_environment_firewall_rules_vm" {
value = proxmox_virtual_environment_firewall_rules.vm_rules
}
output "resource_proxmox_virtual_environment_firewall_rules_container" {
value = proxmox_virtual_environment_firewall_rules.container_rules
}

View File

@ -7,9 +7,10 @@ package main
import (
"flag"
"github.com/bpg/terraform-provider-proxmox/proxmoxtf"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/plugin"
"github.com/bpg/terraform-provider-proxmox/proxmoxtf/provider"
)
func main() {
@ -22,7 +23,7 @@ func main() {
Debug: debug,
ProviderAddr: "registry.terraform.io/bpg/proxmox",
ProviderFunc: func() *schema.Provider {
return proxmoxtf.Provider()
return provider.ProxmoxVirtualEnvironment()
},
}

29
proxmox/cluster/client.go Normal file
View File

@ -0,0 +1,29 @@
/*
* 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 (
"fmt"
clusterfirewall "github.com/bpg/terraform-provider-proxmox/proxmox/cluster/firewall"
"github.com/bpg/terraform-provider-proxmox/proxmox/firewall"
"github.com/bpg/terraform-provider-proxmox/proxmox/types"
)
type Client struct {
types.Client
}
func (c *Client) ExpandPath(path string) string {
return fmt.Sprintf("cluster/%s", path)
}
func (c *Client) Firewall() clusterfirewall.API {
return &clusterfirewall.Client{
Client: firewall.Client{Client: c},
}
}

View File

@ -0,0 +1,33 @@
/*
* 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"
"errors"
"fmt"
"net/http"
)
// GetNextID retrieves the next free VM identifier for the cluster.
func (c *Client) GetNextID(ctx context.Context, vmID *int) (*int, error) {
reqBody := &NextIDRequestBody{
VMID: vmID,
}
resBody := &NextIDResponseBody{}
err := c.DoRequest(ctx, http.MethodGet, "cluster/nextid", reqBody, resBody)
if err != nil {
return nil, fmt.Errorf("error retrieving next VM ID: %w", err)
}
if resBody.Data == nil {
return nil, errors.New("the server did not include a data object in the response")
}
return (*int)(resBody.Data), nil
}

View File

@ -0,0 +1,17 @@
/* 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"
// NextIDRequestBody contains the data for a cluster next id request.
type NextIDRequestBody struct {
VMID *int `json:"vmid,omitempty" url:"vmid,omitempty"`
}
// NextIDResponseBody contains the body from a cluster next id response.
type NextIDResponseBody struct {
Data *types.CustomInt `json:"data,omitempty"`
}

View File

@ -0,0 +1,47 @@
/*
* 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 firewall
import (
"fmt"
"github.com/bpg/terraform-provider-proxmox/proxmox/firewall"
)
type API interface {
firewall.API
SecurityGroup
Options
SecurityGroup(group string) firewall.Rule
}
type Client struct {
firewall.Client
}
type groupClient struct {
firewall.Client
Group string
}
func (c *Client) SecurityGroup(group string) firewall.Rule {
// My head really hurts when I'm looking at this code
// I'm not sure if this is the best way to do the required
// interface composition and method "overrides", but it works.
return &Client{
Client: firewall.Client{
Client: &groupClient{
Client: c.Client,
Group: group,
},
},
}
}
func (c *groupClient) ExpandPath(_ string) string {
return fmt.Sprintf("cluster/firewall/groups/%s", c.Group)
}

View File

@ -0,0 +1,133 @@
/*
* 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 firewall
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"strconv"
"strings"
"github.com/bpg/terraform-provider-proxmox/proxmox/types"
)
type Options interface {
SetGlobalOptions(ctx context.Context, d *OptionsPutRequestBody) error
GetGlobalOptions(ctx context.Context) (*OptionsGetResponseData, error)
}
type OptionsPutRequestBody struct {
EBTables *types.CustomBool `json:"ebtables,omitempty" url:"ebtables,omitempty,int"`
Enable *types.CustomBool `json:"enable,omitempty" url:"enable,omitempty,int"`
LogRateLimit *CustomLogRateLimit `json:"log_ratelimit,omitempty" url:"log_ratelimit,omitempty"`
PolicyIn *string `json:"policy_in,omitempty" url:"policy_in,omitempty"`
PolicyOut *string `json:"policy_out,omitempty" url:"policy_out,omitempty"`
}
type CustomLogRateLimit struct {
Enable types.CustomBool `json:"enable,omitempty" url:"enable,omitempty,int"`
Burst *int `json:"burst,omitempty" url:"burst,omitempty,int"`
Rate *string `json:"rate,omitempty" url:"rate,omitempty"`
}
type OptionsGetResponseBody struct {
Data *OptionsGetResponseData `json:"data,omitempty"`
}
type OptionsGetResponseData struct {
EBTables *types.CustomBool `json:"ebtables" url:"ebtables, int"`
Enable *types.CustomBool `json:"enable" url:"enable,int"`
LogRateLimit *CustomLogRateLimit `json:"log_ratelimit" url:"log_ratelimit"`
PolicyIn *string `json:"policy_in" url:"policy_in"`
PolicyOut *string `json:"policy_out" url:"policy_out"`
}
// EncodeValues converts a CustomWatchdogDevice struct to a URL vlaue.
func (r *CustomLogRateLimit) EncodeValues(key string, v *url.Values) error {
var values []string
if r.Enable {
values = append(values, "enable=1")
} else {
values = append(values, "enable=0")
}
if r.Burst != nil {
values = append(values, fmt.Sprintf("burst=%d", *r.Burst))
}
if r.Rate != nil {
values = append(values, fmt.Sprintf("rate=%s", *r.Rate))
}
v.Add(key, strings.Join(values, ","))
return nil
}
func (r *CustomLogRateLimit) UnmarshalJSON(b []byte) error {
var s string
err := json.Unmarshal(b, &s)
if err != nil {
return fmt.Errorf("error unmarshaling json: %w", err)
}
if s == "" {
return nil
}
pairs := strings.Split(s, ",")
for _, p := range pairs {
v := strings.Split(strings.TrimSpace(p), "=")
if len(v) == 1 {
r.Enable = v[0] == "1"
} else if len(v) == 2 {
switch v[0] {
case "enable":
r.Enable = v[1] == "1"
case "burst":
iv, err := strconv.Atoi(v[1])
if err != nil {
return fmt.Errorf("error converting burst to int: %w", err)
}
r.Burst = &iv
case "rate":
r.Rate = &v[1]
}
}
}
return nil
}
func (c *Client) SetGlobalOptions(ctx context.Context, d *OptionsPutRequestBody) error {
err := c.DoRequest(ctx, http.MethodPut, "cluster/firewall/options", d, nil)
if err != nil {
return fmt.Errorf("error setting optionss: %w", err)
}
return nil
}
func (c *Client) GetGlobalOptions(ctx context.Context) (*OptionsGetResponseData, error) {
resBody := &OptionsGetResponseBody{}
err := c.DoRequest(ctx, http.MethodGet, "cluster/firewall/options", nil, resBody)
if err != nil {
return nil, fmt.Errorf("error retrieving options: %w", err)
}
if resBody.Data == nil {
return nil, fmt.Errorf("the server did not include a data object in the response")
}
return resBody.Data, nil
}

View File

@ -0,0 +1,113 @@
/*
* 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 firewall
import (
"context"
"errors"
"fmt"
"net/http"
"net/url"
"sort"
)
type SecurityGroup interface {
CreateGroup(ctx context.Context, d *GroupCreateRequestBody) error
ListGroups(ctx context.Context) ([]*GroupListResponseData, error)
UpdateGroup(ctx context.Context, d *GroupUpdateRequestBody) error
DeleteGroup(ctx context.Context, group string) error
}
// GroupCreateRequestBody contains the data for a security group create request.
type GroupCreateRequestBody struct {
Group string `json:"group" url:"group"`
Comment *string `json:"comment,omitempty" url:"comment,omitempty"`
Digest *string `json:"digest,omitempty" url:"digest,omitempty"`
}
// GroupListResponseData contains the data from a group list response.
type GroupListResponseData struct {
Comment *string `json:"comment,omitempty" url:"comment,omitempty"`
Group string `json:"group" url:"group"`
Digest string `json:"digest" url:"digest"`
}
// GroupListResponseBody contains the data from a group get response.
type GroupListResponseBody struct {
Data []*GroupListResponseData `json:"data,omitempty"`
}
// GroupUpdateRequestBody contains the data for a group update request.
type GroupUpdateRequestBody struct {
Group string `json:"group" url:"group"`
Comment *string `json:"comment,omitempty" url:"comment,omitempty"`
ReName *string `json:"rename,omitempty" url:"rename,omitempty"`
Digest *string `json:"digest,omitempty" url:"digest,omitempty"`
}
func (c *Client) securityGroupsPath() string {
return "cluster/firewall/groups"
}
// CreateGroup create new security group.
func (c *Client) CreateGroup(ctx context.Context, d *GroupCreateRequestBody) error {
err := c.DoRequest(ctx, http.MethodPost, c.securityGroupsPath(), d, nil)
if err != nil {
return fmt.Errorf("error creating security group: %w", err)
}
return nil
}
// ListGroups retrieve list of security groups.
func (c *Client) ListGroups(ctx context.Context) ([]*GroupListResponseData, error) {
resBody := &GroupListResponseBody{}
err := c.DoRequest(ctx, http.MethodGet, c.securityGroupsPath(), nil, resBody)
if err != nil {
return nil, fmt.Errorf("error retrieving security groups: %w", err)
}
if resBody.Data == nil {
return nil, errors.New("the server did not include a data object in the response")
}
sort.Slice(resBody.Data, func(i, j int) bool {
return resBody.Data[i].Group < resBody.Data[j].Group
})
return resBody.Data, nil
}
// UpdateGroup update security group.
func (c *Client) UpdateGroup(ctx context.Context, d *GroupUpdateRequestBody) error {
err := c.DoRequest(
ctx,
http.MethodPost,
c.securityGroupsPath(),
d,
nil,
)
if err != nil {
return fmt.Errorf("error updating security group: %w", err)
}
return nil
}
// DeleteGroup delete security group.
func (c *Client) DeleteGroup(ctx context.Context, group string) error {
err := c.DoRequest(
ctx,
http.MethodDelete,
fmt.Sprintf("%s/%s", c.securityGroupsPath(), url.PathEscape(group)),
nil,
nil,
)
if err != nil {
return fmt.Errorf("error deleting security group '%s': %w", group, err)
}
return nil
}

View File

@ -0,0 +1,32 @@
/*
* 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 container
import (
"fmt"
"net/url"
containerfirewall "github.com/bpg/terraform-provider-proxmox/proxmox/container/firewall"
"github.com/bpg/terraform-provider-proxmox/proxmox/firewall"
"github.com/bpg/terraform-provider-proxmox/proxmox/types"
)
type Client struct {
types.Client
NodeName string
VMID int
}
func (c *Client) ExpandPath(path string) string {
return fmt.Sprintf("nodes/%s/lxc/%d/%s", url.PathEscape(c.NodeName), c.VMID, path)
}
func (c *Client) Firewall() firewall.API {
return &containerfirewall.Client{
Client: firewall.Client{Client: c},
}
}

View File

@ -0,0 +1,15 @@
/*
* 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 firewall
import (
"github.com/bpg/terraform-provider-proxmox/proxmox/firewall"
)
type Client struct {
firewall.Client
}

140
proxmox/firewall/aliases.go Normal file
View File

@ -0,0 +1,140 @@
/*
* 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 firewall
import (
"context"
"errors"
"fmt"
"net/http"
"net/url"
"sort"
)
type Alias interface {
CreateAlias(ctx context.Context, d *AliasCreateRequestBody) error
DeleteAlias(ctx context.Context, name string) error
GetAlias(ctx context.Context, name string) (*AliasGetResponseData, error)
ListAliases(ctx context.Context) ([]*AliasGetResponseData, error)
UpdateAlias(ctx context.Context, name string, d *AliasUpdateRequestBody) error
}
// AliasCreateRequestBody contains the data for an alias create request.
type AliasCreateRequestBody struct {
Comment *string `json:"comment,omitempty" url:"comment,omitempty"`
Name string `json:"name" url:"name"`
CIDR string `json:"cidr" url:"cidr"`
}
// AliasGetResponseBody contains the body from an alias get response.
type AliasGetResponseBody struct {
Data *AliasGetResponseData `json:"data,omitempty"`
}
// AliasGetResponseData contains the data from an alias get response.
type AliasGetResponseData struct {
Comment *string `json:"comment,omitempty" url:"comment,omitempty"`
Name string `json:"name" url:"name"`
CIDR string `json:"cidr" url:"cidr"`
Digest *string `json:"digest" url:"digest"`
IPVersion int `json:"ipversion" url:"ipversion"`
}
// AliasListResponseBody contains the data from an alias get response.
type AliasListResponseBody struct {
Data []*AliasGetResponseData `json:"data,omitempty"`
}
// AliasUpdateRequestBody contains the data for an alias update request.
type AliasUpdateRequestBody struct {
Comment *string `json:"comment,omitempty" url:"comment,omitempty"`
ReName string `json:"rename" url:"rename"`
CIDR string `json:"cidr" url:"cidr"`
}
func (c *Client) aliasesPath() string {
return c.ExpandPath("firewall/aliases")
}
// CreateAlias create an alias
func (c *Client) CreateAlias(ctx context.Context, d *AliasCreateRequestBody) error {
err := c.DoRequest(ctx, http.MethodPost, c.aliasesPath(), d, nil)
if err != nil {
return fmt.Errorf("error creating alias: %w", err)
}
return nil
}
// DeleteAlias delete an alias
func (c *Client) DeleteAlias(ctx context.Context, name string) error {
err := c.DoRequest(
ctx,
http.MethodDelete,
fmt.Sprintf("%s/%s", c.aliasesPath(), url.PathEscape(name)),
nil,
nil,
)
if err != nil {
return fmt.Errorf("error deleting alias '%s': %w", name, err)
}
return nil
}
// GetAlias retrieves an alias
func (c *Client) GetAlias(ctx context.Context, name string) (*AliasGetResponseData, error) {
resBody := &AliasGetResponseBody{}
err := c.DoRequest(
ctx,
http.MethodGet,
fmt.Sprintf("%s/%s", c.aliasesPath(), url.PathEscape(name)),
nil,
resBody,
)
if err != nil {
return nil, fmt.Errorf("error retrieving alias '%s': %w", name, err)
}
if resBody.Data == nil {
return nil, errors.New("the server did not include a data object in the response")
}
return resBody.Data, nil
}
// ListAliases retrieves a list of aliases.
func (c *Client) ListAliases(ctx context.Context) ([]*AliasGetResponseData, error) {
resBody := &AliasListResponseBody{}
err := c.DoRequest(ctx, http.MethodGet, c.aliasesPath(), nil, resBody)
if err != nil {
return nil, fmt.Errorf("error retrieving aliases: %w", err)
}
if resBody.Data == nil {
return nil, errors.New("the server did not include a data object in the response")
}
sort.Slice(resBody.Data, func(i, j int) bool {
return resBody.Data[i].Name < resBody.Data[j].Name
})
return resBody.Data, nil
}
// UpdateAlias updates an alias.
func (c *Client) UpdateAlias(ctx context.Context, name string, d *AliasUpdateRequestBody) error {
err := c.DoRequest(
ctx,
http.MethodPut,
fmt.Sprintf("%s/%s", c.aliasesPath(), url.PathEscape(name)),
d,
nil,
)
if err != nil {
return fmt.Errorf("error updating alias '%s': %w", name, err)
}
return nil
}

20
proxmox/firewall/api.go Normal file
View File

@ -0,0 +1,20 @@
/*
* 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 firewall
import "github.com/bpg/terraform-provider-proxmox/proxmox/types"
type API interface {
Alias
IPSet
Rule
Options
}
type Client struct {
types.Client
}

178
proxmox/firewall/ipset.go Normal file
View File

@ -0,0 +1,178 @@
/*
* 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/.
*/
/**
* Reference: https://pve.proxmox.com/pve-docs/api-viewer/#/cluster/firewall/ipset
*/
package firewall
import (
"context"
"errors"
"fmt"
"net/http"
"net/url"
"sort"
"github.com/bpg/terraform-provider-proxmox/proxmox/types"
)
type IPSet interface {
CreateIPSet(ctx context.Context, d *IPSetCreateRequestBody) error
AddCIDRToIPSet(ctx context.Context, id string, d IPSetGetResponseData) error
UpdateIPSet(ctx context.Context, d *IPSetUpdateRequestBody) error
DeleteIPSet(ctx context.Context, id string) error
DeleteIPSetContent(ctx context.Context, id string, cidr string) error
GetIPSetContent(ctx context.Context, id string) ([]*IPSetGetResponseData, error)
ListIPSets(ctx context.Context) ([]*IPSetListResponseData, error)
}
// IPSetListResponseBody contains the data from an IPSet get response.
type IPSetListResponseBody struct {
Data []*IPSetListResponseData `json:"data,omitempty"`
}
// IPSetCreateRequestBody contains the data for an IPSet create request
type IPSetCreateRequestBody struct {
Comment string `json:"comment,omitempty" url:"comment,omitempty"`
Name string `json:"name" url:"name"`
}
// IPSetGetResponseBody contains the body from an IPSet get response.
type IPSetGetResponseBody struct {
Data []*IPSetGetResponseData `json:"data,omitempty"`
}
// IPSetGetResponseData contains the data from an IPSet get response.
type IPSetGetResponseData struct {
CIDR string `json:"cidr" url:"cidr"`
NoMatch *types.CustomBool `json:"nomatch,omitempty" url:"nomatch,omitempty,int"`
Comment *string `json:"comment,omitempty" url:"comment,omitempty"`
}
// IPSetUpdateRequestBody contains the data for an IPSet update request.
type IPSetUpdateRequestBody struct {
ReName string `json:"rename,omitempty" url:"rename,omitempty"`
Comment *string `json:"comment,omitempty" url:"comment,omitempty"`
Name string `json:"name" url:"name"`
}
// IPSetListResponseData contains list of IPSets from
type IPSetListResponseData struct {
Comment *string `json:"comment,omitempty" url:"comment,omitempty"`
Name string `json:"name" url:"name"`
}
// IPSetContent is an array of IPSetGetResponseData.
type IPSetContent []IPSetGetResponseData
func (c *Client) ipsetPath() string {
return c.ExpandPath("firewall/ipset")
}
// CreateIPSet create an IPSet
func (c *Client) CreateIPSet(ctx context.Context, d *IPSetCreateRequestBody) error {
err := c.DoRequest(ctx, http.MethodPost, c.ipsetPath(), d, nil)
if err != nil {
return fmt.Errorf("error creating IPSet: %w", err)
}
return nil
}
// AddCIDRToIPSet adds IP or Network to IPSet
func (c *Client) AddCIDRToIPSet(ctx context.Context, id string, d IPSetGetResponseData) error {
err := c.DoRequest(
ctx,
http.MethodPost,
fmt.Sprintf("%s/%s", c.ipsetPath(), url.PathEscape(id)),
&d,
nil,
)
if err != nil {
return fmt.Errorf("error adding CIDR to IPSet: %w", err)
}
return nil
}
// UpdateIPSet updates an IPSet.
func (c *Client) UpdateIPSet(ctx context.Context, d *IPSetUpdateRequestBody) error {
err := c.DoRequest(ctx, http.MethodPost, c.ipsetPath(), d, nil)
if err != nil {
return fmt.Errorf("error updating IPSet: %w", err)
}
return nil
}
// DeleteIPSet delete an IPSet
func (c *Client) DeleteIPSet(ctx context.Context, id string) error {
err := c.DoRequest(
ctx,
http.MethodDelete,
fmt.Sprintf("%s/%s", c.ipsetPath(), url.PathEscape(id)),
nil,
nil,
)
if err != nil {
return fmt.Errorf("error deleting IPSet %s: %w", id, err)
}
return nil
}
// DeleteIPSetContent remove IP or Network from IPSet.
func (c *Client) DeleteIPSetContent(ctx context.Context, id string, cidr string) error {
err := c.DoRequest(
ctx,
http.MethodDelete,
fmt.Sprintf("%s/%s/%s", c.ipsetPath(), url.PathEscape(id), url.PathEscape(cidr)),
nil,
nil,
)
if err != nil {
return fmt.Errorf("error deleting IPSet content %s: %w", id, err)
}
return nil
}
// GetIPSetContent retrieve a list of IPSet content
func (c *Client) GetIPSetContent(ctx context.Context, id string) ([]*IPSetGetResponseData, error) {
resBody := &IPSetGetResponseBody{}
err := c.DoRequest(
ctx,
http.MethodGet,
fmt.Sprintf("%s/%s", c.ipsetPath(), url.PathEscape(id)),
nil,
resBody,
)
if err != nil {
return nil, fmt.Errorf("error getting IPSet content: %w", err)
}
if resBody.Data == nil {
return nil, errors.New("the server did not include a data object in the response")
}
return resBody.Data, nil
}
// ListIPSets retrieves list of IPSets.
func (c *Client) ListIPSets(ctx context.Context) ([]*IPSetListResponseData, error) {
resBody := &IPSetListResponseBody{}
err := c.DoRequest(ctx, http.MethodGet, c.ipsetPath(), nil, resBody)
if err != nil {
return nil, fmt.Errorf("error getting IPSet list: %w", err)
}
if resBody.Data == nil {
return nil, errors.New("the server did not include a data object in the response")
}
sort.Slice(resBody.Data, func(i, j int) bool {
return resBody.Data[i].Name < resBody.Data[j].Name
})
return resBody.Data, nil
}

View File

@ -0,0 +1,84 @@
/*
* 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 firewall
import (
"context"
"fmt"
"net/http"
"strconv"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/bpg/terraform-provider-proxmox/proxmox/types"
)
type Options interface {
GetOptionsID() string
SetOptions(ctx context.Context, d *OptionsPutRequestBody) error
GetOptions(ctx context.Context) (*OptionsGetResponseData, error)
}
type OptionsPutRequestBody struct {
DHCP *types.CustomBool `json:"dhcp,omitempty" url:"dhcp,omitempty,int"`
Enable *types.CustomBool `json:"enable,omitempty" url:"enable,omitempty,int"`
IPFilter *types.CustomBool `json:"ipfilter,omitempty" url:"ipfilter,omitempty,int"`
LogLevelIN *string `json:"log_level_in,omitempty" url:"log_level_in,omitempty"`
LogLevelOUT *string `json:"log_level_out,omitempty" url:"log_level_out,omitempty"`
MACFilter *types.CustomBool `json:"macfilter,omitempty" url:"macfilter,omitempty,int"`
NDP *types.CustomBool `json:"ndp,omitempty" url:"ndp,omitempty,int"`
PolicyIn *string `json:"policy_in,omitempty" url:"policy_in,omitempty"`
PolicyOut *string `json:"policy_out,omitempty" url:"policy_out,omitempty"`
RAdv *types.CustomBool `json:"radv,omitempty" url:"radv,omitempty,int"`
}
type OptionsGetResponseBody struct {
Data *OptionsGetResponseData `json:"data,omitempty"`
}
type OptionsGetResponseData struct {
DHCP *types.CustomBool `json:"dhcp" url:"dhcp,int"`
Enable *types.CustomBool `json:"enable" url:"enable,int"`
IPFilter *types.CustomBool `json:"ipfilter" url:"ipfilter,int"`
LogLevelIN *string `json:"log_level_in" url:"log_level_in"`
LogLevelOUT *string `json:"log_level_out" url:"log_level_out"`
MACFilter *types.CustomBool `json:"macfilter" url:"macfilter,int"`
NDP *types.CustomBool `json:"ndp" url:"ndp,int"`
PolicyIn *string `json:"policy_in" url:"policy_in"`
PolicyOut *string `json:"policy_out" url:"policy_out"`
RAdv *types.CustomBool `json:"radv" url:"radv,int"`
}
func (c *Client) optionsPath() string {
return c.ExpandPath("firewall/options")
}
func (c *Client) GetOptionsID() string {
return "options-" + strconv.Itoa(schema.HashString(c.optionsPath()))
}
func (c *Client) SetOptions(ctx context.Context, d *OptionsPutRequestBody) error {
err := c.DoRequest(ctx, http.MethodPut, c.optionsPath(), d, nil)
if err != nil {
return fmt.Errorf("error setting optionss: %w", err)
}
return nil
}
func (c *Client) GetOptions(ctx context.Context) (*OptionsGetResponseData, error) {
resBody := &OptionsGetResponseBody{}
err := c.DoRequest(ctx, http.MethodGet, c.optionsPath(), nil, resBody)
if err != nil {
return nil, fmt.Errorf("error retrieving options: %w", err)
}
if resBody.Data == nil {
return nil, fmt.Errorf("the server did not include a data object in the response")
}
return resBody.Data, nil
}

172
proxmox/firewall/rules.go Normal file
View File

@ -0,0 +1,172 @@
/*
* 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 firewall
import (
"context"
"errors"
"fmt"
"net/http"
"strconv"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/bpg/terraform-provider-proxmox/proxmox/types"
)
type Rule interface {
GetRulesID() string
CreateRule(ctx context.Context, d *RuleCreateRequestBody) error
GetRule(ctx context.Context, pos int) (*RuleGetResponseData, error)
ListRules(ctx context.Context) ([]*RuleListResponseData, error)
UpdateRule(ctx context.Context, pos int, d *RuleUpdateRequestBody) error
DeleteRule(ctx context.Context, pos int) error
}
// RuleCreateRequestBody contains the data for a firewall rule create request.
type RuleCreateRequestBody struct {
BaseRule
Action string `json:"action" url:"action"`
Type string `json:"type" url:"type"`
Group *string `json:"group,omitempty" url:"group,omitempty"`
}
// RuleGetResponseBody contains the body from a firewall rule get response.
type RuleGetResponseBody struct {
Data *RuleGetResponseData `json:"data,omitempty"`
}
// RuleGetResponseData contains the data from a firewall rule get response.
type RuleGetResponseData struct {
BaseRule
// NOTE: This is `int` in the PVE API docs, but it's actually a string in the response.
Pos string `json:"pos" url:"pos"`
Action string `json:"action" url:"action"`
Type string `json:"type" url:"type"`
}
// RuleListResponseBody contains the data from a firewall rule get response.
type RuleListResponseBody struct {
Data []*RuleListResponseData `json:"data,omitempty"`
}
// RuleListResponseData contains the data from a firewall rule get response.
type RuleListResponseData struct {
Pos int `json:"pos" url:"pos"`
}
// RuleUpdateRequestBody contains the data for a firewall rule update request.
type RuleUpdateRequestBody struct {
BaseRule
Pos *int `json:"pos,omitempty" url:"pos,omitempty"`
Action *string `json:"action,omitempty" url:"action,omitempty"`
Type *string `json:"type,omitempty" url:"type,omitempty"`
Group *string `json:"group,omitempty" url:"group,omitempty"`
}
type BaseRule struct {
Comment *string `json:"comment,omitempty" url:"comment,omitempty"`
Dest *string `json:"dest,omitempty" url:"dest,omitempty"`
Digest *string `json:"digest,omitempty" url:"digest,omitempty"`
DPort *string `json:"dport,omitempty" url:"dport,omitempty"`
Enable *types.CustomBool `json:"enable,omitempty" url:"enable,omitempty,int"`
ICMPType *string `json:"icmp-type,omitempty" url:"icmp-type,omitempty"`
IFace *string `json:"iface,omitempty" url:"iface,omitempty"`
Log *string `json:"log,omitempty" url:"log,omitempty"`
Macro *string `json:"macro,omitempty" url:"macro,omitempty"`
Proto *string `json:"proto,omitempty" url:"proto,omitempty"`
Source *string `json:"source,omitempty" url:"source,omitempty"`
SPort *string `json:"sport,omitempty" url:"sport,omitempty"`
}
func (c *Client) rulesPath() string {
return c.ExpandPath("firewall/rules")
}
func (c *Client) GetRulesID() string {
return "rule-" + strconv.Itoa(schema.HashString(c.rulesPath()))
}
// CreateRule creates a firewall rule.
func (c *Client) CreateRule(ctx context.Context, d *RuleCreateRequestBody) error {
err := c.DoRequest(ctx, http.MethodPost, c.rulesPath(), d, nil)
if err != nil {
return fmt.Errorf("error creating firewall rule: %w", err)
}
return nil
}
// GetRule retrieves a firewall rule.
func (c *Client) GetRule(ctx context.Context, pos int) (*RuleGetResponseData, error) {
resBody := &RuleGetResponseBody{}
err := c.DoRequest(
ctx,
http.MethodGet,
fmt.Sprintf("%s/%d", c.rulesPath(), pos),
nil,
resBody,
)
if err != nil {
return nil, fmt.Errorf("error retrieving firewall rule %d: %w", pos, err)
}
if resBody.Data == nil {
return nil, errors.New("the server did not include a data object in the response")
}
return resBody.Data, nil
}
// ListRules retrieves a list of firewall rules.
func (c *Client) ListRules(ctx context.Context) ([]*RuleListResponseData, error) {
resBody := &RuleListResponseBody{}
err := c.DoRequest(ctx, http.MethodGet, c.rulesPath(), nil, resBody)
if err != nil {
return nil, fmt.Errorf("error retrieving firewall rules: %w", err)
}
if resBody.Data == nil {
return nil, errors.New("the server did not include a data object in the response")
}
return resBody.Data, nil
}
// UpdateRule updates a firewall rule.
func (c *Client) UpdateRule(ctx context.Context, pos int, d *RuleUpdateRequestBody) error {
err := c.DoRequest(
ctx,
http.MethodPut,
fmt.Sprintf("%s/%d", c.rulesPath(), pos),
d,
nil,
)
if err != nil {
return fmt.Errorf("error updating firewall rule %d: %w", pos, err)
}
return nil
}
// DeleteRule deletes a firewall rule.
func (c *Client) DeleteRule(ctx context.Context, pos int) error {
err := c.DoRequest(
ctx,
http.MethodDelete,
fmt.Sprintf("%s/%d", c.rulesPath(), pos),
nil,
nil,
)
if err != nil {
return fmt.Errorf("error deleting firewall rule %d: %w", pos, err)
}
return nil
}

18
proxmox/types/client.go Normal file
View File

@ -0,0 +1,18 @@
package types
import "context"
type Client interface {
// DoRequest performs a request against the Proxmox API.
DoRequest(
ctx context.Context,
method, path string,
requestBody, responseBody interface{},
) error
// ExpandPath expands a path relative to the client's base path.
// For example, if the client is configured for a VM and the
// path is "firewall/options", the returned path will be
// "/nodes/<node>/qemu/<vmid>/firewall/options".
ExpandPath(path string) string
}

View File

@ -2,7 +2,7 @@
* 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 proxmox
package types
import (
"bytes"

View File

@ -7,6 +7,7 @@ package proxmox
import (
"context"
"errors"
"net/http"
"sort"
)
@ -15,7 +16,7 @@ func (c *VirtualEnvironmentClient) GetACL(
ctx context.Context,
) ([]*VirtualEnvironmentACLGetResponseData, error) {
resBody := &VirtualEnvironmentACLGetResponseBody{}
err := c.DoRequest(ctx, hmGET, "access/acl", nil, resBody)
err := c.DoRequest(ctx, http.MethodGet, "access/acl", nil, resBody)
if err != nil {
return nil, err
}
@ -36,5 +37,5 @@ func (c *VirtualEnvironmentClient) UpdateACL(
ctx context.Context,
d *VirtualEnvironmentACLUpdateRequestBody,
) error {
return c.DoRequest(ctx, hmPUT, "access/acl", d, nil)
return c.DoRequest(ctx, http.MethodPut, "access/acl", d, nil)
}

View File

@ -4,6 +4,8 @@
package proxmox
import "github.com/bpg/terraform-provider-proxmox/proxmox/types"
// VirtualEnvironmentACLGetResponseBody contains the body from an access control list response.
type VirtualEnvironmentACLGetResponseBody struct {
Data []*VirtualEnvironmentACLGetResponseData `json:"data,omitempty"`
@ -11,19 +13,19 @@ type VirtualEnvironmentACLGetResponseBody struct {
// VirtualEnvironmentACLGetResponseData contains the data from an access control list response.
type VirtualEnvironmentACLGetResponseData struct {
Path string `json:"path"`
Propagate *CustomBool `json:"propagate,omitempty"`
RoleID string `json:"roleid"`
Type string `json:"type"`
UserOrGroupID string `json:"ugid"`
Path string `json:"path"`
Propagate *types.CustomBool `json:"propagate,omitempty"`
RoleID string `json:"roleid"`
Type string `json:"type"`
UserOrGroupID string `json:"ugid"`
}
// VirtualEnvironmentACLUpdateRequestBody contains the data for an access control list update request.
type VirtualEnvironmentACLUpdateRequestBody struct {
Delete *CustomBool `json:"delete,omitempty" url:"delete,omitempty,int"`
Groups []string `json:"groups,omitempty" url:"groups,omitempty,comma"`
Path string `json:"path" url:"path"`
Propagate *CustomBool `json:"propagate,omitempty" url:"propagate,omitempty,int"`
Roles []string `json:"roles" url:"roles,comma"`
Users []string `json:"users,omitempty" url:"users,omitempty,comma"`
Delete *types.CustomBool `json:"delete,omitempty" url:"delete,omitempty,int"`
Groups []string `json:"groups,omitempty" url:"groups,omitempty,comma"`
Path string `json:"path" url:"path"`
Propagate *types.CustomBool `json:"propagate,omitempty" url:"propagate,omitempty,int"`
Roles []string `json:"roles" url:"roles,comma"`
Users []string `json:"users,omitempty" url:"users,omitempty,comma"`
}

View File

@ -46,7 +46,7 @@ func (c *VirtualEnvironmentClient) Authenticate(ctx context.Context, reset bool)
req, err := http.NewRequestWithContext(
ctx,
hmPOST,
http.MethodPost,
fmt.Sprintf("%s/%s/access/ticket", c.Endpoint, basePathJSONAPI),
reqBody,
)

View File

@ -4,6 +4,8 @@
package proxmox
import "github.com/bpg/terraform-provider-proxmox/proxmox/types"
// VirtualEnvironmentAuthenticationResponseBody contains the body from an authentication response.
type VirtualEnvironmentAuthenticationResponseBody struct {
Data *VirtualEnvironmentAuthenticationResponseData `json:"data,omitempty"`
@ -11,11 +13,11 @@ type VirtualEnvironmentAuthenticationResponseBody struct {
// VirtualEnvironmentAuthenticationResponseCapabilities contains the supported capabilities for a session.
type VirtualEnvironmentAuthenticationResponseCapabilities struct {
Access *CustomPrivileges `json:"access,omitempty"`
Datacenter *CustomPrivileges `json:"dc,omitempty"`
Nodes *CustomPrivileges `json:"nodes,omitempty"`
Storage *CustomPrivileges `json:"storage,omitempty"`
VMs *CustomPrivileges `json:"vms,omitempty"`
Access *types.CustomPrivileges `json:"access,omitempty"`
Datacenter *types.CustomPrivileges `json:"dc,omitempty"`
Nodes *types.CustomPrivileges `json:"nodes,omitempty"`
Storage *types.CustomPrivileges `json:"storage,omitempty"`
VMs *types.CustomPrivileges `json:"vms,omitempty"`
}
// VirtualEnvironmentAuthenticationResponseData contains the data from an authentication response.

View File

@ -8,6 +8,7 @@ import (
"context"
"errors"
"fmt"
"net/http"
"net/url"
)
@ -19,7 +20,7 @@ func (c *VirtualEnvironmentClient) DeleteCertificate(
) error {
return c.DoRequest(
ctx,
hmDELETE,
http.MethodDelete,
fmt.Sprintf("nodes/%s/certificates/custom", url.PathEscape(nodeName)),
d,
nil,
@ -34,7 +35,7 @@ func (c *VirtualEnvironmentClient) ListCertificates(
resBody := &VirtualEnvironmentCertificateListResponseBody{}
err := c.DoRequest(
ctx,
hmGET,
http.MethodGet,
fmt.Sprintf("nodes/%s/certificates/info", url.PathEscape(nodeName)),
nil,
resBody,
@ -58,7 +59,7 @@ func (c *VirtualEnvironmentClient) UpdateCertificate(
) error {
return c.DoRequest(
ctx,
hmPOST,
http.MethodPost,
fmt.Sprintf("nodes/%s/certificates/custom", url.PathEscape(nodeName)),
d,
nil,

View File

@ -4,9 +4,11 @@
package proxmox
import "github.com/bpg/terraform-provider-proxmox/proxmox/types"
// VirtualEnvironmentCertificateDeleteRequestBody contains the data for a custom certificate delete request.
type VirtualEnvironmentCertificateDeleteRequestBody struct {
Restart *CustomBool `json:"restart,omitempty" url:"restart,omitempty,int"`
Restart *types.CustomBool `json:"restart,omitempty" url:"restart,omitempty,int"`
}
// VirtualEnvironmentCertificateListResponseBody contains the body from a certificate list response.
@ -16,22 +18,22 @@ type VirtualEnvironmentCertificateListResponseBody struct {
// VirtualEnvironmentCertificateListResponseData contains the data from a certificate list response.
type VirtualEnvironmentCertificateListResponseData struct {
Certificates *string `json:"pem,omitempty"`
FileName *string `json:"filename,omitempty"`
Fingerprint *string `json:"fingerprint,omitempty"`
Issuer *string `json:"issuer,omitempty"`
NotAfter *CustomTimestamp `json:"notafter,omitempty"`
NotBefore *CustomTimestamp `json:"notbefore,omitempty"`
PublicKeyBits *int `json:"public-key-bits,omitempty"`
PublicKeyType *string `json:"public-key-type,omitempty"`
Subject *string `json:"subject,omitempty"`
SubjectAlternativeNames *[]string `json:"san,omitempty"`
Certificates *string `json:"pem,omitempty"`
FileName *string `json:"filename,omitempty"`
Fingerprint *string `json:"fingerprint,omitempty"`
Issuer *string `json:"issuer,omitempty"`
NotAfter *types.CustomTimestamp `json:"notafter,omitempty"`
NotBefore *types.CustomTimestamp `json:"notbefore,omitempty"`
PublicKeyBits *int `json:"public-key-bits,omitempty"`
PublicKeyType *string `json:"public-key-type,omitempty"`
Subject *string `json:"subject,omitempty"`
SubjectAlternativeNames *[]string `json:"san,omitempty"`
}
// VirtualEnvironmentCertificateUpdateRequestBody contains the body for a custom certificate update request.
type VirtualEnvironmentCertificateUpdateRequestBody struct {
Certificates string `json:"certificates" url:"certificates"`
Force *CustomBool `json:"force,omitempty" url:"force,omitempty,int"`
PrivateKey *string `json:"key,omitempty" url:"key,omitempty"`
Restart *CustomBool `json:"restart,omitempty" url:"restart,omitempty,int"`
Certificates string `json:"certificates" url:"certificates"`
Force *types.CustomBool `json:"force,omitempty" url:"force,omitempty,int"`
PrivateKey *string `json:"key,omitempty" url:"key,omitempty"`
Restart *types.CustomBool `json:"restart,omitempty" url:"restart,omitempty,int"`
}

View File

@ -16,9 +16,9 @@ import (
"net/url"
"strings"
"github.com/hashicorp/terraform-plugin-log/tflog"
"github.com/google/go-querystring/query"
"github.com/hashicorp/terraform-plugin-log/tflog"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/logging"
)
// NewVirtualEnvironmentClient creates and initializes a VirtualEnvironmentClient instance.
@ -57,13 +57,16 @@ func NewVirtualEnvironmentClient(
pOTP = &otp
}
httpClient := &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: insecure,
},
var transport http.RoundTripper = &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: insecure, //nolint:gosec
},
}
if logging.IsDebugOrHigher() {
transport = logging.NewLoggingHTTPTransport(transport)
}
httpClient := &http.Client{Transport: transport}
return &VirtualEnvironmentClient{
Endpoint: strings.TrimRight(u.String(), "/"),
@ -84,11 +87,6 @@ func (c *VirtualEnvironmentClient) DoRequest(
var reqBodyReader io.Reader
var reqContentLength *int64
tflog.Debug(ctx, "performing HTTP request", map[string]interface{}{
"method": method,
"path": path,
})
modifiedPath := path
reqBodyType := ""
@ -100,19 +98,8 @@ func (c *VirtualEnvironmentClient) DoRequest(
reqBodyReader = multipartData.Reader
reqBodyType = fmt.Sprintf("multipart/form-data; boundary=%s", multipartData.Boundary)
reqContentLength = multipartData.Size
tflog.Debug(ctx, "added multipart request body to HTTP request", map[string]interface{}{
"method": method,
"path": modifiedPath,
})
} else if pipedBody {
reqBodyReader = pipedBodyReader
tflog.Debug(ctx, "added piped request body to HTTP request", map[string]interface{}{
"method": method,
"path": modifiedPath,
})
} else {
v, err := query.Values(requestBody)
if err != nil {
@ -124,7 +111,7 @@ func (c *VirtualEnvironmentClient) DoRequest(
encodedValues := v.Encode()
if encodedValues != "" {
if method == hmDELETE || method == hmGET || method == hmHEAD {
if method == http.MethodDelete || method == http.MethodGet || method == http.MethodHead {
if !strings.Contains(modifiedPath, "?") {
modifiedPath = fmt.Sprintf("%s?%s", modifiedPath, encodedValues)
} else {
@ -134,12 +121,6 @@ func (c *VirtualEnvironmentClient) DoRequest(
reqBodyReader = bytes.NewBufferString(encodedValues)
reqBodyType = "application/x-www-form-urlencoded"
}
tflog.Debug(ctx, "added request body to HTTP request", map[string]interface{}{
"method": method,
"path": modifiedPath,
"encodedValues": encodedValues,
})
}
}
} else {
@ -180,9 +161,6 @@ func (c *VirtualEnvironmentClient) DoRequest(
return err
}
tflog.Debug(ctx, "sending request", map[string]interface{}{
"path": req.URL.Path,
})
res, err := c.httpClient.Do(req)
if err != nil {
fErr := fmt.Errorf(

View File

@ -7,15 +7,14 @@ package proxmox
import (
"io"
"net/http"
"github.com/bpg/terraform-provider-proxmox/proxmox/cluster"
"github.com/bpg/terraform-provider-proxmox/proxmox/container"
"github.com/bpg/terraform-provider-proxmox/proxmox/vm"
)
const (
basePathJSONAPI = "api2/json"
hmDELETE = "DELETE"
hmGET = "GET"
hmHEAD = "HEAD"
hmPOST = "POST"
hmPUT = "PUT"
)
// VirtualEnvironmentClient implements an API client for the Proxmox Virtual Environment API.
@ -42,3 +41,33 @@ type VirtualEnvironmentMultiPartData struct {
Reader io.Reader
Size *int64
}
type API interface {
Cluster() *cluster.Client
VM(nodeName string, vmID int) *vm.Client
Container(nodeName string, vmID int) *container.Client
}
func (c *VirtualEnvironmentClient) API() API {
return &client{c}
}
func (c *VirtualEnvironmentClient) ExpandPath(path string) string {
return path
}
type client struct {
c *VirtualEnvironmentClient
}
func (c *client) Cluster() *cluster.Client {
return &cluster.Client{Client: c.c}
}
func (c *client) VM(nodeName string, vmID int) *vm.Client {
return &vm.Client{Client: c.c, NodeName: nodeName, VMID: vmID}
}
func (c *client) Container(nodeName string, vmID int) *container.Client {
return &container.Client{Client: c.c, NodeName: nodeName, VMID: vmID}
}

View File

@ -1,29 +0,0 @@
/* 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 proxmox
import (
"context"
"errors"
)
// GetClusterNextID retrieves the next free VM identifier for the cluster.
func (c *VirtualEnvironmentClient) GetClusterNextID(ctx context.Context, vmID *int) (*int, error) {
reqBody := &VirtualEnvironmentClusterNextIDRequestBody{
VMID: vmID,
}
resBody := &VirtualEnvironmentClusterNextIDResponseBody{}
err := c.DoRequest(ctx, hmGET, "cluster/nextid", reqBody, resBody)
if err != nil {
return nil, err
}
if resBody.Data == nil {
return nil, errors.New("the server did not include a data object in the response")
}
return (*int)(resBody.Data), nil
}

View File

@ -1,92 +0,0 @@
/* 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 proxmox
import (
"context"
"errors"
"fmt"
"net/url"
"sort"
)
// CreateAlias create an alias
func (c *VirtualEnvironmentClient) CreateAlias(
ctx context.Context,
d *VirtualEnvironmentClusterAliasCreateRequestBody,
) error {
return c.DoRequest(ctx, hmPOST, "cluster/firewall/aliases", d, nil)
}
// DeleteAlias delete an alias
func (c *VirtualEnvironmentClient) DeleteAlias(ctx context.Context, id string) error {
return c.DoRequest(
ctx,
hmDELETE,
fmt.Sprintf("cluster/firewall/aliases/%s", url.PathEscape(id)),
nil,
nil,
)
}
// GetAlias retrieves an alias
func (c *VirtualEnvironmentClient) GetAlias(
ctx context.Context,
id string,
) (*VirtualEnvironmentClusterAliasGetResponseData, error) {
resBody := &VirtualEnvironmentClusterAliasGetResponseBody{}
err := c.DoRequest(
ctx,
hmGET,
fmt.Sprintf("cluster/firewall/aliases/%s", url.PathEscape(id)),
nil,
resBody,
)
if err != nil {
return nil, err
}
if resBody.Data == nil {
return nil, errors.New("the server did not include a data object in the response")
}
return resBody.Data, nil
}
// ListAliases retrieves a list of aliases.
func (c *VirtualEnvironmentClient) ListAliases(
ctx context.Context,
) ([]*VirtualEnvironmentClusterAliasGetResponseData, error) {
resBody := &VirtualEnvironmentClusterAliasListResponseBody{}
err := c.DoRequest(ctx, hmGET, "cluster/firewall/aliases", nil, resBody)
if err != nil {
return nil, err
}
if resBody.Data == nil {
return nil, errors.New("the server did not include a data object in the response")
}
sort.Slice(resBody.Data, func(i, j int) bool {
return resBody.Data[i].Name < resBody.Data[j].Name
})
return resBody.Data, nil
}
// UpdateAlias updates an alias.
func (c *VirtualEnvironmentClient) UpdateAlias(
ctx context.Context,
id string,
d *VirtualEnvironmentClusterAliasUpdateRequestBody,
) error {
return c.DoRequest(
ctx,
hmPUT,
fmt.Sprintf("cluster/firewall/aliases/%s", url.PathEscape(id)),
d,
nil,
)
}

View File

@ -1,38 +0,0 @@
/* 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 proxmox
// VirtualEnvironmentClusterAliasCreateRequestBody contains the data for an alias create request.
type VirtualEnvironmentClusterAliasCreateRequestBody struct {
Comment *string `json:"comment,omitempty" url:"comment,omitempty"`
Name string `json:"name" url:"name"`
CIDR string `json:"cidr" url:"cidr"`
}
// VirtualEnvironmentClusterAliasGetResponseBody contains the body from an alias get response.
type VirtualEnvironmentClusterAliasGetResponseBody struct {
Data *VirtualEnvironmentClusterAliasGetResponseData `json:"data,omitempty"`
}
// VirtualEnvironmentClusterAliasGetResponseData contains the data from an alias get response.
type VirtualEnvironmentClusterAliasGetResponseData struct {
Comment *string `json:"comment,omitempty" url:"comment,omitempty"`
Name string `json:"name" url:"name"`
CIDR string `json:"cidr" url:"cidr"`
Digest *string `json:"digest" url:"digest"`
IPVersion int `json:"ipversion" url:"ipversion"`
}
// VirtualEnvironmentClusterAliasListResponseBody contains the data from an alias get response.
type VirtualEnvironmentClusterAliasListResponseBody struct {
Data []*VirtualEnvironmentClusterAliasGetResponseData `json:"data,omitempty"`
}
// VirtualEnvironmentClusterAliasUpdateRequestBody contains the data for an alias update request.
type VirtualEnvironmentClusterAliasUpdateRequestBody struct {
Comment *string `json:"comment,omitempty" url:"comment,omitempty"`
ReName string `json:"rename" url:"rename"`
CIDR string `json:"cidr" url:"cidr"`
}

View File

@ -1,115 +0,0 @@
/* 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 proxmox
import (
"context"
"errors"
"fmt"
"net/url"
"sort"
)
// CreateIPSet create an IPSet
func (c *VirtualEnvironmentClient) CreateIPSet(
ctx context.Context,
d *VirtualEnvironmentClusterIPSetCreateRequestBody,
) error {
return c.DoRequest(ctx, hmPOST, "cluster/firewall/ipset", d, nil)
}
// AddCIDRToIPSet adds IP or Network to IPSet
func (c *VirtualEnvironmentClient) AddCIDRToIPSet(
ctx context.Context,
id string,
d *VirtualEnvironmentClusterIPSetGetResponseData,
) error {
return c.DoRequest(
ctx,
hmPOST,
fmt.Sprintf("cluster/firewall/ipset/%s/", url.PathEscape(id)),
d,
nil,
)
}
// UpdateIPSet updates an IPSet.
func (c *VirtualEnvironmentClient) UpdateIPSet(
ctx context.Context,
d *VirtualEnvironmentClusterIPSetUpdateRequestBody,
) error {
return c.DoRequest(ctx, hmPOST, "cluster/firewall/ipset/", d, nil)
}
// DeleteIPSet delete an IPSet
func (c *VirtualEnvironmentClient) DeleteIPSet(ctx context.Context, id string) error {
return c.DoRequest(
ctx,
hmDELETE,
fmt.Sprintf("cluster/firewall/ipset/%s", url.PathEscape(id)),
nil,
nil,
)
}
// DeleteIPSetContent remove IP or Network from IPSet.
func (c *VirtualEnvironmentClient) DeleteIPSetContent(
ctx context.Context,
id string,
cidr string,
) error {
return c.DoRequest(
ctx,
hmDELETE,
fmt.Sprintf("cluster/firewall/ipset/%s/%s", url.PathEscape(id), url.PathEscape(cidr)),
nil,
nil,
)
}
// GetListIPSetContent retrieve a list of IPSet content
func (c *VirtualEnvironmentClient) GetListIPSetContent(
ctx context.Context,
id string,
) ([]*VirtualEnvironmentClusterIPSetGetResponseData, error) {
resBody := &VirtualEnvironmentClusterIPSetGetResponseBody{}
err := c.DoRequest(
ctx,
hmGET,
fmt.Sprintf("cluster/firewall/ipset/%s", url.PathEscape(id)),
nil,
resBody,
)
if err != nil {
return nil, err
}
if resBody.Data == nil {
return nil, errors.New("the server did not include a data object in the response")
}
return resBody.Data, nil
}
// GetListIPSets retrieves list of IPSets.
func (c *VirtualEnvironmentClient) GetListIPSets(
ctx context.Context,
) (*VirtualEnvironmentClusterIPSetListResponseBody, error) {
resBody := &VirtualEnvironmentClusterIPSetListResponseBody{}
err := c.DoRequest(ctx, hmGET, "cluster/firewall/ipset", nil, resBody)
if err != nil {
return nil, err
}
if resBody.Data == nil {
return nil, errors.New("the server did not include a data object in the response")
}
sort.Slice(resBody.Data, func(i, j int) bool {
return resBody.Data[i].Name < resBody.Data[j].Name
})
return resBody, nil
}

View File

@ -1,48 +0,0 @@
/* 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/. */
/**
* Reference: https://pve.proxmox.com/pve-docs/api-viewer/#/cluster/firewall/ipset
*/
package proxmox
// VirtualEnvironmentClusterIPSetListResponseBody contains the data from an IPSet get response.
type VirtualEnvironmentClusterIPSetListResponseBody struct {
Data []*VirtualEnvironmentClusterIPSetCreateRequestBody `json:"data,omitempty"`
}
// VirtualEnvironmentClusterIPSetCreateRequestBody contains the data for an IPSet create request
type VirtualEnvironmentClusterIPSetCreateRequestBody struct {
Comment string `json:"comment,omitempty" url:"comment,omitempty"`
Name string `json:"name" url:"name"`
}
// VirtualEnvironmentClusterIPSetGetResponseBody contains the body from an IPSet get response.
type VirtualEnvironmentClusterIPSetGetResponseBody struct {
Data []*VirtualEnvironmentClusterIPSetGetResponseData `json:"data,omitempty"`
}
// VirtualEnvironmentClusterIPSetGetResponseData contains the data from an IPSet get response.
type VirtualEnvironmentClusterIPSetGetResponseData struct {
CIDR string `json:"cidr" url:"cidr"`
NoMatch *CustomBool `json:"nomatch,omitempty" url:"nomatch,omitempty,int"`
Comment string `json:"comment,omitempty" url:"comment,omitempty"`
}
// VirtualEnvironmentClusterIPSetUpdateRequestBody contains the data for an IPSet update request.
type VirtualEnvironmentClusterIPSetUpdateRequestBody struct {
ReName string `json:"rename,omitempty" url:"rename,omitempty"`
Comment *string `json:"comment,omitempty" url:"comment,omitempty"`
Name string `json:"name" url:"name"`
}
// VirtualEnvironmentClusterIPSetListResponseData contains list of IPSets from
type VirtualEnvironmentClusterIPSetListResponseData struct {
Comment *string `json:"comment,omitempty" url:"comment,omitempty"`
Name string `json:"name" url:"name"`
}
// VirtualEnvironmentClusterIPSetContent is an array of VirtualEnvironmentClusterIPSetGetResponseData.
type VirtualEnvironmentClusterIPSetContent []VirtualEnvironmentClusterIPSetGetResponseData

View File

@ -1,15 +0,0 @@
/* 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 proxmox
// VirtualEnvironmentClusterNextIDRequestBody contains the data for a cluster next id request.
type VirtualEnvironmentClusterNextIDRequestBody struct {
VMID *int `json:"vmid,omitempty" url:"vmid,omitempty"`
}
// VirtualEnvironmentClusterNextIDResponseBody contains the body from a cluster next id response.
type VirtualEnvironmentClusterNextIDResponseBody struct {
Data *CustomInt `json:"data,omitempty"`
}

View File

@ -8,6 +8,7 @@ import (
"context"
"errors"
"fmt"
"net/http"
"net/url"
"strings"
"time"
@ -22,7 +23,7 @@ func (c *VirtualEnvironmentClient) CloneContainer(
) error {
return c.DoRequest(
ctx,
hmPOST,
http.MethodPost,
fmt.Sprintf("nodes/%s/lxc/%d/clone", url.PathEscape(nodeName), vmID),
d,
nil,
@ -35,7 +36,7 @@ func (c *VirtualEnvironmentClient) CreateContainer(
nodeName string,
d *VirtualEnvironmentContainerCreateRequestBody,
) error {
return c.DoRequest(ctx, hmPOST, fmt.Sprintf("nodes/%s/lxc", url.PathEscape(nodeName)), d, nil)
return c.DoRequest(ctx, http.MethodPost, fmt.Sprintf("nodes/%s/lxc", url.PathEscape(nodeName)), d, nil)
}
// DeleteContainer deletes a container.
@ -46,7 +47,7 @@ func (c *VirtualEnvironmentClient) DeleteContainer(
) error {
return c.DoRequest(
ctx,
hmDELETE,
http.MethodDelete,
fmt.Sprintf("nodes/%s/lxc/%d", url.PathEscape(nodeName), vmID),
nil,
nil,
@ -62,7 +63,7 @@ func (c *VirtualEnvironmentClient) GetContainer(
resBody := &VirtualEnvironmentContainerGetResponseBody{}
err := c.DoRequest(
ctx,
hmGET,
http.MethodGet,
fmt.Sprintf("nodes/%s/lxc/%d/config", url.PathEscape(nodeName), vmID),
nil,
resBody,
@ -87,7 +88,7 @@ func (c *VirtualEnvironmentClient) GetContainerStatus(
resBody := &VirtualEnvironmentContainerGetStatusResponseBody{}
err := c.DoRequest(
ctx,
hmGET,
http.MethodGet,
fmt.Sprintf("nodes/%s/lxc/%d/status/current", url.PathEscape(nodeName), vmID),
nil,
resBody,
@ -112,7 +113,7 @@ func (c *VirtualEnvironmentClient) RebootContainer(
) error {
return c.DoRequest(
ctx,
hmPOST,
http.MethodPost,
fmt.Sprintf("nodes/%s/lxc/%d/status/reboot", url.PathEscape(nodeName), vmID),
d,
nil,
@ -128,7 +129,7 @@ func (c *VirtualEnvironmentClient) ShutdownContainer(
) error {
return c.DoRequest(
ctx,
hmPOST,
http.MethodPost,
fmt.Sprintf("nodes/%s/lxc/%d/status/shutdown", url.PathEscape(nodeName), vmID),
d,
nil,
@ -143,7 +144,7 @@ func (c *VirtualEnvironmentClient) StartContainer(
) error {
return c.DoRequest(
ctx,
hmPOST,
http.MethodPost,
fmt.Sprintf("nodes/%s/lxc/%d/status/start", url.PathEscape(nodeName), vmID),
nil,
nil,
@ -158,7 +159,7 @@ func (c *VirtualEnvironmentClient) StopContainer(
) error {
return c.DoRequest(
ctx,
hmPOST,
http.MethodPost,
fmt.Sprintf("nodes/%s/lxc/%d/status/stop", url.PathEscape(nodeName), vmID),
nil,
nil,
@ -174,7 +175,7 @@ func (c *VirtualEnvironmentClient) UpdateContainer(
) error {
return c.DoRequest(
ctx,
hmPUT,
http.MethodPut,
fmt.Sprintf("nodes/%s/lxc/%d/config", url.PathEscape(nodeName), vmID),
d,
nil,

View File

@ -10,25 +10,27 @@ import (
"net/url"
"strconv"
"strings"
"github.com/bpg/terraform-provider-proxmox/proxmox/types"
)
// VirtualEnvironmentContainerCloneRequestBody contains the data for an container clone request.
type VirtualEnvironmentContainerCloneRequestBody struct {
BandwidthLimit *int `json:"bwlimit,omitempty" url:"bwlimit,omitempty"`
Description *string `json:"description,omitempty" url:"description,omitempty"`
FullCopy *CustomBool `json:"full,omitempty" url:"full,omitempty,int"`
Hostname *string `json:"hostname,omitempty" url:"hostname,omitempty"`
PoolID *string `json:"pool,omitempty" url:"pool,omitempty"`
SnapshotName *string `json:"snapname,omitempty" url:"snapname,omitempty"`
TargetNodeName *string `json:"target,omitempty" url:"target,omitempty"`
TargetStorage *string `json:"storage,omitempty" url:"storage,omitempty"`
VMIDNew int `json:"newid" url:"newid"`
BandwidthLimit *int `json:"bwlimit,omitempty" url:"bwlimit,omitempty"`
Description *string `json:"description,omitempty" url:"description,omitempty"`
FullCopy *types.CustomBool `json:"full,omitempty" url:"full,omitempty,int"`
Hostname *string `json:"hostname,omitempty" url:"hostname,omitempty"`
PoolID *string `json:"pool,omitempty" url:"pool,omitempty"`
SnapshotName *string `json:"snapname,omitempty" url:"snapname,omitempty"`
TargetNodeName *string `json:"target,omitempty" url:"target,omitempty"`
TargetStorage *string `json:"storage,omitempty" url:"storage,omitempty"`
VMIDNew int `json:"newid" url:"newid"`
}
// VirtualEnvironmentContainerCreateRequestBody contains the data for an user create request.
type VirtualEnvironmentContainerCreateRequestBody struct {
BandwidthLimit *float64 `json:"bwlimit,omitempty" url:"bwlimit,omitempty"`
ConsoleEnabled *CustomBool `json:"console,omitempty" url:"console,omitempty,int"`
ConsoleEnabled *types.CustomBool `json:"console,omitempty" url:"console,omitempty,int"`
ConsoleMode *string `json:"cmode,omitempty" url:"cmode,omitempty"`
CPUArchitecture *string `json:"arch,omitempty" url:"arch,omitempty"`
CPUCores *int `json:"cores,omitempty" url:"cores,omitempty"`
@ -41,10 +43,10 @@ type VirtualEnvironmentContainerCreateRequestBody struct {
DNSDomain *string `json:"searchdomain,omitempty" url:"searchdomain,omitempty"`
DNSServer *string `json:"nameserver,omitempty" url:"nameserver,omitempty"`
Features *VirtualEnvironmentContainerCustomFeatures `json:"features,omitempty" url:"features,omitempty"`
Force *CustomBool `json:"force,omitempty" url:"force,omitempty,int"`
Force *types.CustomBool `json:"force,omitempty" url:"force,omitempty,int"`
HookScript *string `json:"hookscript,omitempty" url:"hookscript,omitempty"`
Hostname *string `json:"hostname,omitempty" url:"hostname,omitempty"`
IgnoreUnpackErrors *CustomBool `json:"ignore-unpack-errors,omitempty" url:"force,omitempty,int"`
IgnoreUnpackErrors *types.CustomBool `json:"ignore-unpack-errors,omitempty" url:"force,omitempty,int"`
Lock *string `json:"lock,omitempty" url:"lock,omitempty,int"`
MountPoints VirtualEnvironmentContainerCustomMountPointArray `json:"mp,omitempty" url:"mp,omitempty,numbered"`
NetworkInterfaces VirtualEnvironmentContainerCustomNetworkInterfaceArray `json:"net,omitempty" url:"net,omitempty,numbered"`
@ -52,43 +54,43 @@ type VirtualEnvironmentContainerCreateRequestBody struct {
OSType *string `json:"ostype,omitempty" url:"ostype,omitempty"`
Password *string `json:"password,omitempty" url:"password,omitempty"`
PoolID *string `json:"pool,omitempty" url:"pool,omitempty"`
Protection *CustomBool `json:"protection,omitempty" url:"protection,omitempty,int"`
Restore *CustomBool `json:"restore,omitempty" url:"restore,omitempty,int"`
Protection *types.CustomBool `json:"protection,omitempty" url:"protection,omitempty,int"`
Restore *types.CustomBool `json:"restore,omitempty" url:"restore,omitempty,int"`
RootFS *VirtualEnvironmentContainerCustomRootFS `json:"rootfs,omitempty" url:"rootfs,omitempty"`
SSHKeys *VirtualEnvironmentContainerCustomSSHKeys `json:"ssh-public-keys,omitempty" url:"ssh-public-keys,omitempty"`
Start *CustomBool `json:"start,omitempty" url:"start,omitempty,int"`
StartOnBoot *CustomBool `json:"onboot,omitempty" url:"onboot,omitempty,int"`
Start *types.CustomBool `json:"start,omitempty" url:"start,omitempty,int"`
StartOnBoot *types.CustomBool `json:"onboot,omitempty" url:"onboot,omitempty,int"`
StartupBehavior *VirtualEnvironmentContainerCustomStartupBehavior `json:"startup,omitempty" url:"startup,omitempty"`
Swap *int `json:"swap,omitempty" url:"swap,omitempty"`
Tags *string `json:"tags,omitempty" url:"tags,omitempty"`
Template *CustomBool `json:"template,omitempty" url:"template,omitempty,int"`
Template *types.CustomBool `json:"template,omitempty" url:"template,omitempty,int"`
TTY *int `json:"tty,omitempty" url:"tty,omitempty"`
Unique *CustomBool `json:"unique,omitempty" url:"unique,omitempty,int"`
Unprivileged *CustomBool `json:"unprivileged,omitempty" url:"unprivileged,omitempty,int"`
Unique *types.CustomBool `json:"unique,omitempty" url:"unique,omitempty,int"`
Unprivileged *types.CustomBool `json:"unprivileged,omitempty" url:"unprivileged,omitempty,int"`
VMID *int `json:"vmid,omitempty" url:"vmid,omitempty"`
}
// VirtualEnvironmentContainerCustomFeatures contains the values for the "features" property.
type VirtualEnvironmentContainerCustomFeatures struct {
FUSE *CustomBool `json:"fuse,omitempty" url:"fuse,omitempty,int"`
KeyControl *CustomBool `json:"keyctl,omitempty" url:"keyctl,omitempty,int"`
MountTypes *[]string `json:"mount,omitempty" url:"mount,omitempty"`
Nesting *CustomBool `json:"nesting,omitempty" url:"nesting,omitempty,int"`
FUSE *types.CustomBool `json:"fuse,omitempty" url:"fuse,omitempty,int"`
KeyControl *types.CustomBool `json:"keyctl,omitempty" url:"keyctl,omitempty,int"`
MountTypes *[]string `json:"mount,omitempty" url:"mount,omitempty"`
Nesting *types.CustomBool `json:"nesting,omitempty" url:"nesting,omitempty,int"`
}
// VirtualEnvironmentContainerCustomMountPoint contains the values for the "mp[n]" properties.
type VirtualEnvironmentContainerCustomMountPoint struct {
ACL *CustomBool `json:"acl,omitempty" url:"acl,omitempty,int"`
Backup *CustomBool `json:"backup,omitempty" url:"backup,omitempty,int"`
DiskSize *string `json:"size,omitempty" url:"size,omitempty"`
Enabled bool `json:"-" url:"-"`
MountOptions *[]string `json:"mountoptions,omitempty" url:"mountoptions,omitempty"`
MountPoint string `json:"mp" url:"mp"`
Quota *CustomBool `json:"quota,omitempty" url:"quota,omitempty,int"`
ReadOnly *CustomBool `json:"ro,omitempty" url:"ro,omitempty,int"`
Replicate *CustomBool `json:"replicate,omitempty" url:"replicate,omitempty,int"`
Shared *CustomBool `json:"shared,omitempty" url:"shared,omitempty,int"`
Volume string `json:"volume" url:"volume"`
ACL *types.CustomBool `json:"acl,omitempty" url:"acl,omitempty,int"`
Backup *types.CustomBool `json:"backup,omitempty" url:"backup,omitempty,int"`
DiskSize *string `json:"size,omitempty" url:"size,omitempty"`
Enabled bool `json:"-" url:"-"`
MountOptions *[]string `json:"mountoptions,omitempty" url:"mountoptions,omitempty"`
MountPoint string `json:"mp" url:"mp"`
Quota *types.CustomBool `json:"quota,omitempty" url:"quota,omitempty,int"`
ReadOnly *types.CustomBool `json:"ro,omitempty" url:"ro,omitempty,int"`
Replicate *types.CustomBool `json:"replicate,omitempty" url:"replicate,omitempty,int"`
Shared *types.CustomBool `json:"shared,omitempty" url:"shared,omitempty,int"`
Volume string `json:"volume" url:"volume"`
}
// VirtualEnvironmentContainerCustomMountPointArray is an array of VirtualEnvironmentContainerCustomMountPoint.
@ -96,20 +98,20 @@ type VirtualEnvironmentContainerCustomMountPointArray []VirtualEnvironmentContai
// VirtualEnvironmentContainerCustomNetworkInterface contains the values for the "net[n]" properties.
type VirtualEnvironmentContainerCustomNetworkInterface struct {
Bridge *string `json:"bridge,omitempty" url:"bridge,omitempty"`
Enabled bool `json:"-" url:"-"`
Firewall *CustomBool `json:"firewall,omitempty" url:"firewall,omitempty,int"`
IPv4Address *string `json:"ip,omitempty" url:"ip,omitempty"`
IPv4Gateway *string `json:"gw,omitempty" url:"gw,omitempty"`
IPv6Address *string `json:"ip6,omitempty" url:"ip6,omitempty"`
IPv6Gateway *string `json:"gw6,omitempty" url:"gw6,omitempty"`
MACAddress *string `json:"hwaddr,omitempty" url:"hwaddr,omitempty"`
MTU *int `json:"mtu,omitempty" url:"mtu,omitempty"`
Name string `json:"name" url:"name"`
RateLimit *float64 `json:"rate,omitempty" url:"rate,omitempty"`
Tag *int `json:"tag,omitempty" url:"tag,omitempty"`
Trunks *[]int `json:"trunks,omitempty" url:"trunks,omitempty"`
Type *string `json:"type,omitempty" url:"type,omitempty"`
Bridge *string `json:"bridge,omitempty" url:"bridge,omitempty"`
Enabled bool `json:"-" url:"-"`
Firewall *types.CustomBool `json:"firewall,omitempty" url:"firewall,omitempty,int"`
IPv4Address *string `json:"ip,omitempty" url:"ip,omitempty"`
IPv4Gateway *string `json:"gw,omitempty" url:"gw,omitempty"`
IPv6Address *string `json:"ip6,omitempty" url:"ip6,omitempty"`
IPv6Gateway *string `json:"gw6,omitempty" url:"gw6,omitempty"`
MACAddress *string `json:"hwaddr,omitempty" url:"hwaddr,omitempty"`
MTU *int `json:"mtu,omitempty" url:"mtu,omitempty"`
Name string `json:"name" url:"name"`
RateLimit *float64 `json:"rate,omitempty" url:"rate,omitempty"`
Tag *int `json:"tag,omitempty" url:"tag,omitempty"`
Trunks *[]int `json:"trunks,omitempty" url:"trunks,omitempty"`
Type *string `json:"type,omitempty" url:"type,omitempty"`
}
// VirtualEnvironmentContainerCustomNetworkInterfaceArray is an array of VirtualEnvironmentContainerCustomNetworkInterface.
@ -117,14 +119,14 @@ type VirtualEnvironmentContainerCustomNetworkInterfaceArray []VirtualEnvironment
// VirtualEnvironmentContainerCustomRootFS contains the values for the "rootfs" property.
type VirtualEnvironmentContainerCustomRootFS struct {
ACL *CustomBool `json:"acl,omitempty" url:"acl,omitempty,int"`
DiskSize *string `json:"size,omitempty" url:"size,omitempty"`
MountOptions *[]string `json:"mountoptions,omitempty" url:"mountoptions,omitempty"`
Quota *CustomBool `json:"quota,omitempty" url:"quota,omitempty,int"`
ReadOnly *CustomBool `json:"ro,omitempty" url:"ro,omitempty,int"`
Replicate *CustomBool `json:"replicate,omitempty" url:"replicate,omitempty,int"`
Shared *CustomBool `json:"shared,omitempty" url:"shared,omitempty,int"`
Volume string `json:"volume" url:"volume"`
ACL *types.CustomBool `json:"acl,omitempty" url:"acl,omitempty,int"`
DiskSize *string `json:"size,omitempty" url:"size,omitempty"`
MountOptions *[]string `json:"mountoptions,omitempty" url:"mountoptions,omitempty"`
Quota *types.CustomBool `json:"quota,omitempty" url:"quota,omitempty,int"`
ReadOnly *types.CustomBool `json:"ro,omitempty" url:"ro,omitempty,int"`
Replicate *types.CustomBool `json:"replicate,omitempty" url:"replicate,omitempty,int"`
Shared *types.CustomBool `json:"shared,omitempty" url:"shared,omitempty,int"`
Volume string `json:"volume" url:"volume"`
}
// VirtualEnvironmentContainerCustomSSHKeys contains the values for the "ssh-public-keys" property.
@ -144,7 +146,7 @@ type VirtualEnvironmentContainerGetResponseBody struct {
// VirtualEnvironmentContainerGetResponseData contains the data from an user get response.
type VirtualEnvironmentContainerGetResponseData struct {
ConsoleEnabled *CustomBool `json:"console,omitempty"`
ConsoleEnabled *types.CustomBool `json:"console,omitempty"`
ConsoleMode *string `json:"cmode,omitempty"`
CPUArchitecture *string `json:"arch,omitempty"`
CPUCores *int `json:"cores,omitempty"`
@ -158,7 +160,7 @@ type VirtualEnvironmentContainerGetResponseData struct {
Features *VirtualEnvironmentContainerCustomFeatures `json:"features,omitempty"`
HookScript *string `json:"hookscript,omitempty"`
Hostname *string `json:"hostname,omitempty"`
Lock *CustomBool `json:"lock,omitempty"`
Lock *types.CustomBool `json:"lock,omitempty"`
LXCConfiguration *[][2]string `json:"lxc,omitempty"`
MountPoint0 VirtualEnvironmentContainerCustomMountPoint `json:"mp0,omitempty"`
MountPoint1 VirtualEnvironmentContainerCustomMountPoint `json:"mp1,omitempty"`
@ -173,15 +175,15 @@ type VirtualEnvironmentContainerGetResponseData struct {
NetworkInterface6 *VirtualEnvironmentContainerCustomNetworkInterface `json:"net6,omitempty"`
NetworkInterface7 *VirtualEnvironmentContainerCustomNetworkInterface `json:"net7,omitempty"`
OSType *string `json:"ostype,omitempty"`
Protection *CustomBool `json:"protection,omitempty"`
Protection *types.CustomBool `json:"protection,omitempty"`
RootFS *VirtualEnvironmentContainerCustomRootFS `json:"rootfs,omitempty"`
StartOnBoot *CustomBool `json:"onboot,omitempty"`
StartOnBoot *types.CustomBool `json:"onboot,omitempty"`
StartupBehavior *VirtualEnvironmentContainerCustomStartupBehavior `json:"startup,omitempty"`
Swap *int `json:"swap,omitempty"`
Tags *string `json:"tags,omitempty"`
Template *CustomBool `json:"template,omitempty"`
Template *types.CustomBool `json:"template,omitempty"`
TTY *int `json:"tty,omitempty"`
Unprivileged *CustomBool `json:"unprivileged,omitempty"`
Unprivileged *types.CustomBool `json:"unprivileged,omitempty"`
}
// VirtualEnvironmentContainerGetStatusResponseBody contains the body from a container get status response.
@ -210,8 +212,8 @@ type VirtualEnvironmentContainerRebootRequestBody struct {
// VirtualEnvironmentContainerShutdownRequestBody contains the body for a container shutdown request.
type VirtualEnvironmentContainerShutdownRequestBody struct {
ForceStop *CustomBool `json:"forceStop,omitempty" url:"forceStop,omitempty,int"`
Timeout *int `json:"timeout,omitempty" url:"timeout,omitempty"`
ForceStop *types.CustomBool `json:"forceStop,omitempty" url:"forceStop,omitempty,int"`
Timeout *int `json:"timeout,omitempty" url:"timeout,omitempty"`
}
// VirtualEnvironmentContainerUpdateRequestBody contains the data for an user update request.
@ -548,10 +550,10 @@ func (r *VirtualEnvironmentContainerCustomFeatures) UnmarshalJSON(b []byte) erro
if len(v) == 2 {
switch v[0] {
case "fuse":
bv := CustomBool(v[1] == "1")
bv := types.CustomBool(v[1] == "1")
r.FUSE = &bv
case "keyctl":
bv := CustomBool(v[1] == "1")
bv := types.CustomBool(v[1] == "1")
r.KeyControl = &bv
case "mount":
if v[1] != "" {
@ -562,7 +564,7 @@ func (r *VirtualEnvironmentContainerCustomFeatures) UnmarshalJSON(b []byte) erro
r.MountTypes = &a
}
case "nesting":
bv := CustomBool(v[1] == "1")
bv := types.CustomBool(v[1] == "1")
r.Nesting = &bv
}
}
@ -590,10 +592,10 @@ func (r *VirtualEnvironmentContainerCustomMountPoint) UnmarshalJSON(b []byte) er
} else if len(v) == 2 {
switch v[0] {
case "acl":
bv := CustomBool(v[1] == "1")
bv := types.CustomBool(v[1] == "1")
r.ACL = &bv
case "backup":
bv := CustomBool(v[1] == "1")
bv := types.CustomBool(v[1] == "1")
r.Backup = &bv
case "mountoptions":
if v[1] != "" {
@ -606,16 +608,16 @@ func (r *VirtualEnvironmentContainerCustomMountPoint) UnmarshalJSON(b []byte) er
case "mp":
r.MountPoint = v[1]
case "quota":
bv := CustomBool(v[1] == "1")
bv := types.CustomBool(v[1] == "1")
r.Quota = &bv
case "ro":
bv := CustomBool(v[1] == "1")
bv := types.CustomBool(v[1] == "1")
r.ReadOnly = &bv
case "replicate":
bv := CustomBool(v[1] == "1")
bv := types.CustomBool(v[1] == "1")
r.Replicate = &bv
case "shared":
bv := CustomBool(v[1] == "1")
bv := types.CustomBool(v[1] == "1")
r.Shared = &bv
case "size":
r.DiskSize = &v[1]
@ -647,7 +649,7 @@ func (r *VirtualEnvironmentContainerCustomNetworkInterface) UnmarshalJSON(b []by
case "bridge":
r.Bridge = &v[1]
case "firewall":
bv := CustomBool(v[1] == "1")
bv := types.CustomBool(v[1] == "1")
r.Firewall = &bv
case "gw":
r.IPv4Gateway = &v[1]
@ -728,7 +730,7 @@ func (r *VirtualEnvironmentContainerCustomRootFS) UnmarshalJSON(b []byte) error
} else if len(v) == 2 {
switch v[0] {
case "acl":
bv := CustomBool(v[1] == "1")
bv := types.CustomBool(v[1] == "1")
r.ACL = &bv
case "mountoptions":
if v[1] != "" {
@ -739,16 +741,16 @@ func (r *VirtualEnvironmentContainerCustomRootFS) UnmarshalJSON(b []byte) error
r.MountOptions = &a
}
case "quota":
bv := CustomBool(v[1] == "1")
bv := types.CustomBool(v[1] == "1")
r.Quota = &bv
case "ro":
bv := CustomBool(v[1] == "1")
bv := types.CustomBool(v[1] == "1")
r.ReadOnly = &bv
case "replicate":
bv := CustomBool(v[1] == "1")
bv := types.CustomBool(v[1] == "1")
r.Replicate = &bv
case "shared":
bv := CustomBool(v[1] == "1")
bv := types.CustomBool(v[1] == "1")
r.Shared = &bv
case "size":
r.DiskSize = &v[1]

View File

@ -10,6 +10,7 @@ import (
"fmt"
"io"
"mime/multipart"
"net/http"
"net/url"
"os"
"sort"
@ -27,7 +28,7 @@ func (c *VirtualEnvironmentClient) DeleteDatastoreFile(
) error {
err := c.DoRequest(
ctx,
hmDELETE,
http.MethodDelete,
fmt.Sprintf(
"nodes/%s/storage/%s/content/%s",
url.PathEscape(nodeName),
@ -52,7 +53,7 @@ func (c *VirtualEnvironmentClient) GetDatastoreStatus(
resBody := &VirtualEnvironmentDatastoreGetStatusResponseBody{}
err := c.DoRequest(
ctx,
hmGET,
http.MethodGet,
fmt.Sprintf(
"nodes/%s/storage/%s/status",
url.PathEscape(nodeName),
@ -80,7 +81,7 @@ func (c *VirtualEnvironmentClient) ListDatastoreFiles(
resBody := &VirtualEnvironmentDatastoreFileListResponseBody{}
err := c.DoRequest(
ctx,
hmGET,
http.MethodGet,
fmt.Sprintf(
"nodes/%s/storage/%s/content",
url.PathEscape(nodeName),
@ -113,7 +114,7 @@ func (c *VirtualEnvironmentClient) ListDatastores(
resBody := &VirtualEnvironmentDatastoreListResponseBody{}
err := c.DoRequest(
ctx,
hmGET,
http.MethodGet,
fmt.Sprintf("nodes/%s/storage", url.PathEscape(nodeName)),
d,
resBody,
@ -216,7 +217,7 @@ func (c *VirtualEnvironmentClient) UploadFileToDatastore(
resBody := &VirtualEnvironmentDatastoreUploadResponseBody{}
err = c.DoRequest(
ctx,
hmPOST,
http.MethodPost,
fmt.Sprintf(
"nodes/%s/storage/%s/upload",
url.PathEscape(d.NodeName),

View File

@ -6,6 +6,8 @@ package proxmox
import (
"io"
"github.com/bpg/terraform-provider-proxmox/proxmox/types"
)
// VirtualEnvironmentDatastoreFileListResponseBody contains the body from a datastore content list response.
@ -31,23 +33,23 @@ type VirtualEnvironmentDatastoreGetStatusResponseBody struct {
// VirtualEnvironmentDatastoreGetStatusResponseBody contains the data from a datastore status get request.
type VirtualEnvironmentDatastoreGetStatusResponseData struct {
Active *CustomBool `json:"active,omitempty"`
AvailableBytes *int64 `json:"avail,omitempty"`
Content *CustomCommaSeparatedList `json:"content,omitempty" url:"content,omitempty,comma"`
Enabled *CustomBool `json:"enabled,omitempty"`
Shared *CustomBool `json:"shared,omitempty"`
TotalBytes *int64 `json:"total,omitempty"`
Type *string `json:"type,omitempty"`
UsedBytes *int64 `json:"used,omitempty"`
Active *types.CustomBool `json:"active,omitempty"`
AvailableBytes *int64 `json:"avail,omitempty"`
Content *types.CustomCommaSeparatedList `json:"content,omitempty" url:"content,omitempty,comma"`
Enabled *types.CustomBool `json:"enabled,omitempty"`
Shared *types.CustomBool `json:"shared,omitempty"`
TotalBytes *int64 `json:"total,omitempty"`
Type *string `json:"type,omitempty"`
UsedBytes *int64 `json:"used,omitempty"`
}
// VirtualEnvironmentDatastoreListRequestBody contains the body for a datastore list request.
type VirtualEnvironmentDatastoreListRequestBody struct {
ContentTypes CustomCommaSeparatedList `json:"content,omitempty" url:"content,omitempty,comma"`
Enabled *CustomBool `json:"enabled,omitempty" url:"enabled,omitempty,int"`
Format *CustomBool `json:"format,omitempty" url:"format,omitempty,int"`
ID *string `json:"storage,omitempty" url:"storage,omitempty"`
Target *string `json:"target,omitempty" url:"target,omitempty"`
ContentTypes types.CustomCommaSeparatedList `json:"content,omitempty" url:"content,omitempty,comma"`
Enabled *types.CustomBool `json:"enabled,omitempty" url:"enabled,omitempty,int"`
Format *types.CustomBool `json:"format,omitempty" url:"format,omitempty,int"`
ID *string `json:"storage,omitempty" url:"storage,omitempty"`
Target *string `json:"target,omitempty" url:"target,omitempty"`
}
// VirtualEnvironmentDatastoreListResponseBody contains the body from a datastore list response.
@ -57,16 +59,16 @@ type VirtualEnvironmentDatastoreListResponseBody struct {
// VirtualEnvironmentDatastoreListResponseData contains the data from a datastore list response.
type VirtualEnvironmentDatastoreListResponseData struct {
Active *CustomBool `json:"active,omitempty"`
ContentTypes *CustomCommaSeparatedList `json:"content,omitempty"`
Enabled *CustomBool `json:"enabled,omitempty"`
ID string `json:"storage,omitempty"`
Shared *CustomBool `json:"shared,omitempty"`
SpaceAvailable *int `json:"avail,omitempty"`
SpaceTotal *int `json:"total,omitempty"`
SpaceUsed *int `json:"used,omitempty"`
SpaceUsedPercentage *float64 `json:"used_fraction,omitempty"`
Type string `json:"type,omitempty"`
Active *types.CustomBool `json:"active,omitempty"`
ContentTypes *types.CustomCommaSeparatedList `json:"content,omitempty"`
Enabled *types.CustomBool `json:"enabled,omitempty"`
ID string `json:"storage,omitempty"`
Shared *types.CustomBool `json:"shared,omitempty"`
SpaceAvailable *int `json:"avail,omitempty"`
SpaceTotal *int `json:"total,omitempty"`
SpaceUsed *int `json:"used,omitempty"`
SpaceUsedPercentage *float64 `json:"used_fraction,omitempty"`
Type string `json:"type,omitempty"`
}
// VirtualEnvironmentDatastoreUploadRequestBody contains the body for a datastore upload request.

View File

@ -8,6 +8,7 @@ import (
"context"
"errors"
"fmt"
"net/http"
"net/url"
)
@ -19,7 +20,7 @@ func (c *VirtualEnvironmentClient) GetDNS(
resBody := &VirtualEnvironmentDNSGetResponseBody{}
err := c.DoRequest(
ctx,
hmGET,
http.MethodGet,
fmt.Sprintf("nodes/%s/dns", url.PathEscape(nodeName)),
nil,
resBody,
@ -41,5 +42,5 @@ func (c *VirtualEnvironmentClient) UpdateDNS(
nodeName string,
d *VirtualEnvironmentDNSUpdateRequestBody,
) error {
return c.DoRequest(ctx, hmPUT, fmt.Sprintf("nodes/%s/dns", url.PathEscape(nodeName)), d, nil)
return c.DoRequest(ctx, http.MethodPut, fmt.Sprintf("nodes/%s/dns", url.PathEscape(nodeName)), d, nil)
}

View File

@ -8,6 +8,7 @@ import (
"context"
"errors"
"fmt"
"net/http"
"net/url"
"sort"
)
@ -17,12 +18,12 @@ func (c *VirtualEnvironmentClient) CreateGroup(
ctx context.Context,
d *VirtualEnvironmentGroupCreateRequestBody,
) error {
return c.DoRequest(ctx, hmPOST, "access/groups", d, nil)
return c.DoRequest(ctx, http.MethodPost, "access/groups", d, nil)
}
// DeleteGroup deletes an access group.
func (c *VirtualEnvironmentClient) DeleteGroup(ctx context.Context, id string) error {
return c.DoRequest(ctx, hmDELETE, fmt.Sprintf("access/groups/%s", url.PathEscape(id)), nil, nil)
return c.DoRequest(ctx, http.MethodDelete, fmt.Sprintf("access/groups/%s", url.PathEscape(id)), nil, nil)
}
// GetGroup retrieves an access group.
@ -33,7 +34,7 @@ func (c *VirtualEnvironmentClient) GetGroup(
resBody := &VirtualEnvironmentGroupGetResponseBody{}
err := c.DoRequest(
ctx,
hmGET,
http.MethodGet,
fmt.Sprintf("access/groups/%s", url.PathEscape(id)),
nil,
resBody,
@ -56,7 +57,7 @@ func (c *VirtualEnvironmentClient) ListGroups(
ctx context.Context,
) ([]*VirtualEnvironmentGroupListResponseData, error) {
resBody := &VirtualEnvironmentGroupListResponseBody{}
err := c.DoRequest(ctx, hmGET, "access/groups", nil, resBody)
err := c.DoRequest(ctx, http.MethodGet, "access/groups", nil, resBody)
if err != nil {
return nil, err
}
@ -78,5 +79,5 @@ func (c *VirtualEnvironmentClient) UpdateGroup(
id string,
d *VirtualEnvironmentGroupUpdateRequestBody,
) error {
return c.DoRequest(ctx, hmPUT, fmt.Sprintf("access/groups/%s", url.PathEscape(id)), d, nil)
return c.DoRequest(ctx, http.MethodPut, fmt.Sprintf("access/groups/%s", url.PathEscape(id)), d, nil)
}

View File

@ -8,6 +8,7 @@ import (
"context"
"errors"
"fmt"
"net/http"
"net/url"
)
@ -19,7 +20,7 @@ func (c *VirtualEnvironmentClient) GetHosts(
resBody := &VirtualEnvironmentHostsGetResponseBody{}
err := c.DoRequest(
ctx,
hmGET,
http.MethodGet,
fmt.Sprintf("nodes/%s/hosts", url.PathEscape(nodeName)),
nil,
resBody,
@ -41,5 +42,5 @@ func (c *VirtualEnvironmentClient) UpdateHosts(
nodeName string,
d *VirtualEnvironmentHostsUpdateRequestBody,
) error {
return c.DoRequest(ctx, hmPOST, fmt.Sprintf("nodes/%s/hosts", url.PathEscape(nodeName)), d, nil)
return c.DoRequest(ctx, http.MethodPost, fmt.Sprintf("nodes/%s/hosts", url.PathEscape(nodeName)), d, nil)
}

View File

@ -9,6 +9,7 @@ import (
"errors"
"fmt"
"net"
"net/http"
"net/url"
"os"
"sort"
@ -91,7 +92,7 @@ func (c *VirtualEnvironmentClient) GetNodeTime(
resBody := &VirtualEnvironmentNodeGetTimeResponseBody{}
err := c.DoRequest(
ctx,
hmGET,
http.MethodGet,
fmt.Sprintf("nodes/%s/time", url.PathEscape(nodeName)),
nil,
resBody,
@ -116,7 +117,7 @@ func (c *VirtualEnvironmentClient) GetNodeTaskStatus(
resBody := &VirtualEnvironmentNodeGetTaskStatusResponseBody{}
err := c.DoRequest(
ctx,
hmGET,
http.MethodGet,
fmt.Sprintf("nodes/%s/tasks/%s/status", url.PathEscape(nodeName), url.PathEscape(upid)),
nil,
resBody,
@ -140,7 +141,7 @@ func (c *VirtualEnvironmentClient) ListNodeNetworkDevices(
resBody := &VirtualEnvironmentNodeNetworkDeviceListResponseBody{}
err := c.DoRequest(
ctx,
hmGET,
http.MethodGet,
fmt.Sprintf("nodes/%s/network", url.PathEscape(nodeName)),
nil,
resBody,
@ -165,7 +166,7 @@ func (c *VirtualEnvironmentClient) ListNodes(
ctx context.Context,
) ([]*VirtualEnvironmentNodeListResponseData, error) {
resBody := &VirtualEnvironmentNodeListResponseBody{}
err := c.DoRequest(ctx, hmGET, "nodes", nil, resBody)
err := c.DoRequest(ctx, http.MethodGet, "nodes", nil, resBody)
if err != nil {
return nil, err
}
@ -247,7 +248,7 @@ func (c *VirtualEnvironmentClient) UpdateNodeTime(
nodeName string,
d *VirtualEnvironmentNodeUpdateTimeRequestBody,
) error {
return c.DoRequest(ctx, hmPUT, fmt.Sprintf("nodes/%s/time", url.PathEscape(nodeName)), d, nil)
return c.DoRequest(ctx, http.MethodPut, fmt.Sprintf("nodes/%s/time", url.PathEscape(nodeName)), d, nil)
}
// WaitForNodeTask waits for a specific node task to complete.

View File

@ -7,6 +7,8 @@ package proxmox
import (
"encoding/json"
"net/url"
"github.com/bpg/terraform-provider-proxmox/proxmox/types"
)
// CustomNodeCommands contains an array of commands to execute.
@ -24,9 +26,9 @@ type VirtualEnvironmentNodeGetTimeResponseBody struct {
// VirtualEnvironmentNodeGetTimeResponseData contains the data from a node list response.
type VirtualEnvironmentNodeGetTimeResponseData struct {
LocalTime CustomTimestamp `json:"localtime"`
TimeZone string `json:"timezone"`
UTCTime CustomTimestamp `json:"time"`
LocalTime types.CustomTimestamp `json:"localtime"`
TimeZone string `json:"timezone"`
UTCTime types.CustomTimestamp `json:"time"`
}
// VirtualEnvironmentNodeGetTaskStatusResponseBody contains the body from a node get task status response.
@ -66,22 +68,22 @@ type VirtualEnvironmentNodeNetworkDeviceListResponseBody struct {
// VirtualEnvironmentNodeNetworkDeviceListResponseData contains the data from a node network device list response.
type VirtualEnvironmentNodeNetworkDeviceListResponseData struct {
Active *CustomBool `json:"active,omitempty"`
Address *string `json:"address,omitempty"`
Autostart *CustomBool `json:"autostart,omitempty"`
BridgeFD *string `json:"bridge_fd,omitempty"`
BridgePorts *string `json:"bridge_ports,omitempty"`
BridgeSTP *string `json:"bridge_stp,omitempty"`
CIDR *string `json:"cidr,omitempty"`
Exists *CustomBool `json:"exists,omitempty"`
Families *[]string `json:"families,omitempty"`
Gateway *string `json:"gateway,omitempty"`
Iface string `json:"iface"`
MethodIPv4 *string `json:"method,omitempty"`
MethodIPv6 *string `json:"method6,omitempty"`
Netmask *string `json:"netmask,omitempty"`
Priority int `json:"priority"`
Type string `json:"type"`
Active *types.CustomBool `json:"active,omitempty"`
Address *string `json:"address,omitempty"`
Autostart *types.CustomBool `json:"autostart,omitempty"`
BridgeFD *string `json:"bridge_fd,omitempty"`
BridgePorts *string `json:"bridge_ports,omitempty"`
BridgeSTP *string `json:"bridge_stp,omitempty"`
CIDR *string `json:"cidr,omitempty"`
Exists *types.CustomBool `json:"exists,omitempty"`
Families *[]string `json:"families,omitempty"`
Gateway *string `json:"gateway,omitempty"`
Iface string `json:"iface"`
MethodIPv4 *string `json:"method,omitempty"`
MethodIPv6 *string `json:"method6,omitempty"`
Netmask *string `json:"netmask,omitempty"`
Priority int `json:"priority"`
Type string `json:"type"`
}
// VirtualEnvironmentNodeUpdateTimeRequestBody contains the body for a node time update request.

View File

@ -8,6 +8,7 @@ import (
"context"
"errors"
"fmt"
"net/http"
"net/url"
"sort"
)
@ -17,12 +18,12 @@ func (c *VirtualEnvironmentClient) CreatePool(
ctx context.Context,
d *VirtualEnvironmentPoolCreateRequestBody,
) error {
return c.DoRequest(ctx, hmPOST, "pools", d, nil)
return c.DoRequest(ctx, http.MethodPost, "pools", d, nil)
}
// DeletePool deletes a pool.
func (c *VirtualEnvironmentClient) DeletePool(ctx context.Context, id string) error {
return c.DoRequest(ctx, hmDELETE, fmt.Sprintf("pools/%s", url.PathEscape(id)), nil, nil)
return c.DoRequest(ctx, http.MethodDelete, fmt.Sprintf("pools/%s", url.PathEscape(id)), nil, nil)
}
// GetPool retrieves a pool.
@ -31,7 +32,7 @@ func (c *VirtualEnvironmentClient) GetPool(
id string,
) (*VirtualEnvironmentPoolGetResponseData, error) {
resBody := &VirtualEnvironmentPoolGetResponseBody{}
err := c.DoRequest(ctx, hmGET, fmt.Sprintf("pools/%s", url.PathEscape(id)), nil, resBody)
err := c.DoRequest(ctx, http.MethodGet, fmt.Sprintf("pools/%s", url.PathEscape(id)), nil, resBody)
if err != nil {
return nil, err
}
@ -52,7 +53,7 @@ func (c *VirtualEnvironmentClient) ListPools(
ctx context.Context,
) ([]*VirtualEnvironmentPoolListResponseData, error) {
resBody := &VirtualEnvironmentPoolListResponseBody{}
err := c.DoRequest(ctx, hmGET, "pools", nil, resBody)
err := c.DoRequest(ctx, http.MethodGet, "pools", nil, resBody)
if err != nil {
return nil, err
}
@ -74,5 +75,5 @@ func (c *VirtualEnvironmentClient) UpdatePool(
id string,
d *VirtualEnvironmentPoolUpdateRequestBody,
) error {
return c.DoRequest(ctx, hmPUT, fmt.Sprintf("pools/%s", url.PathEscape(id)), d, nil)
return c.DoRequest(ctx, http.MethodPut, fmt.Sprintf("pools/%s", url.PathEscape(id)), d, nil)
}

View File

@ -8,8 +8,11 @@ import (
"context"
"errors"
"fmt"
"net/http"
"net/url"
"sort"
"github.com/bpg/terraform-provider-proxmox/proxmox/types"
)
// CreateRole creates an access role.
@ -17,21 +20,21 @@ func (c *VirtualEnvironmentClient) CreateRole(
ctx context.Context,
d *VirtualEnvironmentRoleCreateRequestBody,
) error {
return c.DoRequest(ctx, hmPOST, "access/roles", d, nil)
return c.DoRequest(ctx, http.MethodPost, "access/roles", d, nil)
}
// DeleteRole deletes an access role.
func (c *VirtualEnvironmentClient) DeleteRole(ctx context.Context, id string) error {
return c.DoRequest(ctx, hmDELETE, fmt.Sprintf("access/roles/%s", url.PathEscape(id)), nil, nil)
return c.DoRequest(ctx, http.MethodDelete, fmt.Sprintf("access/roles/%s", url.PathEscape(id)), nil, nil)
}
// GetRole retrieves an access role.
func (c *VirtualEnvironmentClient) GetRole(
ctx context.Context,
id string,
) (*CustomPrivileges, error) {
) (*types.CustomPrivileges, error) {
resBody := &VirtualEnvironmentRoleGetResponseBody{}
err := c.DoRequest(ctx, hmGET, fmt.Sprintf("access/roles/%s", url.PathEscape(id)), nil, resBody)
err := c.DoRequest(ctx, http.MethodGet, fmt.Sprintf("access/roles/%s", url.PathEscape(id)), nil, resBody)
if err != nil {
return nil, err
}
@ -50,7 +53,7 @@ func (c *VirtualEnvironmentClient) ListRoles(
ctx context.Context,
) ([]*VirtualEnvironmentRoleListResponseData, error) {
resBody := &VirtualEnvironmentRoleListResponseBody{}
err := c.DoRequest(ctx, hmGET, "access/roles", nil, resBody)
err := c.DoRequest(ctx, http.MethodGet, "access/roles", nil, resBody)
if err != nil {
return nil, err
}
@ -78,5 +81,5 @@ func (c *VirtualEnvironmentClient) UpdateRole(
id string,
d *VirtualEnvironmentRoleUpdateRequestBody,
) error {
return c.DoRequest(ctx, hmPUT, fmt.Sprintf("access/roles/%s", url.PathEscape(id)), d, nil)
return c.DoRequest(ctx, http.MethodPut, fmt.Sprintf("access/roles/%s", url.PathEscape(id)), d, nil)
}

View File

@ -4,15 +4,17 @@
package proxmox
import "github.com/bpg/terraform-provider-proxmox/proxmox/types"
// VirtualEnvironmentRoleCreateRequestBody contains the data for an access group create request.
type VirtualEnvironmentRoleCreateRequestBody struct {
ID string `json:"roleid" url:"roleid"`
Privileges CustomPrivileges `json:"privs" url:"privs,comma"`
ID string `json:"roleid" url:"roleid"`
Privileges types.CustomPrivileges `json:"privs" url:"privs,comma"`
}
// VirtualEnvironmentRoleGetResponseBody contains the body from an access group get response.
type VirtualEnvironmentRoleGetResponseBody struct {
Data *CustomPrivileges `json:"data,omitempty"`
Data *types.CustomPrivileges `json:"data,omitempty"`
}
// VirtualEnvironmentRoleListResponseBody contains the body from an access group list response.
@ -22,12 +24,12 @@ type VirtualEnvironmentRoleListResponseBody struct {
// VirtualEnvironmentRoleListResponseData contains the data from an access group list response.
type VirtualEnvironmentRoleListResponseData struct {
ID string `json:"roleid"`
Privileges *CustomPrivileges `json:"privs,omitempty"`
Special *CustomBool `json:"special,omitempty"`
ID string `json:"roleid"`
Privileges *types.CustomPrivileges `json:"privs,omitempty"`
Special *types.CustomBool `json:"special,omitempty"`
}
// VirtualEnvironmentRoleUpdateRequestBody contains the data for an access group update request.
type VirtualEnvironmentRoleUpdateRequestBody struct {
Privileges CustomPrivileges `json:"privs" url:"privs,comma"`
Privileges types.CustomPrivileges `json:"privs" url:"privs,comma"`
}

View File

@ -8,9 +8,12 @@ import (
"context"
"errors"
"fmt"
"net/http"
"net/url"
"sort"
"time"
"github.com/bpg/terraform-provider-proxmox/proxmox/types"
)
// ChangeUserPassword changes a user's password.
@ -23,7 +26,7 @@ func (c *VirtualEnvironmentClient) ChangeUserPassword(
Password: password,
}
return c.DoRequest(ctx, hmPUT, "access/password", d, nil)
return c.DoRequest(ctx, http.MethodPut, "access/password", d, nil)
}
// CreateUser creates a user.
@ -31,12 +34,12 @@ func (c *VirtualEnvironmentClient) CreateUser(
ctx context.Context,
d *VirtualEnvironmentUserCreateRequestBody,
) error {
return c.DoRequest(ctx, hmPOST, "access/users", d, nil)
return c.DoRequest(ctx, http.MethodPost, "access/users", d, nil)
}
// DeleteUser deletes an user.
func (c *VirtualEnvironmentClient) DeleteUser(ctx context.Context, id string) error {
return c.DoRequest(ctx, hmDELETE, fmt.Sprintf("access/users/%s", url.PathEscape(id)), nil, nil)
return c.DoRequest(ctx, http.MethodDelete, fmt.Sprintf("access/users/%s", url.PathEscape(id)), nil, nil)
}
// GetUser retrieves a user.
@ -45,7 +48,7 @@ func (c *VirtualEnvironmentClient) GetUser(
id string,
) (*VirtualEnvironmentUserGetResponseData, error) {
resBody := &VirtualEnvironmentUserGetResponseBody{}
err := c.DoRequest(ctx, hmGET, fmt.Sprintf("access/users/%s", url.PathEscape(id)), nil, resBody)
err := c.DoRequest(ctx, http.MethodGet, fmt.Sprintf("access/users/%s", url.PathEscape(id)), nil, resBody)
if err != nil {
return nil, err
}
@ -55,7 +58,7 @@ func (c *VirtualEnvironmentClient) GetUser(
}
if resBody.Data.ExpirationDate != nil {
expirationDate := CustomTimestamp(time.Time(*resBody.Data.ExpirationDate).UTC())
expirationDate := types.CustomTimestamp(time.Time(*resBody.Data.ExpirationDate).UTC())
resBody.Data.ExpirationDate = &expirationDate
}
@ -71,7 +74,7 @@ func (c *VirtualEnvironmentClient) ListUsers(
ctx context.Context,
) ([]*VirtualEnvironmentUserListResponseData, error) {
resBody := &VirtualEnvironmentUserListResponseBody{}
err := c.DoRequest(ctx, hmGET, "access/users", nil, resBody)
err := c.DoRequest(ctx, http.MethodGet, "access/users", nil, resBody)
if err != nil {
return nil, err
}
@ -86,7 +89,7 @@ func (c *VirtualEnvironmentClient) ListUsers(
for i := range resBody.Data {
if resBody.Data[i].ExpirationDate != nil {
expirationDate := CustomTimestamp(time.Time(*resBody.Data[i].ExpirationDate).UTC())
expirationDate := types.CustomTimestamp(time.Time(*resBody.Data[i].ExpirationDate).UTC())
resBody.Data[i].ExpirationDate = &expirationDate
}
@ -104,5 +107,5 @@ func (c *VirtualEnvironmentClient) UpdateUser(
id string,
d *VirtualEnvironmentUserUpdateRequestBody,
) error {
return c.DoRequest(ctx, hmPUT, fmt.Sprintf("access/users/%s", url.PathEscape(id)), d, nil)
return c.DoRequest(ctx, http.MethodPut, fmt.Sprintf("access/users/%s", url.PathEscape(id)), d, nil)
}

View File

@ -4,6 +4,8 @@
package proxmox
import "github.com/bpg/terraform-provider-proxmox/proxmox/types"
// VirtualEnvironmentUserChangePasswordRequestBody contains the data for a user password change request.
type VirtualEnvironmentUserChangePasswordRequestBody struct {
ID string `json:"userid" url:"userid"`
@ -12,16 +14,16 @@ type VirtualEnvironmentUserChangePasswordRequestBody struct {
// VirtualEnvironmentUserCreateRequestBody contains the data for an user create request.
type VirtualEnvironmentUserCreateRequestBody struct {
Comment *string `json:"comment,omitempty" url:"comment,omitempty"`
Email *string `json:"email,omitempty" url:"email,omitempty"`
Enabled *CustomBool `json:"enable,omitempty" url:"enable,omitempty,int"`
ExpirationDate *CustomTimestamp `json:"expire,omitempty" url:"expire,omitempty,unix"`
FirstName *string `json:"firstname,omitempty" url:"firstname,omitempty"`
Groups []string `json:"groups,omitempty" url:"groups,omitempty,comma"`
ID string `json:"userid" url:"userid"`
Keys *string `json:"keys,omitempty" url:"keys,omitempty"`
LastName *string `json:"lastname,omitempty" url:"lastname,omitempty"`
Password string `json:"password" url:"password"`
Comment *string `json:"comment,omitempty" url:"comment,omitempty"`
Email *string `json:"email,omitempty" url:"email,omitempty"`
Enabled *types.CustomBool `json:"enable,omitempty" url:"enable,omitempty,int"`
ExpirationDate *types.CustomTimestamp `json:"expire,omitempty" url:"expire,omitempty,unix"`
FirstName *string `json:"firstname,omitempty" url:"firstname,omitempty"`
Groups []string `json:"groups,omitempty" url:"groups,omitempty,comma"`
ID string `json:"userid" url:"userid"`
Keys *string `json:"keys,omitempty" url:"keys,omitempty"`
LastName *string `json:"lastname,omitempty" url:"lastname,omitempty"`
Password string `json:"password" url:"password"`
}
// VirtualEnvironmentUserGetResponseBody contains the body from an user get response.
@ -31,14 +33,14 @@ type VirtualEnvironmentUserGetResponseBody struct {
// VirtualEnvironmentUserGetResponseData contains the data from an user get response.
type VirtualEnvironmentUserGetResponseData struct {
Comment *string `json:"comment,omitempty"`
Email *string `json:"email,omitempty"`
Enabled *CustomBool `json:"enable,omitempty"`
ExpirationDate *CustomTimestamp `json:"expire,omitempty"`
FirstName *string `json:"firstname,omitempty"`
Groups *[]string `json:"groups,omitempty"`
Keys *string `json:"keys,omitempty"`
LastName *string `json:"lastname,omitempty"`
Comment *string `json:"comment,omitempty"`
Email *string `json:"email,omitempty"`
Enabled *types.CustomBool `json:"enable,omitempty"`
ExpirationDate *types.CustomTimestamp `json:"expire,omitempty"`
FirstName *string `json:"firstname,omitempty"`
Groups *[]string `json:"groups,omitempty"`
Keys *string `json:"keys,omitempty"`
LastName *string `json:"lastname,omitempty"`
}
// VirtualEnvironmentUserListResponseBody contains the body from an user list response.
@ -48,26 +50,26 @@ type VirtualEnvironmentUserListResponseBody struct {
// VirtualEnvironmentUserListResponseData contains the data from an user list response.
type VirtualEnvironmentUserListResponseData struct {
Comment *string `json:"comment,omitempty"`
Email *string `json:"email,omitempty"`
Enabled *CustomBool `json:"enable,omitempty"`
ExpirationDate *CustomTimestamp `json:"expire,omitempty"`
FirstName *string `json:"firstname,omitempty"`
Groups *[]string `json:"groups,omitempty"`
ID string `json:"userid"`
Keys *string `json:"keys,omitempty"`
LastName *string `json:"lastname,omitempty"`
Comment *string `json:"comment,omitempty"`
Email *string `json:"email,omitempty"`
Enabled *types.CustomBool `json:"enable,omitempty"`
ExpirationDate *types.CustomTimestamp `json:"expire,omitempty"`
FirstName *string `json:"firstname,omitempty"`
Groups *[]string `json:"groups,omitempty"`
ID string `json:"userid"`
Keys *string `json:"keys,omitempty"`
LastName *string `json:"lastname,omitempty"`
}
// VirtualEnvironmentUserUpdateRequestBody contains the data for an user update request.
type VirtualEnvironmentUserUpdateRequestBody struct {
Append *CustomBool `json:"append,omitempty" url:"append,omitempty"`
Comment *string `json:"comment,omitempty" url:"comment,omitempty"`
Email *string `json:"email,omitempty" url:"email,omitempty"`
Enabled *CustomBool `json:"enable,omitempty" url:"enable,omitempty,int"`
ExpirationDate *CustomTimestamp `json:"expire,omitempty" url:"expire,omitempty,unix"`
FirstName *string `json:"firstname,omitempty" url:"firstname,omitempty"`
Groups []string `json:"groups,omitempty" url:"groups,omitempty,comma"`
Keys *string `json:"keys,omitempty" url:"keys,omitempty"`
LastName *string `json:"lastname,omitempty" url:"lastname,omitempty"`
Append *types.CustomBool `json:"append,omitempty" url:"append,omitempty"`
Comment *string `json:"comment,omitempty" url:"comment,omitempty"`
Email *string `json:"email,omitempty" url:"email,omitempty"`
Enabled *types.CustomBool `json:"enable,omitempty" url:"enable,omitempty,int"`
ExpirationDate *types.CustomTimestamp `json:"expire,omitempty" url:"expire,omitempty,unix"`
FirstName *string `json:"firstname,omitempty" url:"firstname,omitempty"`
Groups []string `json:"groups,omitempty" url:"groups,omitempty,comma"`
Keys *string `json:"keys,omitempty" url:"keys,omitempty"`
LastName *string `json:"lastname,omitempty" url:"lastname,omitempty"`
}

View File

@ -7,6 +7,7 @@ package proxmox
import (
"context"
"errors"
"net/http"
)
// Version retrieves the version information.
@ -14,7 +15,7 @@ func (c *VirtualEnvironmentClient) Version(
ctx context.Context,
) (*VirtualEnvironmentVersionResponseData, error) {
resBody := &VirtualEnvironmentVersionResponseBody{}
err := c.DoRequest(ctx, hmGET, "version", nil, resBody)
err := c.DoRequest(ctx, http.MethodGet, "version", nil, resBody)
if err != nil {
return nil, err
}

View File

@ -9,6 +9,7 @@ import (
"errors"
"fmt"
"net"
"net/http"
"net/url"
"strings"
"sync"
@ -46,7 +47,7 @@ func (c *VirtualEnvironmentClient) CloneVM(
for i := 0; i < retries; i++ {
err = c.DoRequest(
ctx,
hmPOST,
http.MethodPost,
fmt.Sprintf("nodes/%s/qemu/%d/clone", url.PathEscape(nodeName), vmID),
d,
resBody,
@ -77,14 +78,14 @@ func (c *VirtualEnvironmentClient) CreateVM(
nodeName string,
d *VirtualEnvironmentVMCreateRequestBody,
) error {
return c.DoRequest(ctx, hmPOST, fmt.Sprintf("nodes/%s/qemu", url.PathEscape(nodeName)), d, nil)
return c.DoRequest(ctx, http.MethodPost, fmt.Sprintf("nodes/%s/qemu", url.PathEscape(nodeName)), d, nil)
}
// DeleteVM deletes a virtual machine.
func (c *VirtualEnvironmentClient) DeleteVM(ctx context.Context, nodeName string, vmID int) error {
return c.DoRequest(
ctx,
hmDELETE,
http.MethodDelete,
fmt.Sprintf(
"nodes/%s/qemu/%d?destroy-unreferenced-disks=1&purge=1",
url.PathEscape(nodeName),
@ -104,7 +105,7 @@ func (c *VirtualEnvironmentClient) GetVM(
resBody := &VirtualEnvironmentVMGetResponseBody{}
err := c.DoRequest(
ctx,
hmGET,
http.MethodGet,
fmt.Sprintf("nodes/%s/qemu/%d/config", url.PathEscape(nodeName), vmID),
nil,
resBody,
@ -126,7 +127,7 @@ func (c *VirtualEnvironmentClient) GetVMID(ctx context.Context) (*int, error) {
defer getVMIDCounterMutex.Unlock()
if getVMIDCounter < 0 {
nextVMID, err := c.GetClusterNextID(ctx, nil)
nextVMID, err := c.API().Cluster().GetNextID(ctx, nil)
if err != nil {
return nil, err
}
@ -147,7 +148,7 @@ func (c *VirtualEnvironmentClient) GetVMID(ctx context.Context) (*int, error) {
vmID := getVMIDCounter
for vmID <= 2147483637 {
_, err := c.GetClusterNextID(ctx, &vmID)
_, err := c.API().Cluster().GetNextID(ctx, &vmID)
if err != nil {
vmID += getVMIDStep
@ -175,7 +176,7 @@ func (c *VirtualEnvironmentClient) GetVMNetworkInterfacesFromAgent(
resBody := &VirtualEnvironmentVMGetQEMUNetworkInterfacesResponseBody{}
err := c.DoRequest(
ctx,
hmGET,
http.MethodGet,
fmt.Sprintf(
"nodes/%s/qemu/%d/agent/network-get-interfaces",
url.PathEscape(nodeName),
@ -204,7 +205,7 @@ func (c *VirtualEnvironmentClient) GetVMStatus(
resBody := &VirtualEnvironmentVMGetStatusResponseBody{}
err := c.DoRequest(
ctx,
hmGET,
http.MethodGet,
fmt.Sprintf("nodes/%s/qemu/%d/status/current", url.PathEscape(nodeName), vmID),
nil,
resBody,
@ -252,7 +253,7 @@ func (c *VirtualEnvironmentClient) MigrateVMAsync(
resBody := &VirtualEnvironmentVMMigrateResponseBody{}
err := c.DoRequest(
ctx,
hmPOST,
http.MethodPost,
fmt.Sprintf("nodes/%s/qemu/%d/migrate", url.PathEscape(nodeName), vmID),
d,
resBody,
@ -305,7 +306,7 @@ func (c *VirtualEnvironmentClient) MoveVMDiskAsync(
resBody := &VirtualEnvironmentVMMoveDiskResponseBody{}
err := c.DoRequest(
ctx,
hmPOST,
http.MethodPost,
fmt.Sprintf("nodes/%s/qemu/%d/move_disk", url.PathEscape(nodeName), vmID),
d,
resBody,
@ -329,7 +330,7 @@ func (c *VirtualEnvironmentClient) ListVMs(
resBody := &VirtualEnvironmentVMListResponseBody{}
err := c.DoRequest(
ctx,
hmGET,
http.MethodGet,
fmt.Sprintf("nodes/%s/qemu", url.PathEscape(nodeName)),
nil,
resBody,
@ -377,7 +378,7 @@ func (c *VirtualEnvironmentClient) RebootVMAsync(
resBody := &VirtualEnvironmentVMRebootResponseBody{}
err := c.DoRequest(
ctx,
hmPOST,
http.MethodPost,
fmt.Sprintf("nodes/%s/qemu/%d/status/reboot", url.PathEscape(nodeName), vmID),
d,
resBody,
@ -408,7 +409,7 @@ func (c *VirtualEnvironmentClient) ResizeVMDisk(
for i := 0; i < 5; i++ {
err = c.DoRequest(
ctx,
hmPUT,
http.MethodPut,
fmt.Sprintf("nodes/%s/qemu/%d/resize", url.PathEscape(nodeName), vmID),
d,
nil,
@ -460,7 +461,7 @@ func (c *VirtualEnvironmentClient) ShutdownVMAsync(
resBody := &VirtualEnvironmentVMShutdownResponseBody{}
err := c.DoRequest(
ctx,
hmPOST,
http.MethodPost,
fmt.Sprintf("nodes/%s/qemu/%d/status/shutdown", url.PathEscape(nodeName), vmID),
d,
resBody,
@ -506,7 +507,7 @@ func (c *VirtualEnvironmentClient) StartVMAsync(
resBody := &VirtualEnvironmentVMStartResponseBody{}
err := c.DoRequest(
ctx,
hmPOST,
http.MethodPost,
fmt.Sprintf("nodes/%s/qemu/%d/status/start", url.PathEscape(nodeName), vmID),
nil,
resBody,
@ -552,7 +553,7 @@ func (c *VirtualEnvironmentClient) StopVMAsync(
resBody := &VirtualEnvironmentVMStopResponseBody{}
err := c.DoRequest(
ctx,
hmPOST,
http.MethodPost,
fmt.Sprintf("nodes/%s/qemu/%d/status/stop", url.PathEscape(nodeName), vmID),
nil,
resBody,
@ -577,7 +578,7 @@ func (c *VirtualEnvironmentClient) UpdateVM(
) error {
return c.DoRequest(
ctx,
hmPUT,
http.MethodPut,
fmt.Sprintf("nodes/%s/qemu/%d/config", url.PathEscape(nodeName), vmID),
d,
nil,
@ -594,7 +595,7 @@ func (c *VirtualEnvironmentClient) UpdateVMAsync(
resBody := &VirtualEnvironmentVMUpdateAsyncResponseBody{}
err := c.DoRequest(
ctx,
hmPOST,
http.MethodPost,
fmt.Sprintf("nodes/%s/qemu/%d/config", url.PathEscape(nodeName), vmID),
d,
resBody,

View File

@ -12,13 +12,15 @@ import (
"path/filepath"
"strconv"
"strings"
"github.com/bpg/terraform-provider-proxmox/proxmox/types"
)
// CustomAgent handles QEMU agent parameters.
type CustomAgent struct {
Enabled *CustomBool `json:"enabled,omitempty" url:"enabled,int"`
TrimClonedDisks *CustomBool `json:"fstrim_cloned_disks" url:"fstrim_cloned_disks,int"`
Type *string `json:"type" url:"type"`
Enabled *types.CustomBool `json:"enabled,omitempty" url:"enabled,int"`
TrimClonedDisks *types.CustomBool `json:"fstrim_cloned_disks" url:"fstrim_cloned_disks,int"`
Type *string `json:"type" url:"type"`
}
// CustomAudioDevice handles QEMU audio parameters.
@ -64,10 +66,10 @@ type CustomCloudInitSSHKeys []string
// CustomCPUEmulation handles QEMU CPU emulation parameters.
type CustomCPUEmulation struct {
Flags *[]string `json:"flags,omitempty" url:"flags,omitempty,semicolon"`
Hidden *CustomBool `json:"hidden,omitempty" url:"hidden,omitempty,int"`
HVVendorID *string `json:"hv-vendor-id,omitempty" url:"hv-vendor-id,omitempty"`
Type string `json:"cputype,omitempty" url:"cputype,omitempty"`
Flags *[]string `json:"flags,omitempty" url:"flags,omitempty,semicolon"`
Hidden *types.CustomBool `json:"hidden,omitempty" url:"hidden,omitempty,int"`
HVVendorID *string `json:"hv-vendor-id,omitempty" url:"hv-vendor-id,omitempty"`
Type string `json:"cputype,omitempty" url:"cputype,omitempty"`
}
// CustomEFIDisk handles QEMU EFI disk parameters.
@ -79,17 +81,17 @@ type CustomEFIDisk struct {
// CustomNetworkDevice handles QEMU network device parameters.
type CustomNetworkDevice struct {
Model string `json:"model" url:"model"`
Bridge *string `json:"bridge,omitempty" url:"bridge,omitempty"`
Enabled bool `json:"-" url:"-"`
Firewall *CustomBool `json:"firewall,omitempty" url:"firewall,omitempty,int"`
LinkDown *CustomBool `json:"link_down,omitempty" url:"link_down,omitempty,int"`
MACAddress *string `json:"macaddr,omitempty" url:"macaddr,omitempty"`
Queues *int `json:"queues,omitempty" url:"queues,omitempty"`
RateLimit *float64 `json:"rate,omitempty" url:"rate,omitempty"`
Tag *int `json:"tag,omitempty" url:"tag,omitempty"`
MTU *int `json:"mtu,omitempty" url:"mtu,omitempty"`
Trunks []int `json:"trunks,omitempty" url:"trunks,omitempty"`
Model string `json:"model" url:"model"`
Bridge *string `json:"bridge,omitempty" url:"bridge,omitempty"`
Enabled bool `json:"-" url:"-"`
Firewall *types.CustomBool `json:"firewall,omitempty" url:"firewall,omitempty,int"`
LinkDown *types.CustomBool `json:"link_down,omitempty" url:"link_down,omitempty,int"`
MACAddress *string `json:"macaddr,omitempty" url:"macaddr,omitempty"`
Queues *int `json:"queues,omitempty" url:"queues,omitempty"`
RateLimit *float64 `json:"rate,omitempty" url:"rate,omitempty"`
Tag *int `json:"tag,omitempty" url:"tag,omitempty"`
MTU *int `json:"mtu,omitempty" url:"mtu,omitempty"`
Trunks []int `json:"trunks,omitempty" url:"trunks,omitempty"`
}
// CustomNetworkDevices handles QEMU network device parameters.
@ -108,12 +110,12 @@ type CustomNUMADevices []CustomNUMADevice
// CustomPCIDevice handles QEMU host PCI device mapping parameters.
type CustomPCIDevice struct {
DeviceIDs []string `json:"host" url:"host,semicolon"`
MDev *string `json:"mdev,omitempty" url:"mdev,omitempty"`
PCIExpress *CustomBool `json:"pcie,omitempty" url:"pcie,omitempty,int"`
ROMBAR *CustomBool `json:"rombar,omitempty" url:"rombar,omitempty,int"`
ROMFile *string `json:"romfile,omitempty" url:"romfile,omitempty"`
XVGA *CustomBool `json:"x-vga,omitempty" url:"x-vga,omitempty,int"`
DeviceIDs []string `json:"host" url:"host,semicolon"`
MDev *string `json:"mdev,omitempty" url:"mdev,omitempty"`
PCIExpress *types.CustomBool `json:"pcie,omitempty" url:"pcie,omitempty,int"`
ROMBAR *types.CustomBool `json:"rombar,omitempty" url:"rombar,omitempty,int"`
ROMFile *string `json:"romfile,omitempty" url:"romfile,omitempty"`
XVGA *types.CustomBool `json:"x-vga,omitempty" url:"x-vga,omitempty,int"`
}
// CustomPCIDevices handles QEMU host PCI device mapping parameters.
@ -130,20 +132,20 @@ type CustomSharedMemory struct {
// CustomSMBIOS handles QEMU SMBIOS parameters.
type CustomSMBIOS struct {
Base64 *CustomBool `json:"base64,omitempty" url:"base64,omitempty"`
Family *string `json:"family,omitempty" url:"family,omitempty"`
Manufacturer *string `json:"manufacturer,omitempty" url:"manufacturer,omitempty"`
Product *string `json:"product,omitempty" url:"product,omitempty"`
Serial *string `json:"serial,omitempty" url:"serial,omitempty"`
SKU *string `json:"sku,omitempty" url:"sku,omitempty"`
UUID *string `json:"uuid,omitempty" url:"uuid,omitempty"`
Version *string `json:"version,omitempty" url:"version,omitempty"`
Base64 *types.CustomBool `json:"base64,omitempty" url:"base64,omitempty"`
Family *string `json:"family,omitempty" url:"family,omitempty"`
Manufacturer *string `json:"manufacturer,omitempty" url:"manufacturer,omitempty"`
Product *string `json:"product,omitempty" url:"product,omitempty"`
Serial *string `json:"serial,omitempty" url:"serial,omitempty"`
SKU *string `json:"sku,omitempty" url:"sku,omitempty"`
UUID *string `json:"uuid,omitempty" url:"uuid,omitempty"`
Version *string `json:"version,omitempty" url:"version,omitempty"`
}
// CustomSpiceEnhancements handles QEMU spice enhancement parameters.
type CustomSpiceEnhancements struct {
FolderSharing *CustomBool `json:"foldersharing,omitempty" url:"foldersharing,omitempty"`
VideoStreaming *string `json:"videostreaming,omitempty" url:"videostreaming,omitempty"`
FolderSharing *types.CustomBool `json:"foldersharing,omitempty" url:"foldersharing,omitempty"`
VideoStreaming *string `json:"videostreaming,omitempty" url:"videostreaming,omitempty"`
}
// CustomStartupOrder handles QEMU startup order parameters.
@ -155,20 +157,20 @@ type CustomStartupOrder struct {
// CustomStorageDevice handles QEMU SATA device parameters.
type CustomStorageDevice struct {
AIO *string `json:"aio,omitempty" url:"aio,omitempty"`
BackupEnabled *CustomBool `json:"backup,omitempty" url:"backup,omitempty,int"`
BurstableReadSpeedMbps *int `json:"mbps_rd_max,omitempty" url:"mbps_rd_max,omitempty"`
BurstableWriteSpeedMbps *int `json:"mbps_wr_max,omitempty" url:"mbps_wr_max,omitempty"`
Discard *string `json:"discard,omitempty" url:"discard,omitempty"`
Enabled bool `json:"-" url:"-"`
FileVolume string `json:"file" url:"file"`
Format *string `json:"format,omitempty" url:"format,omitempty"`
IOThread *CustomBool `json:"iothread,omitempty" url:"iothread,omitempty,int"`
SSD *CustomBool `json:"ssd,omitempty" url:"ssd,omitempty,int"`
MaxReadSpeedMbps *int `json:"mbps_rd,omitempty" url:"mbps_rd,omitempty"`
MaxWriteSpeedMbps *int `json:"mbps_wr,omitempty" url:"mbps_wr,omitempty"`
Media *string `json:"media,omitempty" url:"media,omitempty"`
Size *string `json:"size,omitempty" url:"size,omitempty"`
AIO *string `json:"aio,omitempty" url:"aio,omitempty"`
BackupEnabled *types.CustomBool `json:"backup,omitempty" url:"backup,omitempty,int"`
BurstableReadSpeedMbps *int `json:"mbps_rd_max,omitempty" url:"mbps_rd_max,omitempty"`
BurstableWriteSpeedMbps *int `json:"mbps_wr_max,omitempty" url:"mbps_wr_max,omitempty"`
Discard *string `json:"discard,omitempty" url:"discard,omitempty"`
Enabled bool `json:"-" url:"-"`
FileVolume string `json:"file" url:"file"`
Format *string `json:"format,omitempty" url:"format,omitempty"`
IOThread *types.CustomBool `json:"iothread,omitempty" url:"iothread,omitempty,int"`
SSD *types.CustomBool `json:"ssd,omitempty" url:"ssd,omitempty,int"`
MaxReadSpeedMbps *int `json:"mbps_rd,omitempty" url:"mbps_rd,omitempty"`
MaxWriteSpeedMbps *int `json:"mbps_wr,omitempty" url:"mbps_wr,omitempty"`
Media *string `json:"media,omitempty" url:"media,omitempty"`
Size *string `json:"size,omitempty" url:"size,omitempty"`
Interface *string
ID *string
FileID *string
@ -180,8 +182,8 @@ type CustomStorageDevices map[string]CustomStorageDevice
// CustomUSBDevice handles QEMU USB device parameters.
type CustomUSBDevice struct {
HostDevice string `json:"host" url:"host"`
USB3 *CustomBool `json:"usb3,omitempty" url:"usb3,omitempty,int"`
HostDevice string `json:"host" url:"host"`
USB3 *types.CustomBool `json:"usb3,omitempty" url:"usb3,omitempty,int"`
}
// CustomUSBDevices handles QEMU USB device parameters.
@ -195,10 +197,10 @@ type CustomVGADevice struct {
// CustomVirtualIODevice handles QEMU VirtIO device parameters.
type CustomVirtualIODevice struct {
AIO *string `json:"aio,omitempty" url:"aio,omitempty"`
BackupEnabled *CustomBool `json:"backup,omitempty" url:"backup,omitempty,int"`
Enabled bool `json:"-" url:"-"`
FileVolume string `json:"file" url:"file"`
AIO *string `json:"aio,omitempty" url:"aio,omitempty"`
BackupEnabled *types.CustomBool `json:"backup,omitempty" url:"backup,omitempty,int"`
Enabled bool `json:"-" url:"-"`
FileVolume string `json:"file" url:"file"`
}
// CustomVirtualIODevices handles QEMU VirtIO device parameters.
@ -212,90 +214,90 @@ type CustomWatchdogDevice struct {
// VirtualEnvironmentVMCloneRequestBody contains the data for an virtual machine clone request.
type VirtualEnvironmentVMCloneRequestBody struct {
BandwidthLimit *int `json:"bwlimit,omitempty" url:"bwlimit,omitempty"`
Description *string `json:"description,omitempty" url:"description,omitempty"`
FullCopy *CustomBool `json:"full,omitempty" url:"full,omitempty,int"`
Name *string `json:"name,omitempty" url:"name,omitempty"`
PoolID *string `json:"pool,omitempty" url:"pool,omitempty"`
SnapshotName *string `json:"snapname,omitempty" url:"snapname,omitempty"`
TargetNodeName *string `json:"target,omitempty" url:"target,omitempty"`
TargetStorage *string `json:"storage,omitempty" url:"storage,omitempty"`
TargetStorageFormat *string `json:"format,omitempty" url:"format,omitempty"`
VMIDNew int `json:"newid" url:"newid"`
BandwidthLimit *int `json:"bwlimit,omitempty" url:"bwlimit,omitempty"`
Description *string `json:"description,omitempty" url:"description,omitempty"`
FullCopy *types.CustomBool `json:"full,omitempty" url:"full,omitempty,int"`
Name *string `json:"name,omitempty" url:"name,omitempty"`
PoolID *string `json:"pool,omitempty" url:"pool,omitempty"`
SnapshotName *string `json:"snapname,omitempty" url:"snapname,omitempty"`
TargetNodeName *string `json:"target,omitempty" url:"target,omitempty"`
TargetStorage *string `json:"storage,omitempty" url:"storage,omitempty"`
TargetStorageFormat *string `json:"format,omitempty" url:"format,omitempty"`
VMIDNew int `json:"newid" url:"newid"`
}
// VirtualEnvironmentVMCreateRequestBody contains the data for a virtual machine create request.
type VirtualEnvironmentVMCreateRequestBody struct {
ACPI *CustomBool `json:"acpi,omitempty" url:"acpi,omitempty,int"`
Agent *CustomAgent `json:"agent,omitempty" url:"agent,omitempty"`
AllowReboot *CustomBool `json:"reboot,omitempty" url:"reboot,omitempty,int"`
AudioDevices CustomAudioDevices `json:"audio,omitempty" url:"audio,omitempty"`
Autostart *CustomBool `json:"autostart,omitempty" url:"autostart,omitempty,int"`
BackupFile *string `json:"archive,omitempty" url:"archive,omitempty"`
BandwidthLimit *int `json:"bwlimit,omitempty" url:"bwlimit,omitempty"`
BIOS *string `json:"bios,omitempty" url:"bios,omitempty"`
BootDisk *string `json:"bootdisk,omitempty" url:"bootdisk,omitempty"`
BootOrder *string `json:"boot,omitempty" url:"boot,omitempty"`
CDROM *string `json:"cdrom,omitempty" url:"cdrom,omitempty"`
CloudInitConfig *CustomCloudInitConfig `json:"cloudinit,omitempty" url:"cloudinit,omitempty"`
CPUArchitecture *string `json:"arch,omitempty" url:"arch,omitempty"`
CPUCores *int `json:"cores,omitempty" url:"cores,omitempty"`
CPUEmulation *CustomCPUEmulation `json:"cpu,omitempty" url:"cpu,omitempty"`
CPULimit *int `json:"cpulimit,omitempty" url:"cpulimit,omitempty"`
CPUSockets *int `json:"sockets,omitempty" url:"sockets,omitempty"`
CPUUnits *int `json:"cpuunits,omitempty" url:"cpuunits,omitempty"`
DedicatedMemory *int `json:"memory,omitempty" url:"memory,omitempty"`
Delete []string `json:"delete,omitempty" url:"delete,omitempty,comma"`
DeletionProtection *CustomBool `json:"protection,omitempty" url:"force,omitempty,int"`
Description *string `json:"description,omitempty" url:"description,omitempty"`
EFIDisk *CustomEFIDisk `json:"efidisk0,omitempty" url:"efidisk0,omitempty"`
FloatingMemory *int `json:"balloon,omitempty" url:"balloon,omitempty"`
FloatingMemoryShares *int `json:"shares,omitempty" url:"shares,omitempty"`
Freeze *CustomBool `json:"freeze,omitempty" url:"freeze,omitempty,int"`
HookScript *string `json:"hookscript,omitempty" url:"hookscript,omitempty"`
Hotplug CustomCommaSeparatedList `json:"hotplug,omitempty" url:"hotplug,omitempty,comma"`
Hugepages *string `json:"hugepages,omitempty" url:"hugepages,omitempty"`
IDEDevices CustomStorageDevices `json:"ide,omitempty" url:",omitempty"`
KeyboardLayout *string `json:"keyboard,omitempty" url:"keyboard,omitempty"`
KVMArguments *string `json:"args,omitempty" url:"args,omitempty,space"`
KVMEnabled *CustomBool `json:"kvm,omitempty" url:"kvm,omitempty,int"`
LocalTime *CustomBool `json:"localtime,omitempty" url:"localtime,omitempty,int"`
Lock *string `json:"lock,omitempty" url:"lock,omitempty"`
Machine *string `json:"machine,omitempty" url:"machine,omitempty"`
MigrateDowntime *float64 `json:"migrate_downtime,omitempty" url:"migrate_downtime,omitempty"`
MigrateSpeed *int `json:"migrate_speed,omitempty" url:"migrate_speed,omitempty"`
Name *string `json:"name,omitempty" url:"name,omitempty"`
NetworkDevices CustomNetworkDevices `json:"net,omitempty" url:"net,omitempty"`
NUMADevices CustomNUMADevices `json:"numa_devices,omitempty" url:"numa,omitempty"`
NUMAEnabled *CustomBool `json:"numa,omitempty" url:"numa,omitempty,int"`
OSType *string `json:"ostype,omitempty" url:"ostype,omitempty"`
Overwrite *CustomBool `json:"force,omitempty" url:"force,omitempty,int"`
PCIDevices CustomPCIDevices `json:"hostpci,omitempty" url:"hostpci,omitempty"`
PoolID *string `json:"pool,omitempty" url:"pool,omitempty"`
Revert *string `json:"revert,omitempty" url:"revert,omitempty"`
SATADevices CustomStorageDevices `json:"sata,omitempty" url:"sata,omitempty"`
SCSIDevices CustomStorageDevices `json:"scsi,omitempty" url:"scsi,omitempty"`
SCSIHardware *string `json:"scsihw,omitempty" url:"scsihw,omitempty"`
SerialDevices CustomSerialDevices `json:"serial,omitempty" url:"serial,omitempty"`
SharedMemory *CustomSharedMemory `json:"ivshmem,omitempty" url:"ivshmem,omitempty"`
SkipLock *CustomBool `json:"skiplock,omitempty" url:"skiplock,omitempty,int"`
SMBIOS *CustomSMBIOS `json:"smbios1,omitempty" url:"smbios1,omitempty"`
SpiceEnhancements *CustomSpiceEnhancements `json:"spice_enhancements,omitempty" url:"spice_enhancements,omitempty"`
StartDate *string `json:"startdate,omitempty" url:"startdate,omitempty"`
StartOnBoot *CustomBool `json:"onboot,omitempty" url:"onboot,omitempty,int"`
StartupOrder *CustomStartupOrder `json:"startup,omitempty" url:"startup,omitempty"`
TabletDeviceEnabled *CustomBool `json:"tablet,omitempty" url:"tablet,omitempty,int"`
Tags *string `json:"tags,omitempty" url:"tags,omitempty"`
Template *CustomBool `json:"template,omitempty" url:"template,omitempty,int"`
TimeDriftFixEnabled *CustomBool `json:"tdf,omitempty" url:"tdf,omitempty,int"`
USBDevices CustomUSBDevices `json:"usb,omitempty" url:"usb,omitempty"`
VGADevice *CustomVGADevice `json:"vga,omitempty" url:"vga,omitempty"`
VirtualCPUCount *int `json:"vcpus,omitempty" url:"vcpus,omitempty"`
VirtualIODevices CustomStorageDevices `json:"virtio,omitempty" url:"virtio,omitempty"`
VMGenerationID *string `json:"vmgenid,omitempty" url:"vmgenid,omitempty"`
VMID *int `json:"vmid,omitempty" url:"vmid,omitempty"`
VMStateDatastoreID *string `json:"vmstatestorage,omitempty" url:"vmstatestorage,omitempty"`
WatchdogDevice *CustomWatchdogDevice `json:"watchdog,omitempty" url:"watchdog,omitempty"`
ACPI *types.CustomBool `json:"acpi,omitempty" url:"acpi,omitempty,int"`
Agent *CustomAgent `json:"agent,omitempty" url:"agent,omitempty"`
AllowReboot *types.CustomBool `json:"reboot,omitempty" url:"reboot,omitempty,int"`
AudioDevices CustomAudioDevices `json:"audio,omitempty" url:"audio,omitempty"`
Autostart *types.CustomBool `json:"autostart,omitempty" url:"autostart,omitempty,int"`
BackupFile *string `json:"archive,omitempty" url:"archive,omitempty"`
BandwidthLimit *int `json:"bwlimit,omitempty" url:"bwlimit,omitempty"`
BIOS *string `json:"bios,omitempty" url:"bios,omitempty"`
BootDisk *string `json:"bootdisk,omitempty" url:"bootdisk,omitempty"`
BootOrder *string `json:"boot,omitempty" url:"boot,omitempty"`
CDROM *string `json:"cdrom,omitempty" url:"cdrom,omitempty"`
CloudInitConfig *CustomCloudInitConfig `json:"cloudinit,omitempty" url:"cloudinit,omitempty"`
CPUArchitecture *string `json:"arch,omitempty" url:"arch,omitempty"`
CPUCores *int `json:"cores,omitempty" url:"cores,omitempty"`
CPUEmulation *CustomCPUEmulation `json:"cpu,omitempty" url:"cpu,omitempty"`
CPULimit *int `json:"cpulimit,omitempty" url:"cpulimit,omitempty"`
CPUSockets *int `json:"sockets,omitempty" url:"sockets,omitempty"`
CPUUnits *int `json:"cpuunits,omitempty" url:"cpuunits,omitempty"`
DedicatedMemory *int `json:"memory,omitempty" url:"memory,omitempty"`
Delete []string `json:"delete,omitempty" url:"delete,omitempty,comma"`
DeletionProtection *types.CustomBool `json:"protection,omitempty" url:"force,omitempty,int"`
Description *string `json:"description,omitempty" url:"description,omitempty"`
EFIDisk *CustomEFIDisk `json:"efidisk0,omitempty" url:"efidisk0,omitempty"`
FloatingMemory *int `json:"balloon,omitempty" url:"balloon,omitempty"`
FloatingMemoryShares *int `json:"shares,omitempty" url:"shares,omitempty"`
Freeze *types.CustomBool `json:"freeze,omitempty" url:"freeze,omitempty,int"`
HookScript *string `json:"hookscript,omitempty" url:"hookscript,omitempty"`
Hotplug types.CustomCommaSeparatedList `json:"hotplug,omitempty" url:"hotplug,omitempty,comma"`
Hugepages *string `json:"hugepages,omitempty" url:"hugepages,omitempty"`
IDEDevices CustomStorageDevices `json:"ide,omitempty" url:",omitempty"`
KeyboardLayout *string `json:"keyboard,omitempty" url:"keyboard,omitempty"`
KVMArguments *string `json:"args,omitempty" url:"args,omitempty,space"`
KVMEnabled *types.CustomBool `json:"kvm,omitempty" url:"kvm,omitempty,int"`
LocalTime *types.CustomBool `json:"localtime,omitempty" url:"localtime,omitempty,int"`
Lock *string `json:"lock,omitempty" url:"lock,omitempty"`
Machine *string `json:"machine,omitempty" url:"machine,omitempty"`
MigrateDowntime *float64 `json:"migrate_downtime,omitempty" url:"migrate_downtime,omitempty"`
MigrateSpeed *int `json:"migrate_speed,omitempty" url:"migrate_speed,omitempty"`
Name *string `json:"name,omitempty" url:"name,omitempty"`
NetworkDevices CustomNetworkDevices `json:"net,omitempty" url:"net,omitempty"`
NUMADevices CustomNUMADevices `json:"numa_devices,omitempty" url:"numa,omitempty"`
NUMAEnabled *types.CustomBool `json:"numa,omitempty" url:"numa,omitempty,int"`
OSType *string `json:"ostype,omitempty" url:"ostype,omitempty"`
Overwrite *types.CustomBool `json:"force,omitempty" url:"force,omitempty,int"`
PCIDevices CustomPCIDevices `json:"hostpci,omitempty" url:"hostpci,omitempty"`
PoolID *string `json:"pool,omitempty" url:"pool,omitempty"`
Revert *string `json:"revert,omitempty" url:"revert,omitempty"`
SATADevices CustomStorageDevices `json:"sata,omitempty" url:"sata,omitempty"`
SCSIDevices CustomStorageDevices `json:"scsi,omitempty" url:"scsi,omitempty"`
SCSIHardware *string `json:"scsihw,omitempty" url:"scsihw,omitempty"`
SerialDevices CustomSerialDevices `json:"serial,omitempty" url:"serial,omitempty"`
SharedMemory *CustomSharedMemory `json:"ivshmem,omitempty" url:"ivshmem,omitempty"`
SkipLock *types.CustomBool `json:"skiplock,omitempty" url:"skiplock,omitempty,int"`
SMBIOS *CustomSMBIOS `json:"smbios1,omitempty" url:"smbios1,omitempty"`
SpiceEnhancements *CustomSpiceEnhancements `json:"spice_enhancements,omitempty" url:"spice_enhancements,omitempty"`
StartDate *string `json:"startdate,omitempty" url:"startdate,omitempty"`
StartOnBoot *types.CustomBool `json:"onboot,omitempty" url:"onboot,omitempty,int"`
StartupOrder *CustomStartupOrder `json:"startup,omitempty" url:"startup,omitempty"`
TabletDeviceEnabled *types.CustomBool `json:"tablet,omitempty" url:"tablet,omitempty,int"`
Tags *string `json:"tags,omitempty" url:"tags,omitempty"`
Template *types.CustomBool `json:"template,omitempty" url:"template,omitempty,int"`
TimeDriftFixEnabled *types.CustomBool `json:"tdf,omitempty" url:"tdf,omitempty,int"`
USBDevices CustomUSBDevices `json:"usb,omitempty" url:"usb,omitempty"`
VGADevice *CustomVGADevice `json:"vga,omitempty" url:"vga,omitempty"`
VirtualCPUCount *int `json:"vcpus,omitempty" url:"vcpus,omitempty"`
VirtualIODevices CustomStorageDevices `json:"virtio,omitempty" url:"virtio,omitempty"`
VMGenerationID *string `json:"vmgenid,omitempty" url:"vmgenid,omitempty"`
VMID *int `json:"vmid,omitempty" url:"vmid,omitempty"`
VMStateDatastoreID *string `json:"vmstatestorage,omitempty" url:"vmstatestorage,omitempty"`
WatchdogDevice *CustomWatchdogDevice `json:"watchdog,omitempty" url:"watchdog,omitempty"`
}
// VirtualEnvironmentVMGetQEMUNetworkInterfacesResponseBody contains the body from a QEMU get network interfaces response.
@ -342,137 +344,137 @@ type VirtualEnvironmentVMGetResponseBody struct {
// VirtualEnvironmentVMGetResponseData contains the data from an virtual machine get response.
type VirtualEnvironmentVMGetResponseData struct {
ACPI *CustomBool `json:"acpi,omitempty"`
Agent *CustomAgent `json:"agent,omitempty"`
AllowReboot *CustomBool `json:"reboot,omitempty"`
AudioDevice *CustomAudioDevice `json:"audio0,omitempty"`
Autostart *CustomBool `json:"autostart,omitempty"`
BackupFile *string `json:"archive,omitempty"`
BandwidthLimit *int `json:"bwlimit,omitempty"`
BIOS *string `json:"bios,omitempty"`
BootDisk *string `json:"bootdisk,omitempty"`
BootOrder *string `json:"boot,omitempty"`
CDROM *string `json:"cdrom,omitempty"`
CloudInitDNSDomain *string `json:"searchdomain,omitempty"`
CloudInitDNSServer *string `json:"nameserver,omitempty"`
CloudInitFiles *CustomCloudInitFiles `json:"cicustom,omitempty"`
CloudInitPassword *string `json:"cipassword,omitempty"`
CloudInitSSHKeys *CustomCloudInitSSHKeys `json:"sshkeys,omitempty"`
CloudInitType *string `json:"citype,omitempty"`
CloudInitUsername *string `json:"ciuser,omitempty"`
CPUArchitecture *string `json:"arch,omitempty"`
CPUCores *int `json:"cores,omitempty"`
CPUEmulation *CustomCPUEmulation `json:"cpu,omitempty"`
CPULimit *int `json:"cpulimit,omitempty"`
CPUSockets *int `json:"sockets,omitempty"`
CPUUnits *int `json:"cpuunits,omitempty"`
DedicatedMemory *int `json:"memory,omitempty"`
DeletionProtection *CustomBool `json:"protection,omitempty"`
Description *string `json:"description,omitempty"`
EFIDisk *CustomEFIDisk `json:"efidisk0,omitempty"`
FloatingMemory *int `json:"balloon,omitempty"`
FloatingMemoryShares *int `json:"shares,omitempty"`
Freeze *CustomBool `json:"freeze,omitempty"`
HookScript *string `json:"hookscript,omitempty"`
Hotplug *CustomCommaSeparatedList `json:"hotplug,omitempty"`
Hugepages *string `json:"hugepages,omitempty"`
IDEDevice0 *CustomStorageDevice `json:"ide0,omitempty"`
IDEDevice1 *CustomStorageDevice `json:"ide1,omitempty"`
IDEDevice2 *CustomStorageDevice `json:"ide2,omitempty"`
IDEDevice3 *CustomStorageDevice `json:"ide3,omitempty"`
IPConfig0 *CustomCloudInitIPConfig `json:"ipconfig0,omitempty"`
IPConfig1 *CustomCloudInitIPConfig `json:"ipconfig1,omitempty"`
IPConfig2 *CustomCloudInitIPConfig `json:"ipconfig2,omitempty"`
IPConfig3 *CustomCloudInitIPConfig `json:"ipconfig3,omitempty"`
IPConfig4 *CustomCloudInitIPConfig `json:"ipconfig4,omitempty"`
IPConfig5 *CustomCloudInitIPConfig `json:"ipconfig5,omitempty"`
IPConfig6 *CustomCloudInitIPConfig `json:"ipconfig6,omitempty"`
IPConfig7 *CustomCloudInitIPConfig `json:"ipconfig7,omitempty"`
KeyboardLayout *string `json:"keyboard,omitempty"`
KVMArguments *string `json:"args,omitempty"`
KVMEnabled *CustomBool `json:"kvm,omitempty"`
LocalTime *CustomBool `json:"localtime,omitempty"`
Lock *string `json:"lock,omitempty"`
Machine *string `json:"machine,omitempty"`
MigrateDowntime *float64 `json:"migrate_downtime,omitempty"`
MigrateSpeed *int `json:"migrate_speed,omitempty"`
Name *string `json:"name,omitempty"`
NetworkDevice0 *CustomNetworkDevice `json:"net0,omitempty"`
NetworkDevice1 *CustomNetworkDevice `json:"net1,omitempty"`
NetworkDevice2 *CustomNetworkDevice `json:"net2,omitempty"`
NetworkDevice3 *CustomNetworkDevice `json:"net3,omitempty"`
NetworkDevice4 *CustomNetworkDevice `json:"net4,omitempty"`
NetworkDevice5 *CustomNetworkDevice `json:"net5,omitempty"`
NetworkDevice6 *CustomNetworkDevice `json:"net6,omitempty"`
NetworkDevice7 *CustomNetworkDevice `json:"net7,omitempty"`
NUMADevices *CustomNUMADevices `json:"numa_devices,omitempty"`
NUMAEnabled *CustomBool `json:"numa,omitempty"`
OSType *string `json:"ostype,omitempty"`
Overwrite *CustomBool `json:"force,omitempty"`
PCIDevice0 *CustomPCIDevice `json:"hostpci0,omitempty"`
PCIDevice1 *CustomPCIDevice `json:"hostpci1,omitempty"`
PCIDevice2 *CustomPCIDevice `json:"hostpci2,omitempty"`
PCIDevice3 *CustomPCIDevice `json:"hostpci3,omitempty"`
PoolID *string `json:"pool,omitempty" url:"pool,omitempty"`
Revert *string `json:"revert,omitempty"`
SATADevice0 *CustomStorageDevice `json:"sata0,omitempty"`
SATADevice1 *CustomStorageDevice `json:"sata1,omitempty"`
SATADevice2 *CustomStorageDevice `json:"sata2,omitempty"`
SATADevice3 *CustomStorageDevice `json:"sata3,omitempty"`
SATADevice4 *CustomStorageDevice `json:"sata4,omitempty"`
SATADevice5 *CustomStorageDevice `json:"sata5,omitempty"`
SCSIDevice0 *CustomStorageDevice `json:"scsi0,omitempty"`
SCSIDevice1 *CustomStorageDevice `json:"scsi1,omitempty"`
SCSIDevice2 *CustomStorageDevice `json:"scsi2,omitempty"`
SCSIDevice3 *CustomStorageDevice `json:"scsi3,omitempty"`
SCSIDevice4 *CustomStorageDevice `json:"scsi4,omitempty"`
SCSIDevice5 *CustomStorageDevice `json:"scsi5,omitempty"`
SCSIDevice6 *CustomStorageDevice `json:"scsi6,omitempty"`
SCSIDevice7 *CustomStorageDevice `json:"scsi7,omitempty"`
SCSIDevice8 *CustomStorageDevice `json:"scsi8,omitempty"`
SCSIDevice9 *CustomStorageDevice `json:"scsi9,omitempty"`
SCSIDevice10 *CustomStorageDevice `json:"scsi10,omitempty"`
SCSIDevice11 *CustomStorageDevice `json:"scsi11,omitempty"`
SCSIDevice12 *CustomStorageDevice `json:"scsi12,omitempty"`
SCSIDevice13 *CustomStorageDevice `json:"scsi13,omitempty"`
SCSIHardware *string `json:"scsihw,omitempty"`
SerialDevice0 *string `json:"serial0,omitempty"`
SerialDevice1 *string `json:"serial1,omitempty"`
SerialDevice2 *string `json:"serial2,omitempty"`
SerialDevice3 *string `json:"serial3,omitempty"`
SharedMemory *CustomSharedMemory `json:"ivshmem,omitempty"`
SkipLock *CustomBool `json:"skiplock,omitempty"`
SMBIOS *CustomSMBIOS `json:"smbios1,omitempty"`
SpiceEnhancements *CustomSpiceEnhancements `json:"spice_enhancements,omitempty"`
StartDate *string `json:"startdate,omitempty"`
StartOnBoot *CustomBool `json:"onboot,omitempty"`
StartupOrder *CustomStartupOrder `json:"startup,omitempty"`
TabletDeviceEnabled *CustomBool `json:"tablet,omitempty"`
Tags *string `json:"tags,omitempty"`
Template *CustomBool `json:"template,omitempty"`
TimeDriftFixEnabled *CustomBool `json:"tdf,omitempty"`
USBDevices *CustomUSBDevices `json:"usb,omitempty"`
VGADevice *CustomVGADevice `json:"vga,omitempty"`
VirtualCPUCount *int `json:"vcpus,omitempty"`
VirtualIODevice0 *CustomStorageDevice `json:"virtio0,omitempty"`
VirtualIODevice1 *CustomStorageDevice `json:"virtio1,omitempty"`
VirtualIODevice2 *CustomStorageDevice `json:"virtio2,omitempty"`
VirtualIODevice3 *CustomStorageDevice `json:"virtio3,omitempty"`
VirtualIODevice4 *CustomStorageDevice `json:"virtio4,omitempty"`
VirtualIODevice5 *CustomStorageDevice `json:"virtio5,omitempty"`
VirtualIODevice6 *CustomStorageDevice `json:"virtio6,omitempty"`
VirtualIODevice7 *CustomStorageDevice `json:"virtio7,omitempty"`
VirtualIODevice8 *CustomStorageDevice `json:"virtio8,omitempty"`
VirtualIODevice9 *CustomStorageDevice `json:"virtio9,omitempty"`
VirtualIODevice10 *CustomStorageDevice `json:"virtio10,omitempty"`
VirtualIODevice11 *CustomStorageDevice `json:"virtio11,omitempty"`
VirtualIODevice12 *CustomStorageDevice `json:"virtio12,omitempty"`
VirtualIODevice13 *CustomStorageDevice `json:"virtio13,omitempty"`
VirtualIODevice14 *CustomStorageDevice `json:"virtio14,omitempty"`
VirtualIODevice15 *CustomStorageDevice `json:"virtio15,omitempty"`
VMGenerationID *string `json:"vmgenid,omitempty"`
VMStateDatastoreID *string `json:"vmstatestorage,omitempty"`
WatchdogDevice *CustomWatchdogDevice `json:"watchdog,omitempty"`
ACPI *types.CustomBool `json:"acpi,omitempty"`
Agent *CustomAgent `json:"agent,omitempty"`
AllowReboot *types.CustomBool `json:"reboot,omitempty"`
AudioDevice *CustomAudioDevice `json:"audio0,omitempty"`
Autostart *types.CustomBool `json:"autostart,omitempty"`
BackupFile *string `json:"archive,omitempty"`
BandwidthLimit *int `json:"bwlimit,omitempty"`
BIOS *string `json:"bios,omitempty"`
BootDisk *string `json:"bootdisk,omitempty"`
BootOrder *string `json:"boot,omitempty"`
CDROM *string `json:"cdrom,omitempty"`
CloudInitDNSDomain *string `json:"searchdomain,omitempty"`
CloudInitDNSServer *string `json:"nameserver,omitempty"`
CloudInitFiles *CustomCloudInitFiles `json:"cicustom,omitempty"`
CloudInitPassword *string `json:"cipassword,omitempty"`
CloudInitSSHKeys *CustomCloudInitSSHKeys `json:"sshkeys,omitempty"`
CloudInitType *string `json:"citype,omitempty"`
CloudInitUsername *string `json:"ciuser,omitempty"`
CPUArchitecture *string `json:"arch,omitempty"`
CPUCores *int `json:"cores,omitempty"`
CPUEmulation *CustomCPUEmulation `json:"cpu,omitempty"`
CPULimit *int `json:"cpulimit,omitempty"`
CPUSockets *int `json:"sockets,omitempty"`
CPUUnits *int `json:"cpuunits,omitempty"`
DedicatedMemory *int `json:"memory,omitempty"`
DeletionProtection *types.CustomBool `json:"protection,omitempty"`
Description *string `json:"description,omitempty"`
EFIDisk *CustomEFIDisk `json:"efidisk0,omitempty"`
FloatingMemory *int `json:"balloon,omitempty"`
FloatingMemoryShares *int `json:"shares,omitempty"`
Freeze *types.CustomBool `json:"freeze,omitempty"`
HookScript *string `json:"hookscript,omitempty"`
Hotplug *types.CustomCommaSeparatedList `json:"hotplug,omitempty"`
Hugepages *string `json:"hugepages,omitempty"`
IDEDevice0 *CustomStorageDevice `json:"ide0,omitempty"`
IDEDevice1 *CustomStorageDevice `json:"ide1,omitempty"`
IDEDevice2 *CustomStorageDevice `json:"ide2,omitempty"`
IDEDevice3 *CustomStorageDevice `json:"ide3,omitempty"`
IPConfig0 *CustomCloudInitIPConfig `json:"ipconfig0,omitempty"`
IPConfig1 *CustomCloudInitIPConfig `json:"ipconfig1,omitempty"`
IPConfig2 *CustomCloudInitIPConfig `json:"ipconfig2,omitempty"`
IPConfig3 *CustomCloudInitIPConfig `json:"ipconfig3,omitempty"`
IPConfig4 *CustomCloudInitIPConfig `json:"ipconfig4,omitempty"`
IPConfig5 *CustomCloudInitIPConfig `json:"ipconfig5,omitempty"`
IPConfig6 *CustomCloudInitIPConfig `json:"ipconfig6,omitempty"`
IPConfig7 *CustomCloudInitIPConfig `json:"ipconfig7,omitempty"`
KeyboardLayout *string `json:"keyboard,omitempty"`
KVMArguments *string `json:"args,omitempty"`
KVMEnabled *types.CustomBool `json:"kvm,omitempty"`
LocalTime *types.CustomBool `json:"localtime,omitempty"`
Lock *string `json:"lock,omitempty"`
Machine *string `json:"machine,omitempty"`
MigrateDowntime *float64 `json:"migrate_downtime,omitempty"`
MigrateSpeed *int `json:"migrate_speed,omitempty"`
Name *string `json:"name,omitempty"`
NetworkDevice0 *CustomNetworkDevice `json:"net0,omitempty"`
NetworkDevice1 *CustomNetworkDevice `json:"net1,omitempty"`
NetworkDevice2 *CustomNetworkDevice `json:"net2,omitempty"`
NetworkDevice3 *CustomNetworkDevice `json:"net3,omitempty"`
NetworkDevice4 *CustomNetworkDevice `json:"net4,omitempty"`
NetworkDevice5 *CustomNetworkDevice `json:"net5,omitempty"`
NetworkDevice6 *CustomNetworkDevice `json:"net6,omitempty"`
NetworkDevice7 *CustomNetworkDevice `json:"net7,omitempty"`
NUMADevices *CustomNUMADevices `json:"numa_devices,omitempty"`
NUMAEnabled *types.CustomBool `json:"numa,omitempty"`
OSType *string `json:"ostype,omitempty"`
Overwrite *types.CustomBool `json:"force,omitempty"`
PCIDevice0 *CustomPCIDevice `json:"hostpci0,omitempty"`
PCIDevice1 *CustomPCIDevice `json:"hostpci1,omitempty"`
PCIDevice2 *CustomPCIDevice `json:"hostpci2,omitempty"`
PCIDevice3 *CustomPCIDevice `json:"hostpci3,omitempty"`
PoolID *string `json:"pool,omitempty" url:"pool,omitempty"`
Revert *string `json:"revert,omitempty"`
SATADevice0 *CustomStorageDevice `json:"sata0,omitempty"`
SATADevice1 *CustomStorageDevice `json:"sata1,omitempty"`
SATADevice2 *CustomStorageDevice `json:"sata2,omitempty"`
SATADevice3 *CustomStorageDevice `json:"sata3,omitempty"`
SATADevice4 *CustomStorageDevice `json:"sata4,omitempty"`
SATADevice5 *CustomStorageDevice `json:"sata5,omitempty"`
SCSIDevice0 *CustomStorageDevice `json:"scsi0,omitempty"`
SCSIDevice1 *CustomStorageDevice `json:"scsi1,omitempty"`
SCSIDevice2 *CustomStorageDevice `json:"scsi2,omitempty"`
SCSIDevice3 *CustomStorageDevice `json:"scsi3,omitempty"`
SCSIDevice4 *CustomStorageDevice `json:"scsi4,omitempty"`
SCSIDevice5 *CustomStorageDevice `json:"scsi5,omitempty"`
SCSIDevice6 *CustomStorageDevice `json:"scsi6,omitempty"`
SCSIDevice7 *CustomStorageDevice `json:"scsi7,omitempty"`
SCSIDevice8 *CustomStorageDevice `json:"scsi8,omitempty"`
SCSIDevice9 *CustomStorageDevice `json:"scsi9,omitempty"`
SCSIDevice10 *CustomStorageDevice `json:"scsi10,omitempty"`
SCSIDevice11 *CustomStorageDevice `json:"scsi11,omitempty"`
SCSIDevice12 *CustomStorageDevice `json:"scsi12,omitempty"`
SCSIDevice13 *CustomStorageDevice `json:"scsi13,omitempty"`
SCSIHardware *string `json:"scsihw,omitempty"`
SerialDevice0 *string `json:"serial0,omitempty"`
SerialDevice1 *string `json:"serial1,omitempty"`
SerialDevice2 *string `json:"serial2,omitempty"`
SerialDevice3 *string `json:"serial3,omitempty"`
SharedMemory *CustomSharedMemory `json:"ivshmem,omitempty"`
SkipLock *types.CustomBool `json:"skiplock,omitempty"`
SMBIOS *CustomSMBIOS `json:"smbios1,omitempty"`
SpiceEnhancements *CustomSpiceEnhancements `json:"spice_enhancements,omitempty"`
StartDate *string `json:"startdate,omitempty"`
StartOnBoot *types.CustomBool `json:"onboot,omitempty"`
StartupOrder *CustomStartupOrder `json:"startup,omitempty"`
TabletDeviceEnabled *types.CustomBool `json:"tablet,omitempty"`
Tags *string `json:"tags,omitempty"`
Template *types.CustomBool `json:"template,omitempty"`
TimeDriftFixEnabled *types.CustomBool `json:"tdf,omitempty"`
USBDevices *CustomUSBDevices `json:"usb,omitempty"`
VGADevice *CustomVGADevice `json:"vga,omitempty"`
VirtualCPUCount *int `json:"vcpus,omitempty"`
VirtualIODevice0 *CustomStorageDevice `json:"virtio0,omitempty"`
VirtualIODevice1 *CustomStorageDevice `json:"virtio1,omitempty"`
VirtualIODevice2 *CustomStorageDevice `json:"virtio2,omitempty"`
VirtualIODevice3 *CustomStorageDevice `json:"virtio3,omitempty"`
VirtualIODevice4 *CustomStorageDevice `json:"virtio4,omitempty"`
VirtualIODevice5 *CustomStorageDevice `json:"virtio5,omitempty"`
VirtualIODevice6 *CustomStorageDevice `json:"virtio6,omitempty"`
VirtualIODevice7 *CustomStorageDevice `json:"virtio7,omitempty"`
VirtualIODevice8 *CustomStorageDevice `json:"virtio8,omitempty"`
VirtualIODevice9 *CustomStorageDevice `json:"virtio9,omitempty"`
VirtualIODevice10 *CustomStorageDevice `json:"virtio10,omitempty"`
VirtualIODevice11 *CustomStorageDevice `json:"virtio11,omitempty"`
VirtualIODevice12 *CustomStorageDevice `json:"virtio12,omitempty"`
VirtualIODevice13 *CustomStorageDevice `json:"virtio13,omitempty"`
VirtualIODevice14 *CustomStorageDevice `json:"virtio14,omitempty"`
VirtualIODevice15 *CustomStorageDevice `json:"virtio15,omitempty"`
VMGenerationID *string `json:"vmgenid,omitempty"`
VMStateDatastoreID *string `json:"vmstatestorage,omitempty"`
WatchdogDevice *CustomWatchdogDevice `json:"watchdog,omitempty"`
}
// VirtualEnvironmentVMGetStatusResponseBody contains the body from a VM get status response.
@ -482,19 +484,19 @@ type VirtualEnvironmentVMGetStatusResponseBody struct {
// VirtualEnvironmentVMGetStatusResponseData contains the data from a VM get status response.
type VirtualEnvironmentVMGetStatusResponseData struct {
AgentEnabled *CustomBool `json:"agent,omitempty"`
CPUCount *float64 `json:"cpus,omitempty"`
Lock *string `json:"lock,omitempty"`
MemoryAllocation *int `json:"maxmem,omitempty"`
Name *string `json:"name,omitempty"`
PID *int `json:"pid,omitempty"`
QMPStatus *string `json:"qmpstatus,omitempty"`
RootDiskSize *int `json:"maxdisk,omitempty"`
SpiceSupport *CustomBool `json:"spice,omitempty"`
Status string `json:"status,omitempty"`
Tags *string `json:"tags,omitempty"`
Uptime *int `json:"uptime,omitempty"`
VMID *int `json:"vmid,omitempty"`
AgentEnabled *types.CustomBool `json:"agent,omitempty"`
CPUCount *float64 `json:"cpus,omitempty"`
Lock *string `json:"lock,omitempty"`
MemoryAllocation *int `json:"maxmem,omitempty"`
Name *string `json:"name,omitempty"`
PID *int `json:"pid,omitempty"`
QMPStatus *string `json:"qmpstatus,omitempty"`
RootDiskSize *int `json:"maxdisk,omitempty"`
SpiceSupport *types.CustomBool `json:"spice,omitempty"`
Status string `json:"status,omitempty"`
Tags *string `json:"tags,omitempty"`
Uptime *int `json:"uptime,omitempty"`
VMID *int `json:"vmid,omitempty"`
}
// VirtualEnvironmentVMListResponseBody contains the body from an virtual machine list response.
@ -511,10 +513,10 @@ type VirtualEnvironmentVMListResponseData struct {
// VirtualEnvironmentVMMigrateRequestBody contains the body for a VM migration request.
type VirtualEnvironmentVMMigrateRequestBody struct {
OnlineMigration *CustomBool `json:"online,omitempty" url:"online,omitempty"`
TargetNode string `json:"target" url:"target"`
TargetStorage *string `json:"targetstorage,omitempty" url:"targetstorage,omitempty"`
WithLocalDisks *CustomBool `json:"with-local-disks,omitempty" url:"with-local-disks,omitempty,int"`
OnlineMigration *types.CustomBool `json:"online,omitempty" url:"online,omitempty"`
TargetNode string `json:"target" url:"target"`
TargetStorage *string `json:"targetstorage,omitempty" url:"targetstorage,omitempty"`
WithLocalDisks *types.CustomBool `json:"with-local-disks,omitempty" url:"with-local-disks,omitempty,int"`
}
// VirtualEnvironmentVMMigrateResponseBody contains the body from a VM migrate response.
@ -524,12 +526,12 @@ type VirtualEnvironmentVMMigrateResponseBody struct {
// VirtualEnvironmentVMMoveDiskRequestBody contains the body for a VM move disk request.
type VirtualEnvironmentVMMoveDiskRequestBody struct {
BandwidthLimit *int `json:"bwlimit,omitempty" url:"bwlimit,omitempty"`
DeleteOriginalDisk *CustomBool `json:"delete,omitempty" url:"delete,omitempty,int"`
Digest *string `json:"digest,omitempty" url:"digest,omitempty"`
Disk string `json:"disk" url:"disk"`
TargetStorage string `json:"storage" url:"storage"`
TargetStorageFormat *string `json:"format,omitempty" url:"format,omitempty"`
BandwidthLimit *int `json:"bwlimit,omitempty" url:"bwlimit,omitempty"`
DeleteOriginalDisk *types.CustomBool `json:"delete,omitempty" url:"delete,omitempty,int"`
Digest *string `json:"digest,omitempty" url:"digest,omitempty"`
Disk string `json:"disk" url:"disk"`
TargetStorage string `json:"storage" url:"storage"`
TargetStorageFormat *string `json:"format,omitempty" url:"format,omitempty"`
}
// VirtualEnvironmentVMMoveDiskResponseBody contains the body from a VM move disk response.
@ -549,18 +551,18 @@ type VirtualEnvironmentVMRebootResponseBody struct {
// VirtualEnvironmentVMResizeDiskRequestBody contains the body for a VM resize disk request.
type VirtualEnvironmentVMResizeDiskRequestBody struct {
Digest *string `json:"digest,omitempty" url:"digest,omitempty"`
Disk string `json:"disk" url:"disk"`
Size string `json:"size" url:"size"`
SkipLock *CustomBool `json:"skiplock,omitempty" url:"skiplock,omitempty,int"`
Digest *string `json:"digest,omitempty" url:"digest,omitempty"`
Disk string `json:"disk" url:"disk"`
Size string `json:"size" url:"size"`
SkipLock *types.CustomBool `json:"skiplock,omitempty" url:"skiplock,omitempty,int"`
}
// VirtualEnvironmentVMShutdownRequestBody contains the body for a VM shutdown request.
type VirtualEnvironmentVMShutdownRequestBody struct {
ForceStop *CustomBool `json:"forceStop,omitempty" url:"forceStop,omitempty,int"`
KeepActive *CustomBool `json:"keepActive,omitempty" url:"keepActive,omitempty,int"`
SkipLock *CustomBool `json:"skipLock,omitempty" url:"skipLock,omitempty,int"`
Timeout *int `json:"timeout,omitempty" url:"timeout,omitempty"`
ForceStop *types.CustomBool `json:"forceStop,omitempty" url:"forceStop,omitempty,int"`
KeepActive *types.CustomBool `json:"keepActive,omitempty" url:"keepActive,omitempty,int"`
SkipLock *types.CustomBool `json:"skipLock,omitempty" url:"skipLock,omitempty,int"`
Timeout *int `json:"timeout,omitempty" url:"timeout,omitempty"`
}
// VirtualEnvironmentVMShutdownResponseBody contains the body from a VM shutdown response.
@ -1251,15 +1253,15 @@ func (r *CustomAgent) UnmarshalJSON(b []byte) error {
v := strings.Split(strings.TrimSpace(p), "=")
if len(v) == 1 {
enabled := CustomBool(v[0] == "1")
enabled := types.CustomBool(v[0] == "1")
r.Enabled = &enabled
} else if len(v) == 2 {
switch v[0] {
case "enabled":
enabled := CustomBool(v[1] == "1")
enabled := types.CustomBool(v[1] == "1")
r.Enabled = &enabled
case "fstrim_cloned_disks":
fstrim := CustomBool(v[1] == "1")
fstrim := types.CustomBool(v[1] == "1")
r.TrimClonedDisks = &fstrim
case "type":
r.Type = &v[1]
@ -1416,7 +1418,7 @@ func (r *CustomCPUEmulation) UnmarshalJSON(b []byte) error {
r.Flags = &f
}
case "hidden":
bv := CustomBool(v[1] == "1")
bv := types.CustomBool(v[1] == "1")
r.Hidden = &bv
case "hv-vendor-id":
r.HVVendorID = &v[1]
@ -1480,10 +1482,10 @@ func (r *CustomNetworkDevice) UnmarshalJSON(b []byte) error {
case "bridge":
r.Bridge = &v[1]
case "firewall":
bv := CustomBool(v[1] == "1")
bv := types.CustomBool(v[1] == "1")
r.Firewall = &bv
case "link_down":
bv := CustomBool(v[1] == "1")
bv := types.CustomBool(v[1] == "1")
r.LinkDown = &bv
case "macaddr":
r.MACAddress = &v[1]
@ -1563,15 +1565,15 @@ func (r *CustomPCIDevice) UnmarshalJSON(b []byte) error {
case "mdev":
r.MDev = &v[1]
case "pcie":
bv := CustomBool(v[1] == "1")
bv := types.CustomBool(v[1] == "1")
r.PCIExpress = &bv
case "rombar":
bv := CustomBool(v[1] == "1")
bv := types.CustomBool(v[1] == "1")
r.ROMBAR = &bv
case "romfile":
r.ROMFile = &v[1]
case "x-vga":
bv := CustomBool(v[1] == "1")
bv := types.CustomBool(v[1] == "1")
r.XVGA = &bv
}
}
@ -1628,7 +1630,7 @@ func (r *CustomSMBIOS) UnmarshalJSON(b []byte) error {
if len(v) == 2 {
switch v[0] {
case "base64":
base64 := CustomBool(v[1] == "1")
base64 := types.CustomBool(v[1] == "1")
r.Base64 = &base64
case "family":
r.Family = &v[1]
@ -1677,7 +1679,7 @@ func (r *CustomStorageDevice) UnmarshalJSON(b []byte) error {
case "aio":
r.AIO = &v[1]
case "backup":
bv := CustomBool(v[1] == "1")
bv := types.CustomBool(v[1] == "1")
r.BackupEnabled = &bv
case "file":
r.FileVolume = v[1]
@ -1716,10 +1718,10 @@ func (r *CustomStorageDevice) UnmarshalJSON(b []byte) error {
case "format":
r.Format = &v[1]
case "iothread":
bv := CustomBool(v[1] == "1")
bv := types.CustomBool(v[1] == "1")
r.IOThread = &bv
case "ssd":
bv := CustomBool(v[1] == "1")
bv := types.CustomBool(v[1] == "1")
r.SSD = &bv
case "discard":
r.Discard = &v[1]

View File

@ -4,6 +4,8 @@ import (
"testing"
"github.com/stretchr/testify/require"
"github.com/bpg/terraform-provider-proxmox/proxmox/types"
)
func TestCustomStorageDevice_UnmarshalJSON(t *testing.T) {
@ -54,7 +56,7 @@ func strPtr(s string) *string {
return &s
}
func boolPtr(s bool) *CustomBool {
customBool := CustomBool(s)
func boolPtr(s bool) *types.CustomBool {
customBool := types.CustomBool(s)
return &customBool
}

32
proxmox/vm/client.go Normal file
View File

@ -0,0 +1,32 @@
/*
* 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 vm
import (
"fmt"
"net/url"
"github.com/bpg/terraform-provider-proxmox/proxmox/firewall"
"github.com/bpg/terraform-provider-proxmox/proxmox/types"
vmfirewall "github.com/bpg/terraform-provider-proxmox/proxmox/vm/firewall"
)
type Client struct {
types.Client
NodeName string
VMID int
}
func (c *Client) ExpandPath(path string) string {
return fmt.Sprintf("nodes/%s/qemu/%d/%s", url.PathEscape(c.NodeName), c.VMID, path)
}
func (c *Client) Firewall() firewall.API {
return &vmfirewall.Client{
Client: firewall.Client{Client: c},
}
}

View File

@ -0,0 +1,15 @@
/*
* 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 firewall
import (
"github.com/bpg/terraform-provider-proxmox/proxmox/firewall"
)
type Client struct {
firewall.Client
}

39
proxmoxtf/config.go Normal file
View File

@ -0,0 +1,39 @@
/*
* 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/.
*/
/*
* 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 proxmoxtf
import (
"errors"
"github.com/bpg/terraform-provider-proxmox/proxmox"
)
type ProviderConfiguration struct {
veClient *proxmox.VirtualEnvironmentClient
}
func NewProviderConfiguration(veClient *proxmox.VirtualEnvironmentClient) ProviderConfiguration {
return ProviderConfiguration{
veClient: veClient,
}
}
func (c *ProviderConfiguration) GetVEClient() (*proxmox.VirtualEnvironmentClient, error) {
if c.veClient == nil {
return nil, errors.New(
"you must specify the virtual environment details in the provider configuration",
)
}
return c.veClient, nil
}

View File

@ -1,77 +0,0 @@
/* 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 proxmoxtf
import (
"context"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)
const (
dvDataVirtualEnvironmentClusterAliasComment = ""
mkDataSourceVirtualEnvironmentClusterAliasName = "name"
mkDataSourceVirtualEnvironmentClusterAliasCIDR = "cidr"
mkDataSourceVirtualEnvironmentClusterAliasComment = "comment"
)
func dataSourceVirtualEnvironmentClusterAlias() *schema.Resource {
return &schema.Resource{
Schema: map[string]*schema.Schema{
mkDataSourceVirtualEnvironmentClusterAliasName: {
Type: schema.TypeString,
Description: "Alias name",
Required: true,
},
mkDataSourceVirtualEnvironmentClusterAliasCIDR: {
Type: schema.TypeString,
Description: "IP/CIDR block",
Computed: true,
},
mkDataSourceVirtualEnvironmentClusterAliasComment: {
Type: schema.TypeString,
Description: "Alias comment",
Computed: true,
},
},
ReadContext: dataSourceVirtualEnvironmentAliasRead,
}
}
func dataSourceVirtualEnvironmentAliasRead(
ctx context.Context,
d *schema.ResourceData,
m interface{},
) diag.Diagnostics {
var diags diag.Diagnostics
config := m.(providerConfiguration)
veClient, err := config.GetVEClient()
if err != nil {
return diag.FromErr(err)
}
AliasID := d.Get(mkDataSourceVirtualEnvironmentClusterAliasName).(string)
Alias, err := veClient.GetAlias(ctx, AliasID)
if err != nil {
return diag.FromErr(err)
}
d.SetId(AliasID)
err = d.Set(mkDataSourceVirtualEnvironmentClusterAliasCIDR, Alias.CIDR)
diags = append(diags, diag.FromErr(err)...)
if Alias.Comment != nil {
err = d.Set(mkDataSourceVirtualEnvironmentClusterAliasComment, Alias.Comment)
} else {
err = d.Set(mkDataSourceVirtualEnvironmentClusterAliasComment, dvDataVirtualEnvironmentClusterAliasComment)
}
diags = append(diags, diag.FromErr(err)...)
return diags
}

View File

@ -1,40 +0,0 @@
/* 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 proxmoxtf
import (
"testing"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)
// TestDataSourceVirtualEnvironmentAliasInstantiation tests whether the DataSourceVirtualEnvironmentAlias instance can be instantiated.
func TestDataSourceVirtualEnvironmentAliasInstantiation(t *testing.T) {
s := dataSourceVirtualEnvironmentClusterAlias()
if s == nil {
t.Fatalf("Cannot instantiate dataSourceVirtualEnvironmentAlias")
}
}
// TestDataSourceVirtualEnvironmentAliasSchema tests the dataSourceVirtualEnvironmentAlias schema.
func TestDataSourceVirtualEnvironmentAliasSchema(t *testing.T) {
s := dataSourceVirtualEnvironmentClusterAlias()
testRequiredArguments(t, s, []string{
mkDataSourceVirtualEnvironmentClusterAliasName,
})
testComputedAttributes(t, s, []string{
mkDataSourceVirtualEnvironmentClusterAliasCIDR,
mkDataSourceVirtualEnvironmentClusterAliasComment,
})
testValueTypes(t, s, map[string]schema.ValueType{
mkDataSourceVirtualEnvironmentClusterAliasName: schema.TypeString,
mkDataSourceVirtualEnvironmentClusterAliasCIDR: schema.TypeString,
mkDataSourceVirtualEnvironmentClusterAliasComment: schema.TypeString,
})
}

View File

@ -1,59 +0,0 @@
/* 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 proxmoxtf
import (
"context"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)
const (
mkDataSourceVirtualEnvironmentClusterAliasesAliasIDs = "alias_ids"
)
func dataSourceVirtualEnvironmentClusterAliases() *schema.Resource {
return &schema.Resource{
Schema: map[string]*schema.Schema{
mkDataSourceVirtualEnvironmentClusterAliasesAliasIDs: {
Type: schema.TypeList,
Description: "Alias IDs",
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
},
ReadContext: dataSourceVirtualEnvironmentClusterAliasesRead,
}
}
func dataSourceVirtualEnvironmentClusterAliasesRead(
ctx context.Context,
d *schema.ResourceData,
m interface{},
) diag.Diagnostics {
config := m.(providerConfiguration)
veClient, err := config.GetVEClient()
if err != nil {
return diag.FromErr(err)
}
list, err := veClient.ListPools(ctx)
if err != nil {
return diag.FromErr(err)
}
aliasIDs := make([]interface{}, len(list))
for i, v := range list {
aliasIDs[i] = v.ID
}
d.SetId("aliases")
err = d.Set(mkDataSourceVirtualEnvironmentClusterAliasesAliasIDs, aliasIDs)
return diag.FromErr(err)
}

View File

@ -1,33 +0,0 @@
/* 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 proxmoxtf
import (
"testing"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)
// TestDataSourceVirtualEnvironmentAliasesInstantiation tests whether the DataSourceVirtualEnvironmentAliases instance can be instantiated.
func TestDataSourceVirtualEnvironmentAliasesInstantiation(t *testing.T) {
s := dataSourceVirtualEnvironmentClusterAliases()
if s == nil {
t.Fatalf("Cannot instantiate dataSourceVirtualEnvironmentAliases")
}
}
// TestDataSourceVirtualEnvironmentAliasesSchema tests the dataSourceVirtualEnvironmentAliases schema.
func TestDataSourceVirtualEnvironmentAliasesSchema(t *testing.T) {
s := dataSourceVirtualEnvironmentClusterAliases()
testComputedAttributes(t, s, []string{
mkDataSourceVirtualEnvironmentClusterAliasesAliasIDs,
})
testValueTypes(t, s, map[string]schema.ValueType{
mkDataSourceVirtualEnvironmentClusterAliasesAliasIDs: schema.TypeList,
})
}

View File

@ -1,40 +0,0 @@
/* 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 proxmoxtf
import (
"testing"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)
// TestDataSourceVirtualEnvironmentDNSInstantiation tests whether the DataSourceVirtualEnvironmentDNS instance can be instantiated.
func TestDataSourceVirtualEnvironmentDNSInstantiation(t *testing.T) {
s := dataSourceVirtualEnvironmentDNS()
if s == nil {
t.Fatalf("Cannot instantiate dataSourceVirtualEnvironmentDNS")
}
}
// TestDataSourceVirtualEnvironmentDNSSchema tests the dataSourceVirtualEnvironmentDNS schema.
func TestDataSourceVirtualEnvironmentDNSSchema(t *testing.T) {
s := dataSourceVirtualEnvironmentDNS()
testRequiredArguments(t, s, []string{
mkDataSourceVirtualEnvironmentDNSNodeName,
})
testComputedAttributes(t, s, []string{
mkDataSourceVirtualEnvironmentDNSDomain,
mkDataSourceVirtualEnvironmentDNSServers,
})
testValueTypes(t, s, map[string]schema.ValueType{
mkDataSourceVirtualEnvironmentDNSDomain: schema.TypeString,
mkDataSourceVirtualEnvironmentDNSNodeName: schema.TypeString,
mkDataSourceVirtualEnvironmentDNSServers: schema.TypeList,
})
}

View File

@ -1,35 +0,0 @@
/* 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 proxmoxtf
import (
"testing"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)
// TestDataSourceVirtualEnvironmentGroupsInstantiation tests whether the DataSourceVirtualEnvironmentGroups instance can be instantiated.
func TestDataSourceVirtualEnvironmentGroupsInstantiation(t *testing.T) {
s := dataSourceVirtualEnvironmentGroups()
if s == nil {
t.Fatalf("Cannot instantiate dataSourceVirtualEnvironmentGroups")
}
}
// TestDataSourceVirtualEnvironmentGroupsSchema tests the dataSourceVirtualEnvironmentGroups schema.
func TestDataSourceVirtualEnvironmentGroupsSchema(t *testing.T) {
s := dataSourceVirtualEnvironmentGroups()
testComputedAttributes(t, s, []string{
mkDataSourceVirtualEnvironmentGroupsComments,
mkDataSourceVirtualEnvironmentGroupsGroupIDs,
})
testValueTypes(t, s, map[string]schema.ValueType{
mkDataSourceVirtualEnvironmentGroupsComments: schema.TypeList,
mkDataSourceVirtualEnvironmentGroupsGroupIDs: schema.TypeList,
})
}

Some files were not shown because too many files have changed in this diff Show More