diff --git a/.golangci.yml b/.golangci.yml index a0e60b85..c151ea4c 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -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 diff --git a/docs/Gemfile.lock b/docs/Gemfile.lock index cb7df890..972deb65 100644 --- a/docs/Gemfile.lock +++ b/docs/Gemfile.lock @@ -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 diff --git a/docs/data-sources/virtual_environment_cluster_alias.md b/docs/data-sources/virtual_environment_cluster_alias.md deleted file mode 100644 index 08d55cc0..00000000 --- a/docs/data-sources/virtual_environment_cluster_alias.md +++ /dev/null @@ -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. diff --git a/docs/data-sources/virtual_environment_cluster_aliases.md b/docs/data-sources/virtual_environment_cluster_aliases.md deleted file mode 100644 index 61047d71..00000000 --- a/docs/data-sources/virtual_environment_cluster_aliases.md +++ /dev/null @@ -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. diff --git a/docs/data-sources/virtual_environment_datastores.md b/docs/data-sources/virtual_environment_datastores.md index 1cc51cf2..f9247ec0 100644 --- a/docs/data-sources/virtual_environment_datastores.md +++ b/docs/data-sources/virtual_environment_datastores.md @@ -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 --- diff --git a/docs/data-sources/virtual_environment_dns.md b/docs/data-sources/virtual_environment_dns.md index 3d061f48..8d486fe7 100644 --- a/docs/data-sources/virtual_environment_dns.md +++ b/docs/data-sources/virtual_environment_dns.md @@ -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 --- diff --git a/docs/data-sources/virtual_environment_group.md b/docs/data-sources/virtual_environment_group.md index ff8f559b..20bef33b 100644 --- a/docs/data-sources/virtual_environment_group.md +++ b/docs/data-sources/virtual_environment_group.md @@ -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 --- diff --git a/docs/data-sources/virtual_environment_groups.md b/docs/data-sources/virtual_environment_groups.md index a3386277..128c7d74 100644 --- a/docs/data-sources/virtual_environment_groups.md +++ b/docs/data-sources/virtual_environment_groups.md @@ -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 --- diff --git a/docs/data-sources/virtual_environment_hosts.md b/docs/data-sources/virtual_environment_hosts.md index 368ad463..ccc45d06 100644 --- a/docs/data-sources/virtual_environment_hosts.md +++ b/docs/data-sources/virtual_environment_hosts.md @@ -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 --- diff --git a/docs/data-sources/virtual_environment_nodes.md b/docs/data-sources/virtual_environment_nodes.md index 75c0ec4a..ade9892b 100644 --- a/docs/data-sources/virtual_environment_nodes.md +++ b/docs/data-sources/virtual_environment_nodes.md @@ -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 --- diff --git a/docs/data-sources/virtual_environment_pool.md b/docs/data-sources/virtual_environment_pool.md index 97297336..d9d0c3b9 100644 --- a/docs/data-sources/virtual_environment_pool.md +++ b/docs/data-sources/virtual_environment_pool.md @@ -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 --- diff --git a/docs/data-sources/virtual_environment_pools.md b/docs/data-sources/virtual_environment_pools.md index 05064055..2681f550 100644 --- a/docs/data-sources/virtual_environment_pools.md +++ b/docs/data-sources/virtual_environment_pools.md @@ -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 --- diff --git a/docs/data-sources/virtual_environment_role.md b/docs/data-sources/virtual_environment_role.md index 4bb0a14b..28a31106 100644 --- a/docs/data-sources/virtual_environment_role.md +++ b/docs/data-sources/virtual_environment_role.md @@ -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 --- diff --git a/docs/data-sources/virtual_environment_roles.md b/docs/data-sources/virtual_environment_roles.md index af172258..3a8d22fa 100644 --- a/docs/data-sources/virtual_environment_roles.md +++ b/docs/data-sources/virtual_environment_roles.md @@ -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 --- diff --git a/docs/data-sources/virtual_environment_time.md b/docs/data-sources/virtual_environment_time.md index f70d936f..8a1cbd35 100644 --- a/docs/data-sources/virtual_environment_time.md +++ b/docs/data-sources/virtual_environment_time.md @@ -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 --- diff --git a/docs/data-sources/virtual_environment_user.md b/docs/data-sources/virtual_environment_user.md index d2d8952b..218f6218 100644 --- a/docs/data-sources/virtual_environment_user.md +++ b/docs/data-sources/virtual_environment_user.md @@ -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 --- diff --git a/docs/data-sources/virtual_environment_users.md b/docs/data-sources/virtual_environment_users.md index cda04793..b1afeda6 100644 --- a/docs/data-sources/virtual_environment_users.md +++ b/docs/data-sources/virtual_environment_users.md @@ -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 --- diff --git a/docs/data-sources/virtual_environment_version.md b/docs/data-sources/virtual_environment_version.md index 43d5d380..a36eac12 100644 --- a/docs/data-sources/virtual_environment_version.md +++ b/docs/data-sources/virtual_environment_version.md @@ -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 --- diff --git a/docs/data-sources/virtual_environment_vm.md b/docs/data-sources/virtual_environment_vm.md index 90b68c7f..dc9e0693 100644 --- a/docs/data-sources/virtual_environment_vm.md +++ b/docs/data-sources/virtual_environment_vm.md @@ -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 --- diff --git a/docs/data-sources/virtual_environment_vms.md b/docs/data-sources/virtual_environment_vms.md index 1cd9fae3..11a52992 100644 --- a/docs/data-sources/virtual_environment_vms.md +++ b/docs/data-sources/virtual_environment_vms.md @@ -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 --- diff --git a/docs/resources/virtual_environment_cluster_alias.md b/docs/resources/virtual_environment_cluster_alias.md deleted file mode 100644 index 49ef6328..00000000 --- a/docs/resources/virtual_environment_cluster_alias.md +++ /dev/null @@ -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. diff --git a/docs/resources/virtual_environment_cluster_firewall.md b/docs/resources/virtual_environment_cluster_firewall.md new file mode 100644 index 00000000..407f19c4 --- /dev/null +++ b/docs/resources/virtual_environment_cluster_firewall.md @@ -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. diff --git a/docs/resources/virtual_environment_cluster_firewall_security_group.md b/docs/resources/virtual_environment_cluster_firewall_security_group.md new file mode 100644 index 00000000..2bfeb348 --- /dev/null +++ b/docs/resources/virtual_environment_cluster_firewall_security_group.md @@ -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. diff --git a/docs/resources/virtual_environment_firewall_alias.md b/docs/resources/virtual_environment_firewall_alias.md new file mode 100644 index 00000000..a9256dc7 --- /dev/null +++ b/docs/resources/virtual_environment_firewall_alias.md @@ -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. diff --git a/docs/resources/virtual_environment_cluster_ipset.md b/docs/resources/virtual_environment_firewall_ipset.md similarity index 51% rename from docs/resources/virtual_environment_cluster_ipset.md rename to docs/resources/virtual_environment_firewall_ipset.md index 85126831..2d334151 100644 --- a/docs/resources/virtual_environment_cluster_ipset.md +++ b/docs/resources/virtual_environment_firewall_ipset.md @@ -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. diff --git a/docs/resources/virtual_environment_firewall_options.md b/docs/resources/virtual_environment_firewall_options.md new file mode 100644 index 00000000..fdd9c4aa --- /dev/null +++ b/docs/resources/virtual_environment_firewall_options.md @@ -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 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. diff --git a/docs/resources/virtual_environment_firewall_rules.md b/docs/resources/virtual_environment_firewall_rules.md new file mode 100644 index 00000000..ff4e46ae --- /dev/null +++ b/docs/resources/virtual_environment_firewall_rules.md @@ -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. diff --git a/docs/resources/virtual_environment_group.md b/docs/resources/virtual_environment_group.md index 8e7406b9..443f52e2 100644 --- a/docs/resources/virtual_environment_group.md +++ b/docs/resources/virtual_environment_group.md @@ -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 --- diff --git a/docs/resources/virtual_environment_hosts.md b/docs/resources/virtual_environment_hosts.md index 2af9ee59..f50dca26 100644 --- a/docs/resources/virtual_environment_hosts.md +++ b/docs/resources/virtual_environment_hosts.md @@ -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 --- diff --git a/docs/resources/virtual_environment_pool.md b/docs/resources/virtual_environment_pool.md index e79a275a..259655cd 100644 --- a/docs/resources/virtual_environment_pool.md +++ b/docs/resources/virtual_environment_pool.md @@ -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 --- diff --git a/docs/resources/virtual_environment_role.md b/docs/resources/virtual_environment_role.md index 70fe90cc..f7f8f215 100644 --- a/docs/resources/virtual_environment_role.md +++ b/docs/resources/virtual_environment_role.md @@ -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 --- diff --git a/docs/resources/virtual_environment_time.md b/docs/resources/virtual_environment_time.md index dbfb0660..9f369915 100644 --- a/docs/resources/virtual_environment_time.md +++ b/docs/resources/virtual_environment_time.md @@ -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 --- diff --git a/docs/resources/virtual_environment_user.md b/docs/resources/virtual_environment_user.md index 7616ef1c..9b3e5875 100644 --- a/docs/resources/virtual_environment_user.md +++ b/docs/resources/virtual_environment_user.md @@ -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 --- diff --git a/docs/resources/virtual_environment_vm.md b/docs/resources/virtual_environment_vm.md index 9dc5a9d8..5272d07b 100644 --- a/docs/resources/virtual_environment_vm.md +++ b/docs/resources/virtual_environment_vm.md @@ -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 --- diff --git a/example/data_source_virtual_environment_cluster_alias.tf b/example/data_source_virtual_environment_cluster_alias.tf deleted file mode 100644 index 20e14b25..00000000 --- a/example/data_source_virtual_environment_cluster_alias.tf +++ /dev/null @@ -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 -} diff --git a/example/data_source_virtual_environment_cluster_aliases.tf b/example/data_source_virtual_environment_cluster_aliases.tf deleted file mode 100644 index 8333f2c8..00000000 --- a/example/data_source_virtual_environment_cluster_aliases.tf +++ /dev/null @@ -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 - } -} diff --git a/example/resource_virtual_environemnt_cluster_alias.tf b/example/resource_virtual_environemnt_cluster_alias.tf deleted file mode 100644 index 762c70f9..00000000 --- a/example/resource_virtual_environemnt_cluster_alias.tf +++ /dev/null @@ -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 -} diff --git a/example/resource_virtual_environment_cluster_firewall_security_group.tf b/example/resource_virtual_environment_cluster_firewall_security_group.tf new file mode 100644 index 00000000..c7f77f02 --- /dev/null +++ b/example/resource_virtual_environment_cluster_firewall_security_group.tf @@ -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 +} diff --git a/example/resource_virtual_environment_cluster_ipset.tf b/example/resource_virtual_environment_cluster_ipset.tf deleted file mode 100644 index 11703ed5..00000000 --- a/example/resource_virtual_environment_cluster_ipset.tf +++ /dev/null @@ -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 -} - diff --git a/example/resource_virtual_environment_firewall_alias.tf b/example/resource_virtual_environment_firewall_alias.tf new file mode 100644 index 00000000..17b42dc0 --- /dev/null +++ b/example/resource_virtual_environment_firewall_alias.tf @@ -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 +} diff --git a/example/resource_virtual_environment_firewall_ipset.tf b/example/resource_virtual_environment_firewall_ipset.tf new file mode 100644 index 00000000..22327418 --- /dev/null +++ b/example/resource_virtual_environment_firewall_ipset.tf @@ -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 +} diff --git a/example/resource_virtual_environment_firewall_options.tf b/example/resource_virtual_environment_firewall_options.tf new file mode 100644 index 00000000..921874b7 --- /dev/null +++ b/example/resource_virtual_environment_firewall_options.tf @@ -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 +} diff --git a/example/resource_virtual_environment_firewall_rules.tf b/example/resource_virtual_environment_firewall_rules.tf new file mode 100644 index 00000000..f9bb4ab3 --- /dev/null +++ b/example/resource_virtual_environment_firewall_rules.tf @@ -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 +} diff --git a/main.go b/main.go index 31233249..5b39cac1 100644 --- a/main.go +++ b/main.go @@ -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() }, } diff --git a/proxmox/cluster/client.go b/proxmox/cluster/client.go new file mode 100644 index 00000000..fb12902b --- /dev/null +++ b/proxmox/cluster/client.go @@ -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}, + } +} diff --git a/proxmox/cluster/cluster.go b/proxmox/cluster/cluster.go new file mode 100644 index 00000000..fe606dec --- /dev/null +++ b/proxmox/cluster/cluster.go @@ -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 +} diff --git a/proxmox/cluster/cluster_types.go b/proxmox/cluster/cluster_types.go new file mode 100644 index 00000000..fd8316df --- /dev/null +++ b/proxmox/cluster/cluster_types.go @@ -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"` +} diff --git a/proxmox/cluster/firewall/client.go b/proxmox/cluster/firewall/client.go new file mode 100644 index 00000000..45f5f875 --- /dev/null +++ b/proxmox/cluster/firewall/client.go @@ -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) +} diff --git a/proxmox/cluster/firewall/options.go b/proxmox/cluster/firewall/options.go new file mode 100644 index 00000000..c7a1db7d --- /dev/null +++ b/proxmox/cluster/firewall/options.go @@ -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 +} diff --git a/proxmox/cluster/firewall/security_groups.go b/proxmox/cluster/firewall/security_groups.go new file mode 100644 index 00000000..5ecf17eb --- /dev/null +++ b/proxmox/cluster/firewall/security_groups.go @@ -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 +} diff --git a/proxmox/container/client.go b/proxmox/container/client.go new file mode 100644 index 00000000..0c525b57 --- /dev/null +++ b/proxmox/container/client.go @@ -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}, + } +} diff --git a/proxmox/container/firewall/client.go b/proxmox/container/firewall/client.go new file mode 100644 index 00000000..943843e3 --- /dev/null +++ b/proxmox/container/firewall/client.go @@ -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 +} diff --git a/proxmox/firewall/aliases.go b/proxmox/firewall/aliases.go new file mode 100644 index 00000000..0993a3b7 --- /dev/null +++ b/proxmox/firewall/aliases.go @@ -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 +} diff --git a/proxmox/firewall/api.go b/proxmox/firewall/api.go new file mode 100644 index 00000000..1d0fad3d --- /dev/null +++ b/proxmox/firewall/api.go @@ -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 +} diff --git a/proxmox/firewall/ipset.go b/proxmox/firewall/ipset.go new file mode 100644 index 00000000..9c818b0a --- /dev/null +++ b/proxmox/firewall/ipset.go @@ -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 +} diff --git a/proxmox/firewall/options.go b/proxmox/firewall/options.go new file mode 100644 index 00000000..c903dbcf --- /dev/null +++ b/proxmox/firewall/options.go @@ -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 +} diff --git a/proxmox/firewall/rules.go b/proxmox/firewall/rules.go new file mode 100644 index 00000000..b3821230 --- /dev/null +++ b/proxmox/firewall/rules.go @@ -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 +} diff --git a/proxmox/types/client.go b/proxmox/types/client.go new file mode 100644 index 00000000..8b245d3f --- /dev/null +++ b/proxmox/types/client.go @@ -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//qemu//firewall/options". + ExpandPath(path string) string +} diff --git a/proxmox/common_types.go b/proxmox/types/common_types.go similarity index 99% rename from proxmox/common_types.go rename to proxmox/types/common_types.go index 7fb17968..845b8374 100644 --- a/proxmox/common_types.go +++ b/proxmox/types/common_types.go @@ -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" diff --git a/proxmox/virtual_environment_acl.go b/proxmox/virtual_environment_acl.go index 1d59b027..a28ca082 100644 --- a/proxmox/virtual_environment_acl.go +++ b/proxmox/virtual_environment_acl.go @@ -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) } diff --git a/proxmox/virtual_environment_acl_types.go b/proxmox/virtual_environment_acl_types.go index 419cfb39..ec2f5ec9 100644 --- a/proxmox/virtual_environment_acl_types.go +++ b/proxmox/virtual_environment_acl_types.go @@ -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"` } diff --git a/proxmox/virtual_environment_authentication.go b/proxmox/virtual_environment_authentication.go index f8572eb3..f13ee581 100644 --- a/proxmox/virtual_environment_authentication.go +++ b/proxmox/virtual_environment_authentication.go @@ -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, ) diff --git a/proxmox/virtual_environment_authentication_types.go b/proxmox/virtual_environment_authentication_types.go index 73ffb99d..4b458498 100644 --- a/proxmox/virtual_environment_authentication_types.go +++ b/proxmox/virtual_environment_authentication_types.go @@ -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. diff --git a/proxmox/virtual_environment_certificate.go b/proxmox/virtual_environment_certificate.go index 91c3ebfe..db756884 100644 --- a/proxmox/virtual_environment_certificate.go +++ b/proxmox/virtual_environment_certificate.go @@ -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, diff --git a/proxmox/virtual_environment_certificate_types.go b/proxmox/virtual_environment_certificate_types.go index 77148196..360f1e92 100644 --- a/proxmox/virtual_environment_certificate_types.go +++ b/proxmox/virtual_environment_certificate_types.go @@ -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"` } diff --git a/proxmox/virtual_environment_client.go b/proxmox/virtual_environment_client.go index 7746728b..81052804 100644 --- a/proxmox/virtual_environment_client.go +++ b/proxmox/virtual_environment_client.go @@ -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( diff --git a/proxmox/virtual_environment_client_types.go b/proxmox/virtual_environment_client_types.go index e80e7d94..4e0d8c91 100644 --- a/proxmox/virtual_environment_client_types.go +++ b/proxmox/virtual_environment_client_types.go @@ -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} +} diff --git a/proxmox/virtual_environment_cluster.go b/proxmox/virtual_environment_cluster.go deleted file mode 100644 index 62151f6a..00000000 --- a/proxmox/virtual_environment_cluster.go +++ /dev/null @@ -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 -} diff --git a/proxmox/virtual_environment_cluster_alias.go b/proxmox/virtual_environment_cluster_alias.go deleted file mode 100644 index 9d42767c..00000000 --- a/proxmox/virtual_environment_cluster_alias.go +++ /dev/null @@ -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, - ) -} diff --git a/proxmox/virtual_environment_cluster_alias_types.go b/proxmox/virtual_environment_cluster_alias_types.go deleted file mode 100644 index 5bc7b0dc..00000000 --- a/proxmox/virtual_environment_cluster_alias_types.go +++ /dev/null @@ -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"` -} diff --git a/proxmox/virtual_environment_cluster_ipset.go b/proxmox/virtual_environment_cluster_ipset.go deleted file mode 100644 index 72ec4c68..00000000 --- a/proxmox/virtual_environment_cluster_ipset.go +++ /dev/null @@ -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 -} diff --git a/proxmox/virtual_environment_cluster_ipset_types.go b/proxmox/virtual_environment_cluster_ipset_types.go deleted file mode 100644 index 32e93a43..00000000 --- a/proxmox/virtual_environment_cluster_ipset_types.go +++ /dev/null @@ -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 diff --git a/proxmox/virtual_environment_cluster_types.go b/proxmox/virtual_environment_cluster_types.go deleted file mode 100644 index a3e49b10..00000000 --- a/proxmox/virtual_environment_cluster_types.go +++ /dev/null @@ -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"` -} diff --git a/proxmox/virtual_environment_container.go b/proxmox/virtual_environment_container.go index 998b16e2..a31aa697 100644 --- a/proxmox/virtual_environment_container.go +++ b/proxmox/virtual_environment_container.go @@ -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, diff --git a/proxmox/virtual_environment_container_types.go b/proxmox/virtual_environment_container_types.go index ef43550c..14f8c867 100644 --- a/proxmox/virtual_environment_container_types.go +++ b/proxmox/virtual_environment_container_types.go @@ -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] diff --git a/proxmox/virtual_environment_datastores.go b/proxmox/virtual_environment_datastores.go index aa94ed84..af261552 100644 --- a/proxmox/virtual_environment_datastores.go +++ b/proxmox/virtual_environment_datastores.go @@ -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), diff --git a/proxmox/virtual_environment_datastores_types.go b/proxmox/virtual_environment_datastores_types.go index 724e7109..03dda7ac 100644 --- a/proxmox/virtual_environment_datastores_types.go +++ b/proxmox/virtual_environment_datastores_types.go @@ -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. diff --git a/proxmox/virtual_environment_dns.go b/proxmox/virtual_environment_dns.go index 9a802aaa..0356b7ef 100644 --- a/proxmox/virtual_environment_dns.go +++ b/proxmox/virtual_environment_dns.go @@ -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) } diff --git a/proxmox/virtual_environment_groups.go b/proxmox/virtual_environment_groups.go index 22ebd6de..e98dc0d0 100644 --- a/proxmox/virtual_environment_groups.go +++ b/proxmox/virtual_environment_groups.go @@ -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) } diff --git a/proxmox/virtual_environment_hosts.go b/proxmox/virtual_environment_hosts.go index c956e1e1..a198a0f2 100644 --- a/proxmox/virtual_environment_hosts.go +++ b/proxmox/virtual_environment_hosts.go @@ -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) } diff --git a/proxmox/virtual_environment_nodes.go b/proxmox/virtual_environment_nodes.go index f74e6c45..9ef5ecd8 100644 --- a/proxmox/virtual_environment_nodes.go +++ b/proxmox/virtual_environment_nodes.go @@ -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. diff --git a/proxmox/virtual_environment_nodes_types.go b/proxmox/virtual_environment_nodes_types.go index 56279c96..552aa872 100644 --- a/proxmox/virtual_environment_nodes_types.go +++ b/proxmox/virtual_environment_nodes_types.go @@ -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. diff --git a/proxmox/virtual_environment_pools.go b/proxmox/virtual_environment_pools.go index c3e41fd3..e30e9098 100644 --- a/proxmox/virtual_environment_pools.go +++ b/proxmox/virtual_environment_pools.go @@ -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) } diff --git a/proxmox/virtual_environment_roles.go b/proxmox/virtual_environment_roles.go index 4af6694f..af68ff8f 100644 --- a/proxmox/virtual_environment_roles.go +++ b/proxmox/virtual_environment_roles.go @@ -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) } diff --git a/proxmox/virtual_environment_roles_types.go b/proxmox/virtual_environment_roles_types.go index bc511286..ab2e9a40 100644 --- a/proxmox/virtual_environment_roles_types.go +++ b/proxmox/virtual_environment_roles_types.go @@ -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"` } diff --git a/proxmox/virtual_environment_users.go b/proxmox/virtual_environment_users.go index 26c3cd1f..f8b6f719 100644 --- a/proxmox/virtual_environment_users.go +++ b/proxmox/virtual_environment_users.go @@ -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) } diff --git a/proxmox/virtual_environment_users_types.go b/proxmox/virtual_environment_users_types.go index b3d08f7a..b35ed9b1 100644 --- a/proxmox/virtual_environment_users_types.go +++ b/proxmox/virtual_environment_users_types.go @@ -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"` } diff --git a/proxmox/virtual_environment_version.go b/proxmox/virtual_environment_version.go index 252914ab..05ecec5d 100644 --- a/proxmox/virtual_environment_version.go +++ b/proxmox/virtual_environment_version.go @@ -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 } diff --git a/proxmox/virtual_environment_vm.go b/proxmox/virtual_environment_vm.go index 79a22271..1b0cdbef 100644 --- a/proxmox/virtual_environment_vm.go +++ b/proxmox/virtual_environment_vm.go @@ -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, diff --git a/proxmox/virtual_environment_vm_types.go b/proxmox/virtual_environment_vm_types.go index caedbfa1..1575a3c9 100644 --- a/proxmox/virtual_environment_vm_types.go +++ b/proxmox/virtual_environment_vm_types.go @@ -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] diff --git a/proxmox/virtual_environment_vm_types_test.go b/proxmox/virtual_environment_vm_types_test.go index 195ce4e7..0ffc07af 100644 --- a/proxmox/virtual_environment_vm_types_test.go +++ b/proxmox/virtual_environment_vm_types_test.go @@ -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 } diff --git a/proxmox/vm/client.go b/proxmox/vm/client.go new file mode 100644 index 00000000..cb75c412 --- /dev/null +++ b/proxmox/vm/client.go @@ -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}, + } +} diff --git a/proxmox/vm/firewall/client.go b/proxmox/vm/firewall/client.go new file mode 100644 index 00000000..943843e3 --- /dev/null +++ b/proxmox/vm/firewall/client.go @@ -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 +} diff --git a/proxmoxtf/config.go b/proxmoxtf/config.go new file mode 100644 index 00000000..6aec2b76 --- /dev/null +++ b/proxmoxtf/config.go @@ -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 +} diff --git a/proxmoxtf/data_source_virtual_environment_cluster_alias.go b/proxmoxtf/data_source_virtual_environment_cluster_alias.go deleted file mode 100644 index c4c6accd..00000000 --- a/proxmoxtf/data_source_virtual_environment_cluster_alias.go +++ /dev/null @@ -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 -} diff --git a/proxmoxtf/data_source_virtual_environment_cluster_alias_test.go b/proxmoxtf/data_source_virtual_environment_cluster_alias_test.go deleted file mode 100644 index e3bb057c..00000000 --- a/proxmoxtf/data_source_virtual_environment_cluster_alias_test.go +++ /dev/null @@ -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, - }) -} diff --git a/proxmoxtf/data_source_virtual_environment_cluster_aliases.go b/proxmoxtf/data_source_virtual_environment_cluster_aliases.go deleted file mode 100644 index d0dfde49..00000000 --- a/proxmoxtf/data_source_virtual_environment_cluster_aliases.go +++ /dev/null @@ -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) -} diff --git a/proxmoxtf/data_source_virtual_environment_cluster_aliases_test.go b/proxmoxtf/data_source_virtual_environment_cluster_aliases_test.go deleted file mode 100644 index 93f5ebcd..00000000 --- a/proxmoxtf/data_source_virtual_environment_cluster_aliases_test.go +++ /dev/null @@ -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, - }) -} diff --git a/proxmoxtf/data_source_virtual_environment_dns_test.go b/proxmoxtf/data_source_virtual_environment_dns_test.go deleted file mode 100644 index 53ff6ff0..00000000 --- a/proxmoxtf/data_source_virtual_environment_dns_test.go +++ /dev/null @@ -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, - }) -} diff --git a/proxmoxtf/data_source_virtual_environment_groups_test.go b/proxmoxtf/data_source_virtual_environment_groups_test.go deleted file mode 100644 index 044d9394..00000000 --- a/proxmoxtf/data_source_virtual_environment_groups_test.go +++ /dev/null @@ -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, - }) -} diff --git a/proxmoxtf/data_source_virtual_environment_pools_test.go b/proxmoxtf/data_source_virtual_environment_pools_test.go deleted file mode 100644 index dd53a2a3..00000000 --- a/proxmoxtf/data_source_virtual_environment_pools_test.go +++ /dev/null @@ -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" -) - -// TestDataSourceVirtualEnvironmentPoolsInstantiation tests whether the DataSourceVirtualEnvironmentPools instance can be instantiated. -func TestDataSourceVirtualEnvironmentPoolsInstantiation(t *testing.T) { - s := dataSourceVirtualEnvironmentPools() - - if s == nil { - t.Fatalf("Cannot instantiate dataSourceVirtualEnvironmentPools") - } -} - -// TestDataSourceVirtualEnvironmentPoolsSchema tests the dataSourceVirtualEnvironmentPools schema. -func TestDataSourceVirtualEnvironmentPoolsSchema(t *testing.T) { - s := dataSourceVirtualEnvironmentPools() - - testComputedAttributes(t, s, []string{ - mkDataSourceVirtualEnvironmentPoolsPoolIDs, - }) - - testValueTypes(t, s, map[string]schema.ValueType{ - mkDataSourceVirtualEnvironmentPoolsPoolIDs: schema.TypeList, - }) -} diff --git a/proxmoxtf/data_source_virtual_environment_role_test.go b/proxmoxtf/data_source_virtual_environment_role_test.go deleted file mode 100644 index 260f21cc..00000000 --- a/proxmoxtf/data_source_virtual_environment_role_test.go +++ /dev/null @@ -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 proxmoxtf - -import ( - "testing" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" -) - -// TestDataSourceVirtualEnvironmentRoleInstantiation tests whether the DataSourceVirtualEnvironmentRole instance can be instantiated. -func TestDataSourceVirtualEnvironmentRoleInstantiation(t *testing.T) { - s := dataSourceVirtualEnvironmentRole() - - if s == nil { - t.Fatalf("Cannot instantiate dataSourceVirtualEnvironmentRole") - } -} - -// TestDataSourceVirtualEnvironmentRoleSchema tests the dataSourceVirtualEnvironmentRole schema. -func TestDataSourceVirtualEnvironmentRoleSchema(t *testing.T) { - s := dataSourceVirtualEnvironmentRole() - - testRequiredArguments(t, s, []string{ - mkDataSourceVirtualEnvironmentRoleID, - }) - - testComputedAttributes(t, s, []string{ - mkDataSourceVirtualEnvironmentRolePrivileges, - }) - - testValueTypes(t, s, map[string]schema.ValueType{ - mkDataSourceVirtualEnvironmentRoleID: schema.TypeString, - mkDataSourceVirtualEnvironmentRolePrivileges: schema.TypeSet, - }) -} diff --git a/proxmoxtf/data_source_virtual_environment_roles_test.go b/proxmoxtf/data_source_virtual_environment_roles_test.go deleted file mode 100644 index 8de21dbf..00000000 --- a/proxmoxtf/data_source_virtual_environment_roles_test.go +++ /dev/null @@ -1,37 +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" -) - -// TestDataSourceVirtualEnvironmentRolesInstantiation tests whether the DataSourceVirtualEnvironmentRoles instance can be instantiated. -func TestDataSourceVirtualEnvironmentRolesInstantiation(t *testing.T) { - s := dataSourceVirtualEnvironmentRoles() - - if s == nil { - t.Fatalf("Cannot instantiate dataSourceVirtualEnvironmentRoles") - } -} - -// TestDataSourceVirtualEnvironmentRolesSchema tests the dataSourceVirtualEnvironmentRoles schema. -func TestDataSourceVirtualEnvironmentRolesSchema(t *testing.T) { - s := dataSourceVirtualEnvironmentRoles() - - testComputedAttributes(t, s, []string{ - mkDataSourceVirtualEnvironmentRolesPrivileges, - mkDataSourceVirtualEnvironmentRolesRoleIDs, - mkDataSourceVirtualEnvironmentRolesSpecial, - }) - - testValueTypes(t, s, map[string]schema.ValueType{ - mkDataSourceVirtualEnvironmentRolesPrivileges: schema.TypeList, - mkDataSourceVirtualEnvironmentRolesRoleIDs: schema.TypeList, - mkDataSourceVirtualEnvironmentRolesSpecial: schema.TypeList, - }) -} diff --git a/proxmoxtf/data_source_virtual_environment_time_test.go b/proxmoxtf/data_source_virtual_environment_time_test.go deleted file mode 100644 index 1451672f..00000000 --- a/proxmoxtf/data_source_virtual_environment_time_test.go +++ /dev/null @@ -1,42 +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" -) - -// TestDataSourceVirtualEnvironmentTimeInstantiation tests whether the DataSourceVirtualEnvironmentRoles instance can be instantiated. -func TestDataSourceVirtualEnvironmentTimeInstantiation(t *testing.T) { - s := dataSourceVirtualEnvironmentTime() - - if s == nil { - t.Fatalf("Cannot instantiate dataSourceVirtualEnvironmentTime") - } -} - -// TestDataSourceVirtualEnvironmentTimeSchema tests the dataSourceVirtualEnvironmentTime schema. -func TestDataSourceVirtualEnvironmentTimeSchema(t *testing.T) { - s := dataSourceVirtualEnvironmentTime() - - testRequiredArguments(t, s, []string{ - mkDataSourceVirtualEnvironmentTimeNodeName, - }) - - testComputedAttributes(t, s, []string{ - mkDataSourceVirtualEnvironmentTimeLocalTime, - mkDataSourceVirtualEnvironmentTimeTimeZone, - mkDataSourceVirtualEnvironmentTimeUTCTime, - }) - - testValueTypes(t, s, map[string]schema.ValueType{ - mkDataSourceVirtualEnvironmentTimeLocalTime: schema.TypeString, - mkDataSourceVirtualEnvironmentTimeNodeName: schema.TypeString, - mkDataSourceVirtualEnvironmentTimeTimeZone: schema.TypeString, - mkDataSourceVirtualEnvironmentTimeUTCTime: schema.TypeString, - }) -} diff --git a/proxmoxtf/data_source_virtual_environment_version_test.go b/proxmoxtf/data_source_virtual_environment_version_test.go deleted file mode 100644 index ed176a70..00000000 --- a/proxmoxtf/data_source_virtual_environment_version_test.go +++ /dev/null @@ -1,39 +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" -) - -// TestDataSourceVirtualEnvironmentVersionInstantiation tests whether the DataSourceVirtualEnvironmentVersion instance can be instantiated. -func TestDataSourceVirtualEnvironmentVersionInstantiation(t *testing.T) { - s := dataSourceVirtualEnvironmentVersion() - - if s == nil { - t.Fatalf("Cannot instantiate dataSourceVirtualEnvironmentVersion") - } -} - -// TestDataSourceVirtualEnvironmentVersionSchema tests the dataSourceVirtualEnvironmentVersion schema. -func TestDataSourceVirtualEnvironmentVersionSchema(t *testing.T) { - s := dataSourceVirtualEnvironmentVersion() - - testComputedAttributes(t, s, []string{ - mkDataSourceVirtualEnvironmentVersionKeyboardLayout, - mkDataSourceVirtualEnvironmentVersionRelease, - mkDataSourceVirtualEnvironmentVersionRepositoryID, - mkDataSourceVirtualEnvironmentVersionVersion, - }) - - testValueTypes(t, s, map[string]schema.ValueType{ - mkDataSourceVirtualEnvironmentVersionKeyboardLayout: schema.TypeString, - mkDataSourceVirtualEnvironmentVersionRelease: schema.TypeString, - mkDataSourceVirtualEnvironmentVersionRepositoryID: schema.TypeString, - mkDataSourceVirtualEnvironmentVersionVersion: schema.TypeString, - }) -} diff --git a/proxmoxtf/data_source_virtual_environment_vm_test.go b/proxmoxtf/data_source_virtual_environment_vm_test.go deleted file mode 100644 index 0cdaf726..00000000 --- a/proxmoxtf/data_source_virtual_environment_vm_test.go +++ /dev/null @@ -1,41 +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" -) - -// TestDataSourceVirtualEnvironmentVMInstantiation tests whether the dataSourceVirtualEnvironmentVM instance can be instantiated. -func TestDataSourceVirtualEnvironmentVMInstantiation(t *testing.T) { - t.Parallel() - - s := dataSourceVirtualEnvironmentVM() - - if s == nil { - t.Fatalf("Cannot instantiate dataSourceVirtualEnvironmentVM") - } -} - -// TestDataSourceVirtualEnvironmentVMSchema tests the dataSourceVirtualEnvironmentVM schema. -func TestDataSourceVirtualEnvironmentVMSchema(t *testing.T) { - t.Parallel() - - s := dataSourceVirtualEnvironmentVM() - - testComputedAttributes(t, s, []string{ - mkDataSourceVirtualEnvironmentVMName, - mkDataSourceVirtualEnvironmentVMTags, - }) - - testValueTypes(t, s, map[string]schema.ValueType{ - mkDataSourceVirtualEnvironmentVMName: schema.TypeString, - mkDataSourceVirtualEnvironmentVMNodeName: schema.TypeString, - mkDataSourceVirtualEnvironmentVMTags: schema.TypeList, - mkDataSourceVirtualEnvironmentVMVMID: schema.TypeInt, - }) -} diff --git a/proxmoxtf/data_source_virtual_environment_vms_test.go b/proxmoxtf/data_source_virtual_environment_vms_test.go deleted file mode 100644 index e1732656..00000000 --- a/proxmoxtf/data_source_virtual_environment_vms_test.go +++ /dev/null @@ -1,53 +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" -) - -// TestDataSourceVirtualEnvironmentVMsInstantiation tests whether the dataSourceVirtualEnvironmentVMs instance can be instantiated. -func TestDataSourceVirtualEnvironmentVMsInstantiation(t *testing.T) { - t.Parallel() - - s := dataSourceVirtualEnvironmentVMs() - - if s == nil { - t.Fatalf("Cannot instantiate dataSourceVirtualEnvironmentVMs") - } -} - -// TestDataSourceVirtualEnvironmentVMsSchema tests the dataSourceVirtualEnvironmentVMs schema. -func TestDataSourceVirtualEnvironmentVMsSchema(t *testing.T) { - t.Parallel() - - s := dataSourceVirtualEnvironmentVMs() - - testComputedAttributes(t, s, []string{ - mkDataSourceVirtualEnvironmentVMs, - }) - - testValueTypes(t, s, map[string]schema.ValueType{ - mkDataSourceVirtualEnvironmentVMNodeName: schema.TypeString, - mkDataSourceVirtualEnvironmentVMTags: schema.TypeList, - mkDataSourceVirtualEnvironmentVMs: schema.TypeList, - }) - - vmsSchema := testNestedSchemaExistence(t, s, mkDataSourceVirtualEnvironmentVMs) - - testComputedAttributes(t, vmsSchema, []string{ - mkDataSourceVirtualEnvironmentVMName, - mkDataSourceVirtualEnvironmentVMTags, - }) - - testValueTypes(t, vmsSchema, map[string]schema.ValueType{ - mkDataSourceVirtualEnvironmentVMName: schema.TypeString, - mkDataSourceVirtualEnvironmentVMNodeName: schema.TypeString, - mkDataSourceVirtualEnvironmentVMTags: schema.TypeList, - mkDataSourceVirtualEnvironmentVMVMID: schema.TypeInt, - }) -} diff --git a/proxmoxtf/datasource/cluster/firewall.go b/proxmoxtf/datasource/cluster/firewall.go new file mode 100644 index 00000000..9f0d8dc9 --- /dev/null +++ b/proxmoxtf/datasource/cluster/firewall.go @@ -0,0 +1,74 @@ +/* + * 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" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + fw "github.com/bpg/terraform-provider-proxmox/proxmox/firewall" + "github.com/bpg/terraform-provider-proxmox/proxmoxtf" + "github.com/bpg/terraform-provider-proxmox/proxmoxtf/datasource/firewall" +) + +func FirewallAlias() *schema.Resource { + return &schema.Resource{ + Schema: firewall.AliasSchema(), + ReadContext: invokeFirewallAPI(firewall.AliasRead), + } +} + +func FirewallAliases() *schema.Resource { + return &schema.Resource{ + Schema: firewall.AliasesSchema(), + ReadContext: invokeFirewallAPI(firewall.AliasesRead), + } +} + +func FirewallIPSet() *schema.Resource { + return &schema.Resource{ + Schema: firewall.IPSetSchema(), + ReadContext: invokeFirewallAPI(firewall.IPSetRead), + } +} + +func FirewallIPSets() *schema.Resource { + return &schema.Resource{ + Schema: firewall.IPSetsSchema(), + ReadContext: invokeFirewallAPI(firewall.IPSetsRead), + } +} + +// func FirewallSecurityGroup() *schema.Resource { +// return &schema.Resource{ +// Schema: firewall.SecurityGroupSchema(), +// ReadContext: invokeFirewallAPI(firewall.SecurityGroupRead), +// } +// } +// +// func FirewallSecurityGroups() *schema.Resource { +// return &schema.Resource{ +// Schema: firewall.SecurityGroupsSchema(), +// ReadContext: invokeFirewallAPI(firewall.SecurityGroupsRead), +// } +// } + +func invokeFirewallAPI( + f func(context.Context, fw.API, *schema.ResourceData) diag.Diagnostics, +) func(context.Context, *schema.ResourceData, interface{}) diag.Diagnostics { + return func(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + config := m.(proxmoxtf.ProviderConfiguration) + veClient, err := config.GetVEClient() + if err != nil { + return diag.FromErr(err) + } + + return f(ctx, veClient.API().Cluster().Firewall(), d) + } +} diff --git a/proxmoxtf/data_source_virtual_environment_datastores.go b/proxmoxtf/datasource/datastores.go similarity index 93% rename from proxmoxtf/data_source_virtual_environment_datastores.go rename to proxmoxtf/datasource/datastores.go index e6d3f744..b48dfb2d 100644 --- a/proxmoxtf/data_source_virtual_environment_datastores.go +++ b/proxmoxtf/datasource/datastores.go @@ -1,8 +1,10 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public +/* + * 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/. */ + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ -package proxmoxtf +package datasource import ( "context" @@ -11,6 +13,8 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf" ) const ( @@ -26,7 +30,7 @@ const ( mkDataSourceVirtualEnvironmentDatastoresTypes = "types" ) -func dataSourceVirtualEnvironmentDatastores() *schema.Resource { +func Datastores() *schema.Resource { return &schema.Resource{ Schema: map[string]*schema.Schema{ mkDataSourceVirtualEnvironmentDatastoresActive: { @@ -92,18 +96,14 @@ func dataSourceVirtualEnvironmentDatastores() *schema.Resource { Elem: &schema.Schema{Type: schema.TypeString}, }, }, - ReadContext: dataSourceVirtualEnvironmentDatastoresRead, + ReadContext: datastoresRead, } } -func dataSourceVirtualEnvironmentDatastoresRead( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { +func datastoresRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { var diags diag.Diagnostics - config := m.(providerConfiguration) + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) diff --git a/proxmoxtf/data_source_virtual_environment_datastores_test.go b/proxmoxtf/datasource/datastores_test.go similarity index 63% rename from proxmoxtf/data_source_virtual_environment_datastores_test.go rename to proxmoxtf/datasource/datastores_test.go index 345ab7b2..a2fa5656 100644 --- a/proxmoxtf/data_source_virtual_environment_datastores_test.go +++ b/proxmoxtf/datasource/datastores_test.go @@ -1,33 +1,39 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public +/* + * 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/. */ + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ -package proxmoxtf +package datasource import ( "testing" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf/test" ) -// TestDataSourceVirtualEnvironmentDatastoresInstantiation tests whether the DataSourceVirtualEnvironmentDatastores instance can be instantiated. -func TestDataSourceVirtualEnvironmentDatastoresInstantiation(t *testing.T) { - s := dataSourceVirtualEnvironmentDatastores() +// TestDatastoresInstantiation tests whether the Datastores instance can be instantiated. +func TestDatastoresInstantiation(t *testing.T) { + t.Parallel() + s := Datastores() if s == nil { - t.Fatalf("Cannot instantiate dataSourceVirtualEnvironmentDatastores") + t.Fatalf("Cannot instantiate Datastores") } } -// TestDataSourceVirtualEnvironmentDatastoresSchema tests the dataSourceVirtualEnvironmentDatastores schema. -func TestDataSourceVirtualEnvironmentDatastoresSchema(t *testing.T) { - s := dataSourceVirtualEnvironmentDatastores() +// TestDatastoresSchema tests the Datastores schema. +func TestDatastoresSchema(t *testing.T) { + t.Parallel() + s := Datastores() - testRequiredArguments(t, s, []string{ + test.AssertRequiredArguments(t, s, []string{ mkDataSourceVirtualEnvironmentDatastoresNodeName, }) - testComputedAttributes(t, s, []string{ + test.AssertComputedAttributes(t, s, []string{ mkDataSourceVirtualEnvironmentDatastoresActive, mkDataSourceVirtualEnvironmentDatastoresContentTypes, mkDataSourceVirtualEnvironmentDatastoresDatastoreIDs, @@ -39,7 +45,7 @@ func TestDataSourceVirtualEnvironmentDatastoresSchema(t *testing.T) { mkDataSourceVirtualEnvironmentDatastoresTypes, }) - testValueTypes(t, s, map[string]schema.ValueType{ + test.AssertValueTypes(t, s, map[string]schema.ValueType{ mkDataSourceVirtualEnvironmentDatastoresActive: schema.TypeList, mkDataSourceVirtualEnvironmentDatastoresContentTypes: schema.TypeList, mkDataSourceVirtualEnvironmentDatastoresDatastoreIDs: schema.TypeList, diff --git a/proxmoxtf/data_source_virtual_environment_dns.go b/proxmoxtf/datasource/dns.go similarity index 81% rename from proxmoxtf/data_source_virtual_environment_dns.go rename to proxmoxtf/datasource/dns.go index 8a0f617e..05b0b8b7 100644 --- a/proxmoxtf/data_source_virtual_environment_dns.go +++ b/proxmoxtf/datasource/dns.go @@ -1,8 +1,10 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public +/* + * 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/. */ + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ -package proxmoxtf +package datasource import ( "context" @@ -10,6 +12,8 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf" ) const ( @@ -18,7 +22,7 @@ const ( mkDataSourceVirtualEnvironmentDNSServers = "servers" ) -func dataSourceVirtualEnvironmentDNS() *schema.Resource { +func DNS() *schema.Resource { return &schema.Resource{ Schema: map[string]*schema.Schema{ mkDataSourceVirtualEnvironmentDNSDomain: { @@ -38,18 +42,14 @@ func dataSourceVirtualEnvironmentDNS() *schema.Resource { Elem: &schema.Schema{Type: schema.TypeString}, }, }, - ReadContext: dataSourceVirtualEnvironmentDNSRead, + ReadContext: dnsRead, } } -func dataSourceVirtualEnvironmentDNSRead( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { +func dnsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { var diags diag.Diagnostics - config := m.(providerConfiguration) + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) diff --git a/proxmoxtf/datasource/dns_test.go b/proxmoxtf/datasource/dns_test.go new file mode 100644 index 00000000..e923889f --- /dev/null +++ b/proxmoxtf/datasource/dns_test.go @@ -0,0 +1,46 @@ +/* + * 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 datasource + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf/test" +) + +// TestDNSInstantiation tests whether the DNS instance can be instantiated. +func TestDNSInstantiation(t *testing.T) { + t.Parallel() + s := DNS() + + if s == nil { + t.Fatalf("Cannot instantiate DNS") + } +} + +// TestDNSSchema tests the DNS schema. +func TestDNSSchema(t *testing.T) { + t.Parallel() + s := DNS() + + test.AssertRequiredArguments(t, s, []string{ + mkDataSourceVirtualEnvironmentDNSNodeName, + }) + + test.AssertComputedAttributes(t, s, []string{ + mkDataSourceVirtualEnvironmentDNSDomain, + mkDataSourceVirtualEnvironmentDNSServers, + }) + + test.AssertValueTypes(t, s, map[string]schema.ValueType{ + mkDataSourceVirtualEnvironmentDNSDomain: schema.TypeString, + mkDataSourceVirtualEnvironmentDNSNodeName: schema.TypeString, + mkDataSourceVirtualEnvironmentDNSServers: schema.TypeList, + }) +} diff --git a/proxmoxtf/datasource/firewall/alias.go b/proxmoxtf/datasource/firewall/alias.go new file mode 100644 index 00000000..aa8dca15 --- /dev/null +++ b/proxmoxtf/datasource/firewall/alias.go @@ -0,0 +1,68 @@ +/* + * 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" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmox/firewall" +) + +const ( + dvAliasComment = "" + + mkAliasName = "name" + mkAliasCIDR = "cidr" + mkAliasComment = "comment" +) + +func AliasSchema() map[string]*schema.Schema { + return map[string]*schema.Schema{ + mkAliasName: { + Type: schema.TypeString, + Description: "Alias name", + Required: true, + }, + mkAliasCIDR: { + Type: schema.TypeString, + Description: "IP/CIDR block", + Computed: true, + }, + mkAliasComment: { + Type: schema.TypeString, + Description: "Alias comment", + Computed: true, + }, + } +} + +func AliasRead(ctx context.Context, fw firewall.API, d *schema.ResourceData) diag.Diagnostics { + var diags diag.Diagnostics + + aliasName := d.Get(mkAliasName).(string) + alias, err := fw.GetAlias(ctx, aliasName) + if err != nil { + return diag.FromErr(err) + } + + d.SetId(aliasName) + + err = d.Set(mkAliasCIDR, alias.CIDR) + diags = append(diags, diag.FromErr(err)...) + + if alias.Comment != nil { + err = d.Set(mkAliasComment, alias.Comment) + } else { + err = d.Set(mkAliasComment, dvAliasComment) + } + diags = append(diags, diag.FromErr(err)...) + + return diags +} diff --git a/proxmoxtf/datasource/firewall/alias_test.go b/proxmoxtf/datasource/firewall/alias_test.go new file mode 100644 index 00000000..0ba643ad --- /dev/null +++ b/proxmoxtf/datasource/firewall/alias_test.go @@ -0,0 +1,43 @@ +/* + * 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 ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/stretchr/testify/require" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf/structure" +) + +// TestAliasSchemaInstantiation tests whether the AliasSchema instance can be instantiated. +func TestAliasSchemaInstantiation(t *testing.T) { + t.Parallel() + require.NotNilf(t, AliasSchema(), "Cannot instantiate AliasSchema") +} + +// TestAliasSchema tests the AliasSchema. +func TestAliasSchema(t *testing.T) { + t.Parallel() + s := AliasSchema() + + structure.AssertRequiredArguments(t, s, []string{ + mkAliasName, + }) + + structure.AssertComputedAttributes(t, s, []string{ + mkAliasCIDR, + mkAliasComment, + }) + + structure.AssertValueTypes(t, s, map[string]schema.ValueType{ + mkAliasName: schema.TypeString, + mkAliasCIDR: schema.TypeString, + mkAliasComment: schema.TypeString, + }) +} diff --git a/proxmoxtf/datasource/firewall/aliases.go b/proxmoxtf/datasource/firewall/aliases.go new file mode 100644 index 00000000..4f727d4d --- /dev/null +++ b/proxmoxtf/datasource/firewall/aliases.go @@ -0,0 +1,51 @@ +/* + * 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" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmox/firewall" +) + +const ( + mkAliasesAliasNames = "alias_names" +) + +func AliasesSchema() map[string]*schema.Schema { + return map[string]*schema.Schema{ + mkAliasesAliasNames: { + Type: schema.TypeList, + Description: "Alias Names", + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + } +} + +func AliasesRead(ctx context.Context, fw firewall.API, d *schema.ResourceData) diag.Diagnostics { + list, err := fw.ListAliases(ctx) + if err != nil { + return diag.FromErr(err) + } + + aliasNames := make([]interface{}, len(list)) + + for i, v := range list { + aliasNames[i] = v.Name + } + + d.SetId(uuid.New().String()) + + err = d.Set(mkAliasesAliasNames, aliasNames) + + return diag.FromErr(err) +} diff --git a/proxmoxtf/datasource/firewall/aliases_test.go b/proxmoxtf/datasource/firewall/aliases_test.go new file mode 100644 index 00000000..867c9e9d --- /dev/null +++ b/proxmoxtf/datasource/firewall/aliases_test.go @@ -0,0 +1,36 @@ +/* + * 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 ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/stretchr/testify/require" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf/structure" +) + +// TestAliasesSchemaInstantiation tests whether the AliasesSchema instance can be instantiated. +func TestAliasesSchemaInstantiation(t *testing.T) { + t.Parallel() + require.NotNil(t, AliasesSchema(), "Cannot instantiate AliasesSchema") +} + +// TestAliasesSchema tests the AliasesSchema. +func TestAliasesSchema(t *testing.T) { + t.Parallel() + s := AliasesSchema() + + structure.AssertComputedAttributes(t, s, []string{ + mkAliasesAliasNames, + }) + + structure.AssertValueTypes(t, s, map[string]schema.ValueType{ + mkAliasesAliasNames: schema.TypeList, + }) +} diff --git a/proxmoxtf/datasource/firewall/ipset.go b/proxmoxtf/datasource/firewall/ipset.go new file mode 100644 index 00000000..8e0a380d --- /dev/null +++ b/proxmoxtf/datasource/firewall/ipset.go @@ -0,0 +1,122 @@ +/* + * 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" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmox/firewall" +) + +const ( + dvIPSetCIDRComment = "" + dvIPSetCIDRNoMatch = false + + mkIPSetName = "name" + mkIPSetCIDR = "cidr" + mkIPSetCIDRName = "name" + mkIPSetCIDRComment = "comment" + mkIPSetCIDRNoMatch = "nomatch" +) + +func IPSetSchema() map[string]*schema.Schema { + return map[string]*schema.Schema{ + mkIPSetName: { + Type: schema.TypeString, + Description: "IPSet name", + Required: true, + }, + mkIPSetCIDRComment: { + Type: schema.TypeString, + Description: "IPSet comment", + Computed: true, + }, + mkIPSetCIDR: { + Type: schema.TypeList, + Description: "List of IP or Networks", + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + mkIPSetCIDRName: { + Type: schema.TypeString, + Description: "Network/IP specification in CIDR format", + Computed: true, + }, + mkIPSetCIDRNoMatch: { + Type: schema.TypeBool, + Description: "No match this IP/CIDR", + Computed: true, + }, + mkIPSetCIDRComment: { + Type: schema.TypeString, + Description: "IP/CIDR comment", + Computed: true, + }, + }, + }, + }, + } +} + +func IPSetRead(ctx context.Context, fw firewall.API, d *schema.ResourceData) diag.Diagnostics { + var diags diag.Diagnostics + + ipSetName := d.Get(mkIPSetName).(string) + d.SetId(ipSetName) + + ipSetList, err := fw.ListIPSets(ctx) + if err != nil { + return diag.FromErr(err) + } + for _, ipSet := range ipSetList { + if ipSet.Name == ipSetName { + if ipSet.Comment != nil { + err = d.Set(mkIPSetCIDRComment, ipSet.Comment) + } else { + err = d.Set(mkIPSetCIDRComment, dvIPSetCIDRComment) + } + diags = append(diags, diag.FromErr(err)...) + break + } + } + + content, err := fw.GetIPSetContent(ctx, ipSetName) + if err != nil { + return diag.FromErr(err) + } + + //nolint:prealloc + var cidrs []interface{} + + for _, v := range content { + cirdEntry := map[string]interface{}{} + + cirdEntry[mkIPSetCIDRName] = v.CIDR + + if v.NoMatch != nil { + cirdEntry[mkIPSetCIDRNoMatch] = bool(*v.NoMatch) + } else { + cirdEntry[mkIPSetCIDRNoMatch] = dvIPSetCIDRNoMatch + } + + if v.Comment != nil { + cirdEntry[mkIPSetCIDRComment] = v.Comment + } else { + cirdEntry[mkIPSetCIDRComment] = dvIPSetCIDRComment + } + + cidrs = append(cidrs, cirdEntry) + } + + err = d.Set(mkIPSetCIDR, cidrs) + diags = append(diags, diag.FromErr(err)...) + + return diags +} diff --git a/proxmoxtf/datasource/firewall/ipset_test.go b/proxmoxtf/datasource/firewall/ipset_test.go new file mode 100644 index 00000000..64451ad5 --- /dev/null +++ b/proxmoxtf/datasource/firewall/ipset_test.go @@ -0,0 +1,57 @@ +/* + * 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 ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/stretchr/testify/require" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf/structure" +) + +// TestIPSetSchemaInstantiation tests whether the IPSetSchema instance can be instantiated. +func TestIPSetSchemaInstantiation(t *testing.T) { + t.Parallel() + require.NotNil(t, IPSetSchema(), "Cannot instantiate IPSetSchema") +} + +// TestIPSetSchema tests the IPSetSchema. +func TestIPSetSchema(t *testing.T) { + t.Parallel() + s := IPSetSchema() + + structure.AssertRequiredArguments(t, s, []string{ + mkIPSetName, + }) + + structure.AssertComputedAttributes(t, s, []string{ + mkIPSetCIDR, + mkIPSetCIDRComment, + }) + + structure.AssertValueTypes(t, s, map[string]schema.ValueType{ + mkIPSetName: schema.TypeString, + mkIPSetCIDR: schema.TypeList, + mkIPSetCIDRComment: schema.TypeString, + }) + + cirdSchema := structure.AssertNestedSchemaExistence(t, s, mkIPSetCIDR).Schema + + structure.AssertComputedAttributes(t, cirdSchema, []string{ + mkIPSetCIDRName, + mkIPSetCIDRNoMatch, + mkIPSetCIDRComment, + }) + + structure.AssertValueTypes(t, cirdSchema, map[string]schema.ValueType{ + mkIPSetCIDRName: schema.TypeString, + mkIPSetCIDRNoMatch: schema.TypeBool, + mkIPSetCIDRComment: schema.TypeString, + }) +} diff --git a/proxmoxtf/datasource/firewall/ipsets.go b/proxmoxtf/datasource/firewall/ipsets.go new file mode 100644 index 00000000..7bb2f727 --- /dev/null +++ b/proxmoxtf/datasource/firewall/ipsets.go @@ -0,0 +1,51 @@ +/* + * 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" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmox/firewall" +) + +const ( + mkIPSetsIPSetNames = "ipset_names" +) + +func IPSetsSchema() map[string]*schema.Schema { + return map[string]*schema.Schema{ + mkIPSetsIPSetNames: { + Type: schema.TypeList, + Description: "IPSet Names", + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + } +} + +func IPSetsRead(ctx context.Context, fw firewall.API, d *schema.ResourceData) diag.Diagnostics { + list, err := fw.ListIPSets(ctx) + if err != nil { + return diag.FromErr(err) + } + + ipSetNames := make([]interface{}, len(list)) + + for i, v := range list { + ipSetNames[i] = v.Name + } + + d.SetId(uuid.New().String()) + + err = d.Set(mkIPSetsIPSetNames, ipSetNames) + + return diag.FromErr(err) +} diff --git a/proxmoxtf/datasource/firewall/ipsets_test.go b/proxmoxtf/datasource/firewall/ipsets_test.go new file mode 100644 index 00000000..ddc78b3a --- /dev/null +++ b/proxmoxtf/datasource/firewall/ipsets_test.go @@ -0,0 +1,36 @@ +/* + * 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 ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/stretchr/testify/require" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf/structure" +) + +// TestIPSetsSchemaInstantiation tests whether the IPSetsSchema instance can be instantiated. +func TestIPSetsSchemaInstantiation(t *testing.T) { + t.Parallel() + require.NotNil(t, IPSetsSchema(), "Cannot instantiate IPSetsSchema") +} + +// TestIPSetsSchema tests the IPSetsSchema. +func TestIPSetsSchema(t *testing.T) { + t.Parallel() + s := IPSetsSchema() + + structure.AssertComputedAttributes(t, s, []string{ + mkIPSetsIPSetNames, + }) + + structure.AssertValueTypes(t, s, map[string]schema.ValueType{ + mkIPSetsIPSetNames: schema.TypeList, + }) +} diff --git a/proxmoxtf/datasource/firewall/rule.go b/proxmoxtf/datasource/firewall/rule.go new file mode 100644 index 00000000..285e69cc --- /dev/null +++ b/proxmoxtf/datasource/firewall/rule.go @@ -0,0 +1,131 @@ +/* + * 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/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +const ( + mkRuleAction = "action" + mkRuleComment = "comment" + mkRuleDPort = "dport" + mkRuleDest = "dest" + mkRuleEnable = "enable" + mkRuleIFace = "iface" + mkRuleLog = "log" + mkRuleMacro = "macro" + mkRulePos = "pos" + mkRuleProto = "proto" + mkRuleSource = "source" + mkRuleSPort = "sport" + mkRuleType = "type" +) + +func RuleSchema() map[string]*schema.Schema { + return map[string]*schema.Schema{ + mkRulePos: { + Type: schema.TypeInt, + Description: "Rule position", + Computed: true, + }, + mkRuleAction: { + Type: schema.TypeString, + Description: "Rule action ('ACCEPT', 'DROP', 'REJECT')", + Required: true, + }, + mkRuleType: { + Type: schema.TypeString, + Description: "Rule type ('in', 'out')", + Required: true, + }, + mkRuleComment: { + Type: schema.TypeString, + Description: "Rule comment", + Computed: true, + }, + mkRuleDest: { + Type: schema.TypeString, + Description: "Packet destination address", + Computed: true, + }, + mkRuleDPort: { + Type: schema.TypeString, + Description: "TCP/UDP destination port.", + Computed: true, + }, + mkRuleEnable: { + Type: schema.TypeBool, + Description: "Enable rule", + Computed: true, + }, + mkRuleIFace: { + Type: schema.TypeString, + Description: "Network interface name.", + Computed: true, + }, + mkRuleLog: { + Type: schema.TypeString, + Description: "Log level for this rule", + Computed: true, + }, + mkRuleMacro: { + Type: schema.TypeString, + Description: "Use predefined standard macro", + Computed: true, + }, + mkRuleProto: { + Type: schema.TypeString, + Description: "Packet protocol.", + Computed: true, + }, + mkRuleSource: { + Type: schema.TypeString, + Description: "Packet source address.", + Computed: true, + }, + mkRuleSPort: { + Type: schema.TypeString, + Description: "TCP/UDP source port.", + Computed: true, + }, + } +} + +// +// func baseRuleToMap(baseRule *firewall.BaseRule, rule map[string]interface{}) { +// if baseRule.Comment != nil { +// rule[mkRuleComment] = *baseRule.Comment +// } +// if baseRule.Dest != nil { +// rule[mkRuleDest] = *baseRule.Dest +// } +// if baseRule.DPort != nil { +// rule[mkRuleDPort] = *baseRule.DPort +// } +// if baseRule.Enable != nil { +// rule[mkRuleEnable] = *baseRule.Enable +// } +// if baseRule.IFace != nil { +// rule[mkRuleIFace] = *baseRule.IFace +// } +// if baseRule.Log != nil { +// rule[mkRuleLog] = *baseRule.Log +// } +// if baseRule.Macro != nil { +// rule[mkRuleMacro] = *baseRule.Macro +// } +// if baseRule.Proto != nil { +// rule[mkRuleProto] = *baseRule.Proto +// } +// if baseRule.Source != nil { +// rule[mkRuleSource] = *baseRule.Source +// } +// if baseRule.SPort != nil { +// rule[mkRuleSPort] = *baseRule.SPort +// } +// } diff --git a/proxmoxtf/datasource/firewall/rule_test.go b/proxmoxtf/datasource/firewall/rule_test.go new file mode 100644 index 00000000..69d50425 --- /dev/null +++ b/proxmoxtf/datasource/firewall/rule_test.go @@ -0,0 +1,62 @@ +/* + * 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 ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/stretchr/testify/require" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf/structure" +) + +// TestRuleInstantiation tests whether the RuleSchema instance can be instantiated. +func TestRuleSchemaInstantiation(t *testing.T) { + t.Parallel() + require.NotNilf(t, RuleSchema(), "Cannot instantiate RuleSchema") +} + +// TestRuleSchema tests the RuleSchema. +func TestRuleSchema(t *testing.T) { + t.Parallel() + ruleSchema := RuleSchema() + + structure.AssertRequiredArguments(t, ruleSchema, []string{ + mkRuleAction, + mkRuleType, + }) + + structure.AssertComputedAttributes(t, ruleSchema, []string{ + mkRuleComment, + mkRuleDest, + mkRuleDPort, + mkRuleEnable, + mkRuleIFace, + mkRuleLog, + mkRuleMacro, + mkRuleProto, + mkRuleSource, + mkRuleSPort, + }) + + structure.AssertValueTypes(t, ruleSchema, map[string]schema.ValueType{ + mkRulePos: schema.TypeInt, + mkRuleAction: schema.TypeString, + mkRuleType: schema.TypeString, + mkRuleComment: schema.TypeString, + mkRuleDest: schema.TypeString, + mkRuleDPort: schema.TypeString, + mkRuleEnable: schema.TypeBool, + mkRuleIFace: schema.TypeString, + mkRuleLog: schema.TypeString, + mkRuleMacro: schema.TypeString, + mkRuleProto: schema.TypeString, + mkRuleSource: schema.TypeString, + mkRuleSPort: schema.TypeString, + }) +} diff --git a/proxmoxtf/datasource/firewall/security_group.go b/proxmoxtf/datasource/firewall/security_group.go new file mode 100644 index 00000000..9335c096 --- /dev/null +++ b/proxmoxtf/datasource/firewall/security_group.go @@ -0,0 +1,119 @@ +/* + * 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" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmox/cluster/firewall" +) + +const ( + mkSecurityGroupName = "name" + mkSecurityGroupComment = "comment" + mkRules = "rules" +) + +func SecurityGroupSchema() map[string]*schema.Schema { + return map[string]*schema.Schema{ + mkSecurityGroupName: { + Type: schema.TypeString, + Description: "Security group name", + Required: true, + }, + mkSecurityGroupComment: { + Type: schema.TypeString, + Description: "Security group comment", + Computed: true, + }, + mkRules: { + Type: schema.TypeList, + Description: "List of rules", + Computed: true, + Elem: &schema.Resource{Schema: RuleSchema()}, + }, + } +} + +func SecurityGroupRead(ctx context.Context, api firewall.SecurityGroup, d *schema.ResourceData) diag.Diagnostics { + var diags diag.Diagnostics + + name := d.Get(mkSecurityGroupName).(string) + + allGroups, err := api.ListGroups(ctx) + if err != nil { + return diag.FromErr(err) + } + + for _, v := range allGroups { + if v.Group == name { + err = d.Set(mkSecurityGroupName, v.Group) + diags = append(diags, diag.FromErr(err)...) + err = d.Set(mkSecurityGroupComment, v.Comment) + diags = append(diags, diag.FromErr(err)...) + break + } + } + + // rules := d.Get(mkRules).([]interface{}) + // ruleIDs, err := fw.ListGroupRules(ctx, name) + // if err != nil { + // if strings.Contains(err.Error(), "no such security group") { + // d.SetId("") + // return nil + // } + // return diag.FromErr(err) + // } + // for _, id := range ruleIDs { + // ruleMap := map[string]interface{}{} + // err = readGroupRule(ctx, fw, name, id.Pos, ruleMap) + // if err != nil { + // diags = append(diags, diag.FromErr(err)...) + // } else { + // rules = append(rules, ruleMap) + // } + // } + + // if diags.HasError() { + // return diags + // } + + // err = d.Set(mkRules, rules) + // diags = append(diags, diag.FromErr(err)...) + + d.SetId(name) + + return diags +} + +// func readGroupRule( +// ctx context.Context, +// fw firewall.API, +// group string, +// pos int, +// ruleMap map[string]interface{}, +// ) error { +// rule, err := fw.GetGroupRule(ctx, group, pos) +// if err != nil { +// if strings.Contains(err.Error(), "no such security group") { +// return nil +// } +// return fmt.Errorf("error reading rule %d for group %s: %w", pos, group, err) +// } +// +// baseRuleToMap(&rule.BaseRule, ruleMap) +// +// // pos in the map should be int! +// ruleMap[mkRulePos] = pos +// ruleMap[mkRuleAction] = rule.Action +// ruleMap[mkRuleType] = rule.Type +// +// return nil +// } diff --git a/proxmoxtf/datasource/firewall/security_group_test.go b/proxmoxtf/datasource/firewall/security_group_test.go new file mode 100644 index 00000000..6d32b9b8 --- /dev/null +++ b/proxmoxtf/datasource/firewall/security_group_test.go @@ -0,0 +1,43 @@ +/* + * 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 ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/stretchr/testify/require" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf/structure" +) + +// TestSecurityGroupSchemaInstantiation tests whether the SecurityGroupSchema instance can be instantiated. +func TestSecurityGroupSchemaInstantiation(t *testing.T) { + t.Parallel() + require.NotNil(t, SecurityGroupSchema(), "Cannot instantiate SecurityGroupSchema") +} + +// TestSecurityGroupSchema tests the SecurityGroupSchema. +func TestSecurityGroupSchema(t *testing.T) { + t.Parallel() + s := SecurityGroupSchema() + + structure.AssertRequiredArguments(t, s, []string{ + mkSecurityGroupName, + }) + + structure.AssertComputedAttributes(t, s, []string{ + mkSecurityGroupComment, + mkRules, + }) + + structure.AssertValueTypes(t, s, map[string]schema.ValueType{ + mkSecurityGroupName: schema.TypeString, + mkSecurityGroupComment: schema.TypeString, + mkRules: schema.TypeList, + }) +} diff --git a/proxmoxtf/datasource/firewall/security_groups.go b/proxmoxtf/datasource/firewall/security_groups.go new file mode 100644 index 00000000..fc89f0ae --- /dev/null +++ b/proxmoxtf/datasource/firewall/security_groups.go @@ -0,0 +1,51 @@ +/* + * 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" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmox/cluster/firewall" +) + +const ( + mkSecurityGroupsSecurityGroupNames = "security_group_names" +) + +func SecurityGroupsSchema() map[string]*schema.Schema { + return map[string]*schema.Schema{ + mkSecurityGroupsSecurityGroupNames: { + Type: schema.TypeList, + Description: "Security Group Names", + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + } +} + +func SecurityGroupsRead(ctx context.Context, api firewall.SecurityGroup, d *schema.ResourceData) diag.Diagnostics { + groups, err := api.ListGroups(ctx) + if err != nil { + return diag.FromErr(err) + } + + groupNames := make([]interface{}, len(groups)) + + for i, v := range groups { + groupNames[i] = v.Group + } + + d.SetId(uuid.New().String()) + + err = d.Set(mkSecurityGroupsSecurityGroupNames, groupNames) + + return diag.FromErr(err) +} diff --git a/proxmoxtf/datasource/firewall/security_groups_test.go b/proxmoxtf/datasource/firewall/security_groups_test.go new file mode 100644 index 00000000..2ce5735c --- /dev/null +++ b/proxmoxtf/datasource/firewall/security_groups_test.go @@ -0,0 +1,36 @@ +/* + * 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 ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/stretchr/testify/require" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf/structure" +) + +// TestSecurityGroupsSchemaInstantiation tests whether the SecurityGroupsSchema instance can be instantiated. +func TestSecurityGroupsSchemaInstantiation(t *testing.T) { + t.Parallel() + require.NotNil(t, SecurityGroupsSchema(), "Cannot instantiate SecurityGroupsSchema") +} + +// TestSecurityGroupsSchema tests the SecurityGroupsSchema. +func TestSecurityGroupsSchema(t *testing.T) { + t.Parallel() + s := SecurityGroupsSchema() + + structure.AssertComputedAttributes(t, s, []string{ + mkSecurityGroupsSecurityGroupNames, + }) + + structure.AssertValueTypes(t, s, map[string]schema.ValueType{ + mkSecurityGroupsSecurityGroupNames: schema.TypeList, + }) +} diff --git a/proxmoxtf/data_source_virtual_environment_group.go b/proxmoxtf/datasource/group.go similarity index 88% rename from proxmoxtf/data_source_virtual_environment_group.go rename to proxmoxtf/datasource/group.go index bc85130c..0f6cdd8e 100644 --- a/proxmoxtf/data_source_virtual_environment_group.go +++ b/proxmoxtf/datasource/group.go @@ -1,14 +1,18 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public +/* + * 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/. */ + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ -package proxmoxtf +package datasource import ( "context" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf" ) const ( @@ -21,7 +25,7 @@ const ( mkDataSourceVirtualEnvironmentGroupMembers = "members" ) -func dataSourceVirtualEnvironmentGroup() *schema.Resource { +func Group() *schema.Resource { return &schema.Resource{ Schema: map[string]*schema.Schema{ mkDataSourceVirtualEnvironmentGroupACL: { @@ -65,18 +69,14 @@ func dataSourceVirtualEnvironmentGroup() *schema.Resource { Elem: &schema.Schema{Type: schema.TypeString}, }, }, - ReadContext: dataSourceVirtualEnvironmentGroupRead, + ReadContext: groupRead, } } -func dataSourceVirtualEnvironmentGroupRead( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { +func groupRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { var diags diag.Diagnostics - config := m.(providerConfiguration) + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) diff --git a/proxmoxtf/data_source_virtual_environment_group_test.go b/proxmoxtf/datasource/group_test.go similarity index 50% rename from proxmoxtf/data_source_virtual_environment_group_test.go rename to proxmoxtf/datasource/group_test.go index 7391680a..7c62770e 100644 --- a/proxmoxtf/data_source_virtual_environment_group_test.go +++ b/proxmoxtf/datasource/group_test.go @@ -1,54 +1,60 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public +/* + * 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/. */ + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ -package proxmoxtf +package datasource import ( "testing" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf/test" ) -// TestDataSourceVirtualEnvironmentGroupInstantiation tests whether the DataSourceVirtualEnvironmentGroup instance can be instantiated. -func TestDataSourceVirtualEnvironmentGroupInstantiation(t *testing.T) { - s := dataSourceVirtualEnvironmentGroup() +// TestGroupInstantiation tests whether the Group instance can be instantiated. +func TestGroupInstantiation(t *testing.T) { + t.Parallel() + s := Group() if s == nil { - t.Fatalf("Cannot instantiate dataSourceVirtualEnvironmentGroup") + t.Fatalf("Cannot instantiate Group") } } -// TestDataSourceVirtualEnvironmentGroupSchema tests the dataSourceVirtualEnvironmentGroup schema. -func TestDataSourceVirtualEnvironmentGroupSchema(t *testing.T) { - s := dataSourceVirtualEnvironmentGroup() +// TestGroupSchema tests the Group schema. +func TestGroupSchema(t *testing.T) { + t.Parallel() + s := Group() - testRequiredArguments(t, s, []string{ + test.AssertRequiredArguments(t, s, []string{ mkDataSourceVirtualEnvironmentGroupID, }) - testComputedAttributes(t, s, []string{ + test.AssertComputedAttributes(t, s, []string{ mkDataSourceVirtualEnvironmentGroupACL, mkDataSourceVirtualEnvironmentGroupComment, mkDataSourceVirtualEnvironmentGroupMembers, }) - testValueTypes(t, s, map[string]schema.ValueType{ + test.AssertValueTypes(t, s, map[string]schema.ValueType{ mkDataSourceVirtualEnvironmentGroupACL: schema.TypeSet, mkDataSourceVirtualEnvironmentGroupID: schema.TypeString, mkDataSourceVirtualEnvironmentGroupComment: schema.TypeString, mkDataSourceVirtualEnvironmentGroupMembers: schema.TypeSet, }) - aclSchema := testNestedSchemaExistence(t, s, mkDataSourceVirtualEnvironmentGroupACL) + aclSchema := test.AssertNestedSchemaExistence(t, s, mkDataSourceVirtualEnvironmentGroupACL) - testComputedAttributes(t, aclSchema, []string{ + test.AssertComputedAttributes(t, aclSchema, []string{ mkDataSourceVirtualEnvironmentGroupACLPath, mkDataSourceVirtualEnvironmentGroupACLPropagate, mkDataSourceVirtualEnvironmentGroupACLRoleID, }) - testValueTypes(t, aclSchema, map[string]schema.ValueType{ + test.AssertValueTypes(t, aclSchema, map[string]schema.ValueType{ mkDataSourceVirtualEnvironmentGroupACLPath: schema.TypeString, mkDataSourceVirtualEnvironmentGroupACLPropagate: schema.TypeBool, mkDataSourceVirtualEnvironmentGroupACLRoleID: schema.TypeString, diff --git a/proxmoxtf/data_source_virtual_environment_groups.go b/proxmoxtf/datasource/groups.go similarity index 78% rename from proxmoxtf/data_source_virtual_environment_groups.go rename to proxmoxtf/datasource/groups.go index eaf12309..e4cdcea8 100644 --- a/proxmoxtf/data_source_virtual_environment_groups.go +++ b/proxmoxtf/datasource/groups.go @@ -1,14 +1,18 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public +/* + * 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/. */ + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ -package proxmoxtf +package datasource import ( "context" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf" ) const ( @@ -16,7 +20,7 @@ const ( mkDataSourceVirtualEnvironmentGroupsGroupIDs = "group_ids" ) -func dataSourceVirtualEnvironmentGroups() *schema.Resource { +func Groups() *schema.Resource { return &schema.Resource{ Schema: map[string]*schema.Schema{ mkDataSourceVirtualEnvironmentGroupsComments: { @@ -32,18 +36,14 @@ func dataSourceVirtualEnvironmentGroups() *schema.Resource { Elem: &schema.Schema{Type: schema.TypeString}, }, }, - ReadContext: dataSourceVirtualEnvironmentGroupsRead, + ReadContext: groupsRead, } } -func dataSourceVirtualEnvironmentGroupsRead( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { +func groupsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { var diags diag.Diagnostics - config := m.(providerConfiguration) + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) diff --git a/proxmoxtf/datasource/groups_test.go b/proxmoxtf/datasource/groups_test.go new file mode 100644 index 00000000..0e5fd9a6 --- /dev/null +++ b/proxmoxtf/datasource/groups_test.go @@ -0,0 +1,41 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +package datasource + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf/test" +) + +// TestGroupsInstantiation tests whether the Groups instance can be instantiated. +func TestGroupsInstantiation(t *testing.T) { + t.Parallel() + s := Groups() + + if s == nil { + t.Fatalf("Cannot instantiate Groups") + } +} + +// TestGroupsSchema tests the Groups schema. +func TestGroupsSchema(t *testing.T) { + t.Parallel() + s := Groups() + + test.AssertComputedAttributes(t, s, []string{ + mkDataSourceVirtualEnvironmentGroupsComments, + mkDataSourceVirtualEnvironmentGroupsGroupIDs, + }) + + test.AssertValueTypes(t, s, map[string]schema.ValueType{ + mkDataSourceVirtualEnvironmentGroupsComments: schema.TypeList, + mkDataSourceVirtualEnvironmentGroupsGroupIDs: schema.TypeList, + }) +} diff --git a/proxmoxtf/data_source_virtual_environment_hosts.go b/proxmoxtf/datasource/hosts.go similarity index 90% rename from proxmoxtf/data_source_virtual_environment_hosts.go rename to proxmoxtf/datasource/hosts.go index 3174517f..d0418edf 100644 --- a/proxmoxtf/data_source_virtual_environment_hosts.go +++ b/proxmoxtf/datasource/hosts.go @@ -1,8 +1,10 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public +/* + * 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/. */ + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ -package proxmoxtf +package datasource import ( "context" @@ -11,6 +13,8 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf" ) const ( @@ -23,7 +27,7 @@ const ( mkDataSourceVirtualEnvironmentHostsNodeName = "node_name" ) -func dataSourceVirtualEnvironmentHosts() *schema.Resource { +func Hosts() *schema.Resource { return &schema.Resource{ Schema: map[string]*schema.Schema{ mkDataSourceVirtualEnvironmentHostsAddresses: { @@ -72,18 +76,14 @@ func dataSourceVirtualEnvironmentHosts() *schema.Resource { Required: true, }, }, - ReadContext: dataSourceVirtualEnvironmentHostsRead, + ReadContext: hostsRead, } } -func dataSourceVirtualEnvironmentHostsRead( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { +func hostsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { var diags diag.Diagnostics - config := m.(providerConfiguration) + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) diff --git a/proxmoxtf/data_source_virtual_environment_hosts_test.go b/proxmoxtf/datasource/hosts_test.go similarity index 50% rename from proxmoxtf/data_source_virtual_environment_hosts_test.go rename to proxmoxtf/datasource/hosts_test.go index 1779f49c..9d9b1b22 100644 --- a/proxmoxtf/data_source_virtual_environment_hosts_test.go +++ b/proxmoxtf/datasource/hosts_test.go @@ -1,40 +1,46 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public +/* + * 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/. */ + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ -package proxmoxtf +package datasource import ( "testing" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf/test" ) -// TestDataSourceVirtualEnvironmentHostsInstantiation tests whether the DataSourceVirtualEnvironmentHosts instance can be instantiated. -func TestDataSourceVirtualEnvironmentHostsInstantiation(t *testing.T) { - s := dataSourceVirtualEnvironmentHosts() +// TestHostsInstantiation tests whether the Hosts instance can be instantiated. +func TestHostsInstantiation(t *testing.T) { + t.Parallel() + s := Hosts() if s == nil { - t.Fatalf("Cannot instantiate dataSourceVirtualEnvironmentHosts") + t.Fatalf("Cannot instantiate Hosts") } } -// TestDataSourceVirtualEnvironmentHostsSchema tests the dataSourceVirtualEnvironmentHosts schema. -func TestDataSourceVirtualEnvironmentHostsSchema(t *testing.T) { - s := dataSourceVirtualEnvironmentHosts() +// TestHostsSchema tests the Hosts schema. +func TestHostsSchema(t *testing.T) { + t.Parallel() + s := Hosts() - testRequiredArguments(t, s, []string{ + test.AssertRequiredArguments(t, s, []string{ mkDataSourceVirtualEnvironmentHostsNodeName, }) - testComputedAttributes(t, s, []string{ + test.AssertComputedAttributes(t, s, []string{ mkDataSourceVirtualEnvironmentHostsAddresses, mkDataSourceVirtualEnvironmentHostsDigest, mkDataSourceVirtualEnvironmentHostsEntries, mkDataSourceVirtualEnvironmentHostsHostnames, }) - testValueTypes(t, s, map[string]schema.ValueType{ + test.AssertValueTypes(t, s, map[string]schema.ValueType{ mkDataSourceVirtualEnvironmentHostsAddresses: schema.TypeList, mkDataSourceVirtualEnvironmentHostsDigest: schema.TypeString, mkDataSourceVirtualEnvironmentHostsEntries: schema.TypeList, @@ -42,14 +48,14 @@ func TestDataSourceVirtualEnvironmentHostsSchema(t *testing.T) { mkDataSourceVirtualEnvironmentHostsNodeName: schema.TypeString, }) - entriesSchema := testNestedSchemaExistence(t, s, mkDataSourceVirtualEnvironmentHostsEntries) + entriesSchema := test.AssertNestedSchemaExistence(t, s, mkDataSourceVirtualEnvironmentHostsEntries) - testComputedAttributes(t, entriesSchema, []string{ + test.AssertComputedAttributes(t, entriesSchema, []string{ mkDataSourceVirtualEnvironmentHostsEntriesAddress, mkDataSourceVirtualEnvironmentHostsEntriesHostnames, }) - testValueTypes(t, entriesSchema, map[string]schema.ValueType{ + test.AssertValueTypes(t, entriesSchema, map[string]schema.ValueType{ mkDataSourceVirtualEnvironmentHostsEntriesAddress: schema.TypeString, mkDataSourceVirtualEnvironmentHostsEntriesHostnames: schema.TypeList, }) diff --git a/proxmoxtf/data_source_virtual_environment_nodes.go b/proxmoxtf/datasource/nodes.go similarity index 92% rename from proxmoxtf/data_source_virtual_environment_nodes.go rename to proxmoxtf/datasource/nodes.go index ce1fe552..572bd910 100644 --- a/proxmoxtf/data_source_virtual_environment_nodes.go +++ b/proxmoxtf/datasource/nodes.go @@ -1,8 +1,10 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public +/* + * 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/. */ + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ -package proxmoxtf +package datasource import ( "context" @@ -10,6 +12,8 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf" ) const ( @@ -24,7 +28,7 @@ const ( mkDataSourceVirtualEnvironmentNodesUptime = "uptime" ) -func dataSourceVirtualEnvironmentNodes() *schema.Resource { +func Nodes() *schema.Resource { return &schema.Resource{ Schema: map[string]*schema.Schema{ mkDataSourceVirtualEnvironmentNodesCPUCount: { @@ -82,18 +86,14 @@ func dataSourceVirtualEnvironmentNodes() *schema.Resource { Elem: &schema.Schema{Type: schema.TypeInt}, }, }, - ReadContext: dataSourceVirtualEnvironmentNodesRead, + ReadContext: nodesRead, } } -func dataSourceVirtualEnvironmentNodesRead( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { +func nodesRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { var diags diag.Diagnostics - config := m.(providerConfiguration) + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) diff --git a/proxmoxtf/data_source_virtual_environment_nodes_test.go b/proxmoxtf/datasource/nodes_test.go similarity index 62% rename from proxmoxtf/data_source_virtual_environment_nodes_test.go rename to proxmoxtf/datasource/nodes_test.go index c738cdf9..03482372 100644 --- a/proxmoxtf/data_source_virtual_environment_nodes_test.go +++ b/proxmoxtf/datasource/nodes_test.go @@ -1,29 +1,35 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public +/* + * 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/. */ + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ -package proxmoxtf +package datasource import ( "testing" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf/test" ) -// TestDataSourceVirtualEnvironmentNodesInstantiation tests whether the DataSourceVirtualEnvironmentNodes instance can be instantiated. -func TestDataSourceVirtualEnvironmentNodesInstantiation(t *testing.T) { - s := dataSourceVirtualEnvironmentNodes() +// TestNodesInstantiation tests whether the Nodes instance can be instantiated. +func TestNodesInstantiation(t *testing.T) { + t.Parallel() + s := Nodes() if s == nil { - t.Fatalf("Cannot instantiate dataSourceVirtualEnvironmentNodes") + t.Fatalf("Cannot instantiate Nodes") } } -// TestDataSourceVirtualEnvironmentNodesSchema tests the dataSourceVirtualEnvironmentNodes schema. -func TestDataSourceVirtualEnvironmentNodesSchema(t *testing.T) { - s := dataSourceVirtualEnvironmentNodes() +// TestNodesSchema tests the Nodes schema. +func TestNodesSchema(t *testing.T) { + t.Parallel() + s := Nodes() - testComputedAttributes(t, s, []string{ + test.AssertComputedAttributes(t, s, []string{ mkDataSourceVirtualEnvironmentNodesCPUCount, mkDataSourceVirtualEnvironmentNodesCPUUtilization, mkDataSourceVirtualEnvironmentNodesMemoryAvailable, @@ -35,7 +41,7 @@ func TestDataSourceVirtualEnvironmentNodesSchema(t *testing.T) { mkDataSourceVirtualEnvironmentNodesUptime, }) - testValueTypes(t, s, map[string]schema.ValueType{ + test.AssertValueTypes(t, s, map[string]schema.ValueType{ mkDataSourceVirtualEnvironmentNodesCPUCount: schema.TypeList, mkDataSourceVirtualEnvironmentNodesCPUUtilization: schema.TypeList, mkDataSourceVirtualEnvironmentNodesMemoryAvailable: schema.TypeList, diff --git a/proxmoxtf/data_source_virtual_environment_pool.go b/proxmoxtf/datasource/pool.go similarity index 89% rename from proxmoxtf/data_source_virtual_environment_pool.go rename to proxmoxtf/datasource/pool.go index 1129da69..d9cc8a91 100644 --- a/proxmoxtf/data_source_virtual_environment_pool.go +++ b/proxmoxtf/datasource/pool.go @@ -1,14 +1,18 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public +/* + * 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/. */ + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ -package proxmoxtf +package datasource import ( "context" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf" ) const ( @@ -22,7 +26,7 @@ const ( mkDataSourceVirtualEnvironmentPoolPoolID = "pool_id" ) -func dataSourceVirtualEnvironmentPool() *schema.Resource { +func Pool() *schema.Resource { return &schema.Resource{ Schema: map[string]*schema.Schema{ mkDataSourceVirtualEnvironmentPoolComment: { @@ -70,18 +74,14 @@ func dataSourceVirtualEnvironmentPool() *schema.Resource { Required: true, }, }, - ReadContext: dataSourceVirtualEnvironmentPoolRead, + ReadContext: poolRead, } } -func dataSourceVirtualEnvironmentPoolRead( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { +func poolRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { var diags diag.Diagnostics - config := m.(providerConfiguration) + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) diff --git a/proxmoxtf/data_source_virtual_environment_pool_test.go b/proxmoxtf/datasource/pool_test.go similarity index 53% rename from proxmoxtf/data_source_virtual_environment_pool_test.go rename to proxmoxtf/datasource/pool_test.go index acc828b8..0f95c41c 100644 --- a/proxmoxtf/data_source_virtual_environment_pool_test.go +++ b/proxmoxtf/datasource/pool_test.go @@ -1,46 +1,52 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public +/* + * 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/. */ + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ -package proxmoxtf +package datasource import ( "testing" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf/test" ) -// TestDataSourceVirtualEnvironmentPoolInstantiation tests whether the DataSourceVirtualEnvironmentPool instance can be instantiated. -func TestDataSourceVirtualEnvironmentPoolInstantiation(t *testing.T) { - s := dataSourceVirtualEnvironmentPool() +// TestPoolInstantiation tests whether the Pool instance can be instantiated. +func TestPoolInstantiation(t *testing.T) { + t.Parallel() + s := Pool() if s == nil { - t.Fatalf("Cannot instantiate dataSourceVirtualEnvironmentPool") + t.Fatalf("Cannot instantiate Pool") } } -// TestDataSourceVirtualEnvironmentPoolSchema tests the dataSourceVirtualEnvironmentPool schema. -func TestDataSourceVirtualEnvironmentPoolSchema(t *testing.T) { - s := dataSourceVirtualEnvironmentPool() +// TestPoolSchema tests the Pool schema. +func TestPoolSchema(t *testing.T) { + t.Parallel() + s := Pool() - testRequiredArguments(t, s, []string{ + test.AssertRequiredArguments(t, s, []string{ mkDataSourceVirtualEnvironmentPoolPoolID, }) - testComputedAttributes(t, s, []string{ + test.AssertComputedAttributes(t, s, []string{ mkDataSourceVirtualEnvironmentPoolComment, mkDataSourceVirtualEnvironmentPoolMembers, }) - testValueTypes(t, s, map[string]schema.ValueType{ + test.AssertValueTypes(t, s, map[string]schema.ValueType{ mkDataSourceVirtualEnvironmentPoolComment: schema.TypeString, mkDataSourceVirtualEnvironmentPoolMembers: schema.TypeList, mkDataSourceVirtualEnvironmentPoolPoolID: schema.TypeString, }) - membersSchema := testNestedSchemaExistence(t, s, mkDataSourceVirtualEnvironmentPoolMembers) + membersSchema := test.AssertNestedSchemaExistence(t, s, mkDataSourceVirtualEnvironmentPoolMembers) - testComputedAttributes(t, membersSchema, []string{ + test.AssertComputedAttributes(t, membersSchema, []string{ mkDataSourceVirtualEnvironmentPoolMembersDatastoreID, mkDataSourceVirtualEnvironmentPoolMembersID, mkDataSourceVirtualEnvironmentPoolMembersNodeName, @@ -48,7 +54,7 @@ func TestDataSourceVirtualEnvironmentPoolSchema(t *testing.T) { mkDataSourceVirtualEnvironmentPoolMembersVMID, }) - testValueTypes(t, membersSchema, map[string]schema.ValueType{ + test.AssertValueTypes(t, membersSchema, map[string]schema.ValueType{ mkDataSourceVirtualEnvironmentPoolMembersDatastoreID: schema.TypeString, mkDataSourceVirtualEnvironmentPoolMembersID: schema.TypeString, mkDataSourceVirtualEnvironmentPoolMembersNodeName: schema.TypeString, diff --git a/proxmoxtf/data_source_virtual_environment_pools.go b/proxmoxtf/datasource/pools.go similarity index 68% rename from proxmoxtf/data_source_virtual_environment_pools.go rename to proxmoxtf/datasource/pools.go index cdc41e9f..af8f5ebb 100644 --- a/proxmoxtf/data_source_virtual_environment_pools.go +++ b/proxmoxtf/datasource/pools.go @@ -1,21 +1,25 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public +/* + * 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/. */ + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ -package proxmoxtf +package datasource import ( "context" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf" ) const ( mkDataSourceVirtualEnvironmentPoolsPoolIDs = "pool_ids" ) -func dataSourceVirtualEnvironmentPools() *schema.Resource { +func Pools() *schema.Resource { return &schema.Resource{ Schema: map[string]*schema.Schema{ mkDataSourceVirtualEnvironmentPoolsPoolIDs: { @@ -25,16 +29,12 @@ func dataSourceVirtualEnvironmentPools() *schema.Resource { Elem: &schema.Schema{Type: schema.TypeString}, }, }, - ReadContext: dataSourceVirtualEnvironmentPoolsRead, + ReadContext: poolsRead, } } -func dataSourceVirtualEnvironmentPoolsRead( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { - config := m.(providerConfiguration) +func poolsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) diff --git a/proxmoxtf/datasource/pools_test.go b/proxmoxtf/datasource/pools_test.go new file mode 100644 index 00000000..e06dfd67 --- /dev/null +++ b/proxmoxtf/datasource/pools_test.go @@ -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/. + */ + +package datasource + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf/test" +) + +// TestPoolsInstantiation tests whether the Pools instance can be instantiated. +func TestPoolsInstantiation(t *testing.T) { + t.Parallel() + s := Pools() + + if s == nil { + t.Fatalf("Cannot instantiate Pools") + } +} + +// TestPoolsSchema tests the Pools schema. +func TestPoolsSchema(t *testing.T) { + t.Parallel() + s := Pools() + + test.AssertComputedAttributes(t, s, []string{ + mkDataSourceVirtualEnvironmentPoolsPoolIDs, + }) + + test.AssertValueTypes(t, s, map[string]schema.ValueType{ + mkDataSourceVirtualEnvironmentPoolsPoolIDs: schema.TypeList, + }) +} diff --git a/proxmoxtf/data_source_virtual_environment_role.go b/proxmoxtf/datasource/role.go similarity index 75% rename from proxmoxtf/data_source_virtual_environment_role.go rename to proxmoxtf/datasource/role.go index 5fb5a8f3..bb31048e 100644 --- a/proxmoxtf/data_source_virtual_environment_role.go +++ b/proxmoxtf/datasource/role.go @@ -1,14 +1,18 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public +/* + * 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/. */ + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ -package proxmoxtf +package datasource import ( "context" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf" ) const ( @@ -16,7 +20,7 @@ const ( mkDataSourceVirtualEnvironmentRolePrivileges = "privileges" ) -func dataSourceVirtualEnvironmentRole() *schema.Resource { +func Role() *schema.Resource { return &schema.Resource{ Schema: map[string]*schema.Schema{ mkDataSourceVirtualEnvironmentRoleID: { @@ -31,16 +35,12 @@ func dataSourceVirtualEnvironmentRole() *schema.Resource { Elem: &schema.Schema{Type: schema.TypeString}, }, }, - ReadContext: dataSourceVirtualEnvironmentRoleRead, + ReadContext: roleRead, } } -func dataSourceVirtualEnvironmentRoleRead( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { - config := m.(providerConfiguration) +func roleRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) diff --git a/proxmoxtf/datasource/role_test.go b/proxmoxtf/datasource/role_test.go new file mode 100644 index 00000000..ee61af59 --- /dev/null +++ b/proxmoxtf/datasource/role_test.go @@ -0,0 +1,44 @@ +/* + * 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 datasource + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf/test" +) + +// TestRoleInstantiation tests whether the Role instance can be instantiated. +func TestRoleInstantiation(t *testing.T) { + t.Parallel() + s := Role() + + if s == nil { + t.Fatalf("Cannot instantiate Role") + } +} + +// TestRoleSchema tests the Role schema. +func TestRoleSchema(t *testing.T) { + t.Parallel() + s := Role() + + test.AssertRequiredArguments(t, s, []string{ + mkDataSourceVirtualEnvironmentRoleID, + }) + + test.AssertComputedAttributes(t, s, []string{ + mkDataSourceVirtualEnvironmentRolePrivileges, + }) + + test.AssertValueTypes(t, s, map[string]schema.ValueType{ + mkDataSourceVirtualEnvironmentRoleID: schema.TypeString, + mkDataSourceVirtualEnvironmentRolePrivileges: schema.TypeSet, + }) +} diff --git a/proxmoxtf/data_source_virtual_environment_roles.go b/proxmoxtf/datasource/roles.go similarity index 84% rename from proxmoxtf/data_source_virtual_environment_roles.go rename to proxmoxtf/datasource/roles.go index 70785117..95d48fa3 100644 --- a/proxmoxtf/data_source_virtual_environment_roles.go +++ b/proxmoxtf/datasource/roles.go @@ -1,14 +1,18 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public +/* + * 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/. */ + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ -package proxmoxtf +package datasource import ( "context" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf" ) const ( @@ -17,7 +21,7 @@ const ( mkDataSourceVirtualEnvironmentRolesSpecial = "special" ) -func dataSourceVirtualEnvironmentRoles() *schema.Resource { +func Roles() *schema.Resource { return &schema.Resource{ Schema: map[string]*schema.Schema{ mkDataSourceVirtualEnvironmentRolesPrivileges: { @@ -42,18 +46,14 @@ func dataSourceVirtualEnvironmentRoles() *schema.Resource { Elem: &schema.Schema{Type: schema.TypeBool}, }, }, - ReadContext: dataSourceVirtualEnvironmentRolesRead, + ReadContext: rolesRead, } } -func dataSourceVirtualEnvironmentRolesRead( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { +func rolesRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { var diags diag.Diagnostics - config := m.(providerConfiguration) + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) diff --git a/proxmoxtf/datasource/roles_test.go b/proxmoxtf/datasource/roles_test.go new file mode 100644 index 00000000..b08b483b --- /dev/null +++ b/proxmoxtf/datasource/roles_test.go @@ -0,0 +1,43 @@ +/* + * 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 datasource + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf/test" +) + +// TestRolesInstantiation tests whether the Roles instance can be instantiated. +func TestRolesInstantiation(t *testing.T) { + t.Parallel() + s := Roles() + + if s == nil { + t.Fatalf("Cannot instantiate Roles") + } +} + +// TestRolesSchema tests the Roles schema. +func TestRolesSchema(t *testing.T) { + t.Parallel() + s := Roles() + + test.AssertComputedAttributes(t, s, []string{ + mkDataSourceVirtualEnvironmentRolesPrivileges, + mkDataSourceVirtualEnvironmentRolesRoleIDs, + mkDataSourceVirtualEnvironmentRolesSpecial, + }) + + test.AssertValueTypes(t, s, map[string]schema.ValueType{ + mkDataSourceVirtualEnvironmentRolesPrivileges: schema.TypeList, + mkDataSourceVirtualEnvironmentRolesRoleIDs: schema.TypeList, + mkDataSourceVirtualEnvironmentRolesSpecial: schema.TypeList, + }) +} diff --git a/proxmoxtf/data_source_virtual_environment_time.go b/proxmoxtf/datasource/time.go similarity index 83% rename from proxmoxtf/data_source_virtual_environment_time.go rename to proxmoxtf/datasource/time.go index d4fffdb3..e9249d58 100644 --- a/proxmoxtf/data_source_virtual_environment_time.go +++ b/proxmoxtf/datasource/time.go @@ -1,8 +1,10 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public +/* + * 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/. */ + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ -package proxmoxtf +package datasource import ( "context" @@ -11,6 +13,8 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf" ) const ( @@ -20,7 +24,7 @@ const ( mkDataSourceVirtualEnvironmentTimeUTCTime = "utc_time" ) -func dataSourceVirtualEnvironmentTime() *schema.Resource { +func Time() *schema.Resource { return &schema.Resource{ Schema: map[string]*schema.Schema{ mkDataSourceVirtualEnvironmentTimeLocalTime: { @@ -44,19 +48,14 @@ func dataSourceVirtualEnvironmentTime() *schema.Resource { Computed: true, }, }, - ReadContext: dataSourceVirtualEnvironmentTimeRead, + ReadContext: timeRead, } } -//nolint:dupl -func dataSourceVirtualEnvironmentTimeRead( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { +func timeRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { var diags diag.Diagnostics - config := m.(providerConfiguration) + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) diff --git a/proxmoxtf/datasource/time_test.go b/proxmoxtf/datasource/time_test.go new file mode 100644 index 00000000..7de3296d --- /dev/null +++ b/proxmoxtf/datasource/time_test.go @@ -0,0 +1,48 @@ +/* + * 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 datasource + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf/test" +) + +// TestTimeInstantiation tests whether the Roles instance can be instantiated. +func TestTimeInstantiation(t *testing.T) { + t.Parallel() + s := Time() + + if s == nil { + t.Fatalf("Cannot instantiate Time") + } +} + +// TestTimeSchema tests the Time schema. +func TestTimeSchema(t *testing.T) { + t.Parallel() + s := Time() + + test.AssertRequiredArguments(t, s, []string{ + mkDataSourceVirtualEnvironmentTimeNodeName, + }) + + test.AssertComputedAttributes(t, s, []string{ + mkDataSourceVirtualEnvironmentTimeLocalTime, + mkDataSourceVirtualEnvironmentTimeTimeZone, + mkDataSourceVirtualEnvironmentTimeUTCTime, + }) + + test.AssertValueTypes(t, s, map[string]schema.ValueType{ + mkDataSourceVirtualEnvironmentTimeLocalTime: schema.TypeString, + mkDataSourceVirtualEnvironmentTimeNodeName: schema.TypeString, + mkDataSourceVirtualEnvironmentTimeTimeZone: schema.TypeString, + mkDataSourceVirtualEnvironmentTimeUTCTime: schema.TypeString, + }) +} diff --git a/proxmoxtf/data_source_virtual_environment_user.go b/proxmoxtf/datasource/user.go similarity index 93% rename from proxmoxtf/data_source_virtual_environment_user.go rename to proxmoxtf/datasource/user.go index 171221af..7373433d 100644 --- a/proxmoxtf/data_source_virtual_environment_user.go +++ b/proxmoxtf/datasource/user.go @@ -1,8 +1,10 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public +/* + * 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/. */ + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ -package proxmoxtf +package datasource import ( "context" @@ -10,6 +12,8 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf" ) const ( @@ -28,7 +32,7 @@ const ( mkDataSourceVirtualEnvironmentUserUserID = "user_id" ) -func dataSourceVirtualEnvironmentUser() *schema.Resource { +func User() *schema.Resource { return &schema.Resource{ Schema: map[string]*schema.Schema{ mkDataSourceVirtualEnvironmentUserACL: { @@ -102,18 +106,14 @@ func dataSourceVirtualEnvironmentUser() *schema.Resource { Required: true, }, }, - ReadContext: dataSourceVirtualEnvironmentUserRead, + ReadContext: userRead, } } -func dataSourceVirtualEnvironmentUserRead( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { +func userRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { var diags diag.Diagnostics - config := m.(providerConfiguration) + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) diff --git a/proxmoxtf/data_source_virtual_environment_user_test.go b/proxmoxtf/datasource/user_test.go similarity index 62% rename from proxmoxtf/data_source_virtual_environment_user_test.go rename to proxmoxtf/datasource/user_test.go index 4fcd2ffd..4131e0af 100644 --- a/proxmoxtf/data_source_virtual_environment_user_test.go +++ b/proxmoxtf/datasource/user_test.go @@ -1,33 +1,39 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public +/* + * 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/. */ + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ -package proxmoxtf +package datasource import ( "testing" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf/test" ) -// TestDataSourceVirtualEnvironmentUserInstantiation tests whether the DataSourceVirtualEnvironmentUser instance can be instantiated. -func TestDataSourceVirtualEnvironmentUserInstantiation(t *testing.T) { - s := dataSourceVirtualEnvironmentUser() +// TestUserInstantiation tests whether the User instance can be instantiated. +func TestUserInstantiation(t *testing.T) { + t.Parallel() + s := User() if s == nil { - t.Fatalf("Cannot instantiate dataSourceVirtualEnvironmentUser") + t.Fatalf("Cannot instantiate User") } } -// TestDataSourceVirtualEnvironmentUserSchema tests the dataSourceVirtualEnvironmentUser schema. -func TestDataSourceVirtualEnvironmentUserSchema(t *testing.T) { - s := dataSourceVirtualEnvironmentUser() +// TestUserSchema tests the User schema. +func TestUserSchema(t *testing.T) { + t.Parallel() + s := User() - testRequiredArguments(t, s, []string{ + test.AssertRequiredArguments(t, s, []string{ mkDataSourceVirtualEnvironmentUserUserID, }) - testComputedAttributes(t, s, []string{ + test.AssertComputedAttributes(t, s, []string{ mkDataSourceVirtualEnvironmentUserACL, mkDataSourceVirtualEnvironmentUserComment, mkDataSourceVirtualEnvironmentUserEmail, @@ -39,7 +45,7 @@ func TestDataSourceVirtualEnvironmentUserSchema(t *testing.T) { mkDataSourceVirtualEnvironmentUserLastName, }) - testValueTypes(t, s, map[string]schema.ValueType{ + test.AssertValueTypes(t, s, map[string]schema.ValueType{ mkDataSourceVirtualEnvironmentUserACL: schema.TypeSet, mkDataSourceVirtualEnvironmentUserComment: schema.TypeString, mkDataSourceVirtualEnvironmentUserEmail: schema.TypeString, @@ -51,15 +57,15 @@ func TestDataSourceVirtualEnvironmentUserSchema(t *testing.T) { mkDataSourceVirtualEnvironmentUserLastName: schema.TypeString, }) - aclSchema := testNestedSchemaExistence(t, s, mkDataSourceVirtualEnvironmentGroupACL) + aclSchema := test.AssertNestedSchemaExistence(t, s, mkDataSourceVirtualEnvironmentGroupACL) - testComputedAttributes(t, aclSchema, []string{ + test.AssertComputedAttributes(t, aclSchema, []string{ mkDataSourceVirtualEnvironmentUserACLPath, mkDataSourceVirtualEnvironmentUserACLPropagate, mkDataSourceVirtualEnvironmentUserACLRoleID, }) - testValueTypes(t, aclSchema, map[string]schema.ValueType{ + test.AssertValueTypes(t, aclSchema, map[string]schema.ValueType{ mkDataSourceVirtualEnvironmentUserACLPath: schema.TypeString, mkDataSourceVirtualEnvironmentUserACLPropagate: schema.TypeBool, mkDataSourceVirtualEnvironmentUserACLRoleID: schema.TypeString, diff --git a/proxmoxtf/data_source_virtual_environment_users.go b/proxmoxtf/datasource/users.go similarity index 92% rename from proxmoxtf/data_source_virtual_environment_users.go rename to proxmoxtf/datasource/users.go index 87d1a563..6e178c2e 100644 --- a/proxmoxtf/data_source_virtual_environment_users.go +++ b/proxmoxtf/datasource/users.go @@ -1,8 +1,10 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public +/* + * 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/. */ + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ -package proxmoxtf +package datasource import ( "context" @@ -10,6 +12,8 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf" ) const ( @@ -24,7 +28,7 @@ const ( mkDataSourceVirtualEnvironmentUsersUserIDs = "user_ids" ) -func dataSourceVirtualEnvironmentUsers() *schema.Resource { +func Users() *schema.Resource { return &schema.Resource{ Schema: map[string]*schema.Schema{ mkDataSourceVirtualEnvironmentUsersComments: { @@ -85,18 +89,14 @@ func dataSourceVirtualEnvironmentUsers() *schema.Resource { Elem: &schema.Schema{Type: schema.TypeString}, }, }, - ReadContext: dataSourceVirtualEnvironmentUsersRead, + ReadContext: usersRead, } } -func dataSourceVirtualEnvironmentUsersRead( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { +func usersRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { var diags diag.Diagnostics - config := m.(providerConfiguration) + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) diff --git a/proxmoxtf/data_source_virtual_environment_users_test.go b/proxmoxtf/datasource/users_test.go similarity index 62% rename from proxmoxtf/data_source_virtual_environment_users_test.go rename to proxmoxtf/datasource/users_test.go index 9a25412d..503fb488 100644 --- a/proxmoxtf/data_source_virtual_environment_users_test.go +++ b/proxmoxtf/datasource/users_test.go @@ -1,29 +1,35 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public +/* + * 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/. */ + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ -package proxmoxtf +package datasource import ( "testing" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf/test" ) -// TestDataSourceVirtualEnvironmentUsersInstantiation tests whether the DataSourceVirtualEnvironmentUsers instance can be instantiated. -func TestDataSourceVirtualEnvironmentUsersInstantiation(t *testing.T) { - s := dataSourceVirtualEnvironmentUsers() +// TestUsersInstantiation tests whether the Users instance can be instantiated. +func TestUsersInstantiation(t *testing.T) { + t.Parallel() + s := Users() if s == nil { - t.Fatalf("Cannot instantiate dataSourceVirtualEnvironmentUsers") + t.Fatalf("Cannot instantiate Users") } } -// TestDataSourceVirtualEnvironmentUsersSchema tests the dataSourceVirtualEnvironmentUsers schema. -func TestDataSourceVirtualEnvironmentUsersSchema(t *testing.T) { - s := dataSourceVirtualEnvironmentUsers() +// TestUsersSchema tests the Users schema. +func TestUsersSchema(t *testing.T) { + t.Parallel() + s := Users() - testComputedAttributes(t, s, []string{ + test.AssertComputedAttributes(t, s, []string{ mkDataSourceVirtualEnvironmentUsersComments, mkDataSourceVirtualEnvironmentUsersEmails, mkDataSourceVirtualEnvironmentUsersEnabled, @@ -35,7 +41,7 @@ func TestDataSourceVirtualEnvironmentUsersSchema(t *testing.T) { mkDataSourceVirtualEnvironmentUsersUserIDs, }) - testValueTypes(t, s, map[string]schema.ValueType{ + test.AssertValueTypes(t, s, map[string]schema.ValueType{ mkDataSourceVirtualEnvironmentUsersComments: schema.TypeList, mkDataSourceVirtualEnvironmentUsersEmails: schema.TypeList, mkDataSourceVirtualEnvironmentUsersEnabled: schema.TypeList, diff --git a/proxmoxtf/data_source_virtual_environment_version.go b/proxmoxtf/datasource/version.go similarity index 82% rename from proxmoxtf/data_source_virtual_environment_version.go rename to proxmoxtf/datasource/version.go index feb41306..b9cd9f7c 100644 --- a/proxmoxtf/data_source_virtual_environment_version.go +++ b/proxmoxtf/datasource/version.go @@ -1,14 +1,18 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public +/* + * 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/. */ + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ -package proxmoxtf +package datasource import ( "context" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf" ) const ( @@ -18,7 +22,7 @@ const ( mkDataSourceVirtualEnvironmentVersionVersion = "version" ) -func dataSourceVirtualEnvironmentVersion() *schema.Resource { +func Version() *schema.Resource { return &schema.Resource{ Schema: map[string]*schema.Schema{ mkDataSourceVirtualEnvironmentVersionKeyboardLayout: { @@ -46,18 +50,14 @@ func dataSourceVirtualEnvironmentVersion() *schema.Resource { ForceNew: true, }, }, - ReadContext: dataSourceVirtualEnvironmentVersionRead, + ReadContext: versionRead, } } -func dataSourceVirtualEnvironmentVersionRead( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { +func versionRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { var diags diag.Diagnostics - config := m.(providerConfiguration) + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) diff --git a/proxmoxtf/datasource/version_test.go b/proxmoxtf/datasource/version_test.go new file mode 100644 index 00000000..f088b103 --- /dev/null +++ b/proxmoxtf/datasource/version_test.go @@ -0,0 +1,45 @@ +/* + * 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 datasource + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf/test" +) + +// TestVersionInstantiation tests whether the Version instance can be instantiated. +func TestVersionInstantiation(t *testing.T) { + t.Parallel() + s := Version() + + if s == nil { + t.Fatalf("Cannot instantiate Version") + } +} + +// TestVersionSchema tests the Version schema. +func TestVersionSchema(t *testing.T) { + t.Parallel() + s := Version() + + test.AssertComputedAttributes(t, s, []string{ + mkDataSourceVirtualEnvironmentVersionKeyboardLayout, + mkDataSourceVirtualEnvironmentVersionRelease, + mkDataSourceVirtualEnvironmentVersionRepositoryID, + mkDataSourceVirtualEnvironmentVersionVersion, + }) + + test.AssertValueTypes(t, s, map[string]schema.ValueType{ + mkDataSourceVirtualEnvironmentVersionKeyboardLayout: schema.TypeString, + mkDataSourceVirtualEnvironmentVersionRelease: schema.TypeString, + mkDataSourceVirtualEnvironmentVersionRepositoryID: schema.TypeString, + mkDataSourceVirtualEnvironmentVersionVersion: schema.TypeString, + }) +} diff --git a/proxmoxtf/data_source_virtual_environment_vm.go b/proxmoxtf/datasource/vm.go similarity index 82% rename from proxmoxtf/data_source_virtual_environment_vm.go rename to proxmoxtf/datasource/vm.go index 9a78f9e9..aff7ca34 100644 --- a/proxmoxtf/data_source_virtual_environment_vm.go +++ b/proxmoxtf/datasource/vm.go @@ -1,8 +1,10 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public +/* + * 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/. */ + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ -package proxmoxtf +package datasource import ( "context" @@ -12,6 +14,8 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf" ) const ( @@ -21,7 +25,7 @@ const ( mkDataSourceVirtualEnvironmentVMVMID = "vm_id" ) -func dataSourceVirtualEnvironmentVM() *schema.Resource { +func VM() *schema.Resource { return &schema.Resource{ Schema: map[string]*schema.Schema{ mkDataSourceVirtualEnvironmentVMName: { @@ -46,15 +50,15 @@ func dataSourceVirtualEnvironmentVM() *schema.Resource { Required: true, }, }, - ReadContext: dataSourceVirtualEnvironmentVMRead, + ReadContext: vmRead, } } -// dataSourceVirtualEnvironmentVMRead reads the data of a VM by ID. -func dataSourceVirtualEnvironmentVMRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { +// vmRead reads the data of a VM by ID. +func vmRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { var diags diag.Diagnostics - config := m.(providerConfiguration) + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) diff --git a/proxmoxtf/datasource/vm_test.go b/proxmoxtf/datasource/vm_test.go new file mode 100644 index 00000000..4c030050 --- /dev/null +++ b/proxmoxtf/datasource/vm_test.go @@ -0,0 +1,45 @@ +/* + * 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 datasource + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf/test" +) + +// TestVMInstantiation tests whether the VM instance can be instantiated. +func TestVMInstantiation(t *testing.T) { + t.Parallel() + + s := VM() + + if s == nil { + t.Fatalf("Cannot instantiate VM") + } +} + +// TestVMSchema tests the VM schema. +func TestVMSchema(t *testing.T) { + t.Parallel() + + s := VM() + + test.AssertComputedAttributes(t, s, []string{ + mkDataSourceVirtualEnvironmentVMName, + mkDataSourceVirtualEnvironmentVMTags, + }) + + test.AssertValueTypes(t, s, map[string]schema.ValueType{ + mkDataSourceVirtualEnvironmentVMName: schema.TypeString, + mkDataSourceVirtualEnvironmentVMNodeName: schema.TypeString, + mkDataSourceVirtualEnvironmentVMTags: schema.TypeList, + mkDataSourceVirtualEnvironmentVMVMID: schema.TypeInt, + }) +} diff --git a/proxmoxtf/data_source_virtual_environment_vms.go b/proxmoxtf/datasource/vms.go similarity index 83% rename from proxmoxtf/data_source_virtual_environment_vms.go rename to proxmoxtf/datasource/vms.go index 696c40d0..400d2569 100644 --- a/proxmoxtf/data_source_virtual_environment_vms.go +++ b/proxmoxtf/datasource/vms.go @@ -1,8 +1,10 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public +/* + * 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/. */ + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ -package proxmoxtf +package datasource import ( "context" @@ -16,13 +18,14 @@ import ( "golang.org/x/exp/slices" "github.com/bpg/terraform-provider-proxmox/proxmox" + "github.com/bpg/terraform-provider-proxmox/proxmoxtf" ) const ( mkDataSourceVirtualEnvironmentVMs = "vms" ) -func dataSourceVirtualEnvironmentVMs() *schema.Resource { +func VMs() *schema.Resource { return &schema.Resource{ Schema: map[string]*schema.Schema{ mkDataSourceVirtualEnvironmentVMNodeName: { @@ -41,19 +44,19 @@ func dataSourceVirtualEnvironmentVMs() *schema.Resource { Description: "VMs", Computed: true, Elem: &schema.Resource{ - Schema: dataSourceVirtualEnvironmentVM().Schema, + Schema: VM().Schema, }, }, }, - ReadContext: dataSourceVirtualEnvironmentVMsRead, + ReadContext: vmsRead, } } -// dataSourceVirtualEnvironmentVMRead reads the data of a VM by ID. -func dataSourceVirtualEnvironmentVMsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { +// vmRead reads the data of a VM by ID. +func vmsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { var diags diag.Diagnostics - config := m.(providerConfiguration) + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) @@ -64,7 +67,7 @@ func dataSourceVirtualEnvironmentVMsRead(ctx context.Context, d *schema.Resource return diag.FromErr(err) } - tagsData := d.Get(mkResourceVirtualEnvironmentVMTags).([]interface{}) + tagsData := d.Get(mkDataSourceVirtualEnvironmentVMTags).([]interface{}) var filterTags []string for i := 0; i < len(tagsData); i++ { tag := strings.TrimSpace(tagsData[i].(string)) diff --git a/proxmoxtf/datasource/vms_test.go b/proxmoxtf/datasource/vms_test.go new file mode 100644 index 00000000..e30caa56 --- /dev/null +++ b/proxmoxtf/datasource/vms_test.go @@ -0,0 +1,57 @@ +/* + * 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 datasource + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf/test" +) + +// TestVMsInstantiation tests whether the dataSourceVirtualEnvironmentVMs instance can be instantiated. +func TestVMsInstantiation(t *testing.T) { + t.Parallel() + + s := VMs() + + if s == nil { + t.Fatalf("Cannot instantiate dataSourceVirtualEnvironmentVMs") + } +} + +// TestVMsSchema tests the dataSourceVirtualEnvironmentVMs schema. +func TestVMsSchema(t *testing.T) { + t.Parallel() + + s := VMs() + + test.AssertComputedAttributes(t, s, []string{ + mkDataSourceVirtualEnvironmentVMs, + }) + + test.AssertValueTypes(t, s, map[string]schema.ValueType{ + mkDataSourceVirtualEnvironmentVMNodeName: schema.TypeString, + mkDataSourceVirtualEnvironmentVMTags: schema.TypeList, + mkDataSourceVirtualEnvironmentVMs: schema.TypeList, + }) + + vmsSchema := test.AssertNestedSchemaExistence(t, s, mkDataSourceVirtualEnvironmentVMs) + + test.AssertComputedAttributes(t, vmsSchema, []string{ + mkDataSourceVirtualEnvironmentVMName, + mkDataSourceVirtualEnvironmentVMTags, + }) + + test.AssertValueTypes(t, vmsSchema, map[string]schema.ValueType{ + mkDataSourceVirtualEnvironmentVMName: schema.TypeString, + mkDataSourceVirtualEnvironmentVMNodeName: schema.TypeString, + mkDataSourceVirtualEnvironmentVMTags: schema.TypeList, + mkDataSourceVirtualEnvironmentVMVMID: schema.TypeInt, + }) +} diff --git a/proxmoxtf/provider.go b/proxmoxtf/provider.go deleted file mode 100644 index 2868534e..00000000 --- a/proxmoxtf/provider.go +++ /dev/null @@ -1,227 +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" - "errors" - "net/url" - "os" - - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - - "github.com/bpg/terraform-provider-proxmox/proxmox" -) - -const ( - dvProviderVirtualEnvironmentEndpoint = "" - dvProviderVirtualEnvironmentOTP = "" - dvProviderVirtualEnvironmentPassword = "" - dvProviderVirtualEnvironmentUsername = "" - - mkProviderVirtualEnvironment = "virtual_environment" - mkProviderVirtualEnvironmentEndpoint = "endpoint" - mkProviderVirtualEnvironmentInsecure = "insecure" - mkProviderVirtualEnvironmentOTP = "otp" - mkProviderVirtualEnvironmentPassword = "password" - mkProviderVirtualEnvironmentUsername = "username" -) - -type providerConfiguration struct { - veClient *proxmox.VirtualEnvironmentClient -} - -// Provider returns the object for this provider. -func Provider() *schema.Provider { - return &schema.Provider{ - ConfigureContextFunc: providerConfigure, - DataSourcesMap: map[string]*schema.Resource{ - "proxmox_virtual_environment_cluster_alias": dataSourceVirtualEnvironmentClusterAlias(), - "proxmox_virtual_environment_cluster_aliases": dataSourceVirtualEnvironmentClusterAliases(), - "proxmox_virtual_environment_datastores": dataSourceVirtualEnvironmentDatastores(), - "proxmox_virtual_environment_dns": dataSourceVirtualEnvironmentDNS(), - "proxmox_virtual_environment_group": dataSourceVirtualEnvironmentGroup(), - "proxmox_virtual_environment_groups": dataSourceVirtualEnvironmentGroups(), - "proxmox_virtual_environment_hosts": dataSourceVirtualEnvironmentHosts(), - "proxmox_virtual_environment_nodes": dataSourceVirtualEnvironmentNodes(), - "proxmox_virtual_environment_pool": dataSourceVirtualEnvironmentPool(), - "proxmox_virtual_environment_pools": dataSourceVirtualEnvironmentPools(), - "proxmox_virtual_environment_role": dataSourceVirtualEnvironmentRole(), - "proxmox_virtual_environment_roles": dataSourceVirtualEnvironmentRoles(), - "proxmox_virtual_environment_time": dataSourceVirtualEnvironmentTime(), - "proxmox_virtual_environment_user": dataSourceVirtualEnvironmentUser(), - "proxmox_virtual_environment_users": dataSourceVirtualEnvironmentUsers(), - "proxmox_virtual_environment_version": dataSourceVirtualEnvironmentVersion(), - "proxmox_virtual_environment_vm": dataSourceVirtualEnvironmentVM(), - "proxmox_virtual_environment_vms": dataSourceVirtualEnvironmentVMs(), - }, - ResourcesMap: map[string]*schema.Resource{ - "proxmox_virtual_environment_certificate": resourceVirtualEnvironmentCertificate(), - "proxmox_virtual_environment_cluster_alias": resourceVirtualEnvironmentClusterAlias(), - "proxmox_virtual_environment_cluster_ipset": resourceVirtualEnvironmentClusterIPSet(), - "proxmox_virtual_environment_container": resourceVirtualEnvironmentContainer(), - "proxmox_virtual_environment_dns": resourceVirtualEnvironmentDNS(), - "proxmox_virtual_environment_file": resourceVirtualEnvironmentFile(), - "proxmox_virtual_environment_group": resourceVirtualEnvironmentGroup(), - "proxmox_virtual_environment_hosts": resourceVirtualEnvironmentHosts(), - "proxmox_virtual_environment_pool": resourceVirtualEnvironmentPool(), - "proxmox_virtual_environment_role": resourceVirtualEnvironmentRole(), - "proxmox_virtual_environment_time": resourceVirtualEnvironmentTime(), - "proxmox_virtual_environment_user": resourceVirtualEnvironmentUser(), - "proxmox_virtual_environment_vm": resourceVirtualEnvironmentVM(), - }, - Schema: map[string]*schema.Schema{ - mkProviderVirtualEnvironment: { - Type: schema.TypeList, - Optional: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - mkProviderVirtualEnvironmentEndpoint: { - Type: schema.TypeString, - Optional: true, - Description: "The endpoint for the Proxmox Virtual Environment API", - DefaultFunc: schema.MultiEnvDefaultFunc( - []string{"PROXMOX_VE_ENDPOINT", "PM_VE_ENDPOINT"}, - dvProviderVirtualEnvironmentEndpoint, - ), - ValidateFunc: func(v interface{}, k string) (warns []string, errs []error) { - value := v.(string) - - if value == "" { - return []string{}, []error{ - errors.New( - "you must specify an endpoint for the Proxmox Virtual Environment API (valid: https://host:port)", - ), - } - } - - _, err := url.ParseRequestURI(value) - if err != nil { - return []string{}, []error{ - errors.New( - "you must specify a valid endpoint for the Proxmox Virtual Environment API (valid: https://host:port)", - ), - } - } - - return []string{}, []error{} - }, - }, - mkProviderVirtualEnvironmentInsecure: { - Type: schema.TypeBool, - Optional: true, - Description: "Whether to skip the TLS verification step", - DefaultFunc: func() (interface{}, error) { - for _, k := range []string{"PROXMOX_VE_INSECURE", "PM_VE_INSECURE"} { - v := os.Getenv(k) - - if v == "true" || v == "1" { - return true, nil - } - } - - return false, nil - }, - }, - mkProviderVirtualEnvironmentOTP: { - Type: schema.TypeString, - Optional: true, - Description: "The one-time password for the Proxmox Virtual Environment API", - DefaultFunc: schema.MultiEnvDefaultFunc( - []string{"PROXMOX_VE_OTP", "PM_VE_OTP"}, - dvProviderVirtualEnvironmentOTP, - ), - }, - mkProviderVirtualEnvironmentPassword: { - Type: schema.TypeString, - Optional: true, - Description: "The password for the Proxmox Virtual Environment API", - DefaultFunc: schema.MultiEnvDefaultFunc( - []string{"PROXMOX_VE_PASSWORD", "PM_VE_PASSWORD"}, - dvProviderVirtualEnvironmentPassword, - ), - ValidateFunc: func(v interface{}, k string) (warns []string, errs []error) { - value := v.(string) - - if value == "" { - return []string{}, []error{ - errors.New( - "you must specify a password for the Proxmox Virtual Environment API", - ), - } - } - - return []string{}, []error{} - }, - }, - mkProviderVirtualEnvironmentUsername: { - Type: schema.TypeString, - Optional: true, - Description: "The username for the Proxmox Virtual Environment API", - DefaultFunc: schema.MultiEnvDefaultFunc( - []string{"PROXMOX_VE_USERNAME", "PM_VE_USERNAME"}, - dvProviderVirtualEnvironmentUsername, - ), - ValidateFunc: func(v interface{}, k string) (warns []string, errs []error) { - value := v.(string) - - if value == "" { - return []string{}, []error{ - errors.New( - "you must specify a username for the Proxmox Virtual Environment API (valid: username@realm)", - ), - } - } - - return []string{}, []error{} - }, - }, - }, - }, - MaxItems: 1, - }, - }, - } -} - -func providerConfigure(_ context.Context, d *schema.ResourceData) (interface{}, diag.Diagnostics) { - var err error - var veClient *proxmox.VirtualEnvironmentClient - - // Initialize the client for the Virtual Environment, if required. - veConfigBlock := d.Get(mkProviderVirtualEnvironment).([]interface{}) - - if len(veConfigBlock) > 0 { - veConfig := veConfigBlock[0].(map[string]interface{}) - - veClient, err = proxmox.NewVirtualEnvironmentClient( - veConfig[mkProviderVirtualEnvironmentEndpoint].(string), - veConfig[mkProviderVirtualEnvironmentUsername].(string), - veConfig[mkProviderVirtualEnvironmentPassword].(string), - veConfig[mkProviderVirtualEnvironmentOTP].(string), - veConfig[mkProviderVirtualEnvironmentInsecure].(bool), - ) - if err != nil { - return nil, diag.FromErr(err) - } - } - - config := providerConfiguration{ - veClient: veClient, - } - - return config, nil -} - -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 -} diff --git a/proxmoxtf/provider/datasources.go b/proxmoxtf/provider/datasources.go new file mode 100644 index 00000000..60cb7a23 --- /dev/null +++ b/proxmoxtf/provider/datasources.go @@ -0,0 +1,34 @@ +/* + * 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 provider + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf/datasource" +) + +func createDatasourceMap() map[string]*schema.Resource { + return map[string]*schema.Resource{ + "proxmox_virtual_environment_datastores": datasource.Datastores(), + "proxmox_virtual_environment_dns": datasource.DNS(), + "proxmox_virtual_environment_group": datasource.Group(), + "proxmox_virtual_environment_groups": datasource.Groups(), + "proxmox_virtual_environment_hosts": datasource.Hosts(), + "proxmox_virtual_environment_nodes": datasource.Nodes(), + "proxmox_virtual_environment_pool": datasource.Pool(), + "proxmox_virtual_environment_pools": datasource.Pools(), + "proxmox_virtual_environment_role": datasource.Role(), + "proxmox_virtual_environment_roles": datasource.Roles(), + "proxmox_virtual_environment_time": datasource.Time(), + "proxmox_virtual_environment_user": datasource.User(), + "proxmox_virtual_environment_users": datasource.Users(), + "proxmox_virtual_environment_version": datasource.Version(), + "proxmox_virtual_environment_vm": datasource.VM(), + "proxmox_virtual_environment_vms": datasource.VMs(), + } +} diff --git a/proxmoxtf/provider/provider.go b/proxmoxtf/provider/provider.go new file mode 100644 index 00000000..8daf1f86 --- /dev/null +++ b/proxmoxtf/provider/provider.go @@ -0,0 +1,68 @@ +/* + * 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 provider + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmox" + "github.com/bpg/terraform-provider-proxmox/proxmoxtf" +) + +const ( + dvProviderVirtualEnvironmentEndpoint = "" + dvProviderVirtualEnvironmentOTP = "" + dvProviderVirtualEnvironmentPassword = "" + dvProviderVirtualEnvironmentUsername = "" + + mkProviderVirtualEnvironment = "virtual_environment" + mkProviderVirtualEnvironmentEndpoint = "endpoint" + mkProviderVirtualEnvironmentInsecure = "insecure" + mkProviderVirtualEnvironmentOTP = "otp" + mkProviderVirtualEnvironmentPassword = "password" + mkProviderVirtualEnvironmentUsername = "username" +) + +// ProxmoxVirtualEnvironment returns the object for this provider. +func ProxmoxVirtualEnvironment() *schema.Provider { + return &schema.Provider{ + ConfigureContextFunc: providerConfigure, + DataSourcesMap: createDatasourceMap(), + ResourcesMap: createResourceMap(), + Schema: createSchema(), + } +} + +func providerConfigure(_ context.Context, d *schema.ResourceData) (interface{}, diag.Diagnostics) { + var err error + var veClient *proxmox.VirtualEnvironmentClient + + // Initialize the client for the Virtual Environment, if required. + veConfigBlock := d.Get(mkProviderVirtualEnvironment).([]interface{}) + + if len(veConfigBlock) > 0 { + veConfig := veConfigBlock[0].(map[string]interface{}) + + veClient, err = proxmox.NewVirtualEnvironmentClient( + veConfig[mkProviderVirtualEnvironmentEndpoint].(string), + veConfig[mkProviderVirtualEnvironmentUsername].(string), + veConfig[mkProviderVirtualEnvironmentPassword].(string), + veConfig[mkProviderVirtualEnvironmentOTP].(string), + veConfig[mkProviderVirtualEnvironmentInsecure].(bool), + ) + if err != nil { + return nil, diag.FromErr(err) + } + } + + config := proxmoxtf.NewProviderConfiguration(veClient) + + return config, nil +} diff --git a/proxmoxtf/provider_test.go b/proxmoxtf/provider/provider_test.go similarity index 51% rename from proxmoxtf/provider_test.go rename to proxmoxtf/provider/provider_test.go index e1064806..fd68ba31 100644 --- a/proxmoxtf/provider_test.go +++ b/proxmoxtf/provider/provider_test.go @@ -1,41 +1,47 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public +/* + * 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/. */ + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ -package proxmoxtf +package provider import ( "testing" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf/test" ) -// TestProviderInstantiation() tests whether the Provider instance can be instantiated. +// TestProviderInstantiation() tests whether the ProxmoxVirtualEnvironment instance can be instantiated. func TestProviderInstantiation(t *testing.T) { - s := Provider() + t.Parallel() + s := ProxmoxVirtualEnvironment() if s == nil { - t.Fatalf("Cannot instantiate Provider") + t.Fatalf("Cannot instantiate ProxmoxVirtualEnvironment") } } -// TestProviderSchema() tests the Provider schema. +// TestProviderSchema() tests the ProxmoxVirtualEnvironment schema. func TestProviderSchema(t *testing.T) { + t.Parallel() s := &schema.Resource{ - Schema: Provider().Schema, + Schema: ProxmoxVirtualEnvironment().Schema, } - testOptionalArguments(t, s, []string{ + test.AssertOptionalArguments(t, s, []string{ mkProviderVirtualEnvironment, }) - testValueTypes(t, s, map[string]schema.ValueType{ + test.AssertValueTypes(t, s, map[string]schema.ValueType{ mkProviderVirtualEnvironment: schema.TypeList, }) - veSchema := testNestedSchemaExistence(t, s, mkProviderVirtualEnvironment) + veSchema := test.AssertNestedSchemaExistence(t, s, mkProviderVirtualEnvironment) - testOptionalArguments(t, veSchema, []string{ + test.AssertOptionalArguments(t, veSchema, []string{ mkProviderVirtualEnvironmentEndpoint, mkProviderVirtualEnvironmentInsecure, mkProviderVirtualEnvironmentOTP, @@ -43,7 +49,7 @@ func TestProviderSchema(t *testing.T) { mkProviderVirtualEnvironmentUsername, }) - testValueTypes(t, veSchema, map[string]schema.ValueType{ + test.AssertValueTypes(t, veSchema, map[string]schema.ValueType{ mkProviderVirtualEnvironmentEndpoint: schema.TypeString, mkProviderVirtualEnvironmentInsecure: schema.TypeBool, mkProviderVirtualEnvironmentOTP: schema.TypeString, diff --git a/proxmoxtf/provider/resources.go b/proxmoxtf/provider/resources.go new file mode 100644 index 00000000..19fa1001 --- /dev/null +++ b/proxmoxtf/provider/resources.go @@ -0,0 +1,37 @@ +/* + * 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 provider + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf/resource" + clusterfirewall "github.com/bpg/terraform-provider-proxmox/proxmoxtf/resource/cluster/firewall" + "github.com/bpg/terraform-provider-proxmox/proxmoxtf/resource/firewall" +) + +func createResourceMap() map[string]*schema.Resource { + return map[string]*schema.Resource{ + "proxmox_virtual_environment_certificate": resource.Certificate(), + "proxmox_virtual_environment_firewall_alias": firewall.Alias(), + "proxmox_virtual_environment_firewall_ipset": firewall.IPSet(), + "proxmox_virtual_environment_firewall_rules": firewall.Rules(), + "proxmox_virtual_environment_firewall_options": firewall.Options(), + "proxmox_virtual_environment_cluster_firewall_security_group": clusterfirewall.SecurityGroup(), + "proxmox_virtual_environment_cluster_firewall": clusterfirewall.Firewall(), + "proxmox_virtual_environment_container": resource.Container(), + "proxmox_virtual_environment_dns": resource.DNS(), + "proxmox_virtual_environment_file": resource.File(), + "proxmox_virtual_environment_group": resource.Group(), + "proxmox_virtual_environment_hosts": resource.Hosts(), + "proxmox_virtual_environment_pool": resource.Pool(), + "proxmox_virtual_environment_role": resource.Role(), + "proxmox_virtual_environment_time": resource.Time(), + "proxmox_virtual_environment_user": resource.User(), + "proxmox_virtual_environment_vm": resource.VM(), + } +} diff --git a/proxmoxtf/provider/schema.go b/proxmoxtf/provider/schema.go new file mode 100644 index 00000000..2f3c19a4 --- /dev/null +++ b/proxmoxtf/provider/schema.go @@ -0,0 +1,129 @@ +/* + * 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 provider + +import ( + "errors" + "net/url" + "os" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func createSchema() map[string]*schema.Schema { + return map[string]*schema.Schema{ + mkProviderVirtualEnvironment: { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + mkProviderVirtualEnvironmentEndpoint: { + Type: schema.TypeString, + Optional: true, + Description: "The endpoint for the Proxmox Virtual Environment API", + DefaultFunc: schema.MultiEnvDefaultFunc( + []string{"PROXMOX_VE_ENDPOINT", "PM_VE_ENDPOINT"}, + dvProviderVirtualEnvironmentEndpoint, + ), + ValidateFunc: func(v interface{}, k string) (warns []string, errs []error) { + value := v.(string) + + if value == "" { + return []string{}, []error{ + errors.New( + "you must specify an endpoint for the Proxmox Virtual Environment API (valid: https://host:port)", + ), + } + } + + _, err := url.ParseRequestURI(value) + if err != nil { + return []string{}, []error{ + errors.New( + "you must specify a valid endpoint for the Proxmox Virtual Environment API (valid: https://host:port)", + ), + } + } + + return []string{}, []error{} + }, + }, + mkProviderVirtualEnvironmentInsecure: { + Type: schema.TypeBool, + Optional: true, + Description: "Whether to skip the TLS verification step", + DefaultFunc: func() (interface{}, error) { + for _, k := range []string{"PROXMOX_VE_INSECURE", "PM_VE_INSECURE"} { + v := os.Getenv(k) + + if v == "true" || v == "1" { + return true, nil + } + } + + return false, nil + }, + }, + mkProviderVirtualEnvironmentOTP: { + Type: schema.TypeString, + Optional: true, + Description: "The one-time password for the Proxmox Virtual Environment API", + DefaultFunc: schema.MultiEnvDefaultFunc( + []string{"PROXMOX_VE_OTP", "PM_VE_OTP"}, + dvProviderVirtualEnvironmentOTP, + ), + }, + mkProviderVirtualEnvironmentPassword: { + Type: schema.TypeString, + Optional: true, + Description: "The password for the Proxmox Virtual Environment API", + DefaultFunc: schema.MultiEnvDefaultFunc( + []string{"PROXMOX_VE_PASSWORD", "PM_VE_PASSWORD"}, + dvProviderVirtualEnvironmentPassword, + ), + ValidateFunc: func(v interface{}, k string) (warns []string, errs []error) { + value := v.(string) + + if value == "" { + return []string{}, []error{ + errors.New( + "you must specify a password for the Proxmox Virtual Environment API", + ), + } + } + + return []string{}, []error{} + }, + }, + mkProviderVirtualEnvironmentUsername: { + Type: schema.TypeString, + Optional: true, + Description: "The username for the Proxmox Virtual Environment API", + DefaultFunc: schema.MultiEnvDefaultFunc( + []string{"PROXMOX_VE_USERNAME", "PM_VE_USERNAME"}, + dvProviderVirtualEnvironmentUsername, + ), + ValidateFunc: func(v interface{}, k string) (warns []string, errs []error) { + value := v.(string) + + if value == "" { + return []string{}, []error{ + errors.New( + "you must specify a username for the Proxmox Virtual Environment API (valid: username@realm)", + ), + } + } + + return []string{}, []error{} + }, + }, + }, + }, + MaxItems: 1, + }, + } +} diff --git a/proxmoxtf/resource_virtual_environment_certificate.go b/proxmoxtf/resource/certificate.go similarity index 85% rename from proxmoxtf/resource_virtual_environment_certificate.go rename to proxmoxtf/resource/certificate.go index 9db9976e..b968db06 100644 --- a/proxmoxtf/resource_virtual_environment_certificate.go +++ b/proxmoxtf/resource/certificate.go @@ -1,8 +1,10 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public +/* + * 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/. */ + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ -package proxmoxtf +package resource import ( "context" @@ -14,6 +16,8 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/bpg/terraform-provider-proxmox/proxmox" + "github.com/bpg/terraform-provider-proxmox/proxmox/types" + "github.com/bpg/terraform-provider-proxmox/proxmoxtf" ) const ( @@ -36,7 +40,7 @@ const ( mkResourceVirtualEnvironmentCertificateSubjectAlternativeNames = "subject_alternative_names" ) -func resourceVirtualEnvironmentCertificate() *schema.Resource { +func Certificate() *schema.Resource { return &schema.Resource{ Schema: map[string]*schema.Schema{ mkResourceVirtualEnvironmentCertificateCertificate: { @@ -115,19 +119,15 @@ func resourceVirtualEnvironmentCertificate() *schema.Resource { Elem: &schema.Schema{Type: schema.TypeString}, }, }, - CreateContext: resourceVirtualEnvironmentCertificateCreate, - ReadContext: resourceVirtualEnvironmentCertificateRead, - UpdateContext: resourceVirtualEnvironmentCertificateUpdate, - DeleteContext: resourceVirtualEnvironmentCertificateDelete, + CreateContext: certificateCreate, + ReadContext: certificateRead, + UpdateContext: certificateUpdate, + DeleteContext: certificateDelete, } } -func resourceVirtualEnvironmentCertificateCreate( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { - diags := resourceVirtualEnvironmentCertificateUpdate(ctx, d, m) +func certificateCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + diags := certificateUpdate(ctx, d, m) if diags.HasError() { return diags } @@ -139,12 +139,10 @@ func resourceVirtualEnvironmentCertificateCreate( return nil } -func resourceVirtualEnvironmentCertificateGetUpdateBody( - d *schema.ResourceData, -) *proxmox.VirtualEnvironmentCertificateUpdateRequestBody { +func certificateGetUpdateBody(d *schema.ResourceData) *proxmox.VirtualEnvironmentCertificateUpdateRequestBody { certificate := d.Get(mkResourceVirtualEnvironmentCertificateCertificate).(string) certificateChain := d.Get(mkResourceVirtualEnvironmentCertificateCertificateChain).(string) - overwrite := proxmox.CustomBool(d.Get(mkResourceVirtualEnvironmentCertificateOverwrite).(bool)) + overwrite := types.CustomBool(d.Get(mkResourceVirtualEnvironmentCertificateOverwrite).(bool)) privateKey := d.Get(mkResourceVirtualEnvironmentCertificatePrivateKey).(string) combinedCertificates := strings.TrimSpace(certificate) + "\n" @@ -159,7 +157,7 @@ func resourceVirtualEnvironmentCertificateGetUpdateBody( force = true } - restart := proxmox.CustomBool(true) + restart := types.CustomBool(true) body := &proxmox.VirtualEnvironmentCertificateUpdateRequestBody{ Certificates: combinedCertificates, @@ -171,14 +169,10 @@ func resourceVirtualEnvironmentCertificateGetUpdateBody( return body } -func resourceVirtualEnvironmentCertificateRead( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { +func certificateRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { var diags diag.Diagnostics - config := m.(providerConfiguration) + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) @@ -305,12 +299,8 @@ func resourceVirtualEnvironmentCertificateRead( return diags } -func resourceVirtualEnvironmentCertificateUpdate( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { - config := m.(providerConfiguration) +func certificateUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) @@ -318,29 +308,25 @@ func resourceVirtualEnvironmentCertificateUpdate( nodeName := d.Get(mkResourceVirtualEnvironmentCertificateNodeName).(string) - body := resourceVirtualEnvironmentCertificateGetUpdateBody(d) + body := certificateGetUpdateBody(d) err = veClient.UpdateCertificate(ctx, nodeName, body) if err != nil { return diag.FromErr(err) } - return resourceVirtualEnvironmentCertificateRead(ctx, d, m) + return certificateRead(ctx, d, m) } -func resourceVirtualEnvironmentCertificateDelete( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { - config := m.(providerConfiguration) +func certificateDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) } nodeName := d.Get(mkResourceVirtualEnvironmentCertificateNodeName).(string) - restart := proxmox.CustomBool(true) + restart := types.CustomBool(true) err = veClient.DeleteCertificate( ctx, diff --git a/proxmoxtf/resource_virtual_environment_certificate_test.go b/proxmoxtf/resource/certificate_test.go similarity index 69% rename from proxmoxtf/resource_virtual_environment_certificate_test.go rename to proxmoxtf/resource/certificate_test.go index 6fdbac20..6595e929 100644 --- a/proxmoxtf/resource_virtual_environment_certificate_test.go +++ b/proxmoxtf/resource/certificate_test.go @@ -1,39 +1,45 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public +/* + * 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/. */ + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ -package proxmoxtf +package resource import ( "testing" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf/test" ) -// TestResourceVirtualEnvironmentCertificateInstantiation tests whether the ResourceVirtualEnvironmentCertificate instance can be instantiated. -func TestResourceVirtualEnvironmentCertificateInstantiation(t *testing.T) { - s := resourceVirtualEnvironmentCertificate() +// TestCertificateInstantiation tests whether the Certificate instance can be instantiated. +func TestCertificateInstantiation(t *testing.T) { + t.Parallel() + s := Certificate() if s == nil { - t.Fatalf("Cannot instantiate resourceVirtualEnvironmentCertificate") + t.Fatalf("Cannot instantiate Certificate") } } -// TestResourceVirtualEnvironmentCertificateSchema tests the resourceVirtualEnvironmentCertificate schema. -func TestResourceVirtualEnvironmentCertificateSchema(t *testing.T) { - s := resourceVirtualEnvironmentCertificate() +// TestCertificateSchema tests the Certificate schema. +func TestCertificateSchema(t *testing.T) { + t.Parallel() + s := Certificate() - testRequiredArguments(t, s, []string{ + test.AssertRequiredArguments(t, s, []string{ mkResourceVirtualEnvironmentCertificateCertificate, mkResourceVirtualEnvironmentCertificateNodeName, mkResourceVirtualEnvironmentCertificatePrivateKey, }) - testOptionalArguments(t, s, []string{ + test.AssertOptionalArguments(t, s, []string{ mkResourceVirtualEnvironmentCertificateCertificateChain, }) - testComputedAttributes(t, s, []string{ + test.AssertComputedAttributes(t, s, []string{ mkResourceVirtualEnvironmentCertificateExpirationDate, mkResourceVirtualEnvironmentCertificateFileName, mkResourceVirtualEnvironmentCertificateIssuer, @@ -45,7 +51,7 @@ func TestResourceVirtualEnvironmentCertificateSchema(t *testing.T) { mkResourceVirtualEnvironmentCertificateSubjectAlternativeNames, }) - testValueTypes(t, s, map[string]schema.ValueType{ + test.AssertValueTypes(t, s, map[string]schema.ValueType{ mkResourceVirtualEnvironmentCertificateCertificate: schema.TypeString, mkResourceVirtualEnvironmentCertificateCertificateChain: schema.TypeString, mkResourceVirtualEnvironmentCertificateExpirationDate: schema.TypeString, diff --git a/proxmoxtf/resource/cluster/firewall/firewall.go b/proxmoxtf/resource/cluster/firewall/firewall.go new file mode 100644 index 00000000..506a1b96 --- /dev/null +++ b/proxmoxtf/resource/cluster/firewall/firewall.go @@ -0,0 +1,229 @@ +/* + * 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" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmox/cluster/firewall" + "github.com/bpg/terraform-provider-proxmox/proxmox/types" + "github.com/bpg/terraform-provider-proxmox/proxmoxtf" + "github.com/bpg/terraform-provider-proxmox/proxmoxtf/resource/validator" +) + +const ( + dvLogRatelimiEnabled = true + dvLogRatelimitBurst = 5 + dvLogRatelimitRate = "1/second" + dvPolicyIn = "DROP" + dvPolicyOut = "ACCEPT" + + mkEBTables = "ebtables" + mkEnabled = "enabled" + mkLogRatelimit = "log_ratelimit" + mkLogRatelimitEnabled = "enabled" + mkLogRatelimitBurst = "burst" + mkLogRatelimitRate = "rate" + mkPolicyIn = "input_policy" + mkPolicyOut = "output_policy" +) + +func Firewall() *schema.Resource { + return &schema.Resource{ + Schema: map[string]*schema.Schema{ + mkEBTables: { + Type: schema.TypeBool, + Description: "Enable ebtables cluster-wide", + Optional: true, + }, + mkEnabled: { + Type: schema.TypeBool, + Description: "Enable or disable the firewall cluster-wide", + Optional: true, + }, + mkLogRatelimit: { + Type: schema.TypeList, + Description: "Log ratelimiting settings", + Optional: true, + DefaultFunc: func() (interface{}, error) { + return []interface{}{ + map[string]interface{}{ + mkLogRatelimitEnabled: dvLogRatelimiEnabled, + mkLogRatelimitBurst: dvLogRatelimitBurst, + mkLogRatelimitRate: dvLogRatelimitRate, + }, + }, nil + }, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + mkLogRatelimitEnabled: { + Type: schema.TypeBool, + Description: "Enable or disable log ratelimiting", + Optional: true, + Default: dvLogRatelimiEnabled, + }, + mkLogRatelimitBurst: { + Type: schema.TypeInt, + Description: "Initial burst of packages which will always get logged before the rate is applied", + Optional: true, + Default: dvLogRatelimitBurst, + }, + mkLogRatelimitRate: { + Type: schema.TypeString, + Description: "Frequency with which the burst bucket gets refilled", + Optional: true, + Default: dvLogRatelimitRate, + ValidateDiagFunc: validator.FirewallRate(), + }, + }, + }, + MaxItems: 1, + MinItems: 0, + }, + mkPolicyIn: { + Type: schema.TypeString, + Description: "Default policy for incoming traffic", + Optional: true, + Default: dvPolicyIn, + ValidateDiagFunc: validator.FirewallPolicy(), + }, + mkPolicyOut: { + Type: schema.TypeString, + Description: "Default policy for outgoing traffic", + Optional: true, + Default: dvPolicyOut, + ValidateDiagFunc: validator.FirewallPolicy(), + }, + }, + CreateContext: selectFirewallAPI(firewallCreate), + ReadContext: selectFirewallAPI(firewallRead), + UpdateContext: selectFirewallAPI(firewallUpdate), + DeleteContext: selectFirewallAPI(firewallDelete), + } +} + +func firewallCreate(ctx context.Context, api firewall.API, d *schema.ResourceData) diag.Diagnostics { + diags := setOptions(ctx, api, d) + if diags.HasError() { + return diags + } + + return firewallRead(ctx, api, d) +} + +func setOptions(ctx context.Context, api firewall.API, d *schema.ResourceData) diag.Diagnostics { + policyIn := d.Get(mkPolicyIn).(string) + policyOut := d.Get(mkPolicyOut).(string) + body := &firewall.OptionsPutRequestBody{ + PolicyIn: &policyIn, + PolicyOut: &policyOut, + } + + logRatelimit := d.Get(mkLogRatelimit).([]interface{}) + if len(logRatelimit) > 0 { + m := logRatelimit[0].(map[string]interface{}) + burst := m[mkLogRatelimitBurst].(int) + rate := m[mkLogRatelimitRate].(string) + rl := firewall.CustomLogRateLimit{ + Enable: types.CustomBool(m[mkLogRatelimitEnabled].(bool)), + Burst: &burst, + Rate: &rate, + } + body.LogRateLimit = &rl + } + + ebtablesBool := types.CustomBool(d.Get(mkEBTables).(bool)) + body.EBTables = &ebtablesBool + + enabledBool := types.CustomBool(d.Get(mkEnabled).(bool)) + body.Enable = &enabledBool + + err := api.SetGlobalOptions(ctx, body) + if err != nil { + return diag.FromErr(err) + } + + d.SetId("cluster-firewall") + + return nil +} + +func firewallRead(ctx context.Context, api firewall.API, d *schema.ResourceData) diag.Diagnostics { + var diags diag.Diagnostics + + options, err := api.GetGlobalOptions(ctx) + if err != nil { + return diag.FromErr(err) + } + + if options.EBTables != nil { + err = d.Set(mkEBTables, *options.EBTables) + diags = append(diags, diag.FromErr(err)...) + } + + if options.Enable != nil { + err = d.Set(mkEnabled, *options.Enable) + diags = append(diags, diag.FromErr(err)...) + } + + if options.LogRateLimit != nil { + err = d.Set(mkLogRatelimit, []interface{}{ + map[string]interface{}{ + mkLogRatelimitEnabled: options.LogRateLimit.Enable, + mkLogRatelimitBurst: *options.LogRateLimit.Burst, + mkLogRatelimitRate: *options.LogRateLimit.Rate, + }, + }) + diags = append(diags, diag.FromErr(err)...) + } + + if options.PolicyIn != nil { + err = d.Set(mkPolicyIn, *options.PolicyIn) + diags = append(diags, diag.FromErr(err)...) + } + + if options.PolicyOut != nil { + err = d.Set(mkPolicyOut, *options.PolicyOut) + diags = append(diags, diag.FromErr(err)...) + } + + return diags +} + +func firewallUpdate(ctx context.Context, api firewall.API, d *schema.ResourceData) diag.Diagnostics { + diags := setOptions(ctx, api, d) + if diags.HasError() { + return diags + } + + return firewallRead(ctx, api, d) +} + +func firewallDelete(_ context.Context, _ firewall.API, d *schema.ResourceData) diag.Diagnostics { + d.SetId("") + + return nil +} + +func selectFirewallAPI( + f func(context.Context, firewall.API, *schema.ResourceData) diag.Diagnostics, +) func(context.Context, *schema.ResourceData, interface{}) diag.Diagnostics { + return func(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + config := m.(proxmoxtf.ProviderConfiguration) + veClient, err := config.GetVEClient() + if err != nil { + return diag.FromErr(err) + } + + api := veClient.API().Cluster().Firewall() + + return f(ctx, api, d) + } +} diff --git a/proxmoxtf/resource/cluster/firewall/security_group.go b/proxmoxtf/resource/cluster/firewall/security_group.go new file mode 100644 index 00000000..07ab12a9 --- /dev/null +++ b/proxmoxtf/resource/cluster/firewall/security_group.go @@ -0,0 +1,152 @@ +/* + * 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" + "strings" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + clusterfirewall "github.com/bpg/terraform-provider-proxmox/proxmox/cluster/firewall" + "github.com/bpg/terraform-provider-proxmox/proxmoxtf/resource/firewall" + "github.com/bpg/terraform-provider-proxmox/proxmoxtf/structure" +) + +const ( + dvSecurityGroupComment = "" + + mkSecurityGroupName = "name" + mkSecurityGroupComment = "comment" +) + +func SecurityGroup() *schema.Resource { + s := map[string]*schema.Schema{ + mkSecurityGroupName: { + Type: schema.TypeString, + Description: "Security group name", + Required: true, + ForceNew: false, + }, + mkSecurityGroupComment: { + Type: schema.TypeString, + Description: "Security group comment", + Optional: true, + Default: dvSecurityGroupComment, + }, + } + + structure.MergeSchema(s, firewall.Rules().Schema) + + return &schema.Resource{ + Schema: s, + CreateContext: selectFirewallAPI(SecurityGroupCreate), + ReadContext: selectFirewallAPI(SecurityGroupRead), + UpdateContext: selectFirewallAPI(SecurityGroupUpdate), + DeleteContext: selectFirewallAPI(SecurityGroupDelete), + } +} + +func SecurityGroupCreate(ctx context.Context, api clusterfirewall.API, d *schema.ResourceData) diag.Diagnostics { + comment := d.Get(mkSecurityGroupComment).(string) + name := d.Get(mkSecurityGroupName).(string) + + body := &clusterfirewall.GroupCreateRequestBody{ + Comment: &comment, + Group: name, + } + + err := api.CreateGroup(ctx, body) + if err != nil { + return diag.FromErr(err) + } + + diags := firewall.RulesCreate(ctx, api.SecurityGroup(name), d) + if diags.HasError() { + return diags + } + + d.SetId(name) + + return SecurityGroupRead(ctx, api, d) +} + +func SecurityGroupRead(ctx context.Context, api clusterfirewall.API, d *schema.ResourceData) diag.Diagnostics { + var diags diag.Diagnostics + + name := d.Id() + + allGroups, err := api.ListGroups(ctx) + if err != nil { + return diag.FromErr(err) + } + + for _, v := range allGroups { + if v.Group == name { + err = d.Set(mkSecurityGroupName, v.Group) + diags = append(diags, diag.FromErr(err)...) + err = d.Set(mkSecurityGroupComment, v.Comment) + diags = append(diags, diag.FromErr(err)...) + break + } + } + + if diags.HasError() { + return diags + } + + return firewall.RulesRead(ctx, api.SecurityGroup(name), d) +} + +func SecurityGroupUpdate(ctx context.Context, api clusterfirewall.API, d *schema.ResourceData) diag.Diagnostics { + comment := d.Get(mkSecurityGroupComment).(string) + newName := d.Get(mkSecurityGroupName).(string) + previousName := d.Id() + + body := &clusterfirewall.GroupUpdateRequestBody{ + Group: newName, + ReName: &previousName, + Comment: &comment, + } + + err := api.UpdateGroup(ctx, body) + if err != nil { + return diag.FromErr(err) + } + + diags := firewall.RulesUpdate(ctx, api.SecurityGroup(previousName), d) + if diags.HasError() { + return diags + } + + d.SetId(newName) + + return SecurityGroupRead(ctx, api, d) +} + +func SecurityGroupDelete(ctx context.Context, api clusterfirewall.API, d *schema.ResourceData) diag.Diagnostics { + group := d.Id() + + diags := firewall.RulesDelete(ctx, api.SecurityGroup(group), d) + if diags.HasError() { + return diags + } + + err := api.DeleteGroup(ctx, group) + if err != nil { + if strings.Contains(err.Error(), "no such security group") { + d.SetId("") + return nil + } + return diag.FromErr(err) + } + + d.SetId("") + + return nil +} diff --git a/proxmoxtf/resource/cluster/firewall/security_group_test.go b/proxmoxtf/resource/cluster/firewall/security_group_test.go new file mode 100644 index 00000000..7578dd0a --- /dev/null +++ b/proxmoxtf/resource/cluster/firewall/security_group_test.go @@ -0,0 +1,44 @@ +/* + * 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 ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/stretchr/testify/require" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf/resource/firewall" + "github.com/bpg/terraform-provider-proxmox/proxmoxtf/structure" +) + +// TestSecurityGroupInstantiation tests whether the SecurityGroup instance can be instantiated. +func TestSecurityGroupInstantiation(t *testing.T) { + t.Parallel() + require.NotNilf(t, SecurityGroup(), "Cannot instantiate SecurityGroup") +} + +// TestSecurityGroupSchema tests the SecurityGroup Schema. +func TestSecurityGroupSchema(t *testing.T) { + t.Parallel() + s := SecurityGroup().Schema + + structure.AssertRequiredArguments(t, s, []string{ + mkSecurityGroupName, + }) + + structure.AssertOptionalArguments(t, s, []string{ + mkSecurityGroupComment, + }) + + structure.AssertValueTypes(t, s, map[string]schema.ValueType{ + mkSecurityGroupName: schema.TypeString, + mkSecurityGroupComment: schema.TypeString, + }) + + structure.AssertNestedSchemaExistence(t, s, firewall.MkRule) +} diff --git a/proxmoxtf/resource_virtual_environment_container.go b/proxmoxtf/resource/container.go similarity index 95% rename from proxmoxtf/resource_virtual_environment_container.go rename to proxmoxtf/resource/container.go index db6454d6..7cab3658 100644 --- a/proxmoxtf/resource_virtual_environment_container.go +++ b/proxmoxtf/resource/container.go @@ -1,8 +1,10 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public +/* + * 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/. */ + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ -package proxmoxtf +package resource import ( "context" @@ -16,6 +18,8 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/bpg/terraform-provider-proxmox/proxmox" + "github.com/bpg/terraform-provider-proxmox/proxmox/types" + "github.com/bpg/terraform-provider-proxmox/proxmoxtf" ) const ( @@ -46,7 +50,6 @@ const ( dvResourceVirtualEnvironmentContainerNetworkInterfaceMACAddress = "" dvResourceVirtualEnvironmentContainerNetworkInterfaceRateLimit = 0 dvResourceVirtualEnvironmentContainerNetworkInterfaceVLANID = 0 - dvResourceVirtualEnvironmentContainerNetworkInterfaceMTU = 0 dvResourceVirtualEnvironmentContainerOperatingSystemType = "unmanaged" dvResourceVirtualEnvironmentContainerPoolID = "" dvResourceVirtualEnvironmentContainerStarted = true @@ -89,7 +92,6 @@ const ( mkResourceVirtualEnvironmentContainerInitializationUserAccount = "user_account" mkResourceVirtualEnvironmentContainerInitializationUserAccountKeys = "keys" mkResourceVirtualEnvironmentContainerInitializationUserAccountPassword = "password" - mkResourceVirtualEnvironmentContainerInitializationUserAccountUsername = "username" mkResourceVirtualEnvironmentContainerMemory = "memory" mkResourceVirtualEnvironmentContainerMemoryDedicated = "dedicated" mkResourceVirtualEnvironmentContainerMemorySwap = "swap" @@ -113,7 +115,7 @@ const ( mkResourceVirtualEnvironmentContainerVMID = "vm_id" ) -func resourceVirtualEnvironmentContainer() *schema.Resource { +func Container() *schema.Resource { return &schema.Resource{ Schema: map[string]*schema.Schema{ mkResourceVirtualEnvironmentContainerClone: { @@ -177,7 +179,7 @@ func resourceVirtualEnvironmentContainer() *schema.Resource { Description: "The console mode", Optional: true, Default: dvResourceVirtualEnvironmentContainerConsoleMode, - ValidateDiagFunc: resourceVirtualEnvironmentContainerGetConsoleModeValidator(), + ValidateDiagFunc: containerGetConsoleModeValidator(), }, mkResourceVirtualEnvironmentContainerConsoleTTYCount: { Type: schema.TypeInt, @@ -211,7 +213,7 @@ func resourceVirtualEnvironmentContainer() *schema.Resource { Description: "The CPU architecture", Optional: true, Default: dvResourceVirtualEnvironmentContainerCPUArchitecture, - ValidateDiagFunc: resourceVirtualEnvironmentContainerGetCPUArchitectureValidator(), + ValidateDiagFunc: containerGetCPUArchitectureValidator(), }, mkResourceVirtualEnvironmentContainerCPUCores: { Type: schema.TypeInt, @@ -571,7 +573,7 @@ func resourceVirtualEnvironmentContainer() *schema.Resource { Description: "The type", Optional: true, Default: dvResourceVirtualEnvironmentContainerOperatingSystemType, - ValidateDiagFunc: resourceVirtualEnvironmentContainerGetOperatingSystemTypeValidator(), + ValidateDiagFunc: containerGetOperatingSystemTypeValidator(), }, }, }, @@ -623,33 +625,25 @@ func resourceVirtualEnvironmentContainer() *schema.Resource { ValidateDiagFunc: getVMIDValidator(), }, }, - CreateContext: resourceVirtualEnvironmentContainerCreate, - ReadContext: resourceVirtualEnvironmentContainerRead, - UpdateContext: resourceVirtualEnvironmentContainerUpdate, - DeleteContext: resourceVirtualEnvironmentContainerDelete, + CreateContext: containerCreate, + ReadContext: containerRead, + UpdateContext: containerUpdate, + DeleteContext: containerDelete, } } -func resourceVirtualEnvironmentContainerCreate( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { +func containerCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { clone := d.Get(mkResourceVirtualEnvironmentContainerClone).([]interface{}) if len(clone) > 0 { - return resourceVirtualEnvironmentContainerCreateClone(ctx, d, m) + return containerCreateClone(ctx, d, m) } - return resourceVirtualEnvironmentContainerCreateCustom(ctx, d, m) + return containerCreateCustom(ctx, d, m) } -func resourceVirtualEnvironmentContainerCreateClone( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { - config := m.(providerConfiguration) +func containerCreateClone(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) @@ -685,7 +679,7 @@ func resourceVirtualEnvironmentContainerCreateClone( vmID = *vmIDNew } - fullCopy := proxmox.CustomBool(true) + fullCopy := types.CustomBool(true) cloneBody := &proxmox.VirtualEnvironmentContainerCloneRequestBody{ FullCopy: &fullCopy, @@ -736,7 +730,7 @@ func resourceVirtualEnvironmentContainerCreateClone( if len(console) > 0 { consoleBlock := console[0].(map[string]interface{}) - consoleEnabled := proxmox.CustomBool( + consoleEnabled := types.CustomBool( consoleBlock[mkResourceVirtualEnvironmentContainerConsoleEnabled].(bool), ) consoleMode := consoleBlock[mkResourceVirtualEnvironmentContainerConsoleMode].(string) @@ -872,7 +866,7 @@ func resourceVirtualEnvironmentContainerCreateClone( networkInterface := d.Get(mkResourceVirtualEnvironmentContainerNetworkInterface).([]interface{}) if len(networkInterface) == 0 { - networkInterface, err = resourceVirtualEnvironmentContainerGetExistingNetworkInterface( + networkInterface, err = containerGetExistingNetworkInterface( ctx, veClient, nodeName, @@ -970,11 +964,11 @@ func resourceVirtualEnvironmentContainerCreateClone( } if len(tags) > 0 { - tagString := resourceVirtualEnvironmentContainerGetTagsString(d) + tagString := containerGetTagsString(d) updateBody.Tags = &tagString } - template := proxmox.CustomBool(d.Get(mkResourceVirtualEnvironmentContainerTemplate).(bool)) + template := types.CustomBool(d.Get(mkResourceVirtualEnvironmentContainerTemplate).(bool)) //nolint:gosimple if template != dvResourceVirtualEnvironmentContainerTemplate { @@ -992,22 +986,18 @@ func resourceVirtualEnvironmentContainerCreateClone( return diag.FromErr(err) } - return resourceVirtualEnvironmentContainerCreateStart(ctx, d, m) + return containerCreateStart(ctx, d, m) } -func resourceVirtualEnvironmentContainerCreateCustom( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { - config := m.(providerConfiguration) +func containerCreateCustom(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) } nodeName := d.Get(mkResourceVirtualEnvironmentContainerNodeName).(string) - resource := resourceVirtualEnvironmentContainer() + resource := Container() consoleBlock, err := getSchemaBlock( resource, @@ -1020,7 +1010,7 @@ func resourceVirtualEnvironmentContainerCreateCustom( return diag.FromErr(err) } - consoleEnabled := proxmox.CustomBool( + consoleEnabled := types.CustomBool( consoleBlock[mkResourceVirtualEnvironmentContainerConsoleEnabled].(bool), ) consoleMode := consoleBlock[mkResourceVirtualEnvironmentContainerConsoleMode].(string) @@ -1077,7 +1067,7 @@ func resourceVirtualEnvironmentContainerCreateCustom( return diag.FromErr(err) } - nesting := proxmox.CustomBool(featuresBlock[mkResourceVirtualEnvironmentContainerFeaturesNesting].(bool)) + nesting := types.CustomBool(featuresBlock[mkResourceVirtualEnvironmentContainerFeaturesNesting].(bool)) features := proxmox.VirtualEnvironmentContainerCustomFeatures{ Nesting: &nesting, } @@ -1254,10 +1244,10 @@ func resourceVirtualEnvironmentContainerCreateCustom( operatingSystemType := operatingSystemBlock[mkResourceVirtualEnvironmentContainerOperatingSystemType].(string) poolID := d.Get(mkResourceVirtualEnvironmentContainerPoolID).(string) - started := proxmox.CustomBool(d.Get(mkResourceVirtualEnvironmentContainerStarted).(bool)) + started := types.CustomBool(d.Get(mkResourceVirtualEnvironmentContainerStarted).(bool)) tags := d.Get(mkResourceVirtualEnvironmentContainerTags).([]interface{}) - template := proxmox.CustomBool(d.Get(mkResourceVirtualEnvironmentContainerTemplate).(bool)) - unprivileged := proxmox.CustomBool(d.Get(mkResourceVirtualEnvironmentContainerUnprivileged).(bool)) + template := types.CustomBool(d.Get(mkResourceVirtualEnvironmentContainerTemplate).(bool)) + unprivileged := types.CustomBool(d.Get(mkResourceVirtualEnvironmentContainerUnprivileged).(bool)) vmID := d.Get(mkResourceVirtualEnvironmentContainerVMID).(int) if vmID == -1 { @@ -1320,7 +1310,7 @@ func resourceVirtualEnvironmentContainerCreateCustom( } if len(tags) > 0 { - tagsString := resourceVirtualEnvironmentContainerGetTagsString(d) + tagsString := containerGetTagsString(d) createBody.Tags = &tagsString } @@ -1337,22 +1327,18 @@ func resourceVirtualEnvironmentContainerCreateCustom( return diag.FromErr(err) } - return resourceVirtualEnvironmentContainerCreateStart(ctx, d, m) + return containerCreateStart(ctx, d, m) } -func resourceVirtualEnvironmentContainerCreateStart( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { +func containerCreateStart(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { started := d.Get(mkResourceVirtualEnvironmentContainerStarted).(bool) template := d.Get(mkResourceVirtualEnvironmentContainerTemplate).(bool) if !started || template { - return resourceVirtualEnvironmentContainerRead(ctx, d, m) + return containerRead(ctx, d, m) } - config := m.(providerConfiguration) + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) @@ -1375,10 +1361,10 @@ func resourceVirtualEnvironmentContainerCreateStart( return diag.FromErr(err) } - return resourceVirtualEnvironmentContainerRead(ctx, d, m) + return containerRead(ctx, d, m) } -func resourceVirtualEnvironmentContainerGetConsoleModeValidator() schema.SchemaValidateDiagFunc { +func containerGetConsoleModeValidator() schema.SchemaValidateDiagFunc { return validation.ToDiagFunc(validation.StringInSlice([]string{ "console", "shell", @@ -1386,7 +1372,7 @@ func resourceVirtualEnvironmentContainerGetConsoleModeValidator() schema.SchemaV }, false)) } -func resourceVirtualEnvironmentContainerGetCPUArchitectureValidator() schema.SchemaValidateDiagFunc { +func containerGetCPUArchitectureValidator() schema.SchemaValidateDiagFunc { return validation.ToDiagFunc(validation.StringInSlice([]string{ "amd64", "arm64", @@ -1395,7 +1381,7 @@ func resourceVirtualEnvironmentContainerGetCPUArchitectureValidator() schema.Sch }, false)) } -func resourceVirtualEnvironmentContainerGetExistingNetworkInterface( +func containerGetExistingNetworkInterface( ctx context.Context, client *proxmox.VirtualEnvironmentClient, nodeName string, @@ -1465,7 +1451,7 @@ func resourceVirtualEnvironmentContainerGetExistingNetworkInterface( return networkInterfaces, nil } -func resourceVirtualEnvironmentContainerGetOperatingSystemTypeValidator() schema.SchemaValidateDiagFunc { +func containerGetOperatingSystemTypeValidator() schema.SchemaValidateDiagFunc { return validation.ToDiagFunc(validation.StringInSlice([]string{ "alpine", "archlinux", @@ -1479,7 +1465,7 @@ func resourceVirtualEnvironmentContainerGetOperatingSystemTypeValidator() schema }, false)) } -func resourceVirtualEnvironmentContainerGetTagsString(d *schema.ResourceData) string { +func containerGetTagsString(d *schema.ResourceData) string { tags := d.Get(mkResourceVirtualEnvironmentContainerTags).([]interface{}) var sanitizedTags []string for i := 0; i < len(tags); i++ { @@ -1492,14 +1478,10 @@ func resourceVirtualEnvironmentContainerGetTagsString(d *schema.ResourceData) st return strings.Join(sanitizedTags, ";") } -func resourceVirtualEnvironmentContainerRead( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { +func containerRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { var diags diag.Diagnostics - config := m.(providerConfiguration) + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) @@ -1572,7 +1554,8 @@ func resourceVirtualEnvironmentContainerRead( diags = append(diags, diag.FromErr(err)...) } } else if len(currentConsole) > 0 || - console[mkResourceVirtualEnvironmentContainerConsoleEnabled] != proxmox.CustomBool(dvResourceVirtualEnvironmentContainerConsoleEnabled) || + //nolint:lll + console[mkResourceVirtualEnvironmentContainerConsoleEnabled] != types.CustomBool(dvResourceVirtualEnvironmentContainerConsoleEnabled) || console[mkResourceVirtualEnvironmentContainerConsoleMode] != dvResourceVirtualEnvironmentContainerConsoleMode || console[mkResourceVirtualEnvironmentContainerConsoleTTYCount] != dvResourceVirtualEnvironmentContainerConsoleTTYCount { err := d.Set(mkResourceVirtualEnvironmentContainerConsole, []interface{}{console}) @@ -1961,12 +1944,8 @@ func resourceVirtualEnvironmentContainerRead( return diags } -func resourceVirtualEnvironmentContainerUpdate( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { - config := m.(providerConfiguration) +func containerUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) @@ -1984,7 +1963,7 @@ func resourceVirtualEnvironmentContainerUpdate( } rebootRequired := false - resource := resourceVirtualEnvironmentContainer() + resource := Container() // Retrieve the clone argument as the update logic varies for clones. clone := d.Get(mkResourceVirtualEnvironmentVMClone).([]interface{}) @@ -1993,7 +1972,7 @@ func resourceVirtualEnvironmentContainerUpdate( description := d.Get(mkResourceVirtualEnvironmentContainerDescription).(string) updateBody.Description = &description - template := proxmox.CustomBool(d.Get(mkResourceVirtualEnvironmentContainerTemplate).(bool)) + template := types.CustomBool(d.Get(mkResourceVirtualEnvironmentContainerTemplate).(bool)) if d.HasChange(mkResourceVirtualEnvironmentContainerTemplate) { updateBody.Template = &template @@ -2012,7 +1991,7 @@ func resourceVirtualEnvironmentContainerUpdate( return diag.FromErr(err) } - consoleEnabled := proxmox.CustomBool( + consoleEnabled := types.CustomBool( consoleBlock[mkResourceVirtualEnvironmentContainerConsoleEnabled].(bool), ) consoleMode := consoleBlock[mkResourceVirtualEnvironmentContainerConsoleMode].(string) @@ -2146,7 +2125,7 @@ func resourceVirtualEnvironmentContainerUpdate( networkInterface := d.Get(mkResourceVirtualEnvironmentContainerNetworkInterface).([]interface{}) if len(networkInterface) == 0 && len(clone) > 0 { - networkInterface, err = resourceVirtualEnvironmentContainerGetExistingNetworkInterface( + networkInterface, err = containerGetExistingNetworkInterface( ctx, veClient, nodeName, @@ -2258,7 +2237,7 @@ func resourceVirtualEnvironmentContainerUpdate( } if d.HasChange(mkResourceVirtualEnvironmentContainerTags) { - tagString := resourceVirtualEnvironmentContainerGetTagsString(d) + tagString := containerGetTagsString(d) updateBody.Tags = &tagString } @@ -2283,7 +2262,7 @@ func resourceVirtualEnvironmentContainerUpdate( return diag.FromErr(err) } } else { - forceStop := proxmox.CustomBool(true) + forceStop := types.CustomBool(true) shutdownTimeout := 300 err = veClient.ShutdownContainer(ctx, nodeName, vmID, &proxmox.VirtualEnvironmentContainerShutdownRequestBody{ @@ -2320,15 +2299,11 @@ func resourceVirtualEnvironmentContainerUpdate( } } - return resourceVirtualEnvironmentContainerRead(ctx, d, m) + return containerRead(ctx, d, m) } -func resourceVirtualEnvironmentContainerDelete( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { - config := m.(providerConfiguration) +func containerDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) @@ -2347,7 +2322,7 @@ func resourceVirtualEnvironmentContainerDelete( } if status.Status != "stopped" { - forceStop := proxmox.CustomBool(true) + forceStop := types.CustomBool(true) shutdownTimeout := 300 err = veClient.ShutdownContainer( diff --git a/proxmoxtf/resource_virtual_environment_container_test.go b/proxmoxtf/resource/container_test.go similarity index 66% rename from proxmoxtf/resource_virtual_environment_container_test.go rename to proxmoxtf/resource/container_test.go index 88557ae8..149c8fa2 100644 --- a/proxmoxtf/resource_virtual_environment_container_test.go +++ b/proxmoxtf/resource/container_test.go @@ -1,33 +1,39 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public +/* + * 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/. */ + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ -package proxmoxtf +package resource import ( "testing" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf/test" ) -// TestResourceVirtualEnvironmentContainerInstantiation tests whether the ResourceVirtualEnvironmentContainer instance can be instantiated. -func TestResourceVirtualEnvironmentContainerInstantiation(t *testing.T) { - s := resourceVirtualEnvironmentContainer() +// TestContainerInstantiation tests whether the Container instance can be instantiated. +func TestContainerInstantiation(t *testing.T) { + t.Parallel() + s := Container() if s == nil { - t.Fatalf("Cannot instantiate resourceVirtualEnvironmentContainer") + t.Fatalf("Cannot instantiate Container") } } -// TestResourceVirtualEnvironmentContainerSchema tests the resourceVirtualEnvironmentContainer schema. -func TestResourceVirtualEnvironmentContainerSchema(t *testing.T) { - s := resourceVirtualEnvironmentContainer() +// TestContainerSchema tests the Container schema. +func TestContainerSchema(t *testing.T) { + t.Parallel() + s := Container() - testRequiredArguments(t, s, []string{ + test.AssertRequiredArguments(t, s, []string{ mkResourceVirtualEnvironmentContainerNodeName, }) - testOptionalArguments(t, s, []string{ + test.AssertOptionalArguments(t, s, []string{ mkResourceVirtualEnvironmentContainerCPU, mkResourceVirtualEnvironmentContainerDescription, mkResourceVirtualEnvironmentContainerDisk, @@ -43,7 +49,7 @@ func TestResourceVirtualEnvironmentContainerSchema(t *testing.T) { mkResourceVirtualEnvironmentContainerVMID, }) - testValueTypes(t, s, map[string]schema.ValueType{ + test.AssertValueTypes(t, s, map[string]schema.ValueType{ mkResourceVirtualEnvironmentContainerCPU: schema.TypeList, mkResourceVirtualEnvironmentContainerDescription: schema.TypeString, mkResourceVirtualEnvironmentContainerDisk: schema.TypeList, @@ -59,180 +65,180 @@ func TestResourceVirtualEnvironmentContainerSchema(t *testing.T) { mkResourceVirtualEnvironmentContainerVMID: schema.TypeInt, }) - cloneSchema := testNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentContainerClone) + cloneSchema := test.AssertNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentContainerClone) - testRequiredArguments(t, cloneSchema, []string{ + test.AssertRequiredArguments(t, cloneSchema, []string{ mkResourceVirtualEnvironmentContainerCloneVMID, }) - testOptionalArguments(t, cloneSchema, []string{ + test.AssertOptionalArguments(t, cloneSchema, []string{ mkResourceVirtualEnvironmentContainerCloneDatastoreID, mkResourceVirtualEnvironmentContainerCloneNodeName, }) - testValueTypes(t, cloneSchema, map[string]schema.ValueType{ + test.AssertValueTypes(t, cloneSchema, map[string]schema.ValueType{ mkResourceVirtualEnvironmentContainerCloneDatastoreID: schema.TypeString, mkResourceVirtualEnvironmentContainerCloneNodeName: schema.TypeString, mkResourceVirtualEnvironmentContainerCloneVMID: schema.TypeInt, }) - cpuSchema := testNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentContainerCPU) + cpuSchema := test.AssertNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentContainerCPU) - testOptionalArguments(t, cpuSchema, []string{ + test.AssertOptionalArguments(t, cpuSchema, []string{ mkResourceVirtualEnvironmentContainerCPUArchitecture, mkResourceVirtualEnvironmentContainerCPUCores, mkResourceVirtualEnvironmentContainerCPUUnits, }) - testValueTypes(t, cpuSchema, map[string]schema.ValueType{ + test.AssertValueTypes(t, cpuSchema, map[string]schema.ValueType{ mkResourceVirtualEnvironmentContainerCPUArchitecture: schema.TypeString, mkResourceVirtualEnvironmentContainerCPUCores: schema.TypeInt, mkResourceVirtualEnvironmentContainerCPUUnits: schema.TypeInt, }) - diskSchema := testNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentContainerDisk) + diskSchema := test.AssertNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentContainerDisk) - testOptionalArguments(t, diskSchema, []string{ + test.AssertOptionalArguments(t, diskSchema, []string{ mkResourceVirtualEnvironmentContainerDiskDatastoreID, }) - testValueTypes(t, diskSchema, map[string]schema.ValueType{ + test.AssertValueTypes(t, diskSchema, map[string]schema.ValueType{ mkResourceVirtualEnvironmentContainerDiskDatastoreID: schema.TypeString, }) - featuresSchema := testNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentContainerFeatures) + featuresSchema := test.AssertNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentContainerFeatures) - testOptionalArguments(t, featuresSchema, []string{ + test.AssertOptionalArguments(t, featuresSchema, []string{ mkResourceVirtualEnvironmentContainerFeaturesNesting, }) - testValueTypes(t, featuresSchema, map[string]schema.ValueType{ + test.AssertValueTypes(t, featuresSchema, map[string]schema.ValueType{ mkResourceVirtualEnvironmentContainerFeaturesNesting: schema.TypeBool, }) - initializationSchema := testNestedSchemaExistence( + initializationSchema := test.AssertNestedSchemaExistence( t, s, mkResourceVirtualEnvironmentContainerInitialization, ) - testOptionalArguments(t, initializationSchema, []string{ + test.AssertOptionalArguments(t, initializationSchema, []string{ mkResourceVirtualEnvironmentContainerInitializationDNS, mkResourceVirtualEnvironmentContainerInitializationHostname, mkResourceVirtualEnvironmentContainerInitializationIPConfig, mkResourceVirtualEnvironmentContainerInitializationUserAccount, }) - testValueTypes(t, initializationSchema, map[string]schema.ValueType{ + test.AssertValueTypes(t, initializationSchema, map[string]schema.ValueType{ mkResourceVirtualEnvironmentContainerInitializationDNS: schema.TypeList, mkResourceVirtualEnvironmentContainerInitializationHostname: schema.TypeString, mkResourceVirtualEnvironmentContainerInitializationIPConfig: schema.TypeList, mkResourceVirtualEnvironmentContainerInitializationUserAccount: schema.TypeList, }) - initializationDNSSchema := testNestedSchemaExistence( + initializationDNSSchema := test.AssertNestedSchemaExistence( t, initializationSchema, mkResourceVirtualEnvironmentContainerInitializationDNS, ) - testOptionalArguments(t, initializationDNSSchema, []string{ + test.AssertOptionalArguments(t, initializationDNSSchema, []string{ mkResourceVirtualEnvironmentContainerInitializationDNSDomain, mkResourceVirtualEnvironmentContainerInitializationDNSServer, }) - testValueTypes(t, initializationDNSSchema, map[string]schema.ValueType{ + test.AssertValueTypes(t, initializationDNSSchema, map[string]schema.ValueType{ mkResourceVirtualEnvironmentContainerInitializationDNSDomain: schema.TypeString, mkResourceVirtualEnvironmentContainerInitializationDNSServer: schema.TypeString, }) - initializationIPConfigSchema := testNestedSchemaExistence( + initializationIPConfigSchema := test.AssertNestedSchemaExistence( t, initializationSchema, mkResourceVirtualEnvironmentContainerInitializationIPConfig, ) - testOptionalArguments(t, initializationIPConfigSchema, []string{ + test.AssertOptionalArguments(t, initializationIPConfigSchema, []string{ mkResourceVirtualEnvironmentContainerInitializationIPConfigIPv4, mkResourceVirtualEnvironmentContainerInitializationIPConfigIPv6, }) - testValueTypes(t, initializationIPConfigSchema, map[string]schema.ValueType{ + test.AssertValueTypes(t, initializationIPConfigSchema, map[string]schema.ValueType{ mkResourceVirtualEnvironmentContainerInitializationIPConfigIPv4: schema.TypeList, mkResourceVirtualEnvironmentContainerInitializationIPConfigIPv6: schema.TypeList, }) - initializationIPConfigIPv4Schema := testNestedSchemaExistence( + initializationIPConfigIPv4Schema := test.AssertNestedSchemaExistence( t, initializationIPConfigSchema, mkResourceVirtualEnvironmentContainerInitializationIPConfigIPv4, ) - testOptionalArguments(t, initializationIPConfigIPv4Schema, []string{ + test.AssertOptionalArguments(t, initializationIPConfigIPv4Schema, []string{ mkResourceVirtualEnvironmentContainerInitializationIPConfigIPv4Address, mkResourceVirtualEnvironmentContainerInitializationIPConfigIPv4Gateway, }) - testValueTypes(t, initializationIPConfigIPv4Schema, map[string]schema.ValueType{ + test.AssertValueTypes(t, initializationIPConfigIPv4Schema, map[string]schema.ValueType{ mkResourceVirtualEnvironmentContainerInitializationIPConfigIPv4Address: schema.TypeString, mkResourceVirtualEnvironmentContainerInitializationIPConfigIPv4Gateway: schema.TypeString, }) - initializationIPConfigIPv6Schema := testNestedSchemaExistence( + initializationIPConfigIPv6Schema := test.AssertNestedSchemaExistence( t, initializationIPConfigSchema, mkResourceVirtualEnvironmentContainerInitializationIPConfigIPv6, ) - testOptionalArguments(t, initializationIPConfigIPv6Schema, []string{ + test.AssertOptionalArguments(t, initializationIPConfigIPv6Schema, []string{ mkResourceVirtualEnvironmentContainerInitializationIPConfigIPv6Address, mkResourceVirtualEnvironmentContainerInitializationIPConfigIPv6Gateway, }) - testValueTypes(t, initializationIPConfigIPv6Schema, map[string]schema.ValueType{ + test.AssertValueTypes(t, initializationIPConfigIPv6Schema, map[string]schema.ValueType{ mkResourceVirtualEnvironmentContainerInitializationIPConfigIPv6Address: schema.TypeString, mkResourceVirtualEnvironmentContainerInitializationIPConfigIPv6Gateway: schema.TypeString, }) - initializationUserAccountSchema := testNestedSchemaExistence( + initializationUserAccountSchema := test.AssertNestedSchemaExistence( t, initializationSchema, mkResourceVirtualEnvironmentContainerInitializationUserAccount, ) - testOptionalArguments(t, initializationUserAccountSchema, []string{ + test.AssertOptionalArguments(t, initializationUserAccountSchema, []string{ mkResourceVirtualEnvironmentContainerInitializationUserAccountKeys, mkResourceVirtualEnvironmentContainerInitializationUserAccountPassword, }) - testValueTypes(t, initializationUserAccountSchema, map[string]schema.ValueType{ + test.AssertValueTypes(t, initializationUserAccountSchema, map[string]schema.ValueType{ mkResourceVirtualEnvironmentContainerInitializationUserAccountKeys: schema.TypeList, mkResourceVirtualEnvironmentContainerInitializationUserAccountPassword: schema.TypeString, }) - memorySchema := testNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentContainerMemory) + memorySchema := test.AssertNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentContainerMemory) - testOptionalArguments(t, memorySchema, []string{ + test.AssertOptionalArguments(t, memorySchema, []string{ mkResourceVirtualEnvironmentContainerMemoryDedicated, mkResourceVirtualEnvironmentContainerMemorySwap, }) - testValueTypes(t, memorySchema, map[string]schema.ValueType{ + test.AssertValueTypes(t, memorySchema, map[string]schema.ValueType{ mkResourceVirtualEnvironmentContainerMemoryDedicated: schema.TypeInt, mkResourceVirtualEnvironmentContainerMemorySwap: schema.TypeInt, }) - networkInterfaceSchema := testNestedSchemaExistence( + networkInterfaceSchema := test.AssertNestedSchemaExistence( t, s, mkResourceVirtualEnvironmentContainerNetworkInterface, ) - testRequiredArguments(t, networkInterfaceSchema, []string{ + test.AssertRequiredArguments(t, networkInterfaceSchema, []string{ mkResourceVirtualEnvironmentContainerNetworkInterfaceName, }) - testOptionalArguments(t, networkInterfaceSchema, []string{ + test.AssertOptionalArguments(t, networkInterfaceSchema, []string{ mkResourceVirtualEnvironmentContainerNetworkInterfaceBridge, mkResourceVirtualEnvironmentContainerNetworkInterfaceEnabled, mkResourceVirtualEnvironmentContainerNetworkInterfaceMACAddress, @@ -241,7 +247,7 @@ func TestResourceVirtualEnvironmentContainerSchema(t *testing.T) { mkResourceVirtualEnvironmentContainerNetworkInterfaceMTU, }) - testValueTypes(t, networkInterfaceSchema, map[string]schema.ValueType{ + test.AssertValueTypes(t, networkInterfaceSchema, map[string]schema.ValueType{ mkResourceVirtualEnvironmentContainerNetworkInterfaceBridge: schema.TypeString, mkResourceVirtualEnvironmentContainerNetworkInterfaceEnabled: schema.TypeBool, mkResourceVirtualEnvironmentContainerNetworkInterfaceMACAddress: schema.TypeString, @@ -251,21 +257,21 @@ func TestResourceVirtualEnvironmentContainerSchema(t *testing.T) { mkResourceVirtualEnvironmentContainerNetworkInterfaceMTU: schema.TypeInt, }) - operatingSystemSchema := testNestedSchemaExistence( + operatingSystemSchema := test.AssertNestedSchemaExistence( t, s, mkResourceVirtualEnvironmentContainerOperatingSystem, ) - testRequiredArguments(t, operatingSystemSchema, []string{ + test.AssertRequiredArguments(t, operatingSystemSchema, []string{ mkResourceVirtualEnvironmentContainerOperatingSystemTemplateFileID, }) - testOptionalArguments(t, operatingSystemSchema, []string{ + test.AssertOptionalArguments(t, operatingSystemSchema, []string{ mkResourceVirtualEnvironmentContainerOperatingSystemType, }) - testValueTypes(t, operatingSystemSchema, map[string]schema.ValueType{ + test.AssertValueTypes(t, operatingSystemSchema, map[string]schema.ValueType{ mkResourceVirtualEnvironmentContainerOperatingSystemTemplateFileID: schema.TypeString, mkResourceVirtualEnvironmentContainerOperatingSystemType: schema.TypeString, }) diff --git a/proxmoxtf/resource_virtual_environment_dns.go b/proxmoxtf/resource/dns.go similarity index 69% rename from proxmoxtf/resource_virtual_environment_dns.go rename to proxmoxtf/resource/dns.go index b515e1a6..2d0114d0 100644 --- a/proxmoxtf/resource_virtual_environment_dns.go +++ b/proxmoxtf/resource/dns.go @@ -1,8 +1,10 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public +/* + * 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/. */ + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ -package proxmoxtf +package resource import ( "context" @@ -12,6 +14,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/bpg/terraform-provider-proxmox/proxmox" + "github.com/bpg/terraform-provider-proxmox/proxmoxtf" ) const ( @@ -20,7 +23,7 @@ const ( mkResourceVirtualEnvironmentDNSServers = "servers" ) -func resourceVirtualEnvironmentDNS() *schema.Resource { +func DNS() *schema.Resource { return &schema.Resource{ Schema: map[string]*schema.Schema{ mkResourceVirtualEnvironmentDNSDomain: { @@ -46,19 +49,15 @@ func resourceVirtualEnvironmentDNS() *schema.Resource { MaxItems: 3, }, }, - CreateContext: resourceVirtualEnvironmentDNSCreate, - ReadContext: resourceVirtualEnvironmentDNSRead, - UpdateContext: resourceVirtualEnvironmentDNSUpdate, - DeleteContext: resourceVirtualEnvironmentDNSDelete, + CreateContext: dnsCreate, + ReadContext: dnsRead, + UpdateContext: dnsUpdate, + DeleteContext: dnsDelete, } } -func resourceVirtualEnvironmentDNSCreate( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { - diags := resourceVirtualEnvironmentDNSUpdate(ctx, d, m) +func dnsCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + diags := dnsUpdate(ctx, d, m) if diags.HasError() { return diags } @@ -70,9 +69,7 @@ func resourceVirtualEnvironmentDNSCreate( return nil } -func resourceVirtualEnvironmentDNSGetUpdateBody( - d *schema.ResourceData, -) *proxmox.VirtualEnvironmentDNSUpdateRequestBody { +func dnsGetUpdateBody(d *schema.ResourceData) *proxmox.VirtualEnvironmentDNSUpdateRequestBody { domain := d.Get(mkResourceVirtualEnvironmentDNSDomain).(string) servers := d.Get(mkResourceVirtualEnvironmentDNSServers).([]interface{}) @@ -96,14 +93,10 @@ func resourceVirtualEnvironmentDNSGetUpdateBody( return body } -func resourceVirtualEnvironmentDNSRead( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { +func dnsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { var diags diag.Diagnostics - config := m.(providerConfiguration) + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) @@ -142,12 +135,8 @@ func resourceVirtualEnvironmentDNSRead( return diags } -func resourceVirtualEnvironmentDNSUpdate( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { - config := m.(providerConfiguration) +func dnsUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) @@ -155,21 +144,17 @@ func resourceVirtualEnvironmentDNSUpdate( nodeName := d.Get(mkResourceVirtualEnvironmentDNSNodeName).(string) - body := resourceVirtualEnvironmentDNSGetUpdateBody(d) + body := dnsGetUpdateBody(d) err = veClient.UpdateDNS(ctx, nodeName, body) if err != nil { return diag.FromErr(err) } - return resourceVirtualEnvironmentDNSRead(ctx, d, m) + return dnsRead(ctx, d, m) } -func resourceVirtualEnvironmentDNSDelete( - _ context.Context, - d *schema.ResourceData, - _ interface{}, -) diag.Diagnostics { +func dnsDelete(_ context.Context, d *schema.ResourceData, _ interface{}) diag.Diagnostics { d.SetId("") return nil diff --git a/proxmoxtf/resource/dns_test.go b/proxmoxtf/resource/dns_test.go new file mode 100644 index 00000000..2337a4bd --- /dev/null +++ b/proxmoxtf/resource/dns_test.go @@ -0,0 +1,46 @@ +/* + * 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 resource + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf/test" +) + +// TestDNSInstantiation tests whether the DNS instance can be instantiated. +func TestDNSInstantiation(t *testing.T) { + t.Parallel() + s := DNS() + + if s == nil { + t.Fatalf("Cannot instantiate DNS") + } +} + +// TestDNSSchema tests the DNS schema. +func TestDNSSchema(t *testing.T) { + t.Parallel() + s := DNS() + + test.AssertRequiredArguments(t, s, []string{ + mkResourceVirtualEnvironmentDNSDomain, + mkResourceVirtualEnvironmentDNSNodeName, + }) + + test.AssertOptionalArguments(t, s, []string{ + mkResourceVirtualEnvironmentDNSServers, + }) + + test.AssertValueTypes(t, s, map[string]schema.ValueType{ + mkResourceVirtualEnvironmentDNSDomain: schema.TypeString, + mkResourceVirtualEnvironmentDNSNodeName: schema.TypeString, + mkResourceVirtualEnvironmentDNSServers: schema.TypeList, + }) +} diff --git a/proxmoxtf/resource_virtual_environment_file.go b/proxmoxtf/resource/file.go similarity index 91% rename from proxmoxtf/resource_virtual_environment_file.go rename to proxmoxtf/resource/file.go index 68c91188..8790e820 100644 --- a/proxmoxtf/resource_virtual_environment_file.go +++ b/proxmoxtf/resource/file.go @@ -1,8 +1,10 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public +/* + * 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/. */ + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ -package proxmoxtf +package resource import ( "bytes" @@ -24,11 +26,11 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/bpg/terraform-provider-proxmox/proxmox" + "github.com/bpg/terraform-provider-proxmox/proxmoxtf" ) const ( dvResourceVirtualEnvironmentFileContentType = "" - dvResourceVirtualEnvironmentFileSourceData = "" dvResourceVirtualEnvironmentFileSourceFileChanged = false dvResourceVirtualEnvironmentFileSourceFileChecksum = "" dvResourceVirtualEnvironmentFileSourceFileFileName = "" @@ -54,7 +56,7 @@ const ( mkResourceVirtualEnvironmentFileSourceRawResize = "resize" ) -func resourceVirtualEnvironmentFile() *schema.Resource { +func File() *schema.Resource { return &schema.Resource{ Schema: map[string]*schema.Schema{ mkResourceVirtualEnvironmentFileContentType: { @@ -184,30 +186,26 @@ func resourceVirtualEnvironmentFile() *schema.Resource { MinItems: 0, }, }, - CreateContext: resourceVirtualEnvironmentFileCreate, - ReadContext: resourceVirtualEnvironmentFileRead, - DeleteContext: resourceVirtualEnvironmentFileDelete, + CreateContext: fileCreate, + ReadContext: fileRead, + DeleteContext: fileDelete, } } -func resourceVirtualEnvironmentFileCreate( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { +func fileCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { var diags diag.Diagnostics - config := m.(providerConfiguration) + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) } - contentType, dg := resourceVirtualEnvironmentFileGetContentType(d) + contentType, dg := fileGetContentType(d) diags = append(diags, dg...) datastoreID := d.Get(mkResourceVirtualEnvironmentFileDatastoreID).(string) - fileName, err := resourceVirtualEnvironmentFileGetFileName(d) + fileName, err := fileGetFileName(d) diags = append(diags, diag.FromErr(err)...) nodeName := d.Get(mkResourceVirtualEnvironmentFileNodeName).(string) @@ -239,7 +237,7 @@ func resourceVirtualEnvironmentFileCreate( sourceFileChecksum := sourceFileBlock[mkResourceVirtualEnvironmentFileSourceFileChecksum].(string) sourceFileInsecure := sourceFileBlock[mkResourceVirtualEnvironmentFileSourceFileInsecure].(bool) - if resourceVirtualEnvironmentFileIsURL(d) { + if fileIsURL(d) { tflog.Debug(ctx, "Downloading file from URL", map[string]interface{}{ "url": sourceFilePath, }) @@ -393,19 +391,17 @@ func resourceVirtualEnvironmentFileCreate( return diag.FromErr(err) } - volumeID, diags := resourceVirtualEnvironmentFileGetVolumeID(d) + volumeID, diags := fileGetVolumeID(d) if diags.HasError() { return diags } d.SetId(*volumeID) - return resourceVirtualEnvironmentFileRead(ctx, d, m) + return fileRead(ctx, d, m) } -func resourceVirtualEnvironmentFileGetContentType( - d *schema.ResourceData, -) (*string, diag.Diagnostics) { +func fileGetContentType(d *schema.ResourceData) (*string, diag.Diagnostics) { contentType := d.Get(mkResourceVirtualEnvironmentFileContentType).(string) sourceFile := d.Get(mkResourceVirtualEnvironmentFileSourceFile).([]interface{}) sourceRaw := d.Get(mkResourceVirtualEnvironmentFileSourceRaw).([]interface{}) @@ -457,7 +453,7 @@ func resourceVirtualEnvironmentFileGetContentType( return &contentType, diags } -func resourceVirtualEnvironmentFileGetFileName(d *schema.ResourceData) (*string, error) { +func fileGetFileName(d *schema.ResourceData) (*string, error) { sourceFile := d.Get(mkResourceVirtualEnvironmentFileSourceFile).([]interface{}) sourceRaw := d.Get(mkResourceVirtualEnvironmentFileSourceRaw).([]interface{}) @@ -480,7 +476,7 @@ func resourceVirtualEnvironmentFileGetFileName(d *schema.ResourceData) (*string, } if sourceFileFileName == "" { - if resourceVirtualEnvironmentFileIsURL(d) { + if fileIsURL(d) { downloadURL, err := url.ParseRequestURI(sourceFilePath) if err != nil { return nil, err @@ -503,21 +499,21 @@ func resourceVirtualEnvironmentFileGetFileName(d *schema.ResourceData) (*string, return &sourceFileFileName, nil } -func resourceVirtualEnvironmentFileGetVolumeID(d *schema.ResourceData) (*string, diag.Diagnostics) { - fileName, err := resourceVirtualEnvironmentFileGetFileName(d) +func fileGetVolumeID(d *schema.ResourceData) (*string, diag.Diagnostics) { + fileName, err := fileGetFileName(d) if err != nil { return nil, diag.FromErr(err) } datastoreID := d.Get(mkResourceVirtualEnvironmentFileDatastoreID).(string) - contentType, diags := resourceVirtualEnvironmentFileGetContentType(d) + contentType, diags := fileGetContentType(d) volumeID := fmt.Sprintf("%s:%s/%s", datastoreID, *contentType, *fileName) return &volumeID, diags } -func resourceVirtualEnvironmentFileIsURL(d *schema.ResourceData) bool { +func fileIsURL(d *schema.ResourceData) bool { sourceFile := d.Get(mkResourceVirtualEnvironmentFileSourceFile).([]interface{}) sourceFilePath := "" @@ -532,12 +528,8 @@ func resourceVirtualEnvironmentFileIsURL(d *schema.ResourceData) bool { strings.HasPrefix(sourceFilePath, "https://") } -func resourceVirtualEnvironmentFileRead( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { - config := m.(providerConfiguration) +func fileRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) @@ -560,8 +552,8 @@ func resourceVirtualEnvironmentFileRead( return diag.FromErr(err) } - fileIsURL := resourceVirtualEnvironmentFileIsURL(d) - fileName, err := resourceVirtualEnvironmentFileGetFileName(d) + fileIsURL := fileIsURL(d) + fileName, err := fileGetFileName(d) if err != nil { return diag.FromErr(err) } @@ -696,12 +688,8 @@ func readURL( return } -func resourceVirtualEnvironmentFileDelete( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { - config := m.(providerConfiguration) +func fileDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) diff --git a/proxmoxtf/resource_virtual_environment_file_test.go b/proxmoxtf/resource/file_test.go similarity index 63% rename from proxmoxtf/resource_virtual_environment_file_test.go rename to proxmoxtf/resource/file_test.go index c96c9001..91f0fe0d 100644 --- a/proxmoxtf/resource_virtual_environment_file_test.go +++ b/proxmoxtf/resource/file_test.go @@ -1,47 +1,53 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public +/* + * 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/. */ + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ -package proxmoxtf +package resource import ( "testing" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf/test" ) -// TestResourceVirtualEnvironmentFileInstantiation tests whether the ResourceVirtualEnvironmentFile instance can be instantiated. -func TestResourceVirtualEnvironmentFileInstantiation(t *testing.T) { - s := resourceVirtualEnvironmentFile() +// TestFileInstantiation tests whether the File instance can be instantiated. +func TestFileInstantiation(t *testing.T) { + t.Parallel() + s := File() if s == nil { - t.Fatalf("Cannot instantiate resourceVirtualEnvironmentFile") + t.Fatalf("Cannot instantiate File") } } -// TestResourceVirtualEnvironmentFileSchema tests the resourceVirtualEnvironmentFile schema. -func TestResourceVirtualEnvironmentFileSchema(t *testing.T) { - s := resourceVirtualEnvironmentFile() +// TestFileSchema tests the File schema. +func TestFileSchema(t *testing.T) { + t.Parallel() + s := File() - testRequiredArguments(t, s, []string{ + test.AssertRequiredArguments(t, s, []string{ mkResourceVirtualEnvironmentFileDatastoreID, mkResourceVirtualEnvironmentFileNodeName, }) - testOptionalArguments(t, s, []string{ + test.AssertOptionalArguments(t, s, []string{ mkResourceVirtualEnvironmentFileContentType, mkResourceVirtualEnvironmentFileSourceFile, mkResourceVirtualEnvironmentFileSourceRaw, }) - testComputedAttributes(t, s, []string{ + test.AssertComputedAttributes(t, s, []string{ mkResourceVirtualEnvironmentFileFileModificationDate, mkResourceVirtualEnvironmentFileFileName, mkResourceVirtualEnvironmentFileFileSize, mkResourceVirtualEnvironmentFileFileTag, }) - testValueTypes(t, s, map[string]schema.ValueType{ + test.AssertValueTypes(t, s, map[string]schema.ValueType{ mkResourceVirtualEnvironmentFileContentType: schema.TypeString, mkResourceVirtualEnvironmentFileDatastoreID: schema.TypeString, mkResourceVirtualEnvironmentFileFileModificationDate: schema.TypeString, @@ -53,20 +59,20 @@ func TestResourceVirtualEnvironmentFileSchema(t *testing.T) { mkResourceVirtualEnvironmentFileSourceRaw: schema.TypeList, }) - sourceFileSchema := testNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentFileSourceFile) + sourceFileSchema := test.AssertNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentFileSourceFile) - testRequiredArguments(t, sourceFileSchema, []string{ + test.AssertRequiredArguments(t, sourceFileSchema, []string{ mkResourceVirtualEnvironmentFileSourceFilePath, }) - testOptionalArguments(t, sourceFileSchema, []string{ + test.AssertOptionalArguments(t, sourceFileSchema, []string{ mkResourceVirtualEnvironmentFileSourceFileChanged, mkResourceVirtualEnvironmentFileSourceFileChecksum, mkResourceVirtualEnvironmentFileSourceFileFileName, mkResourceVirtualEnvironmentFileSourceFileInsecure, }) - testValueTypes(t, sourceFileSchema, map[string]schema.ValueType{ + test.AssertValueTypes(t, sourceFileSchema, map[string]schema.ValueType{ mkResourceVirtualEnvironmentFileSourceFileChanged: schema.TypeBool, mkResourceVirtualEnvironmentFileSourceFileChecksum: schema.TypeString, mkResourceVirtualEnvironmentFileSourceFileFileName: schema.TypeString, @@ -74,18 +80,18 @@ func TestResourceVirtualEnvironmentFileSchema(t *testing.T) { mkResourceVirtualEnvironmentFileSourceFilePath: schema.TypeString, }) - sourceRawSchema := testNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentFileSourceRaw) + sourceRawSchema := test.AssertNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentFileSourceRaw) - testRequiredArguments(t, sourceRawSchema, []string{ + test.AssertRequiredArguments(t, sourceRawSchema, []string{ mkResourceVirtualEnvironmentFileSourceRawData, mkResourceVirtualEnvironmentFileSourceRawFileName, }) - testOptionalArguments(t, sourceRawSchema, []string{ + test.AssertOptionalArguments(t, sourceRawSchema, []string{ mkResourceVirtualEnvironmentFileSourceRawResize, }) - testValueTypes(t, sourceRawSchema, map[string]schema.ValueType{ + test.AssertValueTypes(t, sourceRawSchema, map[string]schema.ValueType{ mkResourceVirtualEnvironmentFileSourceRawData: schema.TypeString, mkResourceVirtualEnvironmentFileSourceRawFileName: schema.TypeString, mkResourceVirtualEnvironmentFileSourceRawResize: schema.TypeInt, diff --git a/proxmoxtf/resource/firewall/alias.go b/proxmoxtf/resource/firewall/alias.go new file mode 100644 index 00000000..a5e069e2 --- /dev/null +++ b/proxmoxtf/resource/firewall/alias.go @@ -0,0 +1,141 @@ +/* + * 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" + "strings" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmox/firewall" + "github.com/bpg/terraform-provider-proxmox/proxmoxtf/structure" +) + +const ( + mkAliasName = "name" + mkAliasCIDR = "cidr" + mkAliasComment = "comment" +) + +func Alias() *schema.Resource { + s := map[string]*schema.Schema{ + mkAliasName: { + Type: schema.TypeString, + Description: "Alias name", + Required: true, + }, + mkAliasCIDR: { + Type: schema.TypeString, + Description: "IP/CIDR block", + Required: true, + }, + mkAliasComment: { + Type: schema.TypeString, + Description: "Alias comment", + Optional: true, + Default: "", + }, + } + + structure.MergeSchema(s, selectorSchema()) + + return &schema.Resource{ + Schema: s, + CreateContext: selectFirewallAPI(aliasCreate), + ReadContext: selectFirewallAPI(aliasRead), + UpdateContext: selectFirewallAPI(aliasUpdate), + DeleteContext: selectFirewallAPI(aliasDelete), + } +} + +func aliasCreate(ctx context.Context, api firewall.API, d *schema.ResourceData) diag.Diagnostics { + comment := d.Get(mkAliasComment).(string) + name := d.Get(mkAliasName).(string) + cidr := d.Get(mkAliasCIDR).(string) + + body := &firewall.AliasCreateRequestBody{ + Comment: &comment, + Name: name, + CIDR: cidr, + } + + err := api.CreateAlias(ctx, body) + if err != nil { + return diag.FromErr(err) + } + + d.SetId(name) + + return aliasRead(ctx, api, d) +} + +func aliasRead(ctx context.Context, api firewall.API, d *schema.ResourceData) diag.Diagnostics { + name := d.Id() + alias, err := api.GetAlias(ctx, name) + if err != nil { + if strings.Contains(err.Error(), "no such alias") { + d.SetId("") + return nil + } + return diag.FromErr(err) + } + + aliasMap := map[string]interface{}{ + mkAliasComment: alias.Comment, + mkAliasName: alias.Name, + mkAliasCIDR: alias.CIDR, + } + + for key, val := range aliasMap { + err = d.Set(key, val) + if err != nil { + return diag.FromErr(err) + } + } + + return nil +} + +func aliasUpdate(ctx context.Context, api firewall.API, d *schema.ResourceData) diag.Diagnostics { + comment := d.Get(mkAliasComment).(string) + cidr := d.Get(mkAliasCIDR).(string) + newName := d.Get(mkAliasName).(string) + previousName := d.Id() + + body := &firewall.AliasUpdateRequestBody{ + ReName: newName, + CIDR: cidr, + Comment: &comment, + } + + err := api.UpdateAlias(ctx, previousName, body) + if err != nil { + return diag.FromErr(err) + } + + d.SetId(newName) + + return aliasRead(ctx, api, d) +} + +func aliasDelete(ctx context.Context, api firewall.API, d *schema.ResourceData) diag.Diagnostics { + name := d.Id() + err := api.DeleteAlias(ctx, name) + if err != nil { + if strings.Contains(err.Error(), "no such alias") { + d.SetId("") + return nil + } + return diag.FromErr(err) + } + + d.SetId("") + + return nil +} diff --git a/proxmoxtf/resource/firewall/alias_test.go b/proxmoxtf/resource/firewall/alias_test.go new file mode 100644 index 00000000..8e655fa9 --- /dev/null +++ b/proxmoxtf/resource/firewall/alias_test.go @@ -0,0 +1,45 @@ +/* + * 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 ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/stretchr/testify/require" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf/structure" +) + +// TestAliasInstantiation tests whether the Alias instance can be instantiated. +func TestAliasInstantiation(t *testing.T) { + t.Parallel() + require.NotNilf(t, Alias(), "Cannot instantiate Alias") +} + +// TestAliasSchema tests the Alias Schema. +func TestAliasSchema(t *testing.T) { + t.Parallel() + s := Alias().Schema + + structure.AssertRequiredArguments(t, s, []string{ + mkAliasName, + mkAliasCIDR, + }) + + structure.AssertOptionalArguments(t, s, []string{ + mkSelectorVMID, + mkSelectorNodeName, + mkAliasComment, + }) + + structure.AssertValueTypes(t, s, map[string]schema.ValueType{ + mkAliasName: schema.TypeString, + mkAliasCIDR: schema.TypeString, + mkAliasComment: schema.TypeString, + }) +} diff --git a/proxmoxtf/resource/firewall/ipset.go b/proxmoxtf/resource/firewall/ipset.go new file mode 100644 index 00000000..8a62a93f --- /dev/null +++ b/proxmoxtf/resource/firewall/ipset.go @@ -0,0 +1,248 @@ +/* + * 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" + "strings" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmox/firewall" + "github.com/bpg/terraform-provider-proxmox/proxmox/types" + "github.com/bpg/terraform-provider-proxmox/proxmoxtf/structure" +) + +const ( + dvIPSetCIDRComment = "" + dvIPSetCIDRNoMatch = false + + mkIPSetName = "name" + mkIPSetCIDR = "cidr" + mkIPSetCIDRName = "name" + mkIPSetCIDRComment = "comment" + mkIPSetCIDRNoMatch = "nomatch" +) + +func IPSet() *schema.Resource { + s := map[string]*schema.Schema{ + mkIPSetName: { + Type: schema.TypeString, + Description: "IPSet name", + Required: true, + ForceNew: false, + }, + mkIPSetCIDRComment: { + Type: schema.TypeString, + Description: "IPSet comment", + Optional: true, + Default: dvIPSetCIDRComment, + }, + mkIPSetCIDR: { + Type: schema.TypeList, + Description: "List of IP or Networks", + Optional: true, + ForceNew: true, + DefaultFunc: func() (interface{}, error) { + return []interface{}{}, nil + }, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + mkIPSetCIDRName: { + Type: schema.TypeString, + Description: "Network/IP specification in CIDR format", + Required: true, + ForceNew: true, + }, + mkIPSetCIDRNoMatch: { + Type: schema.TypeBool, + Description: "No match this IP/CIDR", + Optional: true, + Default: dvIPSetCIDRNoMatch, + ForceNew: true, + }, + mkIPSetCIDRComment: { + Type: schema.TypeString, + Description: "IP/CIDR comment", + Optional: true, + Default: dvIPSetCIDRComment, + ForceNew: true, + }, + }, + }, + MaxItems: 14, + MinItems: 0, + }, + } + + structure.MergeSchema(s, selectorSchema()) + + return &schema.Resource{ + Schema: s, + CreateContext: selectFirewallAPI(ipSetCreate), + ReadContext: selectFirewallAPI(ipSetRead), + UpdateContext: selectFirewallAPI(ipSetUpdate), + DeleteContext: selectFirewallAPI(ipSetDelete), + } +} + +func ipSetCreate(ctx context.Context, api firewall.API, d *schema.ResourceData) diag.Diagnostics { + comment := d.Get(mkIPSetCIDRComment).(string) + name := d.Get(mkIPSetName).(string) + + ipSets := d.Get(mkIPSetCIDR).([]interface{}) + ipSetsArray := make(firewall.IPSetContent, len(ipSets)) + + for i, v := range ipSets { + ipSetMap := v.(map[string]interface{}) + ipSetObject := firewall.IPSetGetResponseData{} + + cidr := ipSetMap[mkIPSetCIDRName].(string) + noMatch := ipSetMap[mkIPSetCIDRNoMatch].(bool) + comm := ipSetMap[mkIPSetCIDRComment].(string) + + if comm != "" { + ipSetObject.Comment = &comm + } + ipSetObject.CIDR = cidr + + if noMatch { + noMatchBool := types.CustomBool(true) + ipSetObject.NoMatch = &noMatchBool + } + + ipSetsArray[i] = ipSetObject + } + + body := &firewall.IPSetCreateRequestBody{ + Comment: comment, + Name: name, + } + + err := api.CreateIPSet(ctx, body) + if err != nil { + return diag.FromErr(err) + } + + for _, v := range ipSetsArray { + err = api.AddCIDRToIPSet(ctx, name, v) + if err != nil { + return diag.FromErr(err) + } + } + + d.SetId(name) + + return ipSetRead(ctx, api, d) +} + +func ipSetRead(ctx context.Context, api firewall.API, d *schema.ResourceData) diag.Diagnostics { + var diags diag.Diagnostics + + name := d.Id() + + allIPSets, err := api.ListIPSets(ctx) + if err != nil { + return diag.FromErr(err) + } + + for _, v := range allIPSets { + if v.Name == name { + err = d.Set(mkIPSetName, v.Name) + diags = append(diags, diag.FromErr(err)...) + err = d.Set(mkIPSetCIDRComment, v.Comment) + diags = append(diags, diag.FromErr(err)...) + break + } + } + + ipSet, err := api.GetIPSetContent(ctx, name) + if err != nil { + if strings.Contains(err.Error(), "no such IPSet") { + d.SetId("") + return nil + } + diags = append(diags, diag.FromErr(err)...) + return diags + } + + //nolint:prealloc + var entries []interface{} + for key := range ipSet { + entry := map[string]interface{}{} + + entry[mkIPSetCIDRName] = ipSet[key].CIDR + entry[mkIPSetCIDRNoMatch] = ipSet[key].NoMatch + entry[mkIPSetCIDRComment] = ipSet[key].Comment + + entries = append(entries, entry) + } + + err = d.Set(mkIPSetCIDR, entries) + diags = append(diags, diag.FromErr(err)...) + + return diags +} + +func ipSetUpdate(ctx context.Context, api firewall.API, d *schema.ResourceData) diag.Diagnostics { + comment := d.Get(mkIPSetCIDRComment).(string) + newName := d.Get(mkIPSetName).(string) + previousName := d.Id() + + body := &firewall.IPSetUpdateRequestBody{ + ReName: previousName, + Name: newName, + Comment: &comment, + } + + err := api.UpdateIPSet(ctx, body) + if err != nil { + return diag.FromErr(err) + } + + d.SetId(newName) + + return ipSetRead(ctx, api, d) +} + +func ipSetDelete(ctx context.Context, api firewall.API, d *schema.ResourceData) diag.Diagnostics { + var diags diag.Diagnostics + + name := d.Id() + + IPSetContent, err := api.GetIPSetContent(ctx, name) + if err != nil { + return diag.FromErr(err) + } + + // PVE requires content of IPSet be cleared before removal + if len(IPSetContent) > 0 { + for _, ipSet := range IPSetContent { + err = api.DeleteIPSetContent(ctx, name, ipSet.CIDR) + diags = append(diags, diag.FromErr(err)...) + } + } + + if diags.HasError() { + return diags + } + + err = api.DeleteIPSet(ctx, name) + if err != nil { + if strings.Contains(err.Error(), "no such IPSet") { + d.SetId("") + return nil + } + + return diag.FromErr(err) + } + + d.SetId("") + + return nil +} diff --git a/proxmoxtf/resource/firewall/ipset_test.go b/proxmoxtf/resource/firewall/ipset_test.go new file mode 100644 index 00000000..51ffdcf9 --- /dev/null +++ b/proxmoxtf/resource/firewall/ipset_test.go @@ -0,0 +1,63 @@ +/* + * 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 ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/stretchr/testify/require" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf/structure" +) + +// TestIPSetInstantiation tests whether the IPSet +// instance can be instantiated. +func TestIPSetInstantiation(t *testing.T) { + t.Parallel() + require.NotNilf(t, IPSet(), "Cannot instantiate IPSet") +} + +// TestIPSetSchema tests the IPSet Schema. +func TestIPSetSchema(t *testing.T) { + t.Parallel() + s := IPSet().Schema + + structure.AssertRequiredArguments(t, s, []string{ + mkIPSetName, + }) + + structure.AssertOptionalArguments(t, s, []string{ + mkSelectorVMID, + mkSelectorNodeName, + mkIPSetCIDR, + mkIPSetCIDRComment, + }) + + structure.AssertValueTypes(t, s, map[string]schema.ValueType{ + mkIPSetName: schema.TypeString, + mkIPSetCIDR: schema.TypeList, + mkIPSetCIDRComment: schema.TypeString, + }) + + nested := structure.AssertNestedSchemaExistence(t, s, mkIPSetCIDR).Schema + + structure.AssertRequiredArguments(t, nested, []string{ + mkIPSetCIDRName, + }) + + structure.AssertOptionalArguments(t, nested, []string{ + mkIPSetCIDRComment, + mkIPSetCIDRNoMatch, + }) + + structure.AssertValueTypes(t, nested, map[string]schema.ValueType{ + mkIPSetCIDRName: schema.TypeString, + mkIPSetCIDRComment: schema.TypeString, + mkIPSetCIDRNoMatch: schema.TypeBool, + }) +} diff --git a/proxmoxtf/resource/firewall/options.go b/proxmoxtf/resource/firewall/options.go new file mode 100644 index 00000000..e2722db8 --- /dev/null +++ b/proxmoxtf/resource/firewall/options.go @@ -0,0 +1,234 @@ +/* + * 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" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmox/firewall" + "github.com/bpg/terraform-provider-proxmox/proxmox/types" + "github.com/bpg/terraform-provider-proxmox/proxmoxtf/resource/validator" + "github.com/bpg/terraform-provider-proxmox/proxmoxtf/structure" +) + +const ( + dvDHCP = false + dvEnabled = false + dvLogLevelIN = "nolog" + dvLogLevelOUT = "nolog" + dvMACFilter = true + dvNDP = false + dvPolicyIn = "DROP" + dvPolicyOut = "ACCEPT" + dvReadv = true + + mkDHCP = "dhcp" + mkEnabled = "enabled" + mkIPFilter = "ipfilter" + mkLogLevelIN = "log_level_in" + mkLogLevelOUT = "log_level_out" + mkMACFilter = "macfilter" + mkNDP = "ndp" + mkPolicyIn = "input_policy" + mkPolicyOut = "output_policy" + mkRadv = "radv" +) + +func Options() *schema.Resource { + s := map[string]*schema.Schema{ + mkDHCP: { + Type: schema.TypeBool, + Description: "Enable DHCP", + Optional: true, + Default: dvDHCP, + }, + mkEnabled: { + Type: schema.TypeBool, + Description: "Enable or disable the firewall", + Optional: true, + Default: dvEnabled, + }, + mkIPFilter: { + Type: schema.TypeBool, + Description: "Enable default IP filters. This is equivalent to adding an empty ipfilter-net 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.", + Optional: true, + }, + mkLogLevelIN: { + Type: schema.TypeString, + Description: "Log level for incoming traffic.", + Optional: true, + Default: dvLogLevelIN, + ValidateDiagFunc: validator.FirewallLogLevel(), + }, + mkLogLevelOUT: { + Type: schema.TypeString, + Description: "Log level for outgoing traffic.", + Optional: true, + Default: dvLogLevelOUT, + ValidateDiagFunc: validator.FirewallLogLevel(), + }, + mkMACFilter: { + Type: schema.TypeBool, + Description: "Enable MAC address filtering", + Optional: true, + Default: dvMACFilter, + }, + mkNDP: { + Type: schema.TypeBool, + Description: "Enable NDP (Neighbor Discovery Protocol)", + Optional: true, + Default: dvNDP, + }, + mkPolicyIn: { + Type: schema.TypeString, + Description: "Default policy for incoming traffic", + Optional: true, + Default: dvPolicyIn, + ValidateDiagFunc: validator.FirewallPolicy(), + }, + mkPolicyOut: { + Type: schema.TypeString, + Description: "Default policy for outgoing traffic", + Optional: true, + Default: dvPolicyOut, + ValidateDiagFunc: validator.FirewallPolicy(), + }, + mkRadv: { + Type: schema.TypeBool, + Description: "Allow sending Router Advertisement", + Optional: true, + Default: dvReadv, + }, + } + + structure.MergeSchema(s, selectorSchemaMandatory()) + + return &schema.Resource{ + Schema: s, + CreateContext: selectFirewallAPI(optionsSet), + ReadContext: selectFirewallAPI(optionsRead), + UpdateContext: selectFirewallAPI(optionsUpdate), + DeleteContext: selectFirewallAPI(optionsDelete), + } +} + +func optionsSet(ctx context.Context, api firewall.API, d *schema.ResourceData) diag.Diagnostics { + dhcp := types.CustomBool(d.Get(mkDHCP).(bool)) + enabled := types.CustomBool(d.Get(mkEnabled).(bool)) + ipFilter := types.CustomBool(d.Get(mkIPFilter).(bool)) + logLevelIn := d.Get(mkLogLevelIN).(string) + logLevelOut := d.Get(mkLogLevelOUT).(string) + macFilter := types.CustomBool(d.Get(mkMACFilter).(bool)) + ndp := types.CustomBool(d.Get(mkNDP).(bool)) + policyIn := d.Get(mkPolicyIn).(string) + policyOut := d.Get(mkPolicyOut).(string) + radv := types.CustomBool(d.Get(mkRadv).(bool)) + + body := &firewall.OptionsPutRequestBody{ + DHCP: &dhcp, + Enable: &enabled, + IPFilter: &ipFilter, + LogLevelIN: &logLevelIn, + LogLevelOUT: &logLevelOut, + MACFilter: &macFilter, + NDP: &ndp, + PolicyIn: &policyIn, + PolicyOut: &policyOut, + RAdv: &radv, + } + + err := api.SetOptions(ctx, body) + if err != nil { + return diag.FromErr(err) + } + + d.SetId(api.GetOptionsID()) + + return optionsRead(ctx, api, d) +} + +func optionsRead(ctx context.Context, api firewall.API, d *schema.ResourceData) diag.Diagnostics { + var diags diag.Diagnostics + + options, err := api.GetOptions(ctx) + if err != nil { + return diag.FromErr(err) + } + + if options.DHCP != nil { + err = d.Set(mkDHCP, *options.DHCP) + diags = append(diags, diag.FromErr(err)...) + } + + if options.Enable != nil { + err = d.Set(mkEnabled, *options.Enable) + diags = append(diags, diag.FromErr(err)...) + } + + if options.IPFilter != nil { + err = d.Set(mkIPFilter, *options.IPFilter) + diags = append(diags, diag.FromErr(err)...) + } + + if options.LogLevelIN != nil { + err = d.Set(mkLogLevelIN, *options.LogLevelIN) + diags = append(diags, diag.FromErr(err)...) + } + + if options.LogLevelOUT != nil { + err = d.Set(mkLogLevelOUT, *options.LogLevelOUT) + diags = append(diags, diag.FromErr(err)...) + } + + if options.MACFilter != nil { + err = d.Set(mkMACFilter, *options.MACFilter) + diags = append(diags, diag.FromErr(err)...) + } + + if options.NDP != nil { + err = d.Set(mkNDP, *options.NDP) + diags = append(diags, diag.FromErr(err)...) + } + + if options.PolicyIn != nil { + err = d.Set(mkPolicyIn, *options.PolicyIn) + diags = append(diags, diag.FromErr(err)...) + } + + if options.PolicyOut != nil { + err = d.Set(mkPolicyOut, *options.PolicyOut) + diags = append(diags, diag.FromErr(err)...) + } + + if options.RAdv != nil { + err = d.Set(mkRadv, *options.RAdv) + diags = append(diags, diag.FromErr(err)...) + } + + return diags +} + +func optionsUpdate(ctx context.Context, api firewall.API, d *schema.ResourceData) diag.Diagnostics { + diags := optionsSet(ctx, api, d) + if diags.HasError() { + return diags + } + + return optionsRead(ctx, api, d) +} + +func optionsDelete(_ context.Context, _ firewall.API, d *schema.ResourceData) diag.Diagnostics { + d.SetId("") + + return nil +} diff --git a/proxmoxtf/resource/firewall/options_test.go b/proxmoxtf/resource/firewall/options_test.go new file mode 100644 index 00000000..83ecfd94 --- /dev/null +++ b/proxmoxtf/resource/firewall/options_test.go @@ -0,0 +1,54 @@ +/* + * 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 ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/stretchr/testify/require" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf/structure" +) + +// TestOptionsInstantiation tests whether the Options instance can be instantiated. +func TestOptionsInstantiation(t *testing.T) { + t.Parallel() + require.NotNilf(t, Options(), "Cannot instantiate Options") +} + +// TestOptionsSchema tests the Options Schema. +func TestOptionsSchema(t *testing.T) { + t.Parallel() + s := Options().Schema + + structure.AssertOptionalArguments(t, s, []string{ + mkDHCP, + mkEnabled, + mkIPFilter, + mkLogLevelIN, + mkLogLevelOUT, + mkMACFilter, + mkNDP, + mkPolicyIn, + mkPolicyOut, + mkRadv, + }) + + structure.AssertValueTypes(t, s, map[string]schema.ValueType{ + mkDHCP: schema.TypeBool, + mkEnabled: schema.TypeBool, + mkIPFilter: schema.TypeBool, + mkLogLevelIN: schema.TypeString, + mkLogLevelOUT: schema.TypeString, + mkMACFilter: schema.TypeBool, + mkNDP: schema.TypeBool, + mkPolicyIn: schema.TypeString, + mkPolicyOut: schema.TypeString, + mkRadv: schema.TypeBool, + }) +} diff --git a/proxmoxtf/resource/firewall/rules.go b/proxmoxtf/resource/firewall/rules.go new file mode 100644 index 00000000..2a15d539 --- /dev/null +++ b/proxmoxtf/resource/firewall/rules.go @@ -0,0 +1,401 @@ +/* + * 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" + "sort" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + + "github.com/bpg/terraform-provider-proxmox/proxmox/firewall" + "github.com/bpg/terraform-provider-proxmox/proxmox/types" + "github.com/bpg/terraform-provider-proxmox/proxmoxtf/resource/validator" + "github.com/bpg/terraform-provider-proxmox/proxmoxtf/structure" +) + +const ( + dvRuleComment = "" + dvRuleDPort = "" + dvRuleDest = "" + dvRuleEnable = true + dvRuleIface = "" + dvRuleLog = "nolog" + dvRuleMacro = "" + dvRuleProto = "" + dvRuleSPort = "" + dvRuleSource = "" + + MkRule = "rule" + + mkRuleAction = "action" + mkRuleComment = "comment" + mkRuleDPort = "dport" + mkRuleDest = "dest" + mkRuleEnable = "enable" + mkRuleIFace = "iface" + mkRuleLog = "log" + mkRuleMacro = "macro" + mkRulePos = "pos" + mkRuleProto = "proto" + mkRuleSource = "source" + mkRuleSPort = "sport" + mkRuleType = "type" +) + +func Rules() *schema.Resource { + rule := map[string]*schema.Schema{ + mkRulePos: { + Type: schema.TypeInt, + Description: "Rules position", + Computed: true, + }, + mkRuleAction: { + Type: schema.TypeString, + Description: "Rules action ('ACCEPT', 'DROP', 'REJECT')", + Required: true, + ValidateDiagFunc: validator.FirewallPolicy(), + }, + mkRuleType: { + Type: schema.TypeString, + Description: "Rules type ('in', 'out')", + Required: true, + ValidateDiagFunc: validation.ToDiagFunc(validation.StringInSlice([]string{"in", "out"}, true)), + }, + mkRuleComment: { + Type: schema.TypeString, + Description: "Rules comment", + Optional: true, + Default: dvRuleComment, + }, + mkRuleDest: { + Type: schema.TypeString, + Description: "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.", + Optional: true, + Default: dvRuleDest, + }, + mkRuleDPort: { + Type: schema.TypeString, + Description: "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.", + Optional: true, + Default: dvRuleDPort, + }, + mkRuleEnable: { + Type: schema.TypeBool, + Description: "Enable rule", + Optional: true, + Default: dvRuleEnable, + }, + mkRuleIFace: { + Type: schema.TypeString, + Description: "Network interface name. You have to use network configuration key names for VMs" + + " and containers ('net\\d+'). Host related rules can use arbitrary strings.", + Optional: true, + Default: dvRuleIface, + }, + mkRuleLog: { + Type: schema.TypeString, + Description: "Log level for this rule ('emerg', 'alert', 'crit', 'err', 'warning', 'notice'," + + " 'info', 'debug', 'nolog')", + Optional: true, + Default: dvRuleLog, + }, + mkRuleMacro: { + Type: schema.TypeString, + Description: "Use predefined standard macro", + Optional: true, + Default: dvRuleMacro, + }, + mkRuleProto: { + Type: schema.TypeString, + Description: "Restrict packet protocol. You can use protocol names or simple numbers " + + "(0-255), as defined in '/etc/protocols'.", + Optional: true, + Default: dvRuleProto, + }, + mkRuleSource: { + Type: schema.TypeString, + Description: "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.", + Optional: true, + Default: dvRuleSource, + }, + mkRuleSPort: { + Type: schema.TypeString, + Description: "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.", + Optional: true, + Default: dvRuleSPort, + }, + } + + s := map[string]*schema.Schema{ + MkRule: { + Type: schema.TypeList, + Description: "List of rules", + Required: true, + ForceNew: true, + Elem: &schema.Resource{Schema: rule}, + }, + } + + structure.MergeSchema(s, selectorSchema()) + + return &schema.Resource{ + Schema: s, + CreateContext: invokeRuleAPI(RulesCreate), + ReadContext: invokeRuleAPI(RulesRead), + UpdateContext: invokeRuleAPI(RulesUpdate), + DeleteContext: invokeRuleAPI(RulesDelete), + } +} + +func RulesCreate(ctx context.Context, api firewall.Rule, d *schema.ResourceData) diag.Diagnostics { + var diags diag.Diagnostics + + rules := d.Get(MkRule).([]interface{}) + for i := len(rules) - 1; i >= 0; i-- { + rule := rules[i].(map[string]interface{}) + + ruleBody := firewall.RuleCreateRequestBody{ + BaseRule: *mapToBaseRule(rule), + Action: rule[mkRuleAction].(string), + Type: rule[mkRuleType].(string), + } + + err := api.CreateRule(ctx, &ruleBody) + diags = append(diags, diag.FromErr(err)...) + } + + if diags.HasError() { + return diags + } + + // reset rules, we re-read them (with proper positions) from the API + err := d.Set(MkRule, nil) + if err != nil { + return diag.FromErr(err) + } + + d.SetId(api.GetRulesID()) + + return RulesRead(ctx, api, d) +} + +func RulesRead(ctx context.Context, api firewall.Rule, d *schema.ResourceData) diag.Diagnostics { + var diags diag.Diagnostics + + readRule := func(pos int, ruleMap map[string]interface{}) error { + rule, err := api.GetRule(ctx, pos) + if err != nil { + return fmt.Errorf("error reading rule %d : %w", pos, err) + } + + baseRuleToMap(&rule.BaseRule, ruleMap) + + // pos in the map should be int! + ruleMap[mkRulePos] = pos + ruleMap[mkRuleAction] = rule.Action + ruleMap[mkRuleType] = rule.Type + + return nil + } + + rules := d.Get(MkRule).([]interface{}) + if len(rules) > 0 { + // We have rules in the state, so we need to read them from the API + for _, v := range rules { + ruleMap := v.(map[string]interface{}) + pos := ruleMap[mkRulePos].(int) + + err := readRule(pos, ruleMap) + diags = append(diags, diag.FromErr(err)...) + } + } else { + ruleIDs, err := api.ListRules(ctx) + if err != nil { + return diag.FromErr(err) + } + for _, id := range ruleIDs { + ruleMap := map[string]interface{}{} + err = readRule(id.Pos, ruleMap) + if err != nil { + diags = append(diags, diag.FromErr(err)...) + } else { + rules = append(rules, ruleMap) + } + } + } + + if diags.HasError() { + return diags + } + + err := d.Set(MkRule, rules) + diags = append(diags, diag.FromErr(err)...) + + return diags +} + +func RulesUpdate(ctx context.Context, api firewall.Rule, d *schema.ResourceData) diag.Diagnostics { + var diags diag.Diagnostics + + rules := d.Get(MkRule).([]interface{}) + for i := len(rules) - 1; i >= 0; i-- { + rule := rules[i].(map[string]interface{}) + + ruleBody := firewall.RuleUpdateRequestBody{ + BaseRule: *mapToBaseRule(rule), + } + + pos := rule[mkRulePos].(int) + if pos >= 0 { + ruleBody.Pos = &pos + } + action := rule[mkRuleAction].(string) + if action != "" { + ruleBody.Action = &action + } + rType := rule[mkRuleType].(string) + if rType != "" { + ruleBody.Type = &rType + } + + err := api.UpdateRule(ctx, pos, &ruleBody) + if err != nil { + diags = append(diags, diag.FromErr(err)...) + } + } + + if diags.HasError() { + return diags + } + + return RulesRead(ctx, api, d) +} + +func RulesDelete(ctx context.Context, api firewall.Rule, d *schema.ResourceData) diag.Diagnostics { + var diags diag.Diagnostics + + rules := d.Get(MkRule).([]interface{}) + sort.Slice(rules, func(i, j int) bool { + ruleI := rules[i].(map[string]interface{}) + ruleJ := rules[j].(map[string]interface{}) + return ruleI[mkRulePos].(int) > ruleJ[mkRulePos].(int) + }) + + for _, v := range rules { + rule := v.(map[string]interface{}) + pos := rule[mkRulePos].(int) + err := api.DeleteRule(ctx, pos) + diags = append(diags, diag.FromErr(err)...) + } + + return diags +} + +func mapToBaseRule(rule map[string]interface{}) *firewall.BaseRule { + baseRule := &firewall.BaseRule{} + + comment := rule[mkRuleComment].(string) + if comment != "" { + baseRule.Comment = &comment + } + dest := rule[mkRuleDest].(string) + if dest != "" { + baseRule.Dest = &dest + } + dport := rule[mkRuleDPort].(string) + if dport != "" { + baseRule.DPort = &dport + } + enable := rule[mkRuleEnable].(bool) + if enable { + enableBool := types.CustomBool(true) + baseRule.Enable = &enableBool + } + iface := rule[mkRuleIFace].(string) + if iface != "" { + baseRule.IFace = &iface + } + log := rule[mkRuleLog].(string) + if log != "" { + baseRule.Log = &log + } + macro := rule[mkRuleMacro].(string) + if macro != "" { + baseRule.Macro = ¯o + } + proto := rule[mkRuleProto].(string) + if proto != "" { + baseRule.Proto = &proto + } + source := rule[mkRuleSource].(string) + if source != "" { + baseRule.Source = &source + } + sport := rule[mkRuleSPort].(string) + if sport != "" { + baseRule.SPort = &sport + } + + return baseRule +} + +func baseRuleToMap(baseRule *firewall.BaseRule, rule map[string]interface{}) { + if baseRule.Comment != nil { + rule[mkRuleComment] = *baseRule.Comment + } + if baseRule.Dest != nil { + rule[mkRuleDest] = *baseRule.Dest + } + if baseRule.DPort != nil { + rule[mkRuleDPort] = *baseRule.DPort + } + if baseRule.Enable != nil { + rule[mkRuleEnable] = *baseRule.Enable + } + if baseRule.IFace != nil { + rule[mkRuleIFace] = *baseRule.IFace + } + if baseRule.Log != nil { + rule[mkRuleLog] = *baseRule.Log + } + if baseRule.Macro != nil { + rule[mkRuleMacro] = *baseRule.Macro + } + if baseRule.Proto != nil { + rule[mkRuleProto] = *baseRule.Proto + } + if baseRule.Source != nil { + rule[mkRuleSource] = *baseRule.Source + } + if baseRule.SPort != nil { + rule[mkRuleSPort] = *baseRule.SPort + } +} + +func invokeRuleAPI( + f func(context.Context, firewall.Rule, *schema.ResourceData) diag.Diagnostics, +) func(context.Context, *schema.ResourceData, interface{}) diag.Diagnostics { + return func(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + return selectFirewallAPI(func(ctx context.Context, api firewall.API, data *schema.ResourceData) diag.Diagnostics { + return f(ctx, api, data) + })(ctx, d, m) + } +} diff --git a/proxmoxtf/resource/firewall/rules_test.go b/proxmoxtf/resource/firewall/rules_test.go new file mode 100644 index 00000000..ea88a8df --- /dev/null +++ b/proxmoxtf/resource/firewall/rules_test.go @@ -0,0 +1,73 @@ +/* + * 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 ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/stretchr/testify/require" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf/structure" +) + +// TestRuleInstantiation tests whether the Rules instance can be instantiated. +func TestRuleInstantiation(t *testing.T) { + t.Parallel() + require.NotNilf(t, Rules(), "Cannot instantiate Rules") +} + +// TestRuleSchema tests the Rules Schema. +func TestRuleSchema(t *testing.T) { + t.Parallel() + rulesSchema := Rules().Schema + + structure.AssertRequiredArguments(t, rulesSchema, []string{ + MkRule, + }) + + structure.AssertOptionalArguments(t, rulesSchema, []string{ + mkSelectorVMID, + mkSelectorNodeName, + }) + + ruleSchema := structure.AssertNestedSchemaExistence(t, rulesSchema, MkRule).Schema + + structure.AssertRequiredArguments(t, ruleSchema, []string{ + mkRuleAction, + mkRuleType, + }) + + structure.AssertOptionalArguments(t, ruleSchema, []string{ + mkRuleComment, + mkRuleDest, + mkRuleDPort, + mkRuleEnable, + mkRuleIFace, + mkRuleLog, + mkRuleMacro, + mkRuleProto, + mkRuleSource, + mkRuleSPort, + }) + + structure.AssertValueTypes(t, ruleSchema, map[string]schema.ValueType{ + mkRulePos: schema.TypeInt, + mkRuleAction: schema.TypeString, + mkRuleType: schema.TypeString, + mkRuleComment: schema.TypeString, + mkRuleDest: schema.TypeString, + mkRuleDPort: schema.TypeString, + mkRuleEnable: schema.TypeBool, + mkRuleIFace: schema.TypeString, + mkRuleLog: schema.TypeString, + mkRuleMacro: schema.TypeString, + mkRuleProto: schema.TypeString, + mkRuleSource: schema.TypeString, + mkRuleSPort: schema.TypeString, + }) +} diff --git a/proxmoxtf/resource/firewall/selector.go b/proxmoxtf/resource/firewall/selector.go new file mode 100644 index 00000000..4eafb23a --- /dev/null +++ b/proxmoxtf/resource/firewall/selector.go @@ -0,0 +1,74 @@ +/* + * 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" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmox/firewall" + "github.com/bpg/terraform-provider-proxmox/proxmoxtf" +) + +const ( + mkSelectorNodeName = "node_name" + mkSelectorVMID = "vm_id" + mkSelectorContainerID = "container_id" +) + +func selectorSchema() map[string]*schema.Schema { + return map[string]*schema.Schema{ + mkSelectorNodeName: { + Type: schema.TypeString, + Optional: true, + Description: "The name of the node.", + }, + mkSelectorVMID: { + Type: schema.TypeInt, + Optional: true, + Description: "The ID of the VM to manage the firewall for.", + }, + mkSelectorContainerID: { + Type: schema.TypeInt, + Optional: true, + Description: "The ID of the container to manage the firewall for.", + }, + } +} + +func selectorSchemaMandatory() map[string]*schema.Schema { + s := selectorSchema() + s[mkSelectorNodeName].Optional = false + s[mkSelectorNodeName].Required = true + return s +} + +func selectFirewallAPI( + f func(context.Context, firewall.API, *schema.ResourceData) diag.Diagnostics, +) func(context.Context, *schema.ResourceData, interface{}) diag.Diagnostics { + return func(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + config := m.(proxmoxtf.ProviderConfiguration) + veClient, err := config.GetVEClient() + if err != nil { + return diag.FromErr(err) + } + + var api firewall.API = veClient.API().Cluster().Firewall() + if nn, ok := d.GetOk(mkSelectorNodeName); ok { + nodeName := nn.(string) + if v, ok := d.GetOk(mkSelectorVMID); ok { + api = veClient.API().VM(nodeName, v.(int)).Firewall() + } else if v, ok := d.GetOk(mkSelectorContainerID); ok { + api = veClient.API().Container(nodeName, v.(int)).Firewall() + } + } + + return f(ctx, api, d) + } +} diff --git a/proxmoxtf/resource_virtual_environment_group.go b/proxmoxtf/resource/group.go similarity index 82% rename from proxmoxtf/resource_virtual_environment_group.go rename to proxmoxtf/resource/group.go index 17044653..64c5fc7a 100644 --- a/proxmoxtf/resource_virtual_environment_group.go +++ b/proxmoxtf/resource/group.go @@ -1,8 +1,10 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public +/* + * 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/. */ + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ -package proxmoxtf +package resource import ( "context" @@ -12,6 +14,8 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/bpg/terraform-provider-proxmox/proxmox" + "github.com/bpg/terraform-provider-proxmox/proxmox/types" + "github.com/bpg/terraform-provider-proxmox/proxmoxtf" ) const ( @@ -26,7 +30,7 @@ const ( mkResourceVirtualEnvironmentGroupMembers = "members" ) -func resourceVirtualEnvironmentGroup() *schema.Resource { +func Group() *schema.Resource { return &schema.Resource{ Schema: map[string]*schema.Schema{ mkResourceVirtualEnvironmentGroupACL: { @@ -76,19 +80,15 @@ func resourceVirtualEnvironmentGroup() *schema.Resource { Elem: &schema.Schema{Type: schema.TypeString}, }, }, - CreateContext: resourceVirtualEnvironmentGroupCreate, - ReadContext: resourceVirtualEnvironmentGroupRead, - UpdateContext: resourceVirtualEnvironmentGroupUpdate, - DeleteContext: resourceVirtualEnvironmentGroupDelete, + CreateContext: groupCreate, + ReadContext: groupRead, + UpdateContext: groupUpdate, + DeleteContext: groupDelete, } } -func resourceVirtualEnvironmentGroupCreate( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { - config := m.(providerConfiguration) +func groupCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) @@ -112,9 +112,9 @@ func resourceVirtualEnvironmentGroupCreate( aclParsed := d.Get(mkResourceVirtualEnvironmentGroupACL).(*schema.Set).List() for _, v := range aclParsed { - aclDelete := proxmox.CustomBool(false) + aclDelete := types.CustomBool(false) aclEntry := v.(map[string]interface{}) - aclPropagate := proxmox.CustomBool( + aclPropagate := types.CustomBool( aclEntry[mkResourceVirtualEnvironmentGroupACLPropagate].(bool), ) @@ -132,17 +132,13 @@ func resourceVirtualEnvironmentGroupCreate( } } - return resourceVirtualEnvironmentGroupRead(ctx, d, m) + return groupRead(ctx, d, m) } -func resourceVirtualEnvironmentGroupRead( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { +func groupRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { var diags diag.Diagnostics - config := m.(providerConfiguration) + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) @@ -200,12 +196,8 @@ func resourceVirtualEnvironmentGroupRead( return diags } -func resourceVirtualEnvironmentGroupUpdate( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { - config := m.(providerConfiguration) +func groupUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) @@ -227,9 +219,9 @@ func resourceVirtualEnvironmentGroupUpdate( aclParsedOld := aclArgOld.(*schema.Set).List() for _, v := range aclParsedOld { - aclDelete := proxmox.CustomBool(true) + aclDelete := types.CustomBool(true) aclEntry := v.(map[string]interface{}) - aclPropagate := proxmox.CustomBool( + aclPropagate := types.CustomBool( aclEntry[mkResourceVirtualEnvironmentGroupACLPropagate].(bool), ) @@ -250,9 +242,9 @@ func resourceVirtualEnvironmentGroupUpdate( aclParsed := aclArg.(*schema.Set).List() for _, v := range aclParsed { - aclDelete := proxmox.CustomBool(false) + aclDelete := types.CustomBool(false) aclEntry := v.(map[string]interface{}) - aclPropagate := proxmox.CustomBool( + aclPropagate := types.CustomBool( aclEntry[mkResourceVirtualEnvironmentGroupACLPropagate].(bool), ) @@ -270,15 +262,11 @@ func resourceVirtualEnvironmentGroupUpdate( } } - return resourceVirtualEnvironmentGroupRead(ctx, d, m) + return groupRead(ctx, d, m) } -func resourceVirtualEnvironmentGroupDelete( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { - config := m.(providerConfiguration) +func groupDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) @@ -288,9 +276,9 @@ func resourceVirtualEnvironmentGroupDelete( groupID := d.Id() for _, v := range aclParsed { - aclDelete := proxmox.CustomBool(true) + aclDelete := types.CustomBool(true) aclEntry := v.(map[string]interface{}) - aclPropagate := proxmox.CustomBool( + aclPropagate := types.CustomBool( aclEntry[mkResourceVirtualEnvironmentGroupACLPropagate].(bool), ) diff --git a/proxmoxtf/resource/group_test.go b/proxmoxtf/resource/group_test.go new file mode 100644 index 00000000..fe5f17a7 --- /dev/null +++ b/proxmoxtf/resource/group_test.go @@ -0,0 +1,68 @@ +/* + * 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 resource + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf/test" +) + +// TestGroupInstantiation tests whether the Group instance can be instantiated. +func TestGroupInstantiation(t *testing.T) { + t.Parallel() + s := Group() + + if s == nil { + t.Fatalf("Cannot instantiate Group") + } +} + +// TestGroupSchema tests the Group schema. +func TestGroupSchema(t *testing.T) { + t.Parallel() + s := Group() + + test.AssertRequiredArguments(t, s, []string{ + mkResourceVirtualEnvironmentGroupID, + }) + + test.AssertOptionalArguments(t, s, []string{ + mkResourceVirtualEnvironmentGroupACL, + mkResourceVirtualEnvironmentGroupComment, + }) + + test.AssertComputedAttributes(t, s, []string{ + mkResourceVirtualEnvironmentGroupMembers, + }) + + test.AssertValueTypes(t, s, map[string]schema.ValueType{ + mkResourceVirtualEnvironmentGroupACL: schema.TypeSet, + mkResourceVirtualEnvironmentGroupComment: schema.TypeString, + mkResourceVirtualEnvironmentGroupID: schema.TypeString, + mkResourceVirtualEnvironmentGroupMembers: schema.TypeSet, + }) + + aclSchema := test.AssertNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentGroupACL) + + test.AssertRequiredArguments(t, aclSchema, []string{ + mkResourceVirtualEnvironmentGroupACLPath, + mkResourceVirtualEnvironmentGroupACLRoleID, + }) + + test.AssertOptionalArguments(t, aclSchema, []string{ + mkResourceVirtualEnvironmentGroupACLPropagate, + }) + + test.AssertValueTypes(t, aclSchema, map[string]schema.ValueType{ + mkResourceVirtualEnvironmentGroupACLPath: schema.TypeString, + mkResourceVirtualEnvironmentGroupACLPropagate: schema.TypeBool, + mkResourceVirtualEnvironmentGroupACLRoleID: schema.TypeString, + }) +} diff --git a/proxmoxtf/resource_virtual_environment_hosts.go b/proxmoxtf/resource/hosts.go similarity index 84% rename from proxmoxtf/resource_virtual_environment_hosts.go rename to proxmoxtf/resource/hosts.go index efb558df..7572812c 100644 --- a/proxmoxtf/resource_virtual_environment_hosts.go +++ b/proxmoxtf/resource/hosts.go @@ -1,8 +1,10 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public +/* + * 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/. */ + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ -package proxmoxtf +package resource import ( "context" @@ -13,6 +15,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/bpg/terraform-provider-proxmox/proxmox" + "github.com/bpg/terraform-provider-proxmox/proxmoxtf" ) const ( @@ -28,7 +31,7 @@ const ( mkResourceVirtualEnvironmentHostsNodeName = "node_name" ) -func resourceVirtualEnvironmentHosts() *schema.Resource { +func Hosts() *schema.Resource { return &schema.Resource{ Schema: map[string]*schema.Schema{ mkResourceVirtualEnvironmentHostsAddresses: { @@ -99,19 +102,15 @@ func resourceVirtualEnvironmentHosts() *schema.Resource { Required: true, }, }, - CreateContext: resourceVirtualEnvironmentHostsCreate, - ReadContext: resourceVirtualEnvironmentHostsRead, - UpdateContext: resourceVirtualEnvironmentHostsUpdate, - DeleteContext: resourceVirtualEnvironmentHostsDelete, + CreateContext: hostsCreate, + ReadContext: hostsRead, + UpdateContext: hostsUpdate, + DeleteContext: hostsDelete, } } -func resourceVirtualEnvironmentHostsCreate( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { - diags := resourceVirtualEnvironmentHostsUpdate(ctx, d, m) +func hostsCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + diags := hostsUpdate(ctx, d, m) if diags.HasError() { return diags } @@ -123,14 +122,10 @@ func resourceVirtualEnvironmentHostsCreate( return diags } -func resourceVirtualEnvironmentHostsRead( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { +func hostsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { var diags diag.Diagnostics - config := m.(providerConfiguration) + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) @@ -197,12 +192,8 @@ func resourceVirtualEnvironmentHostsRead( return diags } -func resourceVirtualEnvironmentHostsUpdate( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { - config := m.(providerConfiguration) +func hostsUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) @@ -237,14 +228,10 @@ func resourceVirtualEnvironmentHostsUpdate( return diag.FromErr(err) } - return resourceVirtualEnvironmentHostsRead(ctx, d, m) + return hostsRead(ctx, d, m) } -func resourceVirtualEnvironmentHostsDelete( - _ context.Context, - d *schema.ResourceData, - _ interface{}, -) diag.Diagnostics { +func hostsDelete(_ context.Context, d *schema.ResourceData, _ interface{}) diag.Diagnostics { d.SetId("") return nil diff --git a/proxmoxtf/resource_virtual_environment_hosts_test.go b/proxmoxtf/resource/hosts_test.go similarity index 53% rename from proxmoxtf/resource_virtual_environment_hosts_test.go rename to proxmoxtf/resource/hosts_test.go index 4a98d1dd..e571a415 100644 --- a/proxmoxtf/resource_virtual_environment_hosts_test.go +++ b/proxmoxtf/resource/hosts_test.go @@ -1,41 +1,47 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public +/* + * 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/. */ + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ -package proxmoxtf +package resource import ( "testing" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf/test" ) -// TestResourceVirtualEnvironmentHostsInstantiation tests whether the ResourceVirtualEnvironmentHosts instance can be instantiated. -func TestResourceVirtualEnvironmentHostsInstantiation(t *testing.T) { - s := resourceVirtualEnvironmentHosts() +// TestHostsInstantiation tests whether the Hosts instance can be instantiated. +func TestHostsInstantiation(t *testing.T) { + t.Parallel() + s := Hosts() if s == nil { - t.Fatalf("Cannot instantiate resourceVirtualEnvironmentHosts") + t.Fatalf("Cannot instantiate Hosts") } } -// TestResourceVirtualEnvironmentHostsSchema tests the resourceVirtualEnvironmentHosts schema. -func TestResourceVirtualEnvironmentHostsSchema(t *testing.T) { - s := resourceVirtualEnvironmentHosts() +// TestHostsSchema tests the Hosts schema. +func TestHostsSchema(t *testing.T) { + t.Parallel() + s := Hosts() - testRequiredArguments(t, s, []string{ + test.AssertRequiredArguments(t, s, []string{ mkResourceVirtualEnvironmentHostsEntry, mkResourceVirtualEnvironmentHostsNodeName, }) - testComputedAttributes(t, s, []string{ + test.AssertComputedAttributes(t, s, []string{ mkResourceVirtualEnvironmentHostsAddresses, mkResourceVirtualEnvironmentHostsDigest, mkResourceVirtualEnvironmentHostsEntries, mkResourceVirtualEnvironmentHostsHostnames, }) - testValueTypes(t, s, map[string]schema.ValueType{ + test.AssertValueTypes(t, s, map[string]schema.ValueType{ mkResourceVirtualEnvironmentHostsAddresses: schema.TypeList, mkResourceVirtualEnvironmentHostsDigest: schema.TypeString, mkResourceVirtualEnvironmentHostsEntries: schema.TypeList, @@ -44,26 +50,26 @@ func TestResourceVirtualEnvironmentHostsSchema(t *testing.T) { mkResourceVirtualEnvironmentHostsNodeName: schema.TypeString, }) - entriesSchema := testNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentHostsEntries) + entriesSchema := test.AssertNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentHostsEntries) - testComputedAttributes(t, entriesSchema, []string{ + test.AssertComputedAttributes(t, entriesSchema, []string{ mkResourceVirtualEnvironmentHostsEntriesAddress, mkResourceVirtualEnvironmentHostsEntriesHostnames, }) - testValueTypes(t, entriesSchema, map[string]schema.ValueType{ + test.AssertValueTypes(t, entriesSchema, map[string]schema.ValueType{ mkResourceVirtualEnvironmentHostsEntriesAddress: schema.TypeString, mkResourceVirtualEnvironmentHostsEntriesHostnames: schema.TypeList, }) - entrySchema := testNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentHostsEntry) + entrySchema := test.AssertNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentHostsEntry) - testRequiredArguments(t, entrySchema, []string{ + test.AssertRequiredArguments(t, entrySchema, []string{ mkResourceVirtualEnvironmentHostsEntryAddress, mkResourceVirtualEnvironmentHostsEntryHostnames, }) - testValueTypes(t, entrySchema, map[string]schema.ValueType{ + test.AssertValueTypes(t, entrySchema, map[string]schema.ValueType{ mkResourceVirtualEnvironmentHostsEntryAddress: schema.TypeString, mkResourceVirtualEnvironmentHostsEntryHostnames: schema.TypeList, }) diff --git a/proxmoxtf/resource_virtual_environment_pool.go b/proxmoxtf/resource/pool.go similarity index 80% rename from proxmoxtf/resource_virtual_environment_pool.go rename to proxmoxtf/resource/pool.go index eab9377b..542ef9c7 100644 --- a/proxmoxtf/resource_virtual_environment_pool.go +++ b/proxmoxtf/resource/pool.go @@ -1,8 +1,10 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public +/* + * 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/. */ + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ -package proxmoxtf +package resource import ( "context" @@ -12,6 +14,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/bpg/terraform-provider-proxmox/proxmox" + "github.com/bpg/terraform-provider-proxmox/proxmoxtf" ) const ( @@ -27,7 +30,7 @@ const ( mkResourceVirtualEnvironmentPoolPoolID = "pool_id" ) -func resourceVirtualEnvironmentPool() *schema.Resource { +func Pool() *schema.Resource { return &schema.Resource{ Schema: map[string]*schema.Schema{ mkResourceVirtualEnvironmentPoolComment: { @@ -77,19 +80,15 @@ func resourceVirtualEnvironmentPool() *schema.Resource { ForceNew: true, }, }, - CreateContext: resourceVirtualEnvironmentPoolCreate, - ReadContext: resourceVirtualEnvironmentPoolRead, - UpdateContext: resourceVirtualEnvironmentPoolUpdate, - DeleteContext: resourceVirtualEnvironmentPoolDelete, + CreateContext: poolCreate, + ReadContext: poolRead, + UpdateContext: poolUpdate, + DeleteContext: poolDelete, } } -func resourceVirtualEnvironmentPoolCreate( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { - config := m.(providerConfiguration) +func poolCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) @@ -110,17 +109,13 @@ func resourceVirtualEnvironmentPoolCreate( d.SetId(poolID) - return resourceVirtualEnvironmentPoolRead(ctx, d, m) + return poolRead(ctx, d, m) } -func resourceVirtualEnvironmentPoolRead( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { +func poolRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { var diags diag.Diagnostics - config := m.(providerConfiguration) + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) @@ -174,12 +169,8 @@ func resourceVirtualEnvironmentPoolRead( return diags } -func resourceVirtualEnvironmentPoolUpdate( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { - config := m.(providerConfiguration) +func poolUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) @@ -197,15 +188,11 @@ func resourceVirtualEnvironmentPoolUpdate( return diag.FromErr(err) } - return resourceVirtualEnvironmentPoolRead(ctx, d, m) + return poolRead(ctx, d, m) } -func resourceVirtualEnvironmentPoolDelete( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { - config := m.(providerConfiguration) +func poolDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) diff --git a/proxmoxtf/resource/pool_test.go b/proxmoxtf/resource/pool_test.go new file mode 100644 index 00000000..2d08775d --- /dev/null +++ b/proxmoxtf/resource/pool_test.go @@ -0,0 +1,61 @@ +/* + * 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 resource + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf/test" +) + +// TestPoolInstantiation tests whether the Pool instance can be instantiated. +func TestPoolInstantiation(t *testing.T) { + t.Parallel() + s := Pool() + + if s == nil { + t.Fatalf("Cannot instantiate Pool") + } +} + +// TestPoolSchema tests the Pool schema. +func TestPoolSchema(t *testing.T) { + t.Parallel() + s := Pool() + + test.AssertRequiredArguments(t, s, []string{ + mkResourceVirtualEnvironmentPoolPoolID, + }) + + test.AssertOptionalArguments(t, s, []string{ + mkResourceVirtualEnvironmentPoolComment, + }) + + test.AssertComputedAttributes(t, s, []string{ + mkResourceVirtualEnvironmentPoolMembers, + }) + + membersSchema := test.AssertNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentPoolMembers) + + test.AssertComputedAttributes(t, membersSchema, []string{ + mkResourceVirtualEnvironmentPoolMembersDatastoreID, + mkResourceVirtualEnvironmentPoolMembersID, + mkResourceVirtualEnvironmentPoolMembersNodeName, + mkResourceVirtualEnvironmentPoolMembersType, + mkResourceVirtualEnvironmentPoolMembersVMID, + }) + + test.AssertValueTypes(t, membersSchema, map[string]schema.ValueType{ + mkResourceVirtualEnvironmentPoolMembersDatastoreID: schema.TypeString, + mkResourceVirtualEnvironmentPoolMembersID: schema.TypeString, + mkResourceVirtualEnvironmentPoolMembersNodeName: schema.TypeString, + mkResourceVirtualEnvironmentPoolMembersType: schema.TypeString, + mkResourceVirtualEnvironmentPoolMembersVMID: schema.TypeInt, + }) +} diff --git a/proxmoxtf/resource_virtual_environment_role.go b/proxmoxtf/resource/role.go similarity index 66% rename from proxmoxtf/resource_virtual_environment_role.go rename to proxmoxtf/resource/role.go index 47d018f7..3f659423 100644 --- a/proxmoxtf/resource_virtual_environment_role.go +++ b/proxmoxtf/resource/role.go @@ -1,8 +1,10 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public +/* + * 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/. */ + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ -package proxmoxtf +package resource import ( "context" @@ -12,6 +14,8 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/bpg/terraform-provider-proxmox/proxmox" + "github.com/bpg/terraform-provider-proxmox/proxmox/types" + "github.com/bpg/terraform-provider-proxmox/proxmoxtf" ) const ( @@ -19,7 +23,7 @@ const ( mkResourceVirtualEnvironmentRoleRoleID = "role_id" ) -func resourceVirtualEnvironmentRole() *schema.Resource { +func Role() *schema.Resource { return &schema.Resource{ Schema: map[string]*schema.Schema{ mkResourceVirtualEnvironmentRolePrivileges: { @@ -35,26 +39,22 @@ func resourceVirtualEnvironmentRole() *schema.Resource { ForceNew: true, }, }, - CreateContext: resourceVirtualEnvironmentRoleCreate, - ReadContext: resourceVirtualEnvironmentRoleRead, - UpdateContext: resourceVirtualEnvironmentRoleUpdate, - DeleteContext: resourceVirtualEnvironmentRoleDelete, + CreateContext: roleCreate, + ReadContext: roleRead, + UpdateContext: roleUpdate, + DeleteContext: roleDelete, } } -func resourceVirtualEnvironmentRoleCreate( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { - config := m.(providerConfiguration) +func roleCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) } privileges := d.Get(mkResourceVirtualEnvironmentRolePrivileges).(*schema.Set).List() - customPrivileges := make(proxmox.CustomPrivileges, len(privileges)) + customPrivileges := make(types.CustomPrivileges, len(privileges)) roleID := d.Get(mkResourceVirtualEnvironmentRoleRoleID).(string) for i, v := range privileges { @@ -73,15 +73,11 @@ func resourceVirtualEnvironmentRoleCreate( d.SetId(roleID) - return resourceVirtualEnvironmentRoleRead(ctx, d, m) + return roleRead(ctx, d, m) } -func resourceVirtualEnvironmentRoleRead( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { - config := m.(providerConfiguration) +func roleRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) @@ -110,19 +106,15 @@ func resourceVirtualEnvironmentRoleRead( return diag.FromErr(err) } -func resourceVirtualEnvironmentRoleUpdate( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { - config := m.(providerConfiguration) +func roleUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) } privileges := d.Get(mkResourceVirtualEnvironmentRolePrivileges).(*schema.Set).List() - customPrivileges := make(proxmox.CustomPrivileges, len(privileges)) + customPrivileges := make(types.CustomPrivileges, len(privileges)) roleID := d.Id() for i, v := range privileges { @@ -138,15 +130,11 @@ func resourceVirtualEnvironmentRoleUpdate( return diag.FromErr(err) } - return resourceVirtualEnvironmentRoleRead(ctx, d, m) + return roleRead(ctx, d, m) } -func resourceVirtualEnvironmentRoleDelete( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { - config := m.(providerConfiguration) +func roleDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) diff --git a/proxmoxtf/resource/role_test.go b/proxmoxtf/resource/role_test.go new file mode 100644 index 00000000..58ddf066 --- /dev/null +++ b/proxmoxtf/resource/role_test.go @@ -0,0 +1,41 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +package resource + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf/test" +) + +// TestRoleInstantiation tests whether the Role instance can be instantiated. +func TestRoleInstantiation(t *testing.T) { + t.Parallel() + s := Role() + + if s == nil { + t.Fatalf("Cannot instantiate Role") + } +} + +// TestRoleSchema tests the Role schema. +func TestRoleSchema(t *testing.T) { + t.Parallel() + s := Role() + + test.AssertRequiredArguments(t, s, []string{ + mkResourceVirtualEnvironmentRolePrivileges, + mkResourceVirtualEnvironmentRoleRoleID, + }) + + test.AssertValueTypes(t, s, map[string]schema.ValueType{ + mkResourceVirtualEnvironmentRolePrivileges: schema.TypeSet, + mkResourceVirtualEnvironmentRoleRoleID: schema.TypeString, + }) +} diff --git a/proxmoxtf/resource_virtual_environment_time.go b/proxmoxtf/resource/time.go similarity index 71% rename from proxmoxtf/resource_virtual_environment_time.go rename to proxmoxtf/resource/time.go index 253b2654..7c9e8df4 100644 --- a/proxmoxtf/resource_virtual_environment_time.go +++ b/proxmoxtf/resource/time.go @@ -1,8 +1,10 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public +/* + * 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/. */ + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ -package proxmoxtf +package resource import ( "context" @@ -13,6 +15,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/bpg/terraform-provider-proxmox/proxmox" + "github.com/bpg/terraform-provider-proxmox/proxmoxtf" ) const ( @@ -22,7 +25,7 @@ const ( mkResourceVirtualEnvironmentTimeUTCTime = "utc_time" ) -func resourceVirtualEnvironmentTime() *schema.Resource { +func Time() *schema.Resource { return &schema.Resource{ Schema: map[string]*schema.Schema{ mkResourceVirtualEnvironmentTimeLocalTime: { @@ -46,19 +49,15 @@ func resourceVirtualEnvironmentTime() *schema.Resource { Computed: true, }, }, - CreateContext: resourceVirtualEnvironmentTimeCreate, - ReadContext: resourceVirtualEnvironmentTimeRead, - UpdateContext: resourceVirtualEnvironmentTimeUpdate, - DeleteContext: resourceVirtualEnvironmentTimeDelete, + CreateContext: timeCreate, + ReadContext: timeRead, + UpdateContext: timeUpdate, + DeleteContext: timeDelete, } } -func resourceVirtualEnvironmentTimeCreate( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { - diags := resourceVirtualEnvironmentTimeUpdate(ctx, d, m) +func timeCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + diags := timeUpdate(ctx, d, m) if diags.HasError() { return diags } @@ -70,15 +69,10 @@ func resourceVirtualEnvironmentTimeCreate( return nil } -//nolint:dupl -func resourceVirtualEnvironmentTimeRead( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { +func timeRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { var diags diag.Diagnostics - config := m.(providerConfiguration) + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) @@ -113,12 +107,8 @@ func resourceVirtualEnvironmentTimeRead( return diags } -func resourceVirtualEnvironmentTimeUpdate( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { - config := m.(providerConfiguration) +func timeUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) @@ -138,14 +128,10 @@ func resourceVirtualEnvironmentTimeUpdate( return diag.FromErr(err) } - return resourceVirtualEnvironmentTimeRead(ctx, d, m) + return timeRead(ctx, d, m) } -func resourceVirtualEnvironmentTimeDelete( - _ context.Context, - d *schema.ResourceData, - _ interface{}, -) diag.Diagnostics { +func timeDelete(_ context.Context, d *schema.ResourceData, _ interface{}) diag.Diagnostics { d.SetId("") return nil diff --git a/proxmoxtf/resource/time_test.go b/proxmoxtf/resource/time_test.go new file mode 100644 index 00000000..8db4e47f --- /dev/null +++ b/proxmoxtf/resource/time_test.go @@ -0,0 +1,48 @@ +/* + * 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 resource + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf/test" +) + +// TestTimeInstantiation tests whether the Time instance can be instantiated. +func TestTimeInstantiation(t *testing.T) { + t.Parallel() + s := Time() + + if s == nil { + t.Fatalf("Cannot instantiate Time") + } +} + +// TestTimeSchema tests the Time schema. +func TestTimeSchema(t *testing.T) { + t.Parallel() + s := Time() + + test.AssertRequiredArguments(t, s, []string{ + mkResourceVirtualEnvironmentTimeNodeName, + mkResourceVirtualEnvironmentTimeTimeZone, + }) + + test.AssertComputedAttributes(t, s, []string{ + mkResourceVirtualEnvironmentTimeLocalTime, + mkResourceVirtualEnvironmentTimeUTCTime, + }) + + test.AssertValueTypes(t, s, map[string]schema.ValueType{ + mkResourceVirtualEnvironmentTimeLocalTime: schema.TypeString, + mkResourceVirtualEnvironmentTimeNodeName: schema.TypeString, + mkResourceVirtualEnvironmentTimeTimeZone: schema.TypeString, + mkResourceVirtualEnvironmentTimeUTCTime: schema.TypeString, + }) +} diff --git a/proxmoxtf/resource_virtual_environment_user.go b/proxmoxtf/resource/user.go similarity index 87% rename from proxmoxtf/resource_virtual_environment_user.go rename to proxmoxtf/resource/user.go index 0938731e..da9346ba 100644 --- a/proxmoxtf/resource_virtual_environment_user.go +++ b/proxmoxtf/resource/user.go @@ -1,8 +1,10 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public +/* + * 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/. */ + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ -package proxmoxtf +package resource import ( "context" @@ -14,6 +16,8 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/bpg/terraform-provider-proxmox/proxmox" + "github.com/bpg/terraform-provider-proxmox/proxmox/types" + "github.com/bpg/terraform-provider-proxmox/proxmoxtf" ) const ( @@ -40,7 +44,7 @@ const ( mkResourceVirtualEnvironmentUserUserID = "user_id" ) -func resourceVirtualEnvironmentUser() *schema.Resource { +func User() *schema.Resource { return &schema.Resource{ Schema: map[string]*schema.Schema{ mkResourceVirtualEnvironmentUserACL: { @@ -135,19 +139,15 @@ func resourceVirtualEnvironmentUser() *schema.Resource { ForceNew: true, }, }, - CreateContext: resourceVirtualEnvironmentUserCreate, - ReadContext: resourceVirtualEnvironmentUserRead, - UpdateContext: resourceVirtualEnvironmentUserUpdate, - DeleteContext: resourceVirtualEnvironmentUserDelete, + CreateContext: userCreate, + ReadContext: userRead, + UpdateContext: userUpdate, + DeleteContext: userDelete, } } -func resourceVirtualEnvironmentUserCreate( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { - config := m.(providerConfiguration) +func userCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) @@ -155,7 +155,7 @@ func resourceVirtualEnvironmentUserCreate( comment := d.Get(mkResourceVirtualEnvironmentUserComment).(string) email := d.Get(mkResourceVirtualEnvironmentUserEmail).(string) - enabled := proxmox.CustomBool(d.Get(mkResourceVirtualEnvironmentUserEnabled).(bool)) + enabled := types.CustomBool(d.Get(mkResourceVirtualEnvironmentUserEnabled).(bool)) expirationDate, err := time.Parse( time.RFC3339, d.Get(mkResourceVirtualEnvironmentUserExpirationDate).(string), @@ -164,7 +164,7 @@ func resourceVirtualEnvironmentUserCreate( return diag.FromErr(err) } - expirationDateCustom := proxmox.CustomTimestamp(expirationDate) + expirationDateCustom := types.CustomTimestamp(expirationDate) firstName := d.Get(mkResourceVirtualEnvironmentUserFirstName).(string) groups := d.Get(mkResourceVirtualEnvironmentUserGroups).(*schema.Set).List() groupsCustom := make([]string, len(groups)) @@ -201,9 +201,9 @@ func resourceVirtualEnvironmentUserCreate( aclParsed := d.Get(mkResourceVirtualEnvironmentUserACL).(*schema.Set).List() for _, v := range aclParsed { - aclDelete := proxmox.CustomBool(false) + aclDelete := types.CustomBool(false) aclEntry := v.(map[string]interface{}) - aclPropagate := proxmox.CustomBool( + aclPropagate := types.CustomBool( aclEntry[mkResourceVirtualEnvironmentUserACLPropagate].(bool), ) @@ -221,15 +221,11 @@ func resourceVirtualEnvironmentUserCreate( } } - return resourceVirtualEnvironmentUserRead(ctx, d, m) + return userRead(ctx, d, m) } -func resourceVirtualEnvironmentUserRead( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { - config := m.(providerConfiguration) +func userRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) @@ -342,12 +338,8 @@ func resourceVirtualEnvironmentUserRead( return diags } -func resourceVirtualEnvironmentUserUpdate( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { - config := m.(providerConfiguration) +func userUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) @@ -355,7 +347,7 @@ func resourceVirtualEnvironmentUserUpdate( comment := d.Get(mkResourceVirtualEnvironmentUserComment).(string) email := d.Get(mkResourceVirtualEnvironmentUserEmail).(string) - enabled := proxmox.CustomBool(d.Get(mkResourceVirtualEnvironmentUserEnabled).(bool)) + enabled := types.CustomBool(d.Get(mkResourceVirtualEnvironmentUserEnabled).(bool)) expirationDate, err := time.Parse( time.RFC3339, d.Get(mkResourceVirtualEnvironmentUserExpirationDate).(string), @@ -364,7 +356,7 @@ func resourceVirtualEnvironmentUserUpdate( return diag.FromErr(err) } - expirationDateCustom := proxmox.CustomTimestamp(expirationDate) + expirationDateCustom := types.CustomTimestamp(expirationDate) firstName := d.Get(mkResourceVirtualEnvironmentUserFirstName).(string) groups := d.Get(mkResourceVirtualEnvironmentUserGroups).(*schema.Set).List() groupsCustom := make([]string, len(groups)) @@ -405,9 +397,9 @@ func resourceVirtualEnvironmentUserUpdate( aclParsedOld := aclArgOld.(*schema.Set).List() for _, v := range aclParsedOld { - aclDelete := proxmox.CustomBool(true) + aclDelete := types.CustomBool(true) aclEntry := v.(map[string]interface{}) - aclPropagate := proxmox.CustomBool( + aclPropagate := types.CustomBool( aclEntry[mkResourceVirtualEnvironmentUserACLPropagate].(bool), ) @@ -428,9 +420,9 @@ func resourceVirtualEnvironmentUserUpdate( aclParsed := aclArg.(*schema.Set).List() for _, v := range aclParsed { - aclDelete := proxmox.CustomBool(false) + aclDelete := types.CustomBool(false) aclEntry := v.(map[string]interface{}) - aclPropagate := proxmox.CustomBool( + aclPropagate := types.CustomBool( aclEntry[mkResourceVirtualEnvironmentUserACLPropagate].(bool), ) @@ -448,15 +440,11 @@ func resourceVirtualEnvironmentUserUpdate( } } - return resourceVirtualEnvironmentUserRead(ctx, d, m) + return userRead(ctx, d, m) } -func resourceVirtualEnvironmentUserDelete( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { - config := m.(providerConfiguration) +func userDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) @@ -466,9 +454,9 @@ func resourceVirtualEnvironmentUserDelete( userID := d.Id() for _, v := range aclParsed { - aclDelete := proxmox.CustomBool(true) + aclDelete := types.CustomBool(true) aclEntry := v.(map[string]interface{}) - aclPropagate := proxmox.CustomBool( + aclPropagate := types.CustomBool( aclEntry[mkResourceVirtualEnvironmentUserACLPropagate].(bool), ) diff --git a/proxmoxtf/resource_virtual_environment_user_test.go b/proxmoxtf/resource/user_test.go similarity index 63% rename from proxmoxtf/resource_virtual_environment_user_test.go rename to proxmoxtf/resource/user_test.go index 1f14ad3b..e951af00 100644 --- a/proxmoxtf/resource_virtual_environment_user_test.go +++ b/proxmoxtf/resource/user_test.go @@ -1,34 +1,40 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public +/* + * 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/. */ + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ -package proxmoxtf +package resource import ( "testing" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf/test" ) -// TestResourceVirtualEnvironmentUserInstantiation tests whether the ResourceVirtualEnvironmentUser instance can be instantiated. -func TestResourceVirtualEnvironmentUserInstantiation(t *testing.T) { - s := resourceVirtualEnvironmentUser() +// TestUserInstantiation tests whether the User instance can be instantiated. +func TestUserInstantiation(t *testing.T) { + t.Parallel() + s := User() if s == nil { - t.Fatalf("Cannot instantiate resourceVirtualEnvironmentUser") + t.Fatalf("Cannot instantiate User") } } -// TestResourceVirtualEnvironmentUserSchema tests the resourceVirtualEnvironmentUser schema. -func TestResourceVirtualEnvironmentUserSchema(t *testing.T) { - s := resourceVirtualEnvironmentUser() +// TestUserSchema tests the User schema. +func TestUserSchema(t *testing.T) { + t.Parallel() + s := User() - testRequiredArguments(t, s, []string{ + test.AssertRequiredArguments(t, s, []string{ mkResourceVirtualEnvironmentUserPassword, mkResourceVirtualEnvironmentUserUserID, }) - testOptionalArguments(t, s, []string{ + test.AssertOptionalArguments(t, s, []string{ mkResourceVirtualEnvironmentUserACL, mkResourceVirtualEnvironmentUserComment, mkResourceVirtualEnvironmentUserEmail, @@ -40,7 +46,7 @@ func TestResourceVirtualEnvironmentUserSchema(t *testing.T) { mkResourceVirtualEnvironmentUserLastName, }) - testValueTypes(t, s, map[string]schema.ValueType{ + test.AssertValueTypes(t, s, map[string]schema.ValueType{ mkResourceVirtualEnvironmentUserACL: schema.TypeSet, mkResourceVirtualEnvironmentUserComment: schema.TypeString, mkResourceVirtualEnvironmentUserEmail: schema.TypeString, @@ -54,18 +60,18 @@ func TestResourceVirtualEnvironmentUserSchema(t *testing.T) { mkResourceVirtualEnvironmentUserUserID: schema.TypeString, }) - aclSchema := testNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentUserACL) + aclSchema := test.AssertNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentUserACL) - testRequiredArguments(t, aclSchema, []string{ + test.AssertRequiredArguments(t, aclSchema, []string{ mkResourceVirtualEnvironmentUserACLPath, mkResourceVirtualEnvironmentUserACLRoleID, }) - testOptionalArguments(t, aclSchema, []string{ + test.AssertOptionalArguments(t, aclSchema, []string{ mkResourceVirtualEnvironmentUserACLPropagate, }) - testValueTypes(t, aclSchema, map[string]schema.ValueType{ + test.AssertValueTypes(t, aclSchema, map[string]schema.ValueType{ mkResourceVirtualEnvironmentUserACLPath: schema.TypeString, mkResourceVirtualEnvironmentUserACLPropagate: schema.TypeBool, mkResourceVirtualEnvironmentUserACLRoleID: schema.TypeString, diff --git a/proxmoxtf/utils.go b/proxmoxtf/resource/utils.go similarity index 88% rename from proxmoxtf/utils.go rename to proxmoxtf/resource/utils.go index 6d1561d9..e36701c6 100644 --- a/proxmoxtf/utils.go +++ b/proxmoxtf/resource/utils.go @@ -1,15 +1,16 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public +/* + * 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/. */ + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ -package proxmoxtf +package resource import ( "errors" "fmt" "regexp" "strings" - "testing" "time" "unicode" @@ -519,66 +520,6 @@ func getCloudInitTypeValidator() schema.SchemaValidateDiagFunc { }, false)) } -func testComputedAttributes(t *testing.T, s *schema.Resource, keys []string) { - for _, v := range keys { - if s.Schema[v] == nil { - t.Fatalf("Error in Schema: Missing definition for \"%s\"", v) - } - - if !s.Schema[v].Computed { - t.Fatalf("Error in Schema: Attribute \"%s\" is not computed", v) - } - } -} - -func testNestedSchemaExistence(t *testing.T, s *schema.Resource, key string) *schema.Resource { - sh, ok := s.Schema[key].Elem.(*schema.Resource) - - if !ok { - t.Fatalf("Error in Schema: Missing nested schema for \"%s\"", key) - - return nil - } - - return sh -} - -func testOptionalArguments(t *testing.T, s *schema.Resource, keys []string) { - for _, v := range keys { - if s.Schema[v] == nil { - t.Fatalf("Error in Schema: Missing definition for \"%s\"", v) - } - - if !s.Schema[v].Optional { - t.Fatalf("Error in Schema: Argument \"%s\" is not optional", v) - } - } -} - -func testRequiredArguments(t *testing.T, s *schema.Resource, keys []string) { - for _, v := range keys { - if s.Schema[v] == nil { - t.Fatalf("Error in Schema: Missing definition for \"%s\"", v) - } - - if !s.Schema[v].Required { - t.Fatalf("Error in Schema: Argument \"%s\" is not required", v) - } - } -} - -func testValueTypes(t *testing.T, s *schema.Resource, f map[string]schema.ValueType) { - for fn, ft := range f { - if s.Schema[fn] == nil { - t.Fatalf("Error in Schema: Missing definition for \"%s\"", fn) - } - - if s.Schema[fn].Type != ft { - t.Fatalf("Error in Schema: Argument or attribute \"%s\" is not of type \"%v\"", fn, ft) - } - } -} - type ErrorDiags diag.Diagnostics func (diags ErrorDiags) Errors() []error { diff --git a/proxmoxtf/utils_test.go b/proxmoxtf/resource/utils_test.go similarity index 97% rename from proxmoxtf/utils_test.go rename to proxmoxtf/resource/utils_test.go index 48b25d98..84e578ed 100644 --- a/proxmoxtf/utils_test.go +++ b/proxmoxtf/resource/utils_test.go @@ -4,7 +4,7 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -package proxmoxtf +package resource import ( "testing" diff --git a/proxmoxtf/resource/validator/firewall.go b/proxmoxtf/resource/validator/firewall.go new file mode 100644 index 00000000..d5c5df29 --- /dev/null +++ b/proxmoxtf/resource/validator/firewall.go @@ -0,0 +1,37 @@ +/* + * 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 validator + +import ( + "regexp" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +var rateExpression = regexp.MustCompile(`[1-9][0-9]*/(second|minute|hour|day)`) + +func FirewallRate() schema.SchemaValidateDiagFunc { + return validation.ToDiagFunc(validation.StringMatch( + rateExpression, + "Must be a valid rate expression, e.g. '1/second'", + )) +} + +func FirewallPolicy() schema.SchemaValidateDiagFunc { + return validation.ToDiagFunc(validation.StringInSlice( + []string{"ACCEPT", "REJECT", "DROP"}, + false, + )) +} + +func FirewallLogLevel() schema.SchemaValidateDiagFunc { + return validation.ToDiagFunc(validation.StringInSlice( + []string{"emerg", "alert", "crit", "err", "warning", "notice", "info", "debug", "nolog"}, + false, + )) +} diff --git a/proxmoxtf/resource_virtual_environment_vm.go b/proxmoxtf/resource/vm.go similarity index 93% rename from proxmoxtf/resource_virtual_environment_vm.go rename to proxmoxtf/resource/vm.go index 12685ee7..a51179ba 100644 --- a/proxmoxtf/resource_virtual_environment_vm.go +++ b/proxmoxtf/resource/vm.go @@ -1,8 +1,10 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public +/* + * 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/. */ + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ -package proxmoxtf +package resource import ( "context" @@ -19,6 +21,8 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/bpg/terraform-provider-proxmox/proxmox" + "github.com/bpg/terraform-provider-proxmox/proxmox/types" + "github.com/bpg/terraform-provider-proxmox/proxmoxtf" ) const ( @@ -58,13 +62,6 @@ const ( dvResourceVirtualEnvironmentVMDiskSpeedReadBurstable = 0 dvResourceVirtualEnvironmentVMDiskSpeedWrite = 0 dvResourceVirtualEnvironmentVMDiskSpeedWriteBurstable = 0 - dvResourceVirtualEnvironmentVMHostPCIDevice = "" - dvResourceVirtualEnvironmentVMHostPCIDeviceID = "" - dvResourceVirtualEnvironmentVMHostPCIDeviceMDev = "" - dvResourceVirtualEnvironmentVMHostPCIDevicePCIE = 0 - dvResourceVirtualEnvironmentVMHostPCIDeviceROMBAR = 1 - dvResourceVirtualEnvironmentVMHostPCIDeviceROMFile = "" - dvResourceVirtualEnvironmentVMHostPCIDeviceXVGA = 0 dvResourceVirtualEnvironmentVMInitializationDatastoreID = "local-lvm" dvResourceVirtualEnvironmentVMInitializationDNSDomain = "" dvResourceVirtualEnvironmentVMInitializationDNSServer = "" @@ -230,7 +227,7 @@ const ( mkResourceVirtualEnvironmentVMSCSIHardware = "scsi_hardware" ) -func resourceVirtualEnvironmentVM() *schema.Resource { +func VM() *schema.Resource { return &schema.Resource{ Schema: map[string]*schema.Schema{ mkResourceVirtualEnvironmentVMRebootAfterCreation: { @@ -318,14 +315,14 @@ func resourceVirtualEnvironmentVM() *schema.Resource { Description: "The device", Optional: true, Default: dvResourceVirtualEnvironmentVMAudioDeviceDevice, - ValidateDiagFunc: resourceVirtualEnvironmentVMGetAudioDeviceValidator(), + ValidateDiagFunc: vmGetAudioDeviceValidator(), }, mkResourceVirtualEnvironmentVMAudioDeviceDriver: { Type: schema.TypeString, Description: "The driver", Optional: true, Default: dvResourceVirtualEnvironmentVMAudioDeviceDriver, - ValidateDiagFunc: resourceVirtualEnvironmentVMGetAudioDriverValidator(), + ValidateDiagFunc: vmGetAudioDriverValidator(), }, mkResourceVirtualEnvironmentVMAudioDeviceEnabled: { Type: schema.TypeBool, @@ -450,7 +447,7 @@ func resourceVirtualEnvironmentVM() *schema.Resource { Description: "The CPU architecture", Optional: true, Default: dvResourceVirtualEnvironmentVMCPUArchitecture, - ValidateDiagFunc: resourceVirtualEnvironmentVMGetCPUArchitectureValidator(), + ValidateDiagFunc: vmGetCPUArchitectureValidator(), }, mkResourceVirtualEnvironmentVMCPUCores: { Type: schema.TypeInt, @@ -1045,7 +1042,7 @@ func resourceVirtualEnvironmentVM() *schema.Resource { Description: "The type", Optional: true, Default: dvResourceVirtualEnvironmentVMOperatingSystemType, - ValidateDiagFunc: resourceVirtualEnvironmentVMGetOperatingSystemTypeValidator(), + ValidateDiagFunc: vmGetOperatingSystemTypeValidator(), }, }, }, @@ -1077,7 +1074,7 @@ func resourceVirtualEnvironmentVM() *schema.Resource { Description: "The device", Optional: true, Default: dvResourceVirtualEnvironmentVMSerialDeviceDevice, - ValidateDiagFunc: resourceVirtualEnvironmentVMGetSerialDeviceValidator(), + ValidateDiagFunc: vmGetSerialDeviceValidator(), }, }, }, @@ -1204,10 +1201,10 @@ func resourceVirtualEnvironmentVM() *schema.Resource { ValidateDiagFunc: getSCSIHardwareValidator(), }, }, - CreateContext: resourceVirtualEnvironmentVMCreate, - ReadContext: resourceVirtualEnvironmentVMRead, - UpdateContext: resourceVirtualEnvironmentVMUpdate, - DeleteContext: resourceVirtualEnvironmentVMDelete, + CreateContext: vmCreate, + ReadContext: vmRead, + UpdateContext: vmUpdate, + DeleteContext: vmDelete, CustomizeDiff: customdiff.All( customdiff.ComputedIf( mkResourceVirtualEnvironmentVMIPv4Addresses, @@ -1234,26 +1231,18 @@ func resourceVirtualEnvironmentVM() *schema.Resource { } } -func resourceVirtualEnvironmentVMCreate( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { +func vmCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { clone := d.Get(mkResourceVirtualEnvironmentVMClone).([]interface{}) if len(clone) > 0 { - return resourceVirtualEnvironmentVMCreateClone(ctx, d, m) + return vmCreateClone(ctx, d, m) } - return resourceVirtualEnvironmentVMCreateCustom(ctx, d, m) + return vmCreateCustom(ctx, d, m) } -func resourceVirtualEnvironmentVMCreateClone( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { - config := m.(providerConfiguration) +func vmCreateClone(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) @@ -1282,7 +1271,7 @@ func resourceVirtualEnvironmentVMCreateClone( vmID = *vmIDNew } - fullCopy := proxmox.CustomBool(cloneFull) + fullCopy := types.CustomBool(cloneFull) cloneBody := &proxmox.VirtualEnvironmentVMCloneRequestBody{ FullCopy: &fullCopy, @@ -1324,7 +1313,7 @@ func resourceVirtualEnvironmentVMCreateClone( } if datastoreStatus.Shared != nil && - *datastoreStatus.Shared == proxmox.CustomBool(false) { + *datastoreStatus.Shared == types.CustomBool(false) { onlySharedDatastores = false break } @@ -1365,7 +1354,7 @@ func resourceVirtualEnvironmentVMCreateClone( } // Migrate to target node - withLocalDisks := proxmox.CustomBool(true) + withLocalDisks := types.CustomBool(true) migrateBody := &proxmox.VirtualEnvironmentVMMigrateRequestBody{ TargetNode: nodeName, WithLocalDisks: &withLocalDisks, @@ -1396,9 +1385,9 @@ func resourceVirtualEnvironmentVMCreateClone( } // Now that the virtual machine has been cloned, we need to perform some modifications. - acpi := proxmox.CustomBool(d.Get(mkResourceVirtualEnvironmentVMACPI).(bool)) + acpi := types.CustomBool(d.Get(mkResourceVirtualEnvironmentVMACPI).(bool)) agent := d.Get(mkResourceVirtualEnvironmentVMAgent).([]interface{}) - audioDevices := resourceVirtualEnvironmentVMGetAudioDeviceList(d) + audioDevices := vmGetAudioDeviceList(d) bios := d.Get(mkResourceVirtualEnvironmentVMBIOS).(string) kvmArguments := d.Get(mkResourceVirtualEnvironmentVMKVMArguments).(string) @@ -1412,9 +1401,9 @@ func resourceVirtualEnvironmentVMCreateClone( networkDevice := d.Get(mkResourceVirtualEnvironmentVMNetworkDevice).([]interface{}) operatingSystem := d.Get(mkResourceVirtualEnvironmentVMOperatingSystem).([]interface{}) serialDevice := d.Get(mkResourceVirtualEnvironmentVMSerialDevice).([]interface{}) - onBoot := proxmox.CustomBool(d.Get(mkResourceVirtualEnvironmentVMOnBoot).(bool)) - tabletDevice := proxmox.CustomBool(d.Get(mkResourceVirtualEnvironmentVMTabletDevice).(bool)) - template := proxmox.CustomBool(d.Get(mkResourceVirtualEnvironmentVMTemplate).(bool)) + onBoot := types.CustomBool(d.Get(mkResourceVirtualEnvironmentVMOnBoot).(bool)) + tabletDevice := types.CustomBool(d.Get(mkResourceVirtualEnvironmentVMTabletDevice).(bool)) + template := types.CustomBool(d.Get(mkResourceVirtualEnvironmentVMTemplate).(bool)) vga := d.Get(mkResourceVirtualEnvironmentVMVGA).([]interface{}) updateBody := &proxmox.VirtualEnvironmentVMUpdateRequestBody{ @@ -1433,10 +1422,10 @@ func resourceVirtualEnvironmentVMCreateClone( if len(agent) > 0 { agentBlock := agent[0].(map[string]interface{}) - agentEnabled := proxmox.CustomBool( + agentEnabled := types.CustomBool( agentBlock[mkResourceVirtualEnvironmentVMAgentEnabled].(bool), ) - agentTrim := proxmox.CustomBool(agentBlock[mkResourceVirtualEnvironmentVMAgentTrim].(bool)) + agentTrim := types.CustomBool(agentBlock[mkResourceVirtualEnvironmentVMAgentTrim].(bool)) agentType := agentBlock[mkResourceVirtualEnvironmentVMAgentType].(string) updateBody.Agent = &proxmox.CustomAgent{ @@ -1553,13 +1542,13 @@ func resourceVirtualEnvironmentVMCreateClone( if err != nil { return diag.FromErr(err) } - initializationConfig := resourceVirtualEnvironmentVMGetCloudInitConfig(d) + initializationConfig := vmGetCloudInitConfig(d) updateBody.CloudInitConfig = initializationConfig } if len(hostPCI) > 0 { - updateBody.PCIDevices = resourceVirtualEnvironmentVMGetHostPCIDeviceObjects(d) + updateBody.PCIDevices = vmGetHostPCIDeviceObjects(d) } if len(cdrom) > 0 || len(initialization) > 0 { @@ -1591,7 +1580,7 @@ func resourceVirtualEnvironmentVMCreateClone( } if len(networkDevice) > 0 { - updateBody.NetworkDevices = resourceVirtualEnvironmentVMGetNetworkDeviceObjects(d) + updateBody.NetworkDevices = vmGetNetworkDeviceObjects(d) for i := 0; i < len(updateBody.NetworkDevices); i++ { if !updateBody.NetworkDevices[i].Enabled { @@ -1612,7 +1601,7 @@ func resourceVirtualEnvironmentVMCreateClone( } if len(serialDevice) > 0 { - updateBody.SerialDevices = resourceVirtualEnvironmentVMGetSerialDeviceList(d) + updateBody.SerialDevices = vmGetSerialDeviceList(d) for i := len(updateBody.SerialDevices); i < maxResourceVirtualEnvironmentVMSerialDevices; i++ { del = append(del, fmt.Sprintf("serial%d", i)) @@ -1627,7 +1616,7 @@ func resourceVirtualEnvironmentVMCreateClone( } if len(tags) > 0 { - tagString := resourceVirtualEnvironmentVMGetTagsString(d) + tagString := vmGetTagsString(d) updateBody.Tags = &tagString } @@ -1637,7 +1626,7 @@ func resourceVirtualEnvironmentVMCreateClone( } if len(vga) > 0 { - vgaDevice, err := resourceVirtualEnvironmentVMGetVGADeviceObject(d) + vgaDevice, err := vmGetVGADeviceObject(d) if err != nil { return diag.FromErr(err) } @@ -1666,7 +1655,7 @@ func resourceVirtualEnvironmentVMCreateClone( } allDiskInfo := getDiskInfo(vmConfig, d) - diskDeviceObjects, err := resourceVirtualEnvironmentVMGetDiskDeviceObjects(d, nil) + diskDeviceObjects, err := vmGetDiskDeviceObjects(d, nil) if err != nil { return diag.FromErr(err) } @@ -1722,7 +1711,7 @@ func resourceVirtualEnvironmentVMCreateClone( ) } - deleteOriginalDisk := proxmox.CustomBool(true) + deleteOriginalDisk := types.CustomBool(true) diskMoveBody := &proxmox.VirtualEnvironmentVMMoveDiskRequestBody{ DeleteOriginalDisk: &deleteOriginalDisk, @@ -1762,23 +1751,19 @@ func resourceVirtualEnvironmentVMCreateClone( } } - return resourceVirtualEnvironmentVMCreateStart(ctx, d, m) + return vmCreateStart(ctx, d, m) } -func resourceVirtualEnvironmentVMCreateCustom( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { - config := m.(providerConfiguration) +func vmCreateCustom(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) } - resource := resourceVirtualEnvironmentVM() + resource := VM() - acpi := proxmox.CustomBool(d.Get(mkResourceVirtualEnvironmentVMACPI).(bool)) + acpi := types.CustomBool(d.Get(mkResourceVirtualEnvironmentVMACPI).(bool)) agentBlock, err := getSchemaBlock( resource, @@ -1791,15 +1776,15 @@ func resourceVirtualEnvironmentVMCreateCustom( return diag.FromErr(err) } - agentEnabled := proxmox.CustomBool( + agentEnabled := types.CustomBool( agentBlock[mkResourceVirtualEnvironmentVMAgentEnabled].(bool), ) - agentTrim := proxmox.CustomBool(agentBlock[mkResourceVirtualEnvironmentVMAgentTrim].(bool)) + agentTrim := types.CustomBool(agentBlock[mkResourceVirtualEnvironmentVMAgentTrim].(bool)) agentType := agentBlock[mkResourceVirtualEnvironmentVMAgentType].(string) kvmArguments := d.Get(mkResourceVirtualEnvironmentVMKVMArguments).(string) - audioDevices := resourceVirtualEnvironmentVMGetAudioDeviceList(d) + audioDevices := vmGetAudioDeviceList(d) bios := d.Get(mkResourceVirtualEnvironmentVMBIOS).(string) @@ -1844,7 +1829,7 @@ func resourceVirtualEnvironmentVMCreateCustom( cpuUnits := cpuBlock[mkResourceVirtualEnvironmentVMCPUUnits].(int) description := d.Get(mkResourceVirtualEnvironmentVMDescription).(string) - diskDeviceObjects, err := resourceVirtualEnvironmentVMGetDiskDeviceObjects(d, nil) + diskDeviceObjects, err := vmGetDiskDeviceObjects(d, nil) if err != nil { return diag.FromErr(err) } @@ -1854,7 +1839,7 @@ func resourceVirtualEnvironmentVMCreateCustom( // ideDeviceObjects := getOrderedDiskDeviceList(diskDeviceObjects, "ide") sataDeviceObjects := diskDeviceObjects["sata"] - initializationConfig := resourceVirtualEnvironmentVMGetCloudInitConfig(d) + initializationConfig := vmGetCloudInitConfig(d) if initializationConfig != nil { initialization := d.Get(mkResourceVirtualEnvironmentVMInitialization).([]interface{}) @@ -1865,7 +1850,7 @@ func resourceVirtualEnvironmentVMCreateCustom( cdromCloudInitFileID = fmt.Sprintf("%s:cloudinit", initializationDatastoreID) } - pciDeviceObjects := resourceVirtualEnvironmentVMGetHostPCIDeviceObjects(d) + pciDeviceObjects := vmGetHostPCIDeviceObjects(d) keyboardLayout := d.Get(mkResourceVirtualEnvironmentVMKeyboardLayout).(string) memoryBlock, err := getSchemaBlock( @@ -1887,7 +1872,7 @@ func resourceVirtualEnvironmentVMCreateCustom( name := d.Get(mkResourceVirtualEnvironmentVMName).(string) tags := d.Get(mkResourceVirtualEnvironmentVMTags).([]interface{}) - networkDeviceObjects := resourceVirtualEnvironmentVMGetNetworkDeviceObjects(d) + networkDeviceObjects := vmGetNetworkDeviceObjects(d) nodeName := d.Get(mkResourceVirtualEnvironmentVMNodeName).(string) @@ -1906,13 +1891,13 @@ func resourceVirtualEnvironmentVMCreateCustom( poolID := d.Get(mkResourceVirtualEnvironmentVMPoolID).(string) - serialDevices := resourceVirtualEnvironmentVMGetSerialDeviceList(d) + serialDevices := vmGetSerialDeviceList(d) - onBoot := proxmox.CustomBool(d.Get(mkResourceVirtualEnvironmentVMOnBoot).(bool)) - tabletDevice := proxmox.CustomBool(d.Get(mkResourceVirtualEnvironmentVMTabletDevice).(bool)) - template := proxmox.CustomBool(d.Get(mkResourceVirtualEnvironmentVMTemplate).(bool)) + onBoot := types.CustomBool(d.Get(mkResourceVirtualEnvironmentVMOnBoot).(bool)) + tabletDevice := types.CustomBool(d.Get(mkResourceVirtualEnvironmentVMTabletDevice).(bool)) + template := types.CustomBool(d.Get(mkResourceVirtualEnvironmentVMTemplate).(bool)) - vgaDevice, err := resourceVirtualEnvironmentVMGetVGADeviceObject(d) + vgaDevice, err := vmGetVGADeviceObject(d) if err != nil { return diag.FromErr(err) } @@ -2030,7 +2015,7 @@ func resourceVirtualEnvironmentVMCreateCustom( } if len(tags) > 0 { - tagsString := resourceVirtualEnvironmentVMGetTagsString(d) + tagsString := vmGetTagsString(d) createBody.Tags = &tagsString } @@ -2057,7 +2042,7 @@ func resourceVirtualEnvironmentVMCreateCustom( d.SetId(strconv.Itoa(vmID)) - // TODO: The VM creation is not atomic, and not synchronous. This means that the VM might not be + // NOTE: The VM creation is not atomic, and not synchronous. This means that the VM might not be // available immediately after the creation, or its state reported by the API might not be // up to date. This is a problem for the following operations, which rely on the VM information // returned by API calls, particularly read-back to populate the Terraform state. @@ -2065,15 +2050,11 @@ func resourceVirtualEnvironmentVMCreateCustom( // the correct state? // time.Sleep(5 * time.Second) - return resourceVirtualEnvironmentVMCreateCustomDisks(ctx, d, m) + return vmCreateCustomDisks(ctx, d, m) } -func resourceVirtualEnvironmentVMCreateCustomDisks( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { - config := m.(providerConfiguration) +func vmCreateCustomDisks(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) @@ -2101,7 +2082,7 @@ func resourceVirtualEnvironmentVMCreateCustomDisks( } // Retrieve some information about the disk schema. - resourceSchema := resourceVirtualEnvironmentVM().Schema + resourceSchema := VM().Schema diskSchemaElem := resourceSchema[mkResourceVirtualEnvironmentVMDisk].Elem diskSchemaResource := diskSchemaElem.(*schema.Resource) diskSpeedResource := diskSchemaResource.Schema[mkResourceVirtualEnvironmentVMDiskSpeed] @@ -2123,8 +2104,8 @@ func resourceVirtualEnvironmentVMCreateCustomDisks( size, _ := block[mkResourceVirtualEnvironmentVMDiskSize].(int) speed := block[mkResourceVirtualEnvironmentVMDiskSpeed].([]interface{}) diskInterface, _ := block[mkResourceVirtualEnvironmentVMDiskInterface].(string) - ioThread := proxmox.CustomBool(block[mkResourceVirtualEnvironmentVMDiskIOThread].(bool)) - ssd := proxmox.CustomBool(block[mkResourceVirtualEnvironmentVMDiskSSD].(bool)) + ioThread := types.CustomBool(block[mkResourceVirtualEnvironmentVMDiskIOThread].(bool)) + ssd := types.CustomBool(block[mkResourceVirtualEnvironmentVMDiskSSD].(bool)) discard, _ := block[mkResourceVirtualEnvironmentVMDiskDiscard].(string) if fileFormat == "" { @@ -2215,23 +2196,19 @@ func resourceVirtualEnvironmentVMCreateCustomDisks( } } - return resourceVirtualEnvironmentVMCreateStart(ctx, d, m) + return vmCreateStart(ctx, d, m) } -func resourceVirtualEnvironmentVMCreateStart( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { +func vmCreateStart(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { started := d.Get(mkResourceVirtualEnvironmentVMStarted).(bool) template := d.Get(mkResourceVirtualEnvironmentVMTemplate).(bool) reboot := d.Get(mkResourceVirtualEnvironmentVMRebootAfterCreation).(bool) if !started || template { - return resourceVirtualEnvironmentVMRead(ctx, d, m) + return vmRead(ctx, d, m) } - config := m.(providerConfiguration) + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) @@ -2267,12 +2244,10 @@ func resourceVirtualEnvironmentVMCreateStart( } } - return resourceVirtualEnvironmentVMRead(ctx, d, m) + return vmRead(ctx, d, m) } -func resourceVirtualEnvironmentVMGetAudioDeviceList( - d *schema.ResourceData, -) proxmox.CustomAudioDevices { +func vmGetAudioDeviceList(d *schema.ResourceData) proxmox.CustomAudioDevices { devices := d.Get(mkResourceVirtualEnvironmentVMAudioDevice).([]interface{}) list := make(proxmox.CustomAudioDevices, len(devices)) @@ -2291,7 +2266,7 @@ func resourceVirtualEnvironmentVMGetAudioDeviceList( return list } -func resourceVirtualEnvironmentVMGetAudioDeviceValidator() schema.SchemaValidateDiagFunc { +func vmGetAudioDeviceValidator() schema.SchemaValidateDiagFunc { return validation.ToDiagFunc(validation.StringInSlice([]string{ "AC97", "ich9-intel-hda", @@ -2299,15 +2274,13 @@ func resourceVirtualEnvironmentVMGetAudioDeviceValidator() schema.SchemaValidate }, false)) } -func resourceVirtualEnvironmentVMGetAudioDriverValidator() schema.SchemaValidateDiagFunc { +func vmGetAudioDriverValidator() schema.SchemaValidateDiagFunc { return validation.ToDiagFunc(validation.StringInSlice([]string{ "spice", }, false)) } -func resourceVirtualEnvironmentVMGetCloudInitConfig( - d *schema.ResourceData, -) *proxmox.CustomCloudInitConfig { +func vmGetCloudInitConfig(d *schema.ResourceData) *proxmox.CustomCloudInitConfig { var initializationConfig *proxmox.CustomCloudInitConfig initialization := d.Get(mkResourceVirtualEnvironmentVMInitialization).([]interface{}) @@ -2438,14 +2411,14 @@ func resourceVirtualEnvironmentVMGetCloudInitConfig( return initializationConfig } -func resourceVirtualEnvironmentVMGetCPUArchitectureValidator() schema.SchemaValidateDiagFunc { +func vmGetCPUArchitectureValidator() schema.SchemaValidateDiagFunc { return validation.ToDiagFunc(validation.StringInSlice([]string{ "aarch64", "x86_64", }, false)) } -func resourceVirtualEnvironmentVMGetDiskDeviceObjects( +func vmGetDiskDeviceObjects( d *schema.ResourceData, disks []interface{}, ) (map[string]map[string]proxmox.CustomStorageDevice, error) { @@ -2458,7 +2431,7 @@ func resourceVirtualEnvironmentVMGetDiskDeviceObjects( } diskDeviceObjects := map[string]map[string]proxmox.CustomStorageDevice{} - resource := resourceVirtualEnvironmentVM() + resource := VM() for _, diskEntry := range diskDevice { diskDevice := proxmox.CustomStorageDevice{ @@ -2471,8 +2444,8 @@ func resourceVirtualEnvironmentVMGetDiskDeviceObjects( fileID, _ := block[mkResourceVirtualEnvironmentVMDiskFileID].(string) size, _ := block[mkResourceVirtualEnvironmentVMDiskSize].(int) diskInterface, _ := block[mkResourceVirtualEnvironmentVMDiskInterface].(string) - ioThread := proxmox.CustomBool(block[mkResourceVirtualEnvironmentVMDiskIOThread].(bool)) - ssd := proxmox.CustomBool(block[mkResourceVirtualEnvironmentVMDiskSSD].(bool)) + ioThread := types.CustomBool(block[mkResourceVirtualEnvironmentVMDiskIOThread].(bool)) + ssd := types.CustomBool(block[mkResourceVirtualEnvironmentVMDiskSSD].(bool)) discard := block[mkResourceVirtualEnvironmentVMDiskDiscard].(string) speedBlock, err := getSchemaBlock( @@ -2553,9 +2526,7 @@ func resourceVirtualEnvironmentVMGetDiskDeviceObjects( return diskDeviceObjects, nil } -func resourceVirtualEnvironmentVMGetHostPCIDeviceObjects( - d *schema.ResourceData, -) proxmox.CustomPCIDevices { +func vmGetHostPCIDeviceObjects(d *schema.ResourceData) proxmox.CustomPCIDevices { pciDevice := d.Get(mkResourceVirtualEnvironmentVMHostPCI).([]interface{}) pciDeviceObjects := make(proxmox.CustomPCIDevices, len(pciDevice)) @@ -2564,12 +2535,12 @@ func resourceVirtualEnvironmentVMGetHostPCIDeviceObjects( ids, _ := block[mkResourceVirtualEnvironmentVMHostPCIDeviceID].(string) mdev, _ := block[mkResourceVirtualEnvironmentVMHostPCIDeviceMDev].(string) - pcie := proxmox.CustomBool(block[mkResourceVirtualEnvironmentVMHostPCIDevicePCIE].(bool)) - rombar := proxmox.CustomBool( + pcie := types.CustomBool(block[mkResourceVirtualEnvironmentVMHostPCIDevicePCIE].(bool)) + rombar := types.CustomBool( block[mkResourceVirtualEnvironmentVMHostPCIDeviceROMBAR].(bool), ) romfile, _ := block[mkResourceVirtualEnvironmentVMHostPCIDeviceROMFile].(string) - xvga := proxmox.CustomBool(block[mkResourceVirtualEnvironmentVMHostPCIDeviceXVGA].(bool)) + xvga := types.CustomBool(block[mkResourceVirtualEnvironmentVMHostPCIDeviceXVGA].(bool)) device := proxmox.CustomPCIDevice{ DeviceIDs: strings.Split(ids, ";"), @@ -2595,9 +2566,7 @@ func resourceVirtualEnvironmentVMGetHostPCIDeviceObjects( return pciDeviceObjects } -func resourceVirtualEnvironmentVMGetNetworkDeviceObjects( - d *schema.ResourceData, -) proxmox.CustomNetworkDevices { +func vmGetNetworkDeviceObjects(d *schema.ResourceData) proxmox.CustomNetworkDevices { networkDevice := d.Get(mkResourceVirtualEnvironmentVMNetworkDevice).([]interface{}) networkDeviceObjects := make(proxmox.CustomNetworkDevices, len(networkDevice)) @@ -2643,7 +2612,7 @@ func resourceVirtualEnvironmentVMGetNetworkDeviceObjects( return networkDeviceObjects } -func resourceVirtualEnvironmentVMGetOperatingSystemTypeValidator() schema.SchemaValidateDiagFunc { +func vmGetOperatingSystemTypeValidator() schema.SchemaValidateDiagFunc { return validation.ToDiagFunc(validation.StringInSlice([]string{ "l24", "l26", @@ -2660,9 +2629,7 @@ func resourceVirtualEnvironmentVMGetOperatingSystemTypeValidator() schema.Schema }, false)) } -func resourceVirtualEnvironmentVMGetSerialDeviceList( - d *schema.ResourceData, -) proxmox.CustomSerialDevices { +func vmGetSerialDeviceList(d *schema.ResourceData) proxmox.CustomSerialDevices { device := d.Get(mkResourceVirtualEnvironmentVMSerialDevice).([]interface{}) list := make(proxmox.CustomSerialDevices, len(device)) @@ -2677,7 +2644,7 @@ func resourceVirtualEnvironmentVMGetSerialDeviceList( return list } -func resourceVirtualEnvironmentVMGetTagsString(d *schema.ResourceData) string { +func vmGetTagsString(d *schema.ResourceData) string { tags := d.Get(mkResourceVirtualEnvironmentVMTags).([]interface{}) var sanitizedTags []string for i := 0; i < len(tags); i++ { @@ -2690,7 +2657,7 @@ func resourceVirtualEnvironmentVMGetTagsString(d *schema.ResourceData) string { return strings.Join(sanitizedTags, ";") } -func resourceVirtualEnvironmentVMGetSerialDeviceValidator() schema.SchemaValidateDiagFunc { +func vmGetSerialDeviceValidator() schema.SchemaValidateDiagFunc { return validation.ToDiagFunc(func(i interface{}, k string) (s []string, es []error) { v, ok := i.(string) @@ -2708,10 +2675,8 @@ func resourceVirtualEnvironmentVMGetSerialDeviceValidator() schema.SchemaValidat }) } -func resourceVirtualEnvironmentVMGetVGADeviceObject( - d *schema.ResourceData, -) (*proxmox.CustomVGADevice, error) { - resource := resourceVirtualEnvironmentVM() +func vmGetVGADeviceObject(d *schema.ResourceData) (*proxmox.CustomVGADevice, error) { + resource := VM() vgaBlock, err := getSchemaBlock( resource, @@ -2724,7 +2689,7 @@ func resourceVirtualEnvironmentVMGetVGADeviceObject( return nil, err } - vgaEnabled := proxmox.CustomBool(vgaBlock[mkResourceVirtualEnvironmentVMAgentEnabled].(bool)) + vgaEnabled := types.CustomBool(vgaBlock[mkResourceVirtualEnvironmentVMAgentEnabled].(bool)) vgaMemory := vgaBlock[mkResourceVirtualEnvironmentVMVGAMemory].(int) vgaType := vgaBlock[mkResourceVirtualEnvironmentVMVGAType].(string) @@ -2747,12 +2712,8 @@ func resourceVirtualEnvironmentVMGetVGADeviceObject( return vgaDevice, nil } -func resourceVirtualEnvironmentVMRead( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { - config := m.(providerConfiguration) +func vmRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) @@ -2782,10 +2743,10 @@ func resourceVirtualEnvironmentVMRead( return diag.FromErr(err) } - return resourceVirtualEnvironmentVMReadCustom(ctx, d, m, vmID, vmConfig, vmStatus) + return vmReadCustom(ctx, d, m, vmID, vmConfig, vmStatus) } -func resourceVirtualEnvironmentVMReadCustom( +func vmReadCustom( ctx context.Context, d *schema.ResourceData, m interface{}, @@ -2793,13 +2754,13 @@ func resourceVirtualEnvironmentVMReadCustom( vmConfig *proxmox.VirtualEnvironmentVMGetResponseData, vmStatus *proxmox.VirtualEnvironmentVMGetStatusResponseData, ) diag.Diagnostics { - config := m.(providerConfiguration) + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) } - diags := resourceVirtualEnvironmentVMReadPrimitiveValues(d, vmConfig, vmStatus) + diags := vmReadPrimitiveValues(d, vmConfig, vmStatus) if diags.HasError() { return diags } @@ -3673,12 +3634,12 @@ func resourceVirtualEnvironmentVMReadCustom( diags = append( diags, - resourceVirtualEnvironmentVMReadNetworkValues(ctx, d, m, vmID, vmConfig)...) + vmReadNetworkValues(ctx, d, m, vmID, vmConfig)...) return diags } -func resourceVirtualEnvironmentVMReadNetworkValues( +func vmReadNetworkValues( ctx context.Context, d *schema.ResourceData, m interface{}, @@ -3687,7 +3648,7 @@ func resourceVirtualEnvironmentVMReadNetworkValues( ) diag.Diagnostics { var diags diag.Diagnostics - config := m.(providerConfiguration) + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) @@ -3702,7 +3663,7 @@ func resourceVirtualEnvironmentVMReadNetworkValues( if started { if vmConfig.Agent != nil && vmConfig.Agent.Enabled != nil && *vmConfig.Agent.Enabled { - resource := resourceVirtualEnvironmentVM() + resource := VM() agentBlock, err := getSchemaBlock( resource, d, @@ -3774,7 +3735,7 @@ func resourceVirtualEnvironmentVMReadNetworkValues( return diags } -func resourceVirtualEnvironmentVMReadPrimitiveValues( +func vmReadPrimitiveValues( d *schema.ResourceData, vmConfig *proxmox.VirtualEnvironmentVMGetResponseData, vmStatus *proxmox.VirtualEnvironmentVMGetStatusResponseData, @@ -3922,12 +3883,8 @@ func resourceVirtualEnvironmentVMReadPrimitiveValues( return diags } -func resourceVirtualEnvironmentVMUpdate( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { - config := m.(providerConfiguration) +func vmUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) @@ -3959,7 +3916,7 @@ func resourceVirtualEnvironmentVMUpdate( } var del []string - resource := resourceVirtualEnvironmentVM() + resource := VM() // Retrieve the entire configuration as we need to process certain values. vmConfig, err := veClient.GetVM(ctx, nodeName, vmID) @@ -3969,7 +3926,7 @@ func resourceVirtualEnvironmentVMUpdate( // Prepare the new primitive configuration values. if d.HasChange(mkResourceVirtualEnvironmentVMACPI) { - acpi := proxmox.CustomBool(d.Get(mkResourceVirtualEnvironmentVMACPI).(bool)) + acpi := types.CustomBool(d.Get(mkResourceVirtualEnvironmentVMACPI).(bool)) updateBody.ACPI = &acpi rebootRequired = true } @@ -3992,12 +3949,12 @@ func resourceVirtualEnvironmentVMUpdate( } if d.HasChange(mkResourceVirtualEnvironmentVMOnBoot) { - startOnBoot := proxmox.CustomBool(d.Get(mkResourceVirtualEnvironmentVMOnBoot).(bool)) + startOnBoot := types.CustomBool(d.Get(mkResourceVirtualEnvironmentVMOnBoot).(bool)) updateBody.StartOnBoot = &startOnBoot } if d.HasChange(mkResourceVirtualEnvironmentVMTags) { - tagString := resourceVirtualEnvironmentVMGetTagsString(d) + tagString := vmGetTagsString(d) updateBody.Tags = &tagString } @@ -4022,12 +3979,12 @@ func resourceVirtualEnvironmentVMUpdate( } if d.HasChange(mkResourceVirtualEnvironmentVMTabletDevice) { - tabletDevice := proxmox.CustomBool(d.Get(mkResourceVirtualEnvironmentVMTabletDevice).(bool)) + tabletDevice := types.CustomBool(d.Get(mkResourceVirtualEnvironmentVMTabletDevice).(bool)) updateBody.TabletDeviceEnabled = &tabletDevice rebootRequired = true } - template := proxmox.CustomBool(d.Get(mkResourceVirtualEnvironmentVMTemplate).(bool)) + template := types.CustomBool(d.Get(mkResourceVirtualEnvironmentVMTemplate).(bool)) if d.HasChange(mkResourceVirtualEnvironmentVMTemplate) { updateBody.Template = &template @@ -4047,10 +4004,10 @@ func resourceVirtualEnvironmentVMUpdate( return diag.FromErr(err) } - agentEnabled := proxmox.CustomBool( + agentEnabled := types.CustomBool( agentBlock[mkResourceVirtualEnvironmentVMAgentEnabled].(bool), ) - agentTrim := proxmox.CustomBool(agentBlock[mkResourceVirtualEnvironmentVMAgentTrim].(bool)) + agentTrim := types.CustomBool(agentBlock[mkResourceVirtualEnvironmentVMAgentTrim].(bool)) agentType := agentBlock[mkResourceVirtualEnvironmentVMAgentType].(string) updateBody.Agent = &proxmox.CustomAgent{ @@ -4064,7 +4021,7 @@ func resourceVirtualEnvironmentVMUpdate( // Prepare the new audio devices. if d.HasChange(mkResourceVirtualEnvironmentVMAudioDevice) { - updateBody.AudioDevices = resourceVirtualEnvironmentVMGetAudioDeviceList(d) + updateBody.AudioDevices = vmGetAudioDeviceList(d) for i := 0; i < len(updateBody.AudioDevices); i++ { if !updateBody.AudioDevices[i].Enabled { @@ -4165,7 +4122,7 @@ func resourceVirtualEnvironmentVMUpdate( // Prepare the new disk device configuration. if d.HasChange(mkResourceVirtualEnvironmentVMDisk) { - diskDeviceObjects, err := resourceVirtualEnvironmentVMGetDiskDeviceObjects(d, nil) + diskDeviceObjects, err := vmGetDiskDeviceObjects(d, nil) if err != nil { return diag.FromErr(err) } @@ -4226,7 +4183,7 @@ func resourceVirtualEnvironmentVMUpdate( // Prepare the new cloud-init configuration. if d.HasChange(mkResourceVirtualEnvironmentVMInitialization) { - initializationConfig := resourceVirtualEnvironmentVMGetCloudInitConfig(d) + initializationConfig := vmGetCloudInitConfig(d) updateBody.CloudInitConfig = initializationConfig @@ -4260,7 +4217,7 @@ func resourceVirtualEnvironmentVMUpdate( // Prepare the new hostpci devices configuration. if d.HasChange(mkResourceVirtualEnvironmentVMHostPCI) { - updateBody.PCIDevices = resourceVirtualEnvironmentVMGetHostPCIDeviceObjects(d) + updateBody.PCIDevices = vmGetHostPCIDeviceObjects(d) if err != nil { return diag.FromErr(err) } @@ -4302,7 +4259,7 @@ func resourceVirtualEnvironmentVMUpdate( // Prepare the new network device configuration. if d.HasChange(mkResourceVirtualEnvironmentVMNetworkDevice) { - updateBody.NetworkDevices = resourceVirtualEnvironmentVMGetNetworkDeviceObjects(d) + updateBody.NetworkDevices = vmGetNetworkDeviceObjects(d) for i := 0; i < len(updateBody.NetworkDevices); i++ { if !updateBody.NetworkDevices[i].Enabled { @@ -4339,7 +4296,7 @@ func resourceVirtualEnvironmentVMUpdate( // Prepare the new serial devices. if d.HasChange(mkResourceVirtualEnvironmentVMSerialDevice) { - updateBody.SerialDevices = resourceVirtualEnvironmentVMGetSerialDeviceList(d) + updateBody.SerialDevices = vmGetSerialDeviceList(d) for i := len(updateBody.SerialDevices); i < maxResourceVirtualEnvironmentVMSerialDevices; i++ { del = append(del, fmt.Sprintf("serial%d", i)) @@ -4350,7 +4307,7 @@ func resourceVirtualEnvironmentVMUpdate( // Prepare the new VGA configuration. if d.HasChange(mkResourceVirtualEnvironmentVMVGA) { - updateBody.VGADevice, err = resourceVirtualEnvironmentVMGetVGADeviceObject(d) + updateBody.VGADevice, err = vmGetVGADeviceObject(d) if err != nil { return diag.FromErr(err) } @@ -4385,7 +4342,7 @@ func resourceVirtualEnvironmentVMUpdate( return diag.FromErr(err) } } else { - forceStop := proxmox.CustomBool(true) + forceStop := types.CustomBool(true) shutdownTimeout := d.Get(mkResourceVirtualEnvironmentVMTimeoutShutdownVM).(int) err = veClient.ShutdownVM(ctx, nodeName, vmID, &proxmox.VirtualEnvironmentVMShutdownRequestBody{ @@ -4401,7 +4358,7 @@ func resourceVirtualEnvironmentVMUpdate( } // Change the disk locations and/or sizes, if necessary. - return resourceVirtualEnvironmentVMUpdateDiskLocationAndSize( + return vmUpdateDiskLocationAndSize( ctx, d, m, @@ -4409,13 +4366,13 @@ func resourceVirtualEnvironmentVMUpdate( ) } -func resourceVirtualEnvironmentVMUpdateDiskLocationAndSize( +func vmUpdateDiskLocationAndSize( ctx context.Context, d *schema.ResourceData, m interface{}, reboot bool, ) diag.Diagnostics { - config := m.(providerConfiguration) + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) @@ -4433,7 +4390,7 @@ func resourceVirtualEnvironmentVMUpdateDiskLocationAndSize( if d.HasChange(mkResourceVirtualEnvironmentVMDisk) { diskOld, diskNew := d.GetChange(mkResourceVirtualEnvironmentVMDisk) - diskOldEntries, err := resourceVirtualEnvironmentVMGetDiskDeviceObjects( + diskOldEntries, err := vmGetDiskDeviceObjects( d, diskOld.([]interface{}), ) @@ -4441,7 +4398,7 @@ func resourceVirtualEnvironmentVMUpdateDiskLocationAndSize( return diag.FromErr(err) } - diskNewEntries, err := resourceVirtualEnvironmentVMGetDiskDeviceObjects( + diskNewEntries, err := vmGetDiskDeviceObjects( d, diskNew.([]interface{}), ) @@ -4464,7 +4421,7 @@ func resourceVirtualEnvironmentVMUpdateDiskLocationAndSize( } if *oldDisk.ID != *diskNewEntries[prefix][oldKey].ID { - deleteOriginalDisk := proxmox.CustomBool(true) + deleteOriginalDisk := types.CustomBool(true) diskMoveBodies = append( diskMoveBodies, @@ -4492,7 +4449,7 @@ func resourceVirtualEnvironmentVMUpdateDiskLocationAndSize( } if shutdownForDisksRequired && !template { - forceStop := proxmox.CustomBool(true) + forceStop := types.CustomBool(true) shutdownTimeout := d.Get(mkResourceVirtualEnvironmentVMTimeoutShutdownVM).(int) err = veClient.ShutdownVM( @@ -4555,15 +4512,11 @@ func resourceVirtualEnvironmentVMUpdateDiskLocationAndSize( } } - return resourceVirtualEnvironmentVMRead(ctx, d, m) + return vmRead(ctx, d, m) } -func resourceVirtualEnvironmentVMDelete( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { - config := m.(providerConfiguration) +func vmDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + config := m.(proxmoxtf.ProviderConfiguration) veClient, err := config.GetVEClient() if err != nil { return diag.FromErr(err) @@ -4582,7 +4535,7 @@ func resourceVirtualEnvironmentVMDelete( } if status.Status != "stopped" { - forceStop := proxmox.CustomBool(true) + forceStop := types.CustomBool(true) shutdownTimeout := d.Get(mkResourceVirtualEnvironmentVMTimeoutShutdownVM).(int) err = veClient.ShutdownVM( diff --git a/proxmoxtf/resource_virtual_environment_vm_test.go b/proxmoxtf/resource/vm_test.go similarity index 71% rename from proxmoxtf/resource_virtual_environment_vm_test.go rename to proxmoxtf/resource/vm_test.go index d87189c4..12561f67 100644 --- a/proxmoxtf/resource_virtual_environment_vm_test.go +++ b/proxmoxtf/resource/vm_test.go @@ -1,33 +1,39 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public +/* + * 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/. */ + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ -package proxmoxtf +package resource import ( "testing" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf/test" ) -// TestResourceVirtualEnvironmentVMInstantiation tests whether the ResourceVirtualEnvironmentVM instance can be instantiated. -func TestResourceVirtualEnvironmentVMInstantiation(t *testing.T) { - s := resourceVirtualEnvironmentVM() +// TestVMInstantiation tests whether the VM instance can be instantiated. +func TestVMInstantiation(t *testing.T) { + t.Parallel() + s := VM() if s == nil { - t.Fatalf("Cannot instantiate resourceVirtualEnvironmentVM") + t.Fatalf("Cannot instantiate VM") } } -// TestResourceVirtualEnvironmentVMSchema tests the resourceVirtualEnvironmentVM schema. -func TestResourceVirtualEnvironmentVMSchema(t *testing.T) { - s := resourceVirtualEnvironmentVM() +// TestVMSchema tests the VM schema. +func TestVMSchema(t *testing.T) { + t.Parallel() + s := VM() - testRequiredArguments(t, s, []string{ + test.AssertRequiredArguments(t, s, []string{ mkResourceVirtualEnvironmentVMNodeName, }) - testOptionalArguments(t, s, []string{ + test.AssertOptionalArguments(t, s, []string{ mkResourceVirtualEnvironmentVMACPI, mkResourceVirtualEnvironmentVMAgent, mkResourceVirtualEnvironmentVMAudioDevice, @@ -55,14 +61,14 @@ func TestResourceVirtualEnvironmentVMSchema(t *testing.T) { mkResourceVirtualEnvironmentVMSCSIHardware, }) - testComputedAttributes(t, s, []string{ + test.AssertComputedAttributes(t, s, []string{ mkResourceVirtualEnvironmentVMIPv4Addresses, mkResourceVirtualEnvironmentVMIPv6Addresses, mkResourceVirtualEnvironmentVMMACAddresses, mkResourceVirtualEnvironmentVMNetworkInterfaceNames, }) - testValueTypes(t, s, map[string]schema.ValueType{ + test.AssertValueTypes(t, s, map[string]schema.ValueType{ mkResourceVirtualEnvironmentVMACPI: schema.TypeBool, mkResourceVirtualEnvironmentVMAgent: schema.TypeList, mkResourceVirtualEnvironmentVMAudioDevice: schema.TypeList, @@ -93,65 +99,65 @@ func TestResourceVirtualEnvironmentVMSchema(t *testing.T) { mkResourceVirtualEnvironmentVMSCSIHardware: schema.TypeString, }) - agentSchema := testNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentVMAgent) + agentSchema := test.AssertNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentVMAgent) - testOptionalArguments(t, agentSchema, []string{ + test.AssertOptionalArguments(t, agentSchema, []string{ mkResourceVirtualEnvironmentVMAgentEnabled, mkResourceVirtualEnvironmentVMAgentTimeout, mkResourceVirtualEnvironmentVMAgentTrim, mkResourceVirtualEnvironmentVMAgentType, }) - testValueTypes(t, agentSchema, map[string]schema.ValueType{ + test.AssertValueTypes(t, agentSchema, map[string]schema.ValueType{ mkResourceVirtualEnvironmentVMAgentEnabled: schema.TypeBool, mkResourceVirtualEnvironmentVMAgentTrim: schema.TypeBool, mkResourceVirtualEnvironmentVMAgentType: schema.TypeString, }) - audioDeviceSchema := testNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentVMAudioDevice) + audioDeviceSchema := test.AssertNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentVMAudioDevice) - testOptionalArguments(t, audioDeviceSchema, []string{ + test.AssertOptionalArguments(t, audioDeviceSchema, []string{ mkResourceVirtualEnvironmentVMAudioDeviceDevice, mkResourceVirtualEnvironmentVMAudioDeviceDriver, }) - testValueTypes(t, audioDeviceSchema, map[string]schema.ValueType{ + test.AssertValueTypes(t, audioDeviceSchema, map[string]schema.ValueType{ mkResourceVirtualEnvironmentVMAudioDeviceDevice: schema.TypeString, mkResourceVirtualEnvironmentVMAudioDeviceDriver: schema.TypeString, }) - cdromSchema := testNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentVMCDROM) + cdromSchema := test.AssertNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentVMCDROM) - testOptionalArguments(t, cdromSchema, []string{ + test.AssertOptionalArguments(t, cdromSchema, []string{ mkResourceVirtualEnvironmentVMCDROMEnabled, mkResourceVirtualEnvironmentVMCDROMFileID, }) - testValueTypes(t, cdromSchema, map[string]schema.ValueType{ + test.AssertValueTypes(t, cdromSchema, map[string]schema.ValueType{ mkResourceVirtualEnvironmentVMCDROMEnabled: schema.TypeBool, mkResourceVirtualEnvironmentVMCDROMFileID: schema.TypeString, }) - cloneSchema := testNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentVMClone) + cloneSchema := test.AssertNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentVMClone) - testRequiredArguments(t, cloneSchema, []string{ + test.AssertRequiredArguments(t, cloneSchema, []string{ mkResourceVirtualEnvironmentVMCloneVMID, }) - testOptionalArguments(t, cloneSchema, []string{ + test.AssertOptionalArguments(t, cloneSchema, []string{ mkResourceVirtualEnvironmentVMCloneDatastoreID, mkResourceVirtualEnvironmentVMCloneNodeName, }) - testValueTypes(t, cloneSchema, map[string]schema.ValueType{ + test.AssertValueTypes(t, cloneSchema, map[string]schema.ValueType{ mkResourceVirtualEnvironmentVMCloneDatastoreID: schema.TypeString, mkResourceVirtualEnvironmentVMCloneNodeName: schema.TypeString, mkResourceVirtualEnvironmentVMCloneVMID: schema.TypeInt, }) - cpuSchema := testNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentVMCPU) + cpuSchema := test.AssertNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentVMCPU) - testOptionalArguments(t, cpuSchema, []string{ + test.AssertOptionalArguments(t, cpuSchema, []string{ mkResourceVirtualEnvironmentVMCPUArchitecture, mkResourceVirtualEnvironmentVMCPUCores, mkResourceVirtualEnvironmentVMCPUFlags, @@ -161,7 +167,7 @@ func TestResourceVirtualEnvironmentVMSchema(t *testing.T) { mkResourceVirtualEnvironmentVMCPUUnits, }) - testValueTypes(t, cpuSchema, map[string]schema.ValueType{ + test.AssertValueTypes(t, cpuSchema, map[string]schema.ValueType{ mkResourceVirtualEnvironmentVMCPUArchitecture: schema.TypeString, mkResourceVirtualEnvironmentVMCPUCores: schema.TypeInt, mkResourceVirtualEnvironmentVMCPUFlags: schema.TypeList, @@ -171,65 +177,65 @@ func TestResourceVirtualEnvironmentVMSchema(t *testing.T) { mkResourceVirtualEnvironmentVMCPUUnits: schema.TypeInt, }) - diskSchema := testNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentVMDisk) + diskSchema := test.AssertNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentVMDisk) - testOptionalArguments(t, diskSchema, []string{ + test.AssertOptionalArguments(t, diskSchema, []string{ mkResourceVirtualEnvironmentVMDiskDatastoreID, mkResourceVirtualEnvironmentVMDiskFileFormat, mkResourceVirtualEnvironmentVMDiskFileID, mkResourceVirtualEnvironmentVMDiskSize, }) - testValueTypes(t, diskSchema, map[string]schema.ValueType{ + test.AssertValueTypes(t, diskSchema, map[string]schema.ValueType{ mkResourceVirtualEnvironmentVMDiskDatastoreID: schema.TypeString, mkResourceVirtualEnvironmentVMDiskFileFormat: schema.TypeString, mkResourceVirtualEnvironmentVMDiskFileID: schema.TypeString, mkResourceVirtualEnvironmentVMDiskSize: schema.TypeInt, }) - diskSpeedSchema := testNestedSchemaExistence( + diskSpeedSchema := test.AssertNestedSchemaExistence( t, diskSchema, mkResourceVirtualEnvironmentVMDiskSpeed, ) - testOptionalArguments(t, diskSpeedSchema, []string{ + test.AssertOptionalArguments(t, diskSpeedSchema, []string{ mkResourceVirtualEnvironmentVMDiskSpeedRead, mkResourceVirtualEnvironmentVMDiskSpeedReadBurstable, mkResourceVirtualEnvironmentVMDiskSpeedWrite, mkResourceVirtualEnvironmentVMDiskSpeedWriteBurstable, }) - testValueTypes(t, diskSpeedSchema, map[string]schema.ValueType{ + test.AssertValueTypes(t, diskSpeedSchema, map[string]schema.ValueType{ mkResourceVirtualEnvironmentVMDiskSpeedRead: schema.TypeInt, mkResourceVirtualEnvironmentVMDiskSpeedReadBurstable: schema.TypeInt, mkResourceVirtualEnvironmentVMDiskSpeedWrite: schema.TypeInt, mkResourceVirtualEnvironmentVMDiskSpeedWriteBurstable: schema.TypeInt, }) - initializationSchema := testNestedSchemaExistence( + initializationSchema := test.AssertNestedSchemaExistence( t, s, mkResourceVirtualEnvironmentVMInitialization, ) - testOptionalArguments(t, initializationSchema, []string{ + test.AssertOptionalArguments(t, initializationSchema, []string{ mkResourceVirtualEnvironmentVMInitializationDatastoreID, mkResourceVirtualEnvironmentVMInitializationDNS, mkResourceVirtualEnvironmentVMInitializationIPConfig, mkResourceVirtualEnvironmentVMInitializationUserAccount, }) - testValueTypes(t, initializationSchema, map[string]schema.ValueType{ + test.AssertValueTypes(t, initializationSchema, map[string]schema.ValueType{ mkResourceVirtualEnvironmentVMInitializationDatastoreID: schema.TypeString, mkResourceVirtualEnvironmentVMInitializationDNS: schema.TypeList, mkResourceVirtualEnvironmentVMInitializationIPConfig: schema.TypeList, mkResourceVirtualEnvironmentVMInitializationUserAccount: schema.TypeList, }) - hostPCISchema := testNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentVMHostPCI) + hostPCISchema := test.AssertNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentVMHostPCI) - testOptionalArguments(t, hostPCISchema, []string{ + test.AssertOptionalArguments(t, hostPCISchema, []string{ mkResourceVirtualEnvironmentVMHostPCIDeviceMDev, mkResourceVirtualEnvironmentVMHostPCIDevicePCIE, mkResourceVirtualEnvironmentVMHostPCIDeviceROMBAR, @@ -237,7 +243,7 @@ func TestResourceVirtualEnvironmentVMSchema(t *testing.T) { mkResourceVirtualEnvironmentVMHostPCIDeviceXVGA, }) - testValueTypes(t, hostPCISchema, map[string]schema.ValueType{ + test.AssertValueTypes(t, hostPCISchema, map[string]schema.ValueType{ mkResourceVirtualEnvironmentVMHostPCIDevice: schema.TypeString, mkResourceVirtualEnvironmentVMHostPCIDeviceMDev: schema.TypeString, mkResourceVirtualEnvironmentVMHostPCIDevicePCIE: schema.TypeBool, @@ -246,109 +252,109 @@ func TestResourceVirtualEnvironmentVMSchema(t *testing.T) { mkResourceVirtualEnvironmentVMHostPCIDeviceXVGA: schema.TypeBool, }) - initializationDNSSchema := testNestedSchemaExistence( + initializationDNSSchema := test.AssertNestedSchemaExistence( t, initializationSchema, mkResourceVirtualEnvironmentVMInitializationDNS, ) - testOptionalArguments(t, initializationDNSSchema, []string{ + test.AssertOptionalArguments(t, initializationDNSSchema, []string{ mkResourceVirtualEnvironmentVMInitializationDNSDomain, mkResourceVirtualEnvironmentVMInitializationDNSServer, }) - testValueTypes(t, initializationDNSSchema, map[string]schema.ValueType{ + test.AssertValueTypes(t, initializationDNSSchema, map[string]schema.ValueType{ mkResourceVirtualEnvironmentVMInitializationDNSDomain: schema.TypeString, mkResourceVirtualEnvironmentVMInitializationDNSServer: schema.TypeString, }) - initializationIPConfigSchema := testNestedSchemaExistence( + initializationIPConfigSchema := test.AssertNestedSchemaExistence( t, initializationSchema, mkResourceVirtualEnvironmentVMInitializationIPConfig, ) - testOptionalArguments(t, initializationIPConfigSchema, []string{ + test.AssertOptionalArguments(t, initializationIPConfigSchema, []string{ mkResourceVirtualEnvironmentVMInitializationIPConfigIPv4, mkResourceVirtualEnvironmentVMInitializationIPConfigIPv6, }) - testValueTypes(t, initializationIPConfigSchema, map[string]schema.ValueType{ + test.AssertValueTypes(t, initializationIPConfigSchema, map[string]schema.ValueType{ mkResourceVirtualEnvironmentVMInitializationIPConfigIPv4: schema.TypeList, mkResourceVirtualEnvironmentVMInitializationIPConfigIPv6: schema.TypeList, }) - initializationIPConfigIPv4Schema := testNestedSchemaExistence( + initializationIPConfigIPv4Schema := test.AssertNestedSchemaExistence( t, initializationIPConfigSchema, mkResourceVirtualEnvironmentVMInitializationIPConfigIPv4, ) - testOptionalArguments(t, initializationIPConfigIPv4Schema, []string{ + test.AssertOptionalArguments(t, initializationIPConfigIPv4Schema, []string{ mkResourceVirtualEnvironmentVMInitializationIPConfigIPv4Address, mkResourceVirtualEnvironmentVMInitializationIPConfigIPv4Gateway, }) - testValueTypes(t, initializationIPConfigIPv4Schema, map[string]schema.ValueType{ + test.AssertValueTypes(t, initializationIPConfigIPv4Schema, map[string]schema.ValueType{ mkResourceVirtualEnvironmentVMInitializationIPConfigIPv4Address: schema.TypeString, mkResourceVirtualEnvironmentVMInitializationIPConfigIPv4Gateway: schema.TypeString, }) - initializationIPConfigIPv6Schema := testNestedSchemaExistence( + initializationIPConfigIPv6Schema := test.AssertNestedSchemaExistence( t, initializationIPConfigSchema, mkResourceVirtualEnvironmentVMInitializationIPConfigIPv6, ) - testOptionalArguments(t, initializationIPConfigIPv6Schema, []string{ + test.AssertOptionalArguments(t, initializationIPConfigIPv6Schema, []string{ mkResourceVirtualEnvironmentVMInitializationIPConfigIPv6Address, mkResourceVirtualEnvironmentVMInitializationIPConfigIPv6Gateway, }) - testValueTypes(t, initializationIPConfigIPv6Schema, map[string]schema.ValueType{ + test.AssertValueTypes(t, initializationIPConfigIPv6Schema, map[string]schema.ValueType{ mkResourceVirtualEnvironmentVMInitializationIPConfigIPv6Address: schema.TypeString, mkResourceVirtualEnvironmentVMInitializationIPConfigIPv6Gateway: schema.TypeString, }) - initializationUserAccountSchema := testNestedSchemaExistence( + initializationUserAccountSchema := test.AssertNestedSchemaExistence( t, initializationSchema, mkResourceVirtualEnvironmentVMInitializationUserAccount, ) - testOptionalArguments(t, initializationUserAccountSchema, []string{ + test.AssertOptionalArguments(t, initializationUserAccountSchema, []string{ mkResourceVirtualEnvironmentVMInitializationUserAccountKeys, mkResourceVirtualEnvironmentVMInitializationUserAccountPassword, mkResourceVirtualEnvironmentVMInitializationUserAccountUsername, }) - testValueTypes(t, initializationUserAccountSchema, map[string]schema.ValueType{ + test.AssertValueTypes(t, initializationUserAccountSchema, map[string]schema.ValueType{ mkResourceVirtualEnvironmentVMInitializationUserAccountKeys: schema.TypeList, mkResourceVirtualEnvironmentVMInitializationUserAccountPassword: schema.TypeString, mkResourceVirtualEnvironmentVMInitializationUserAccountUsername: schema.TypeString, }) - memorySchema := testNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentVMMemory) + memorySchema := test.AssertNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentVMMemory) - testOptionalArguments(t, memorySchema, []string{ + test.AssertOptionalArguments(t, memorySchema, []string{ mkResourceVirtualEnvironmentVMMemoryDedicated, mkResourceVirtualEnvironmentVMMemoryFloating, mkResourceVirtualEnvironmentVMMemoryShared, }) - testValueTypes(t, memorySchema, map[string]schema.ValueType{ + test.AssertValueTypes(t, memorySchema, map[string]schema.ValueType{ mkResourceVirtualEnvironmentVMMemoryDedicated: schema.TypeInt, mkResourceVirtualEnvironmentVMMemoryFloating: schema.TypeInt, mkResourceVirtualEnvironmentVMMemoryShared: schema.TypeInt, }) - networkDeviceSchema := testNestedSchemaExistence( + networkDeviceSchema := test.AssertNestedSchemaExistence( t, s, mkResourceVirtualEnvironmentVMNetworkDevice, ) - testOptionalArguments(t, networkDeviceSchema, []string{ + test.AssertOptionalArguments(t, networkDeviceSchema, []string{ mkResourceVirtualEnvironmentVMNetworkDeviceBridge, mkResourceVirtualEnvironmentVMNetworkDeviceEnabled, mkResourceVirtualEnvironmentVMNetworkDeviceMACAddress, @@ -358,7 +364,7 @@ func TestResourceVirtualEnvironmentVMSchema(t *testing.T) { mkResourceVirtualEnvironmentVMNetworkDeviceMTU, }) - testValueTypes(t, networkDeviceSchema, map[string]schema.ValueType{ + test.AssertValueTypes(t, networkDeviceSchema, map[string]schema.ValueType{ mkResourceVirtualEnvironmentVMNetworkDeviceBridge: schema.TypeString, mkResourceVirtualEnvironmentVMNetworkDeviceEnabled: schema.TypeBool, mkResourceVirtualEnvironmentVMNetworkDeviceMACAddress: schema.TypeString, @@ -368,43 +374,43 @@ func TestResourceVirtualEnvironmentVMSchema(t *testing.T) { mkResourceVirtualEnvironmentVMNetworkDeviceMTU: schema.TypeInt, }) - operatingSystemSchema := testNestedSchemaExistence( + operatingSystemSchema := test.AssertNestedSchemaExistence( t, s, mkResourceVirtualEnvironmentVMOperatingSystem, ) - testOptionalArguments(t, operatingSystemSchema, []string{ + test.AssertOptionalArguments(t, operatingSystemSchema, []string{ mkResourceVirtualEnvironmentVMOperatingSystemType, }) - testValueTypes(t, operatingSystemSchema, map[string]schema.ValueType{ + test.AssertValueTypes(t, operatingSystemSchema, map[string]schema.ValueType{ mkResourceVirtualEnvironmentVMOperatingSystemType: schema.TypeString, }) - serialDeviceSchema := testNestedSchemaExistence( + serialDeviceSchema := test.AssertNestedSchemaExistence( t, s, mkResourceVirtualEnvironmentVMSerialDevice, ) - testOptionalArguments(t, serialDeviceSchema, []string{ + test.AssertOptionalArguments(t, serialDeviceSchema, []string{ mkResourceVirtualEnvironmentVMSerialDeviceDevice, }) - testValueTypes(t, serialDeviceSchema, map[string]schema.ValueType{ + test.AssertValueTypes(t, serialDeviceSchema, map[string]schema.ValueType{ mkResourceVirtualEnvironmentVMSerialDeviceDevice: schema.TypeString, }) - vgaSchema := testNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentVMVGA) + vgaSchema := test.AssertNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentVMVGA) - testOptionalArguments(t, vgaSchema, []string{ + test.AssertOptionalArguments(t, vgaSchema, []string{ mkResourceVirtualEnvironmentVMVGAEnabled, mkResourceVirtualEnvironmentVMVGAMemory, mkResourceVirtualEnvironmentVMVGAType, }) - testValueTypes(t, vgaSchema, map[string]schema.ValueType{ + test.AssertValueTypes(t, vgaSchema, map[string]schema.ValueType{ mkResourceVirtualEnvironmentVMVGAEnabled: schema.TypeBool, mkResourceVirtualEnvironmentVMVGAMemory: schema.TypeInt, mkResourceVirtualEnvironmentVMVGAType: schema.TypeString, diff --git a/proxmoxtf/resource_virtual_environment_cluster_alias.go b/proxmoxtf/resource_virtual_environment_cluster_alias.go deleted file mode 100644 index e521656b..00000000 --- a/proxmoxtf/resource_virtual_environment_cluster_alias.go +++ /dev/null @@ -1,179 +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" - "strings" - - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - - "github.com/bpg/terraform-provider-proxmox/proxmox" -) - -const ( - dvResourceVirtualEnvironmentClusterAliasComment = "" - - mkResourceVirtualEnvironmentClusterAliasName = "name" - mkResourceVirtualEnvironmentClusterAliasCIDR = "cidr" - mkResourceVirtualEnvironmentClusterAliasComment = "comment" -) - -func resourceVirtualEnvironmentClusterAlias() *schema.Resource { - return &schema.Resource{ - Schema: map[string]*schema.Schema{ - mkResourceVirtualEnvironmentClusterAliasName: { - Type: schema.TypeString, - Description: "Alias name", - Required: true, - ForceNew: false, - }, - mkResourceVirtualEnvironmentClusterAliasCIDR: { - Type: schema.TypeString, - Description: "IP/CIDR block", - Required: true, - ForceNew: false, - }, - mkResourceVirtualEnvironmentClusterAliasComment: { - Type: schema.TypeString, - Description: "Alias comment", - Optional: true, - Default: dvResourceVirtualEnvironmentClusterAliasComment, - }, - }, - CreateContext: resourceVirtualEnvironmentClusterAliasCreate, - ReadContext: resourceVirtualEnvironmentClusterAliasRead, - UpdateContext: resourceVirtualEnvironmentClusterAliasUpdate, - DeleteContext: resourceVirtualEnvironmentClusterAliasDelete, - } -} - -func resourceVirtualEnvironmentClusterAliasCreate( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { - config := m.(providerConfiguration) - veClient, err := config.GetVEClient() - if err != nil { - return diag.FromErr(err) - } - - comment := d.Get(mkResourceVirtualEnvironmentClusterAliasComment).(string) - name := d.Get(mkResourceVirtualEnvironmentClusterAliasName).(string) - cidr := d.Get(mkResourceVirtualEnvironmentClusterAliasCIDR).(string) - - body := &proxmox.VirtualEnvironmentClusterAliasCreateRequestBody{ - Comment: &comment, - Name: name, - CIDR: cidr, - } - - err = veClient.CreateAlias(ctx, body) - if err != nil { - return diag.FromErr(err) - } - - d.SetId(name) - - return resourceVirtualEnvironmentClusterAliasRead(ctx, d, m) -} - -func resourceVirtualEnvironmentClusterAliasRead( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { - config := m.(providerConfiguration) - veClient, err := config.GetVEClient() - if err != nil { - return diag.FromErr(err) - } - - name := d.Id() - alias, err := veClient.GetAlias(ctx, name) - if err != nil { - if strings.Contains(err.Error(), "HTTP 404") { - d.SetId("") - return nil - } - return diag.FromErr(err) - } - - aliasMap := map[string]interface{}{ - mkResourceVirtualEnvironmentClusterAliasComment: alias.Comment, - mkResourceVirtualEnvironmentClusterAliasName: alias.Name, - mkResourceVirtualEnvironmentClusterAliasCIDR: alias.CIDR, - } - - for key, val := range aliasMap { - err = d.Set(key, val) - if err != nil { - return diag.FromErr(err) - } - } - - return nil -} - -func resourceVirtualEnvironmentClusterAliasUpdate( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { - config := m.(providerConfiguration) - veClient, err := config.GetVEClient() - if err != nil { - return diag.FromErr(err) - } - - comment := d.Get(mkResourceVirtualEnvironmentClusterAliasComment).(string) - cidr := d.Get(mkResourceVirtualEnvironmentClusterAliasCIDR).(string) - newName := d.Get(mkResourceVirtualEnvironmentClusterAliasName).(string) - previousName := d.Id() - - body := &proxmox.VirtualEnvironmentClusterAliasUpdateRequestBody{ - ReName: newName, - CIDR: cidr, - Comment: &comment, - } - - err = veClient.UpdateAlias(ctx, previousName, body) - if err != nil { - return diag.FromErr(err) - } - - d.SetId(newName) - - return resourceVirtualEnvironmentClusterAliasRead(ctx, d, m) -} - -func resourceVirtualEnvironmentClusterAliasDelete( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { - config := m.(providerConfiguration) - veClient, err := config.GetVEClient() - if err != nil { - return diag.FromErr(err) - } - - name := d.Id() - err = veClient.DeleteAlias(ctx, name) - - if err != nil { - if strings.Contains(err.Error(), "HTTP 404") { - d.SetId("") - return nil - } - return diag.FromErr(err) - } - - d.SetId("") - - return nil -} diff --git a/proxmoxtf/resource_virtual_environment_cluster_alias_test.go b/proxmoxtf/resource_virtual_environment_cluster_alias_test.go deleted file mode 100644 index 5c0b0eee..00000000 --- a/proxmoxtf/resource_virtual_environment_cluster_alias_test.go +++ /dev/null @@ -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" -) - -// TestResourceVirtualEnvironmentAliasInstantiation tests whether the ResourceVirtualEnvironmentAlias instance can be instantiated. -func TestResourceVirtualEnvironmentAliasInstantiation(t *testing.T) { - s := resourceVirtualEnvironmentClusterAlias() - - if s == nil { - t.Fatalf("Cannot instantiate resourceVirtualEnvironmentAlias") - } -} - -// TestResourceVirtualEnvironmentAliasSchema tests the resourceVirtualEnvironmentAlias schema. -func TestResourceVirtualEnvironmentAliasSchema(t *testing.T) { - s := resourceVirtualEnvironmentClusterAlias() - - testRequiredArguments(t, s, []string{ - mkResourceVirtualEnvironmentClusterAliasName, - mkResourceVirtualEnvironmentClusterAliasCIDR, - }) - - testOptionalArguments(t, s, []string{ - mkResourceVirtualEnvironmentClusterAliasComment, - }) - - testValueTypes(t, s, map[string]schema.ValueType{ - mkResourceVirtualEnvironmentClusterAliasName: schema.TypeString, - mkResourceVirtualEnvironmentClusterAliasCIDR: schema.TypeString, - mkResourceVirtualEnvironmentClusterAliasComment: schema.TypeString, - }) -} diff --git a/proxmoxtf/resource_virtual_environment_cluster_ipset.go b/proxmoxtf/resource_virtual_environment_cluster_ipset.go deleted file mode 100644 index a296bb6a..00000000 --- a/proxmoxtf/resource_virtual_environment_cluster_ipset.go +++ /dev/null @@ -1,275 +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" - "strings" - - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - - "github.com/bpg/terraform-provider-proxmox/proxmox" -) - -const ( - dvResourceVirtualEnvironmentClusterIPSetCIDRComment = "" - dvResourceVirtualEnvironmentClusterIPSetCIDRNoMatch = false - - mkResourceVirtualEnvironmentClusterIPSetName = "name" - mkResourceVirtualEnvironmentClusterIPSetCIDR = "cidr" - mkResourceVirtualEnvironmentClusterIPSetCIDRName = "name" - mkResourceVirtualEnvironmentClusterIPSetCIDRComment = "comment" - mkResourceVirtualEnvironmentClusterIPSetCIDRNoMatch = "nomatch" -) - -func resourceVirtualEnvironmentClusterIPSet() *schema.Resource { - return &schema.Resource{ - Schema: map[string]*schema.Schema{ - mkResourceVirtualEnvironmentClusterIPSetName: { - Type: schema.TypeString, - Description: "IPSet name", - Required: true, - ForceNew: false, - }, - mkResourceVirtualEnvironmentClusterIPSetCIDR: { - Type: schema.TypeList, - Description: "List of IP or Networks", - Optional: true, - ForceNew: true, - DefaultFunc: func() (interface{}, error) { - return []interface{}{}, nil - }, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - mkResourceVirtualEnvironmentClusterIPSetCIDRName: { - Type: schema.TypeString, - Description: "Network/IP specification in CIDR format", - Required: true, - ForceNew: true, - }, - mkResourceVirtualEnvironmentClusterIPSetCIDRNoMatch: { - Type: schema.TypeBool, - Description: "No match this IP/CIDR", - Optional: true, - Default: dvResourceVirtualEnvironmentClusterIPSetCIDRNoMatch, - ForceNew: true, - }, - mkResourceVirtualEnvironmentClusterIPSetCIDRComment: { - Type: schema.TypeString, - Description: "IP/CIDR comment", - Optional: true, - Default: dvResourceVirtualEnvironmentClusterIPSetCIDRComment, - ForceNew: true, - }, - }, - }, - MaxItems: 14, - MinItems: 0, - }, - mkResourceVirtualEnvironmentClusterIPSetCIDRComment: { - Type: schema.TypeString, - Description: "IPSet comment", - Optional: true, - Default: dvResourceVirtualEnvironmentClusterIPSetCIDRComment, - }, - }, - CreateContext: resourceVirtualEnvironmentClusterIPSetCreate, - ReadContext: resourceVirtualEnvironmentClusterIPSetRead, - UpdateContext: resourceVirtualEnvironmentClusterIPSetUpdate, - DeleteContext: resourceVirtualEnvironmentClusterIPSetDelete, - } -} - -func resourceVirtualEnvironmentClusterIPSetCreate( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { - config := m.(providerConfiguration) - veClient, err := config.GetVEClient() - if err != nil { - return diag.FromErr(err) - } - - comment := d.Get(mkResourceVirtualEnvironmentClusterIPSetCIDRComment).(string) - name := d.Get(mkResourceVirtualEnvironmentClusterIPSetName).(string) - - IPSets := d.Get(mkResourceVirtualEnvironmentClusterIPSetCIDR).([]interface{}) - IPSetsArray := make(proxmox.VirtualEnvironmentClusterIPSetContent, len(IPSets)) - - for i, v := range IPSets { - IPSetMap := v.(map[string]interface{}) - IPSetObject := proxmox.VirtualEnvironmentClusterIPSetGetResponseData{} - - cidr := IPSetMap[mkResourceVirtualEnvironmentClusterIPSetCIDRName].(string) - noMatch := IPSetMap[mkResourceVirtualEnvironmentClusterIPSetCIDRNoMatch].(bool) - comment := IPSetMap[mkResourceVirtualEnvironmentClusterIPSetCIDRComment].(string) - - IPSetObject.Comment = comment - IPSetObject.CIDR = cidr - - if noMatch { - noMatchBool := proxmox.CustomBool(true) - IPSetObject.NoMatch = &noMatchBool - } - - IPSetsArray[i] = IPSetObject - } - - body := &proxmox.VirtualEnvironmentClusterIPSetCreateRequestBody{ - Comment: comment, - Name: name, - } - - err = veClient.CreateIPSet(ctx, body) - if err != nil { - return diag.FromErr(err) - } - - for _, v := range IPSetsArray { - err = veClient.AddCIDRToIPSet(ctx, name, &v) - if err != nil { - return diag.FromErr(err) - } - } - - d.SetId(name) - return resourceVirtualEnvironmentClusterIPSetRead(ctx, d, m) -} - -func resourceVirtualEnvironmentClusterIPSetRead( - 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) - } - - name := d.Id() - - allIPSets, err := veClient.GetListIPSets(ctx) - if err != nil { - return diag.FromErr(err) - } - - for _, v := range allIPSets.Data { - if v.Name == name { - err = d.Set(mkResourceVirtualEnvironmentClusterIPSetName, v.Name) - diags = append(diags, diag.FromErr(err)...) - err = d.Set(mkResourceVirtualEnvironmentClusterIPSetCIDRComment, v.Comment) - diags = append(diags, diag.FromErr(err)...) - } - } - - IPSet, err := veClient.GetListIPSetContent(ctx, name) - if err != nil { - if strings.Contains(err.Error(), "HTTP 404") { - d.SetId("") - return nil - } - diags = append(diags, diag.FromErr(err)...) - return diags - } - - var entries []interface{} - - for key := range IPSet { - entry := map[string]interface{}{} - - entry[mkResourceVirtualEnvironmentClusterIPSetCIDRName] = IPSet[key].CIDR - entry[mkResourceVirtualEnvironmentClusterIPSetCIDRNoMatch] = IPSet[key].NoMatch - entry[mkResourceVirtualEnvironmentClusterIPSetCIDRComment] = IPSet[key].Comment - - entries = append(entries, entry) - } - - err = d.Set(mkResourceVirtualEnvironmentClusterIPSetCIDR, entries) - diags = append(diags, diag.FromErr(err)...) - return diags -} - -func resourceVirtualEnvironmentClusterIPSetUpdate( - ctx context.Context, - d *schema.ResourceData, - m interface{}, -) diag.Diagnostics { - config := m.(providerConfiguration) - veClient, err := config.GetVEClient() - if err != nil { - return diag.FromErr(err) - } - - comment := d.Get(mkResourceVirtualEnvironmentClusterIPSetCIDRComment).(string) - newName := d.Get(mkResourceVirtualEnvironmentClusterIPSetName).(string) - previousName := d.Id() - - body := &proxmox.VirtualEnvironmentClusterIPSetUpdateRequestBody{ - ReName: previousName, - Name: newName, - Comment: &comment, - } - - err = veClient.UpdateIPSet(ctx, body) - if err != nil { - return diag.FromErr(err) - } - - d.SetId(newName) - - return resourceVirtualEnvironmentClusterIPSetRead(ctx, d, m) -} - -func resourceVirtualEnvironmentClusterIPSetDelete( - 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) - } - - name := d.Id() - - IPSetContent, err := veClient.GetListIPSetContent(ctx, name) - if err != nil { - return diag.FromErr(err) - } - - // PVE requires content of IPSet be cleared before removal - if len(IPSetContent) > 0 { - for _, IPSet := range IPSetContent { - err = veClient.DeleteIPSetContent(ctx, name, IPSet.CIDR) - diags = append(diags, diag.FromErr(err)...) - } - } - - if diags.HasError() { - return diags - } - - err = veClient.DeleteIPSet(ctx, name) - - if err != nil { - if strings.Contains(err.Error(), "HTTP 404") { - d.SetId("") - return nil - } - - return diag.FromErr(err) - } - - d.SetId("") - - return nil -} diff --git a/proxmoxtf/resource_virtual_environment_cluster_ipset_test.go b/proxmoxtf/resource_virtual_environment_cluster_ipset_test.go deleted file mode 100644 index 775a618d..00000000 --- a/proxmoxtf/resource_virtual_environment_cluster_ipset_test.go +++ /dev/null @@ -1,58 +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" -) - -// TestResourceVirtualEnvironmentIPSetInstantiation tests whether the resourceVirtualEnvironmentClusterIPSet -// instance can be instantiated. -func TestResourceVirtualEnvironmentIPSetInstantiation(t *testing.T) { - s := resourceVirtualEnvironmentClusterIPSet() - - if s == nil { - t.Fatalf("Cannot instantiate resourceVirtualEnvironmentAlias") - } -} - -// TestResourceVirtualEnvironmentIPSetSchema tests the resourceVirtualEnvironmentClusterIPSet schema. -func TestResourceVirtualEnvironmentIPSetSchema(t *testing.T) { - s := resourceVirtualEnvironmentClusterIPSet() - - testRequiredArguments(t, s, []string{ - mkResourceVirtualEnvironmentClusterIPSetName, - }) - - testOptionalArguments(t, s, []string{ - mkResourceVirtualEnvironmentClusterIPSetCIDR, - mkResourceVirtualEnvironmentClusterIPSetCIDRComment, - }) - - testValueTypes(t, s, map[string]schema.ValueType{ - mkResourceVirtualEnvironmentClusterIPSetName: schema.TypeString, - mkResourceVirtualEnvironmentClusterIPSetCIDR: schema.TypeList, - mkResourceVirtualEnvironmentClusterIPSetCIDRComment: schema.TypeString, - }) - - IPSetSchema := testNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentClusterIPSetCIDR) - - testRequiredArguments(t, IPSetSchema, []string{ - mkResourceVirtualEnvironmentClusterIPSetCIDRName, - }) - - testOptionalArguments(t, IPSetSchema, []string{ - mkResourceVirtualEnvironmentClusterIPSetCIDRComment, - mkResourceVirtualEnvironmentClusterIPSetCIDRNoMatch, - }) - - testValueTypes(t, IPSetSchema, map[string]schema.ValueType{ - mkResourceVirtualEnvironmentClusterIPSetCIDRName: schema.TypeString, - mkResourceVirtualEnvironmentClusterIPSetCIDRComment: schema.TypeString, - mkResourceVirtualEnvironmentClusterIPSetCIDRNoMatch: schema.TypeBool, - }) -} diff --git a/proxmoxtf/resource_virtual_environment_dns_test.go b/proxmoxtf/resource_virtual_environment_dns_test.go deleted file mode 100644 index 3d2e69d9..00000000 --- a/proxmoxtf/resource_virtual_environment_dns_test.go +++ /dev/null @@ -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" -) - -// TestResourceVirtualEnvironmentDNSInstantiation tests whether the ResourceVirtualEnvironmentDNS instance can be instantiated. -func TestResourceVirtualEnvironmentDNSInstantiation(t *testing.T) { - s := resourceVirtualEnvironmentDNS() - - if s == nil { - t.Fatalf("Cannot instantiate resourceVirtualEnvironmentDNS") - } -} - -// TestResourceVirtualEnvironmentDNSSchema tests the resourceVirtualEnvironmentDNS schema. -func TestResourceVirtualEnvironmentDNSSchema(t *testing.T) { - s := resourceVirtualEnvironmentDNS() - - testRequiredArguments(t, s, []string{ - mkResourceVirtualEnvironmentDNSDomain, - mkResourceVirtualEnvironmentDNSNodeName, - }) - - testOptionalArguments(t, s, []string{ - mkResourceVirtualEnvironmentDNSServers, - }) - - testValueTypes(t, s, map[string]schema.ValueType{ - mkResourceVirtualEnvironmentDNSDomain: schema.TypeString, - mkResourceVirtualEnvironmentDNSNodeName: schema.TypeString, - mkResourceVirtualEnvironmentDNSServers: schema.TypeList, - }) -} diff --git a/proxmoxtf/resource_virtual_environment_group_test.go b/proxmoxtf/resource_virtual_environment_group_test.go deleted file mode 100644 index d44b1ff2..00000000 --- a/proxmoxtf/resource_virtual_environment_group_test.go +++ /dev/null @@ -1,62 +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" -) - -// TestResourceVirtualEnvironmentGroupInstantiation tests whether the ResourceVirtualEnvironmentGroup instance can be instantiated. -func TestResourceVirtualEnvironmentGroupInstantiation(t *testing.T) { - s := resourceVirtualEnvironmentGroup() - - if s == nil { - t.Fatalf("Cannot instantiate resourceVirtualEnvironmentGroup") - } -} - -// TestResourceVirtualEnvironmentGroupSchema tests the resourceVirtualEnvironmentGroup schema. -func TestResourceVirtualEnvironmentGroupSchema(t *testing.T) { - s := resourceVirtualEnvironmentGroup() - - testRequiredArguments(t, s, []string{ - mkResourceVirtualEnvironmentGroupID, - }) - - testOptionalArguments(t, s, []string{ - mkResourceVirtualEnvironmentGroupACL, - mkResourceVirtualEnvironmentGroupComment, - }) - - testComputedAttributes(t, s, []string{ - mkResourceVirtualEnvironmentGroupMembers, - }) - - testValueTypes(t, s, map[string]schema.ValueType{ - mkResourceVirtualEnvironmentGroupACL: schema.TypeSet, - mkResourceVirtualEnvironmentGroupComment: schema.TypeString, - mkResourceVirtualEnvironmentGroupID: schema.TypeString, - mkResourceVirtualEnvironmentGroupMembers: schema.TypeSet, - }) - - aclSchema := testNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentGroupACL) - - testRequiredArguments(t, aclSchema, []string{ - mkResourceVirtualEnvironmentGroupACLPath, - mkResourceVirtualEnvironmentGroupACLRoleID, - }) - - testOptionalArguments(t, aclSchema, []string{ - mkResourceVirtualEnvironmentGroupACLPropagate, - }) - - testValueTypes(t, aclSchema, map[string]schema.ValueType{ - mkResourceVirtualEnvironmentGroupACLPath: schema.TypeString, - mkResourceVirtualEnvironmentGroupACLPropagate: schema.TypeBool, - mkResourceVirtualEnvironmentGroupACLRoleID: schema.TypeString, - }) -} diff --git a/proxmoxtf/resource_virtual_environment_pool_test.go b/proxmoxtf/resource_virtual_environment_pool_test.go deleted file mode 100644 index 07e3c27f..00000000 --- a/proxmoxtf/resource_virtual_environment_pool_test.go +++ /dev/null @@ -1,55 +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" -) - -// TestResourceVirtualEnvironmentPoolInstantiation tests whether the ResourceVirtualEnvironmentPool instance can be instantiated. -func TestResourceVirtualEnvironmentPoolInstantiation(t *testing.T) { - s := resourceVirtualEnvironmentPool() - - if s == nil { - t.Fatalf("Cannot instantiate resourceVirtualEnvironmentPool") - } -} - -// TestResourceVirtualEnvironmentPoolSchema tests the resourceVirtualEnvironmentPool schema. -func TestResourceVirtualEnvironmentPoolSchema(t *testing.T) { - s := resourceVirtualEnvironmentPool() - - testRequiredArguments(t, s, []string{ - mkResourceVirtualEnvironmentPoolPoolID, - }) - - testOptionalArguments(t, s, []string{ - mkResourceVirtualEnvironmentPoolComment, - }) - - testComputedAttributes(t, s, []string{ - mkResourceVirtualEnvironmentPoolMembers, - }) - - membersSchema := testNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentPoolMembers) - - testComputedAttributes(t, membersSchema, []string{ - mkResourceVirtualEnvironmentPoolMembersDatastoreID, - mkResourceVirtualEnvironmentPoolMembersID, - mkResourceVirtualEnvironmentPoolMembersNodeName, - mkResourceVirtualEnvironmentPoolMembersType, - mkResourceVirtualEnvironmentPoolMembersVMID, - }) - - testValueTypes(t, membersSchema, map[string]schema.ValueType{ - mkResourceVirtualEnvironmentPoolMembersDatastoreID: schema.TypeString, - mkResourceVirtualEnvironmentPoolMembersID: schema.TypeString, - mkResourceVirtualEnvironmentPoolMembersNodeName: schema.TypeString, - mkResourceVirtualEnvironmentPoolMembersType: schema.TypeString, - mkResourceVirtualEnvironmentPoolMembersVMID: schema.TypeInt, - }) -} diff --git a/proxmoxtf/resource_virtual_environment_role_test.go b/proxmoxtf/resource_virtual_environment_role_test.go deleted file mode 100644 index a014cd97..00000000 --- a/proxmoxtf/resource_virtual_environment_role_test.go +++ /dev/null @@ -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" -) - -// TestResourceVirtualEnvironmentRoleInstantiation tests whether the ResourceVirtualEnvironmentRole instance can be instantiated. -func TestResourceVirtualEnvironmentRoleInstantiation(t *testing.T) { - s := resourceVirtualEnvironmentRole() - - if s == nil { - t.Fatalf("Cannot instantiate resourceVirtualEnvironmentRole") - } -} - -// TestResourceVirtualEnvironmentRoleSchema tests the resourceVirtualEnvironmentRole schema. -func TestResourceVirtualEnvironmentRoleSchema(t *testing.T) { - s := resourceVirtualEnvironmentRole() - - testRequiredArguments(t, s, []string{ - mkResourceVirtualEnvironmentRolePrivileges, - mkResourceVirtualEnvironmentRoleRoleID, - }) - - testValueTypes(t, s, map[string]schema.ValueType{ - mkResourceVirtualEnvironmentRolePrivileges: schema.TypeSet, - mkResourceVirtualEnvironmentRoleRoleID: schema.TypeString, - }) -} diff --git a/proxmoxtf/resource_virtual_environment_time_test.go b/proxmoxtf/resource_virtual_environment_time_test.go deleted file mode 100644 index f69a1eef..00000000 --- a/proxmoxtf/resource_virtual_environment_time_test.go +++ /dev/null @@ -1,42 +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" -) - -// TestResourceVirtualEnvironmentTimeInstantiation tests whether the ResourceVirtualEnvironmentTime instance can be instantiated. -func TestResourceVirtualEnvironmentTimeInstantiation(t *testing.T) { - s := resourceVirtualEnvironmentTime() - - if s == nil { - t.Fatalf("Cannot instantiate resourceVirtualEnvironmentTime") - } -} - -// TestResourceVirtualEnvironmentTimeSchema tests the resourceVirtualEnvironmentTime schema. -func TestResourceVirtualEnvironmentTimeSchema(t *testing.T) { - s := resourceVirtualEnvironmentTime() - - testRequiredArguments(t, s, []string{ - mkResourceVirtualEnvironmentTimeNodeName, - mkResourceVirtualEnvironmentTimeTimeZone, - }) - - testComputedAttributes(t, s, []string{ - mkResourceVirtualEnvironmentTimeLocalTime, - mkResourceVirtualEnvironmentTimeUTCTime, - }) - - testValueTypes(t, s, map[string]schema.ValueType{ - mkResourceVirtualEnvironmentTimeLocalTime: schema.TypeString, - mkResourceVirtualEnvironmentTimeNodeName: schema.TypeString, - mkResourceVirtualEnvironmentTimeTimeZone: schema.TypeString, - mkResourceVirtualEnvironmentTimeUTCTime: schema.TypeString, - }) -} diff --git a/proxmoxtf/structure/test.go b/proxmoxtf/structure/test.go new file mode 100644 index 00000000..9af495cc --- /dev/null +++ b/proxmoxtf/structure/test.go @@ -0,0 +1,55 @@ +/* + * 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 structure + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func AssertComputedAttributes(t *testing.T, s map[string]*schema.Schema, keys []string) { + for _, v := range keys { + require.NotNil(t, s[v], "Error in Schema: Missing definition for \"%s\"", v) + assert.True(t, s[v].Computed, "Error in Schema: Attribute \"%s\" is not computed", v) + } +} + +func AssertNestedSchemaExistence(t *testing.T, s map[string]*schema.Schema, key string) *schema.Resource { + sh, ok := s[key].Elem.(*schema.Resource) + + if !ok { + t.Fatalf("Error in Schema: Missing nested schema for \"%s\"", key) + + return nil + } + + return sh +} + +func AssertOptionalArguments(t *testing.T, s map[string]*schema.Schema, keys []string) { + for _, v := range keys { + require.NotNil(t, s[v], "Error in Schema: Missing definition for \"%s\"", v) + assert.True(t, s[v].Optional, "Error in Schema: Argument \"%s\" is not optional", v) + } +} + +func AssertRequiredArguments(t *testing.T, s map[string]*schema.Schema, keys []string) { + for _, v := range keys { + require.NotNil(t, s[v], "Error in Schema: Missing definition for \"%s\"", v) + assert.True(t, s[v].Required, "Error in Schema: Argument \"%s\" is not required", v) + } +} + +func AssertValueTypes(t *testing.T, s map[string]*schema.Schema, f map[string]schema.ValueType) { + for fn, ft := range f { + require.NotNil(t, s[fn], "Error in Schema: Missing definition for \"%s\"", fn) + assert.Equal(t, ft, s[fn].Type, "Error in Schema: Argument or attribute \"%s\" is not of type \"%v\"", fn, ft) + } +} diff --git a/proxmoxtf/structure/tools.go b/proxmoxtf/structure/tools.go new file mode 100644 index 00000000..05249295 --- /dev/null +++ b/proxmoxtf/structure/tools.go @@ -0,0 +1,24 @@ +/* + * 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 structure + +import ( + "fmt" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +// MergeSchema merges the map[string]*schema.Schema from src into dst. Safety +// against conflicts is enforced by panicing. +func MergeSchema(dst, src map[string]*schema.Schema) { + for k, v := range src { + if _, ok := dst[k]; ok { + panic(fmt.Errorf("conflicting schema key: %s", k)) + } + dst[k] = v + } +} diff --git a/proxmoxtf/test/test_utils.go b/proxmoxtf/test/test_utils.go new file mode 100644 index 00000000..2b4a1271 --- /dev/null +++ b/proxmoxtf/test/test_utils.go @@ -0,0 +1,55 @@ +/* + * 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 test + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func AssertComputedAttributes(t *testing.T, s *schema.Resource, keys []string) { + for _, v := range keys { + require.NotNil(t, s.Schema[v], "Error in Schema: Missing definition for \"%s\"", v) + assert.True(t, s.Schema[v].Computed, "Error in Schema: Attribute \"%s\" is not computed", v) + } +} + +func AssertNestedSchemaExistence(t *testing.T, s *schema.Resource, key string) *schema.Resource { + sh, ok := s.Schema[key].Elem.(*schema.Resource) + + if !ok { + t.Fatalf("Error in Schema: Missing nested schema for \"%s\"", key) + + return nil + } + + return sh +} + +func AssertOptionalArguments(t *testing.T, s *schema.Resource, keys []string) { + for _, v := range keys { + require.NotNil(t, s.Schema[v], "Error in Schema: Missing definition for \"%s\"", v) + assert.True(t, s.Schema[v].Optional, "Error in Schema: Argument \"%s\" is not optional", v) + } +} + +func AssertRequiredArguments(t *testing.T, s *schema.Resource, keys []string) { + for _, v := range keys { + require.NotNil(t, s.Schema[v], "Error in Schema: Missing definition for \"%s\"", v) + assert.True(t, s.Schema[v].Required, "Error in Schema: Argument \"%s\" is not required", v) + } +} + +func AssertValueTypes(t *testing.T, s *schema.Resource, f map[string]schema.ValueType) { + for fn, ft := range f { + require.NotNil(t, s.Schema[fn], "Error in Schema: Missing definition for \"%s\"", fn) + assert.Equal(t, ft, s.Schema[fn].Type, "Error in Schema: Argument or attribute \"%s\" is not of type \"%v\"", fn, ft) + } +}