mirror of
https://github.com/bpg/terraform-provider-proxmox.git
synced 2025-06-29 18:21:10 +00:00
feat(vm): add network device resources (#376)
* wip * experimenting with terraform plugin framework * cleaning up poc and adding tests * adding read / update / delete * update bridge_vlan_aware and MTU * add ipv6 and simplify IP support * fix provider's schema * add docs * run linter from cmdline * disable TF acceptance tests * add VLAN * update docs * add examole * cleanup
This commit is contained in:
parent
2863aa6e2d
commit
343e8045c1
6
.github/workflows/golangci-lint.yml
vendored
6
.github/workflows/golangci-lint.yml
vendored
@ -21,7 +21,5 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
go-version-file: 'go.mod'
|
go-version-file: 'go.mod'
|
||||||
- name: golangci-lint
|
- name: golangci-lint
|
||||||
uses: golangci/golangci-lint-action@v3
|
run: |
|
||||||
with:
|
go run -modfile=tools/go.mod github.com/golangci/golangci-lint/cmd/golangci-lint run -v --timeout 5m
|
||||||
version: v1.52
|
|
||||||
only-new-issues: true
|
|
||||||
|
12
.github/workflows/test.yml
vendored
12
.github/workflows/test.yml
vendored
@ -65,11 +65,15 @@ jobs:
|
|||||||
- name: Get dependencies
|
- name: Get dependencies
|
||||||
run: go mod download
|
run: go mod download
|
||||||
|
|
||||||
- name: TF acceptance tests
|
# - name: TF acceptance tests
|
||||||
|
# timeout-minutes: 10
|
||||||
|
# env:
|
||||||
|
# TF_ACC: "1"
|
||||||
|
# TF_ACC_TERRAFORM_VERSION: ${{ matrix.terraform }}
|
||||||
|
# run: go test -v -cover ./...
|
||||||
|
|
||||||
|
- name: Unit tests
|
||||||
timeout-minutes: 10
|
timeout-minutes: 10
|
||||||
env:
|
|
||||||
TF_ACC: "1"
|
|
||||||
TF_ACC_TERRAFORM_VERSION: ${{ matrix.terraform }}
|
|
||||||
run: go test -v -cover ./...
|
run: go test -v -cover ./...
|
||||||
|
|
||||||
all-tests-passed:
|
all-tests-passed:
|
||||||
|
@ -73,6 +73,7 @@ linters:
|
|||||||
- funlen
|
- funlen
|
||||||
- gocognit
|
- gocognit
|
||||||
# others
|
# others
|
||||||
|
- depguard
|
||||||
- exhaustivestruct
|
- exhaustivestruct
|
||||||
- exhaustruct
|
- exhaustruct
|
||||||
- gci
|
- gci
|
||||||
|
@ -35,7 +35,20 @@ We expect that all commit messages follow the
|
|||||||
|
|
||||||
Please use the `scope` field to indicate the area of the codebase that is being
|
Please use the `scope` field to indicate the area of the codebase that is being
|
||||||
changed. For example, `vm` for changes in the Virtual Machine resource, or
|
changed. For example, `vm` for changes in the Virtual Machine resource, or
|
||||||
`lcx` for changes in the Container resource:
|
`lcx` for changes in the Container resource.
|
||||||
|
|
||||||
|
Common scopes are:
|
||||||
|
|
||||||
|
- `vm` - Virtual Machine resources
|
||||||
|
- `lcx` - Container resources
|
||||||
|
- `provider` - Provider configuration and resources
|
||||||
|
- `core` - Core libraries and utilities
|
||||||
|
- `docs` - Documentation
|
||||||
|
- `ci` - Continuous Integration / Actions / GitHub Workflows
|
||||||
|
|
||||||
|
Please use lowercase for the description and do not end it with a period.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
```
|
```
|
||||||
feat(vm): add support for the `clone` operation
|
feat(vm): add support for the `clone` operation
|
||||||
@ -56,7 +69,7 @@ well.
|
|||||||
We use automated release management orchestrated
|
We use automated release management orchestrated
|
||||||
by https://github.com/googleapis/release-please GitHub Action. The action
|
by https://github.com/googleapis/release-please GitHub Action. The action
|
||||||
creates a new release PR with the changelog and bumps the version based on the
|
creates a new release PR with the changelog and bumps the version based on the
|
||||||
commit messages. The release PR is merged by the maintainers.
|
commit messages. The release PR is merged by the maintainers.
|
||||||
|
|
||||||
The release will be published to the GitHub Releases page and the Terraform
|
The release will be published to the GitHub Releases page and the Terraform
|
||||||
Registry.
|
Registry.
|
||||||
|
46
docs/resources/virtual_environment_network_linux_bridge.md
Normal file
46
docs/resources/virtual_environment_network_linux_bridge.md
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
---
|
||||||
|
layout: page
|
||||||
|
title: proxmox_virtual_environment_network_linux_bridge
|
||||||
|
permalink: /resources/virtual_environment_network_linux_bridge
|
||||||
|
nav_order: 13
|
||||||
|
parent: Resources
|
||||||
|
subcategory: Virtual Environment
|
||||||
|
---
|
||||||
|
|
||||||
|
# Resource: proxmox_virtual_environment_network_linux_bridge
|
||||||
|
|
||||||
|
Manages a Linux Bridge network interface in a Proxmox VE node.
|
||||||
|
|
||||||
|
## Example Usage
|
||||||
|
|
||||||
|
```terraform
|
||||||
|
resource "proxmox_virtual_environment_network_linux_bridge" "bridge99" {
|
||||||
|
node_name = "pve"
|
||||||
|
iface = "vmbr99"
|
||||||
|
address = "3.3.3.3/24"
|
||||||
|
comment = "created by terraform"
|
||||||
|
mtu = 1499
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Argument Reference
|
||||||
|
|
||||||
|
- `node_name` - (Required) The name of the node to manage the interface on.
|
||||||
|
- `name` - (Required) The interface name. Must be "vmbrN", where N is a number
|
||||||
|
between 0 and 9999.
|
||||||
|
|
||||||
|
- `address` - (Optional) The interface IPv4/CIDR address.
|
||||||
|
- `address6` - (Optional) The interface IPv6/CIDR address.
|
||||||
|
- `autostart` - (Optional) Automatically start interface on boot (defaults
|
||||||
|
to `true`).
|
||||||
|
- `ports` - (Optional) Specify the list of the interface bridge ports.
|
||||||
|
- `vlan_aware` - (Optional) Whether the interface bridge is VLAN aware (defaults
|
||||||
|
to `true`).
|
||||||
|
- `comment` - (Optional) Comment for the interface.
|
||||||
|
- `gateway` - (Optional) Default gateway address.
|
||||||
|
- `gateway6` - (Optional) Default IPv6 gateway address.
|
||||||
|
- `mtu` - (Optional) The interface MTU.
|
||||||
|
|
||||||
|
### Read-Only
|
||||||
|
|
||||||
|
- `id` (String) A unique identifier with format '<node name>:<iface>'
|
43
docs/resources/virtual_environment_network_linux_vlan.md
Normal file
43
docs/resources/virtual_environment_network_linux_vlan.md
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
---
|
||||||
|
layout: page
|
||||||
|
title: proxmox_virtual_environment_network_linux_vlan
|
||||||
|
permalink: /resources/virtual_environment_network_linux_vlan
|
||||||
|
nav_order: 13
|
||||||
|
parent: Resources
|
||||||
|
subcategory: Virtual Environment
|
||||||
|
---
|
||||||
|
|
||||||
|
# Resource: proxmox_virtual_environment_network_linux_vlan
|
||||||
|
|
||||||
|
Manages a Linux VLAN network interface in a Proxmox VE node.
|
||||||
|
|
||||||
|
## Example Usage
|
||||||
|
|
||||||
|
```terraform
|
||||||
|
resource "proxmox_virtual_environment_network_linux_vlan" "vlan21" {
|
||||||
|
node_name = "pve"
|
||||||
|
iface = "ens18.21"
|
||||||
|
comment = "created by terraform"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Argument Reference
|
||||||
|
|
||||||
|
- `node_name` - (Required) The name of the node to manage the interface on.
|
||||||
|
- `name` - (Required) The interface name. Add the VLAN tag number to an
|
||||||
|
existing interface name, e.g. "ens18.21".
|
||||||
|
|
||||||
|
- `address` - (Optional) The interface IPv4/CIDR address.
|
||||||
|
- `address6` - (Optional) The interface IPv6/CIDR address.
|
||||||
|
- `autostart` - (Optional) Automatically start interface on boot (defaults
|
||||||
|
to `true`).
|
||||||
|
- `comment` - (Optional) Comment for the interface.
|
||||||
|
- `gateway` - (Optional) Default gateway address.
|
||||||
|
- `gateway6` - (Optional) Default IPv6 gateway address.
|
||||||
|
- `mtu` - (Optional) The interface MTU.
|
||||||
|
|
||||||
|
### Read-Only
|
||||||
|
|
||||||
|
- `id` (String) A unique identifier with format '<node name>:<iface>'
|
||||||
|
- `interface` (String) The VLAN raw device.
|
||||||
|
- `vlan` (Number) The VLAN tag
|
@ -1,7 +1,7 @@
|
|||||||
data "proxmox_virtual_environment_vm" "example" {
|
data "proxmox_virtual_environment_vm" "example" {
|
||||||
depends_on = [proxmox_virtual_environment_vm.example]
|
depends_on = [proxmox_virtual_environment_vm.example]
|
||||||
vm_id = proxmox_virtual_environment_vm.example.vm_id
|
vm_id = proxmox_virtual_environment_vm.example.vm_id
|
||||||
node_name = data.proxmox_virtual_environment_nodes.example.names[0]
|
node_name = data.proxmox_virtual_environment_nodes.example.names[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
output "proxmox_virtual_environment_vm_example" {
|
output "proxmox_virtual_environment_vm_example" {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
data "proxmox_virtual_environment_vms" "example" {
|
data "proxmox_virtual_environment_vms" "example" {
|
||||||
depends_on = [proxmox_virtual_environment_vm.example]
|
depends_on = [proxmox_virtual_environment_vm.example]
|
||||||
tags = ["ubuntu"]
|
tags = ["ubuntu"]
|
||||||
|
|
||||||
lifecycle {
|
lifecycle {
|
||||||
postcondition {
|
postcondition {
|
||||||
|
@ -18,8 +18,8 @@ resource "proxmox_virtual_environment_firewall_alias" "vm_alias" {
|
|||||||
resource "proxmox_virtual_environment_firewall_alias" "container_alias" {
|
resource "proxmox_virtual_environment_firewall_alias" "container_alias" {
|
||||||
depends_on = [proxmox_virtual_environment_container.example]
|
depends_on = [proxmox_virtual_environment_container.example]
|
||||||
|
|
||||||
node_name = proxmox_virtual_environment_container.example.node_name
|
node_name = proxmox_virtual_environment_container.example.node_name
|
||||||
container_id = proxmox_virtual_environment_container.example.vm_id
|
container_id = proxmox_virtual_environment_container.example.vm_id
|
||||||
|
|
||||||
name = "container-alias"
|
name = "container-alias"
|
||||||
cidr = "192.168.2.0/23"
|
cidr = "192.168.2.0/23"
|
||||||
|
@ -38,8 +38,8 @@ resource "proxmox_virtual_environment_firewall_ipset" "vm_ipset" {
|
|||||||
resource "proxmox_virtual_environment_firewall_ipset" "container_ipset" {
|
resource "proxmox_virtual_environment_firewall_ipset" "container_ipset" {
|
||||||
depends_on = [proxmox_virtual_environment_container.example]
|
depends_on = [proxmox_virtual_environment_container.example]
|
||||||
|
|
||||||
node_name = proxmox_virtual_environment_container.example.node_name
|
node_name = proxmox_virtual_environment_container.example.node_name
|
||||||
container_id = proxmox_virtual_environment_container.example.vm_id
|
container_id = proxmox_virtual_environment_container.example.vm_id
|
||||||
|
|
||||||
name = "container-ipset"
|
name = "container-ipset"
|
||||||
comment = "Managed by Terraform"
|
comment = "Managed by Terraform"
|
||||||
|
@ -34,8 +34,8 @@ resource "proxmox_virtual_environment_firewall_options" "vm_options" {
|
|||||||
resource "proxmox_virtual_environment_firewall_options" "container_options" {
|
resource "proxmox_virtual_environment_firewall_options" "container_options" {
|
||||||
depends_on = [proxmox_virtual_environment_container.example]
|
depends_on = [proxmox_virtual_environment_container.example]
|
||||||
|
|
||||||
node_name = proxmox_virtual_environment_container.example.node_name
|
node_name = proxmox_virtual_environment_container.example.node_name
|
||||||
container_id = proxmox_virtual_environment_container.example.vm_id
|
container_id = proxmox_virtual_environment_container.example.vm_id
|
||||||
|
|
||||||
dhcp = false
|
dhcp = false
|
||||||
enabled = false
|
enabled = false
|
||||||
|
@ -58,8 +58,8 @@ resource "proxmox_virtual_environment_firewall_rules" "vm_rules" {
|
|||||||
resource "proxmox_virtual_environment_firewall_rules" "container_rules" {
|
resource "proxmox_virtual_environment_firewall_rules" "container_rules" {
|
||||||
depends_on = [proxmox_virtual_environment_container.example]
|
depends_on = [proxmox_virtual_environment_container.example]
|
||||||
|
|
||||||
node_name = proxmox_virtual_environment_container.example.node_name
|
node_name = proxmox_virtual_environment_container.example.node_name
|
||||||
container_id = proxmox_virtual_environment_container.example.vm_id
|
container_id = proxmox_virtual_environment_container.example.vm_id
|
||||||
|
|
||||||
rule {
|
rule {
|
||||||
type = "in"
|
type = "in"
|
||||||
|
23
example/resource_virtual_environment_network.tf
Normal file
23
example/resource_virtual_environment_network.tf
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
resource "proxmox_virtual_environment_network_linux_vlan" "vlan99" {
|
||||||
|
node_name = "pve"
|
||||||
|
name = "ens18.99"
|
||||||
|
|
||||||
|
comment = "VLAN 99"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "proxmox_virtual_environment_network_linux_bridge" "vmbr99" {
|
||||||
|
depends_on = [
|
||||||
|
proxmox_virtual_environment_network_linux_vlan.vlan99
|
||||||
|
]
|
||||||
|
|
||||||
|
node_name = "pve"
|
||||||
|
name = "vmbr99"
|
||||||
|
|
||||||
|
address = "99.99.99.99/16"
|
||||||
|
|
||||||
|
comment = "vmbr99 comment"
|
||||||
|
|
||||||
|
ports = [
|
||||||
|
"ens18.99"
|
||||||
|
]
|
||||||
|
}
|
@ -9,12 +9,12 @@ resource "proxmox_virtual_environment_vm" "example_template" {
|
|||||||
|
|
||||||
description = "Managed by Terraform"
|
description = "Managed by Terraform"
|
||||||
|
|
||||||
# disk {
|
# disk {
|
||||||
# datastore_id = local.datastore_id
|
# datastore_id = local.datastore_id
|
||||||
# file_id = proxmox_virtual_environment_file.ubuntu_cloud_image.id
|
# file_id = proxmox_virtual_environment_file.ubuntu_cloud_image.id
|
||||||
# interface = "virtio0"
|
# interface = "virtio0"
|
||||||
# iothread = true
|
# iothread = true
|
||||||
# }
|
# }
|
||||||
|
|
||||||
disk {
|
disk {
|
||||||
datastore_id = local.datastore_id
|
datastore_id = local.datastore_id
|
||||||
@ -24,12 +24,12 @@ resource "proxmox_virtual_environment_vm" "example_template" {
|
|||||||
ssd = true
|
ssd = true
|
||||||
}
|
}
|
||||||
|
|
||||||
# disk {
|
# disk {
|
||||||
# datastore_id = "nfs"
|
# datastore_id = "nfs"
|
||||||
# interface = "scsi1"
|
# interface = "scsi1"
|
||||||
# discard = "ignore"
|
# discard = "ignore"
|
||||||
# file_format = "raw"
|
# file_format = "raw"
|
||||||
# }
|
# }
|
||||||
|
|
||||||
initialization {
|
initialization {
|
||||||
datastore_id = local.datastore_id
|
datastore_id = local.datastore_id
|
||||||
@ -47,14 +47,14 @@ resource "proxmox_virtual_environment_vm" "example_template" {
|
|||||||
#}
|
#}
|
||||||
}
|
}
|
||||||
|
|
||||||
user_data_file_id = proxmox_virtual_environment_file.user_config.id
|
user_data_file_id = proxmox_virtual_environment_file.user_config.id
|
||||||
vendor_data_file_id = proxmox_virtual_environment_file.vendor_config.id
|
vendor_data_file_id = proxmox_virtual_environment_file.vendor_config.id
|
||||||
}
|
}
|
||||||
|
|
||||||
name = "terraform-provider-proxmox-example-template"
|
name = "terraform-provider-proxmox-example-template"
|
||||||
|
|
||||||
network_device {
|
network_device {
|
||||||
mtu = 1450
|
mtu = 1450
|
||||||
}
|
}
|
||||||
|
|
||||||
network_device {
|
network_device {
|
||||||
@ -81,7 +81,7 @@ resource "proxmox_virtual_environment_vm" "example" {
|
|||||||
node_name = data.proxmox_virtual_environment_nodes.example.names[0]
|
node_name = data.proxmox_virtual_environment_nodes.example.names[0]
|
||||||
pool_id = proxmox_virtual_environment_pool.example.id
|
pool_id = proxmox_virtual_environment_pool.example.id
|
||||||
vm_id = 2041
|
vm_id = 2041
|
||||||
tags = ["terraform", "ubuntu"]
|
tags = ["terraform", "ubuntu"]
|
||||||
|
|
||||||
clone {
|
clone {
|
||||||
vm_id = proxmox_virtual_environment_vm.example_template.id
|
vm_id = proxmox_virtual_environment_vm.example_template.id
|
||||||
@ -105,13 +105,13 @@ resource "proxmox_virtual_environment_vm" "example" {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
# While overwriting the initialization block when cloning a template is possible, it is not recommended.
|
# While overwriting the initialization block when cloning a template is possible, it is not recommended.
|
||||||
# This will cause the coned VM to be reinitialized each time on re-apply.
|
# This will cause the coned VM to be reinitialized each time on re-apply.
|
||||||
# initialization {
|
# initialization {
|
||||||
# dns {
|
# dns {
|
||||||
# server = "8.8.8.8"
|
# server = "8.8.8.8"
|
||||||
# }
|
# }
|
||||||
# }
|
# }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
resource "local_sensitive_file" "example_ssh_private_key" {
|
resource "local_sensitive_file" "example_ssh_private_key" {
|
||||||
filename = "${path.module}/autogenerated/id_rsa"
|
filename = "${path.module}/autogenerated/id_rsa"
|
||||||
content = tls_private_key.example.private_key_pem
|
content = tls_private_key.example.private_key_pem
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "local_sensitive_file" "example_ssh_public_key" {
|
resource "local_sensitive_file" "example_ssh_public_key" {
|
||||||
filename = "${path.module}/autogenerated/id_rsa.pub"
|
filename = "${path.module}/autogenerated/id_rsa.pub"
|
||||||
content = tls_private_key.example.public_key_openssh
|
content = tls_private_key.example.public_key_openssh
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "tls_private_key" "example" {
|
resource "tls_private_key" "example" {
|
||||||
|
@ -9,7 +9,7 @@ terraform {
|
|||||||
version = "3.1.0"
|
version = "3.1.0"
|
||||||
}
|
}
|
||||||
proxmox = {
|
proxmox = {
|
||||||
source = "bpg/proxmox"
|
source = "bpg/proxmox"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
31
go.mod
31
go.mod
@ -7,7 +7,11 @@ require (
|
|||||||
github.com/google/uuid v1.3.0
|
github.com/google/uuid v1.3.0
|
||||||
github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320
|
github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320
|
||||||
github.com/hashicorp/go-multierror v1.1.1
|
github.com/hashicorp/go-multierror v1.1.1
|
||||||
|
github.com/hashicorp/terraform-plugin-framework v1.3.0
|
||||||
|
github.com/hashicorp/terraform-plugin-framework-validators v0.10.0
|
||||||
|
github.com/hashicorp/terraform-plugin-go v0.15.0
|
||||||
github.com/hashicorp/terraform-plugin-log v0.9.0
|
github.com/hashicorp/terraform-plugin-log v0.9.0
|
||||||
|
github.com/hashicorp/terraform-plugin-mux v0.10.0
|
||||||
github.com/hashicorp/terraform-plugin-sdk/v2 v2.26.1
|
github.com/hashicorp/terraform-plugin-sdk/v2 v2.26.1
|
||||||
github.com/pkg/sftp v1.13.5
|
github.com/pkg/sftp v1.13.5
|
||||||
github.com/skeema/knownhosts v1.1.1
|
github.com/skeema/knownhosts v1.1.1
|
||||||
@ -17,26 +21,31 @@ require (
|
|||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 // indirect
|
||||||
github.com/agext/levenshtein v1.2.3 // indirect
|
github.com/agext/levenshtein v1.2.3 // indirect
|
||||||
github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
|
github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
|
||||||
|
github.com/cloudflare/circl v1.3.3 // indirect
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
github.com/fatih/color v1.14.1 // indirect
|
github.com/fatih/color v1.14.1 // indirect
|
||||||
github.com/golang/protobuf v1.5.2 // indirect
|
github.com/golang/protobuf v1.5.2 // indirect
|
||||||
github.com/google/go-cmp v0.5.9 // indirect
|
github.com/google/go-cmp v0.5.9 // indirect
|
||||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||||
|
github.com/hashicorp/go-checkpoint v0.5.0 // indirect
|
||||||
|
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
||||||
github.com/hashicorp/go-hclog v1.5.0 // indirect
|
github.com/hashicorp/go-hclog v1.5.0 // indirect
|
||||||
github.com/hashicorp/go-plugin v1.4.8 // indirect
|
github.com/hashicorp/go-plugin v1.4.9 // indirect
|
||||||
github.com/hashicorp/go-uuid v1.0.3 // indirect
|
github.com/hashicorp/go-uuid v1.0.3 // indirect
|
||||||
github.com/hashicorp/go-version v1.6.0 // indirect
|
github.com/hashicorp/go-version v1.6.0 // indirect
|
||||||
|
github.com/hashicorp/hc-install v0.5.2 // indirect
|
||||||
github.com/hashicorp/hcl/v2 v2.16.2 // indirect
|
github.com/hashicorp/hcl/v2 v2.16.2 // indirect
|
||||||
github.com/hashicorp/logutils v1.0.0 // indirect
|
github.com/hashicorp/logutils v1.0.0 // indirect
|
||||||
github.com/hashicorp/terraform-plugin-go v0.14.3 // indirect
|
github.com/hashicorp/terraform-exec v0.18.1 // indirect
|
||||||
github.com/hashicorp/terraform-registry-address v0.1.0 // indirect
|
github.com/hashicorp/terraform-json v0.16.0 // indirect
|
||||||
|
github.com/hashicorp/terraform-registry-address v0.2.0 // indirect
|
||||||
github.com/hashicorp/terraform-svchost v0.1.0 // indirect
|
github.com/hashicorp/terraform-svchost v0.1.0 // indirect
|
||||||
github.com/hashicorp/yamux v0.1.1 // indirect
|
github.com/hashicorp/yamux v0.1.1 // indirect
|
||||||
github.com/kr/fs v0.1.0 // indirect
|
github.com/kr/fs v0.1.0 // indirect
|
||||||
github.com/kr/pretty v0.2.1 // indirect
|
github.com/kr/pretty v0.3.0 // indirect
|
||||||
github.com/kr/text v0.2.0 // indirect
|
|
||||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.17 // indirect
|
github.com/mattn/go-isatty v0.0.17 // indirect
|
||||||
github.com/mitchellh/copystructure v1.2.0 // indirect
|
github.com/mitchellh/copystructure v1.2.0 // indirect
|
||||||
@ -47,16 +56,16 @@ require (
|
|||||||
github.com/oklog/run v1.1.0 // indirect
|
github.com/oklog/run v1.1.0 // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect
|
github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect
|
||||||
github.com/vmihailenco/msgpack/v4 v4.3.12 // indirect
|
github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect
|
||||||
github.com/vmihailenco/tagparser v0.1.2 // indirect
|
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
|
||||||
github.com/zclconf/go-cty v1.13.1 // indirect
|
github.com/zclconf/go-cty v1.13.2 // indirect
|
||||||
|
golang.org/x/mod v0.10.0 // indirect
|
||||||
golang.org/x/net v0.10.0 // indirect
|
golang.org/x/net v0.10.0 // indirect
|
||||||
golang.org/x/sys v0.9.0 // indirect
|
golang.org/x/sys v0.9.0 // indirect
|
||||||
golang.org/x/text v0.10.0 // indirect
|
golang.org/x/text v0.10.0 // indirect
|
||||||
google.golang.org/appengine v1.6.7 // indirect
|
google.golang.org/appengine v1.6.7 // indirect
|
||||||
google.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44 // indirect
|
google.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44 // indirect
|
||||||
google.golang.org/grpc v1.53.0 // indirect
|
google.golang.org/grpc v1.54.0 // indirect
|
||||||
google.golang.org/protobuf v1.28.1 // indirect
|
google.golang.org/protobuf v1.30.0 // indirect
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
|
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
)
|
)
|
||||||
|
105
go.sum
105
go.sum
@ -1,22 +1,30 @@
|
|||||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA=
|
||||||
|
github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 h1:wPbRQzjjwFc0ih8puEVAOFGELsn1zoIIYdxvML7mDxA=
|
||||||
|
github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8/go.mod h1:I0gYDMZ6Z5GRU7l58bNFSkPTFN6Yl12dsUlAZ8xy98g=
|
||||||
|
github.com/acomagu/bufpipe v1.0.4 h1:e3H4WUzM3npvo5uv95QuJM3cQspFNtFBzvJ2oNjKIDQ=
|
||||||
github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo=
|
github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo=
|
||||||
github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
|
github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
|
||||||
github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk=
|
|
||||||
github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec=
|
github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec=
|
||||||
github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw=
|
github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw=
|
||||||
github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo=
|
github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo=
|
||||||
|
github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
|
||||||
|
github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I=
|
||||||
|
github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs=
|
||||||
|
github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
|
||||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
|
||||||
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
|
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
|
||||||
github.com/fatih/color v1.14.1 h1:qfhVLaG5s+nCROl1zJsZRxFeYrHLqWroPOQ8BWiNb4w=
|
github.com/fatih/color v1.14.1 h1:qfhVLaG5s+nCROl1zJsZRxFeYrHLqWroPOQ8BWiNb4w=
|
||||||
github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg=
|
github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg=
|
||||||
|
github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4=
|
||||||
|
github.com/go-git/go-billy/v5 v5.4.1 h1:Uwp5tDRkPr+l/TnbHOQzp+tmJfLceOlbVucgpTz8ix4=
|
||||||
|
github.com/go-git/go-git/v5 v5.6.1 h1:q4ZRqQl4pR/ZJHc1L5CFjGA1a10u76aV1iC+nh+bHsk=
|
||||||
github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68=
|
github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68=
|
||||||
github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
|
||||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
|
||||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||||
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
||||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||||
@ -32,48 +40,65 @@ github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
|
|||||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||||
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
|
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
|
||||||
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||||
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
github.com/hashicorp/go-checkpoint v0.5.0 h1:MFYpPZCnQqQTE18jFwSII6eUQrD/oxMFp3mlgcqk5mU=
|
||||||
|
github.com/hashicorp/go-checkpoint v0.5.0/go.mod h1:7nfLNL10NsxqO4iWuW6tWW0HjZuDrwkBuEQsVcpCOgg=
|
||||||
|
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
||||||
|
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
|
||||||
|
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
|
||||||
github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 h1:1/D3zfFHttUKaCaGKZ/dR2roBXv0vKbSCnssIldfQdI=
|
github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 h1:1/D3zfFHttUKaCaGKZ/dR2roBXv0vKbSCnssIldfQdI=
|
||||||
github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320/go.mod h1:EiZBMaudVLy8fmjf9Npq1dq9RalhveqZG5w/yz3mHWs=
|
github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320/go.mod h1:EiZBMaudVLy8fmjf9Npq1dq9RalhveqZG5w/yz3mHWs=
|
||||||
github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c=
|
github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c=
|
||||||
github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
|
github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
|
||||||
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
|
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
|
||||||
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
||||||
github.com/hashicorp/go-plugin v1.4.8 h1:CHGwpxYDOttQOY7HOWgETU9dyVjOXzniXDqJcYJE1zM=
|
github.com/hashicorp/go-plugin v1.4.9 h1:ESiK220/qE0aGxWdzKIvRH69iLiuN/PjoLTm69RoWtU=
|
||||||
github.com/hashicorp/go-plugin v1.4.8/go.mod h1:viDMjcLJuDui6pXb8U4HVfb8AamCWhHGUjr2IrTF67s=
|
github.com/hashicorp/go-plugin v1.4.9/go.mod h1:viDMjcLJuDui6pXb8U4HVfb8AamCWhHGUjr2IrTF67s=
|
||||||
|
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||||
github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
|
github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
|
||||||
github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||||
github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
|
||||||
github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek=
|
github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek=
|
||||||
github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||||
|
github.com/hashicorp/hc-install v0.5.2 h1:SfwMFnEXVVirpwkDuSF5kymUOhrUxrTq3udEseZdOD0=
|
||||||
|
github.com/hashicorp/hc-install v0.5.2/go.mod h1:9QISwe6newMWIfEiXpzuu1k9HAGtQYgnSH8H9T8wmoI=
|
||||||
github.com/hashicorp/hcl/v2 v2.16.2 h1:mpkHZh/Tv+xet3sy3F9Ld4FyI2tUpWe9x3XtPx9f1a0=
|
github.com/hashicorp/hcl/v2 v2.16.2 h1:mpkHZh/Tv+xet3sy3F9Ld4FyI2tUpWe9x3XtPx9f1a0=
|
||||||
github.com/hashicorp/hcl/v2 v2.16.2/go.mod h1:JRmR89jycNkrrqnMmvPDMd56n1rQJ2Q6KocSLCMCXng=
|
github.com/hashicorp/hcl/v2 v2.16.2/go.mod h1:JRmR89jycNkrrqnMmvPDMd56n1rQJ2Q6KocSLCMCXng=
|
||||||
github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y=
|
github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y=
|
||||||
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
|
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
|
||||||
github.com/hashicorp/terraform-plugin-go v0.14.3 h1:nlnJ1GXKdMwsC8g1Nh05tK2wsC3+3BL/DBBxFEki+j0=
|
github.com/hashicorp/terraform-exec v0.18.1 h1:LAbfDvNQU1l0NOQlTuudjczVhHj061fNX5H8XZxHlH4=
|
||||||
github.com/hashicorp/terraform-plugin-go v0.14.3/go.mod h1:7ees7DMZ263q8wQ6E4RdIdR6nHHJtrdt4ogX5lPkX1A=
|
github.com/hashicorp/terraform-exec v0.18.1/go.mod h1:58wg4IeuAJ6LVsLUeD2DWZZoc/bYi6dzhLHzxM41980=
|
||||||
|
github.com/hashicorp/terraform-json v0.16.0 h1:UKkeWRWb23do5LNAFlh/K3N0ymn1qTOO8c+85Albo3s=
|
||||||
|
github.com/hashicorp/terraform-json v0.16.0/go.mod h1:v0Ufk9jJnk6tcIZvScHvetlKfiNTC+WS21mnXIlc0B0=
|
||||||
|
github.com/hashicorp/terraform-plugin-framework v1.3.0 h1:WtP1CIaWAfbzME17xoUXvJcyh5Ewu9attdhbfWNnYLs=
|
||||||
|
github.com/hashicorp/terraform-plugin-framework v1.3.0/go.mod h1:A1WD3Ry7FhrThViUTbkx4ZDsMq9oaAv4U9oTI8bBzCU=
|
||||||
|
github.com/hashicorp/terraform-plugin-framework-validators v0.10.0 h1:4L0tmy/8esP6OcvocVymw52lY0HyQ5OxB7VNl7k4bS0=
|
||||||
|
github.com/hashicorp/terraform-plugin-framework-validators v0.10.0/go.mod h1:qdQJCdimB9JeX2YwOpItEu+IrfoJjWQ5PhLpAOMDQAE=
|
||||||
|
github.com/hashicorp/terraform-plugin-go v0.15.0 h1:1BJNSUFs09DS8h/XNyJNJaeusQuWc/T9V99ylU9Zwp0=
|
||||||
|
github.com/hashicorp/terraform-plugin-go v0.15.0/go.mod h1:tk9E3/Zx4RlF/9FdGAhwxHExqIHHldqiQGt20G6g+nQ=
|
||||||
github.com/hashicorp/terraform-plugin-log v0.9.0 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9TFvymaRGZED3FCV0=
|
github.com/hashicorp/terraform-plugin-log v0.9.0 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9TFvymaRGZED3FCV0=
|
||||||
github.com/hashicorp/terraform-plugin-log v0.9.0/go.mod h1:rKL8egZQ/eXSyDqzLUuwUYLVdlYeamldAHSxjUFADow=
|
github.com/hashicorp/terraform-plugin-log v0.9.0/go.mod h1:rKL8egZQ/eXSyDqzLUuwUYLVdlYeamldAHSxjUFADow=
|
||||||
|
github.com/hashicorp/terraform-plugin-mux v0.10.0 h1:VejY1BffxGy2iYOaa8DDHavY4k9jbvAE8F3lhruspKY=
|
||||||
|
github.com/hashicorp/terraform-plugin-mux v0.10.0/go.mod h1:9sdnpmY20xIsl4ItsfODZYE+MgpSy/osXpSf+RwaZCY=
|
||||||
github.com/hashicorp/terraform-plugin-sdk/v2 v2.26.1 h1:G9WAfb8LHeCxu7Ae8nc1agZlQOSCUWsb610iAogBhCs=
|
github.com/hashicorp/terraform-plugin-sdk/v2 v2.26.1 h1:G9WAfb8LHeCxu7Ae8nc1agZlQOSCUWsb610iAogBhCs=
|
||||||
github.com/hashicorp/terraform-plugin-sdk/v2 v2.26.1/go.mod h1:xcOSYlRVdPLmDUoqPhO9fiO/YCN/l6MGYeTzGt5jgkQ=
|
github.com/hashicorp/terraform-plugin-sdk/v2 v2.26.1/go.mod h1:xcOSYlRVdPLmDUoqPhO9fiO/YCN/l6MGYeTzGt5jgkQ=
|
||||||
github.com/hashicorp/terraform-registry-address v0.1.0 h1:W6JkV9wbum+m516rCl5/NjKxCyTVaaUBbzYcMzBDO3U=
|
github.com/hashicorp/terraform-registry-address v0.2.0 h1:92LUg03NhfgZv44zpNTLBGIbiyTokQCDcdH5BhVHT3s=
|
||||||
github.com/hashicorp/terraform-registry-address v0.1.0/go.mod h1:EnyO2jYO6j29DTHbJcm00E5nQTFeTtyZH3H5ycydQ5A=
|
github.com/hashicorp/terraform-registry-address v0.2.0/go.mod h1:478wuzJPzdmqT6OGbB/iH82EDcI8VFM4yujknh/1nIs=
|
||||||
github.com/hashicorp/terraform-svchost v0.0.0-20200729002733-f050f53b9734/go.mod h1:kNDNcF7sN4DocDLBkQYz73HGKwN1ANB1blq4lIYLYvg=
|
|
||||||
github.com/hashicorp/terraform-svchost v0.1.0 h1:0+RcgZdZYNd81Vw7tu62g9JiLLvbOigp7QtyNh6CjXk=
|
github.com/hashicorp/terraform-svchost v0.1.0 h1:0+RcgZdZYNd81Vw7tu62g9JiLLvbOigp7QtyNh6CjXk=
|
||||||
github.com/hashicorp/terraform-svchost v0.1.0/go.mod h1:ut8JaH0vumgdCfJaihdcZULqkAwHdQNwNH7taIDdsZM=
|
github.com/hashicorp/terraform-svchost v0.1.0/go.mod h1:ut8JaH0vumgdCfJaihdcZULqkAwHdQNwNH7taIDdsZM=
|
||||||
github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE=
|
github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE=
|
||||||
github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ=
|
github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ=
|
||||||
|
github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk=
|
||||||
|
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
|
||||||
github.com/jhump/protoreflect v1.6.0 h1:h5jfMVslIg6l29nsMs0D8Wj17RDVdNYti0vDN/PZZoE=
|
github.com/jhump/protoreflect v1.6.0 h1:h5jfMVslIg6l29nsMs0D8Wj17RDVdNYti0vDN/PZZoE=
|
||||||
|
github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=
|
||||||
github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8=
|
github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8=
|
||||||
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||||
github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k=
|
|
||||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||||
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||||
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
||||||
@ -96,13 +121,18 @@ github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zx
|
|||||||
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
||||||
github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA=
|
github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA=
|
||||||
github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU=
|
github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU=
|
||||||
|
github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4=
|
||||||
github.com/pkg/sftp v1.13.5 h1:a3RLUqkyjYRtBTZJZ1VRrKbN3zhuPLlUc3sphVz81go=
|
github.com/pkg/sftp v1.13.5 h1:a3RLUqkyjYRtBTZJZ1VRrKbN3zhuPLlUc3sphVz81go=
|
||||||
github.com/pkg/sftp v1.13.5/go.mod h1:wHDZ0IZX6JcBYRK1TH9bcVq8G7TLpVHYIGJRFnmPfxg=
|
github.com/pkg/sftp v1.13.5/go.mod h1:wHDZ0IZX6JcBYRK1TH9bcVq8G7TLpVHYIGJRFnmPfxg=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k=
|
||||||
|
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||||
|
github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
|
||||||
github.com/skeema/knownhosts v1.1.1 h1:MTk78x9FPgDFVFkDLTrsnnfCJl7g1C/nnKvePgrIngE=
|
github.com/skeema/knownhosts v1.1.1 h1:MTk78x9FPgDFVFkDLTrsnnfCJl7g1C/nnKvePgrIngE=
|
||||||
github.com/skeema/knownhosts v1.1.1/go.mod h1:g4fPeYpque7P0xefxtGzV81ihjC8sX2IqpAoNkjxbMo=
|
github.com/skeema/knownhosts v1.1.1/go.mod h1:g4fPeYpque7P0xefxtGzV81ihjC8sX2IqpAoNkjxbMo=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
|
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
|
||||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||||
@ -110,34 +140,29 @@ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl
|
|||||||
github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
|
github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
|
||||||
github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI=
|
github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI=
|
||||||
github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
|
github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
|
||||||
github.com/vmihailenco/msgpack/v4 v4.3.12 h1:07s4sz9IReOgdikxLTKNbBdqDMLsjPKXwvCazn8G65U=
|
github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU=
|
||||||
github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4=
|
github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc=
|
||||||
github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI=
|
github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
|
||||||
github.com/vmihailenco/tagparser v0.1.2 h1:gnjoVuB/kljJ5wICEEOpx98oXMWPLj22G67Vbd1qPqc=
|
github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
|
||||||
github.com/vmihailenco/tagparser v0.1.2/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI=
|
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
|
||||||
github.com/zclconf/go-cty v1.1.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s=
|
github.com/zclconf/go-cty v1.13.2 h1:4GvrUxe/QUDYuJKAav4EYqdM47/kZa672LwmXFmEKT0=
|
||||||
github.com/zclconf/go-cty v1.13.1 h1:0a6bRwuiSHtAmqCqNOE+c2oHgepv0ctoxU4FUe43kwc=
|
github.com/zclconf/go-cty v1.13.2/go.mod h1:YKQzy/7pZ7iq2jNFzy5go57xdxdWoLLpaEp4u238AE0=
|
||||||
github.com/zclconf/go-cty v1.13.1/go.mod h1:YKQzy/7pZ7iq2jNFzy5go57xdxdWoLLpaEp4u238AE0=
|
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM=
|
golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM=
|
||||||
golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I=
|
golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I=
|
||||||
golang.org/x/exp v0.0.0-20230315142452-642cacee5cc0 h1:pVgRXcIictcr+lBQIFeiwuwtDIs4eL21OuM9nyAADmo=
|
golang.org/x/exp v0.0.0-20230315142452-642cacee5cc0 h1:pVgRXcIictcr+lBQIFeiwuwtDIs4eL21OuM9nyAADmo=
|
||||||
golang.org/x/exp v0.0.0-20230315142452-642cacee5cc0/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
|
golang.org/x/exp v0.0.0-20230315142452-642cacee5cc0/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk=
|
||||||
golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||||
golang.org/x/net v0.0.0-20191009170851-d66e71096ffb/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
|
||||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
|
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
|
||||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
@ -146,6 +171,7 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
@ -162,22 +188,21 @@ golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
|||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
|
||||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
|
||||||
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
||||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||||
google.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44 h1:EfLuoKW5WfkgVdDy7dTK8qSbH37AX5mj/MFh+bGPz14=
|
google.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44 h1:EfLuoKW5WfkgVdDy7dTK8qSbH37AX5mj/MFh+bGPz14=
|
||||||
google.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44/go.mod h1:8B0gmkoRebU8ukX6HP+4wrVQUY1+6PkQ44BSyIlflHA=
|
google.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44/go.mod h1:8B0gmkoRebU8ukX6HP+4wrVQUY1+6PkQ44BSyIlflHA=
|
||||||
google.golang.org/grpc v1.53.0 h1:LAv2ds7cmFV/XTS3XG1NneeENYrXGmorPxsBbptIjNc=
|
google.golang.org/grpc v1.54.0 h1:EhTqbhiYeixwWQtAEZAxmV9MGqcjEU2mFx52xCzNyag=
|
||||||
google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw=
|
google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g=
|
||||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||||
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
|
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
|
||||||
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
8
internal/internal.go
Normal file
8
internal/internal.go
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
/*
|
||||||
|
* 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 internal contains implementation of the provider created with Terraform Plugin Framework.
|
||||||
|
package internal
|
488
internal/network/resource_linux_bridge.go
Normal file
488
internal/network/resource_linux_bridge.go
Normal file
@ -0,0 +1,488 @@
|
|||||||
|
/*
|
||||||
|
* 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 network
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"regexp"
|
||||||
|
"sort"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/diag"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/resource"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||||
|
|
||||||
|
pvetypes "github.com/bpg/terraform-provider-proxmox/internal/types"
|
||||||
|
"github.com/bpg/terraform-provider-proxmox/proxmox"
|
||||||
|
"github.com/bpg/terraform-provider-proxmox/proxmox/nodes"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
_ resource.Resource = &linuxBridgeResource{}
|
||||||
|
_ resource.ResourceWithConfigure = &linuxBridgeResource{}
|
||||||
|
_ resource.ResourceWithImportState = &linuxBridgeResource{}
|
||||||
|
)
|
||||||
|
|
||||||
|
type linuxBridgeResourceModel struct {
|
||||||
|
// Base attributes
|
||||||
|
ID types.String `tfsdk:"id"`
|
||||||
|
NodeName types.String `tfsdk:"node_name"`
|
||||||
|
Name types.String `tfsdk:"name"`
|
||||||
|
Address pvetypes.IPCIDRValue `tfsdk:"address"`
|
||||||
|
Gateway pvetypes.IPAddrValue `tfsdk:"gateway"`
|
||||||
|
Address6 pvetypes.IPCIDRValue `tfsdk:"address6"`
|
||||||
|
Gateway6 pvetypes.IPAddrValue `tfsdk:"gateway6"`
|
||||||
|
Autostart types.Bool `tfsdk:"autostart"`
|
||||||
|
MTU types.Int64 `tfsdk:"mtu"`
|
||||||
|
Comment types.String `tfsdk:"comment"`
|
||||||
|
// Linux bridge attributes
|
||||||
|
Ports []types.String `tfsdk:"ports"`
|
||||||
|
VLANAware types.Bool `tfsdk:"vlan_aware"`
|
||||||
|
}
|
||||||
|
|
||||||
|
//nolint:lll
|
||||||
|
func (m *linuxBridgeResourceModel) exportToNetworkInterfaceCreateUpdateBody() *nodes.NetworkInterfaceCreateUpdateRequestBody {
|
||||||
|
body := &nodes.NetworkInterfaceCreateUpdateRequestBody{
|
||||||
|
Iface: m.Name.ValueString(),
|
||||||
|
Type: "bridge",
|
||||||
|
Autostart: pvetypes.CustomBool(m.Autostart.ValueBool()).Pointer(),
|
||||||
|
}
|
||||||
|
|
||||||
|
body.CIDR = m.Address.ValueStringPointer()
|
||||||
|
body.Gateway = m.Gateway.ValueStringPointer()
|
||||||
|
body.CIDR6 = m.Address6.ValueStringPointer()
|
||||||
|
body.Gateway6 = m.Gateway6.ValueStringPointer()
|
||||||
|
|
||||||
|
if !m.MTU.IsUnknown() {
|
||||||
|
body.MTU = m.MTU.ValueInt64Pointer()
|
||||||
|
}
|
||||||
|
|
||||||
|
body.Comments = m.Comment.ValueStringPointer()
|
||||||
|
|
||||||
|
var sanitizedPorts []string
|
||||||
|
|
||||||
|
for i := 0; i < len(m.Ports); i++ {
|
||||||
|
port := strings.TrimSpace(m.Ports[i].ValueString())
|
||||||
|
if len(port) > 0 {
|
||||||
|
sanitizedPorts = append(sanitizedPorts, port)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sort.Strings(sanitizedPorts)
|
||||||
|
bridgePorts := strings.Join(sanitizedPorts, " ")
|
||||||
|
|
||||||
|
if len(bridgePorts) > 0 {
|
||||||
|
body.BridgePorts = &bridgePorts
|
||||||
|
}
|
||||||
|
|
||||||
|
body.BridgeVLANAware = pvetypes.CustomBool(m.VLANAware.ValueBool()).Pointer()
|
||||||
|
|
||||||
|
return body
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *linuxBridgeResourceModel) importFromNetworkInterfaceList(
|
||||||
|
ctx context.Context,
|
||||||
|
iface *nodes.NetworkInterfaceListResponseData,
|
||||||
|
) error {
|
||||||
|
m.Address = pvetypes.NewIPCIDRPointerValue(iface.CIDR)
|
||||||
|
m.Gateway = pvetypes.NewIPAddrPointerValue(iface.Gateway)
|
||||||
|
m.Address6 = pvetypes.NewIPCIDRPointerValue(iface.CIDR6)
|
||||||
|
m.Gateway6 = pvetypes.NewIPAddrPointerValue(iface.Gateway6)
|
||||||
|
m.Autostart = types.BoolPointerValue(iface.Autostart.PointerBool())
|
||||||
|
|
||||||
|
if iface.MTU != nil {
|
||||||
|
if v, err := strconv.Atoi(*iface.MTU); err == nil {
|
||||||
|
m.MTU = types.Int64Value(int64(v))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
m.MTU = types.Int64Null()
|
||||||
|
}
|
||||||
|
|
||||||
|
if iface.Comments != nil {
|
||||||
|
m.Comment = types.StringValue(strings.TrimSpace(*iface.Comments))
|
||||||
|
} else {
|
||||||
|
m.Comment = types.StringNull()
|
||||||
|
}
|
||||||
|
|
||||||
|
if iface.BridgeVLANAware != nil {
|
||||||
|
m.VLANAware = types.BoolPointerValue(iface.BridgeVLANAware.PointerBool())
|
||||||
|
} else {
|
||||||
|
m.VLANAware = types.BoolValue(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
if iface.BridgePorts != nil && len(*iface.BridgePorts) > 0 {
|
||||||
|
ports, diags := types.ListValueFrom(ctx, types.StringType, strings.Split(*iface.BridgePorts, " "))
|
||||||
|
if diags.HasError() {
|
||||||
|
return fmt.Errorf("failed to parse bridge ports: %s", *iface.BridgePorts)
|
||||||
|
}
|
||||||
|
|
||||||
|
diags = ports.ElementsAs(ctx, &m.Ports, false)
|
||||||
|
if diags.HasError() {
|
||||||
|
return fmt.Errorf("failed to build bridge ports list: %s", *iface.BridgePorts)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewLinuxBridgeResource creates a new resource for managing Linux Bridge network interfaces.
|
||||||
|
func NewLinuxBridgeResource() resource.Resource {
|
||||||
|
return &linuxBridgeResource{}
|
||||||
|
}
|
||||||
|
|
||||||
|
type linuxBridgeResource struct {
|
||||||
|
client proxmox.Client
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *linuxBridgeResource) Metadata(
|
||||||
|
_ context.Context,
|
||||||
|
req resource.MetadataRequest,
|
||||||
|
resp *resource.MetadataResponse,
|
||||||
|
) {
|
||||||
|
resp.TypeName = req.ProviderTypeName + "_network_linux_bridge"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Schema defines the schema for the resource.
|
||||||
|
func (r *linuxBridgeResource) Schema(
|
||||||
|
_ context.Context,
|
||||||
|
_ resource.SchemaRequest,
|
||||||
|
resp *resource.SchemaResponse,
|
||||||
|
) {
|
||||||
|
resp.Schema = schema.Schema{
|
||||||
|
Description: "Manages a Linux Bridge network interface in a Proxmox VE node.",
|
||||||
|
Attributes: map[string]schema.Attribute{
|
||||||
|
// Base attributes
|
||||||
|
"id": schema.StringAttribute{
|
||||||
|
Computed: true,
|
||||||
|
PlanModifiers: []planmodifier.String{
|
||||||
|
stringplanmodifier.UseStateForUnknown(),
|
||||||
|
},
|
||||||
|
Description: "A unique identifier with format '<node name>:<iface>'",
|
||||||
|
},
|
||||||
|
"node_name": schema.StringAttribute{
|
||||||
|
Description: "The name of the node.",
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
"name": schema.StringAttribute{
|
||||||
|
Description: "The interface name.",
|
||||||
|
Required: true,
|
||||||
|
Validators: []validator.String{
|
||||||
|
stringvalidator.RegexMatches(
|
||||||
|
regexp.MustCompile(`^vmbr(\d{1,4})$`),
|
||||||
|
`must be "vmbrN", where N is a number between 0 and 9999`,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
PlanModifiers: []planmodifier.String{
|
||||||
|
stringplanmodifier.RequiresReplace(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"address": schema.StringAttribute{
|
||||||
|
Description: "The interface IPv4/CIDR address.",
|
||||||
|
CustomType: pvetypes.IPCIDRType{},
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
"gateway": schema.StringAttribute{
|
||||||
|
Description: "Default gateway address.",
|
||||||
|
CustomType: pvetypes.IPAddrType{},
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
"address6": schema.StringAttribute{
|
||||||
|
Description: "The interface IPv6/CIDR address.",
|
||||||
|
CustomType: pvetypes.IPCIDRType{},
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
"gateway6": schema.StringAttribute{
|
||||||
|
Description: "Default IPv6 gateway address.",
|
||||||
|
CustomType: pvetypes.IPAddrType{},
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
"autostart": schema.BoolAttribute{
|
||||||
|
Description: "Automatically start interface on boot.",
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
Default: booldefault.StaticBool(true),
|
||||||
|
},
|
||||||
|
"mtu": schema.Int64Attribute{
|
||||||
|
Description: "The interface MTU.",
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"comment": schema.StringAttribute{
|
||||||
|
Description: "Comment for the interface.",
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
// Linux Bridge attributes
|
||||||
|
"ports": schema.ListAttribute{
|
||||||
|
Description: "The interface bridge ports.",
|
||||||
|
Optional: true,
|
||||||
|
ElementType: types.StringType,
|
||||||
|
},
|
||||||
|
"vlan_aware": schema.BoolAttribute{
|
||||||
|
Description: "Whether the interface bridge is VLAN aware.",
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *linuxBridgeResource) Configure(
|
||||||
|
_ context.Context,
|
||||||
|
req resource.ConfigureRequest,
|
||||||
|
resp *resource.ConfigureResponse,
|
||||||
|
) {
|
||||||
|
if req.ProviderData == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
client, ok := req.ProviderData.(proxmox.Client)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
resp.Diagnostics.AddError(
|
||||||
|
"Unexpected Resource Configure Type",
|
||||||
|
fmt.Sprintf("Expected *proxmox.Client, got: %T. Please report this issue to the provider developers.",
|
||||||
|
req.ProviderData),
|
||||||
|
)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
r.client = client
|
||||||
|
}
|
||||||
|
|
||||||
|
//nolint:dupl
|
||||||
|
func (r *linuxBridgeResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
|
||||||
|
var plan linuxBridgeResourceModel
|
||||||
|
diags := req.Plan.Get(ctx, &plan)
|
||||||
|
resp.Diagnostics.Append(diags...)
|
||||||
|
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
body := plan.exportToNetworkInterfaceCreateUpdateBody()
|
||||||
|
|
||||||
|
err := r.client.Node(plan.NodeName.ValueString()).CreateNetworkInterface(ctx, body)
|
||||||
|
if err != nil {
|
||||||
|
resp.Diagnostics.AddError(
|
||||||
|
"Error creating Linux Bridge interface",
|
||||||
|
"Could not create Linux Bridge, unexpected error: "+err.Error(),
|
||||||
|
)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
plan.ID = types.StringValue(plan.NodeName.ValueString() + ":" + plan.Name.ValueString())
|
||||||
|
|
||||||
|
r.read(ctx, &plan, &resp.Diagnostics)
|
||||||
|
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
resp.State.Set(ctx, plan)
|
||||||
|
resp.Diagnostics.Append(diags...)
|
||||||
|
|
||||||
|
err = r.client.Node(plan.NodeName.ValueString()).ReloadNetworkConfiguration(ctx)
|
||||||
|
if err != nil {
|
||||||
|
resp.Diagnostics.AddError(
|
||||||
|
"Error reloading network configuration",
|
||||||
|
fmt.Sprintf("Could not reload network configuration on node '%s', unexpected error: %s",
|
||||||
|
plan.NodeName.ValueString(), err.Error()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *linuxBridgeResource) read(ctx context.Context, model *linuxBridgeResourceModel, diags *diag.Diagnostics) {
|
||||||
|
ifaces, err := r.client.Node(model.NodeName.ValueString()).ListNetworkInterfaces(ctx)
|
||||||
|
if err != nil {
|
||||||
|
diags.AddError(
|
||||||
|
"Error listing network interfaces",
|
||||||
|
"Could not list network interfaces, unexpected error: "+err.Error(),
|
||||||
|
)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, iface := range ifaces {
|
||||||
|
if iface.Iface != model.Name.ValueString() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
err = model.importFromNetworkInterfaceList(ctx, iface)
|
||||||
|
if err != nil {
|
||||||
|
diags.AddError(
|
||||||
|
"Error converting network interface to a model",
|
||||||
|
"Could not import network interface from API response, unexpected error: "+err.Error(),
|
||||||
|
)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read reads a Linux Bridge interface.
|
||||||
|
func (r *linuxBridgeResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
|
||||||
|
// Get current state
|
||||||
|
var state linuxBridgeResourceModel
|
||||||
|
diags := req.State.Get(ctx, &state)
|
||||||
|
resp.Diagnostics.Append(diags...)
|
||||||
|
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
r.read(ctx, &state, &resp.Diagnostics)
|
||||||
|
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
diags = resp.State.Set(ctx, state)
|
||||||
|
resp.Diagnostics.Append(diags...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update updates a Linux Bridge interface.
|
||||||
|
func (r *linuxBridgeResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
|
||||||
|
var plan, state linuxBridgeResourceModel
|
||||||
|
|
||||||
|
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
|
||||||
|
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
|
||||||
|
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
body := plan.exportToNetworkInterfaceCreateUpdateBody()
|
||||||
|
|
||||||
|
var toDelete []string
|
||||||
|
|
||||||
|
if !plan.MTU.Equal(state.MTU) && (plan.MTU.IsUnknown() || plan.MTU.ValueInt64() == 0) {
|
||||||
|
toDelete = append(toDelete, "mtu")
|
||||||
|
body.MTU = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// VLANAware is computed, will never be null
|
||||||
|
if !plan.VLANAware.Equal(state.VLANAware) && !plan.VLANAware.ValueBool() {
|
||||||
|
toDelete = append(toDelete, "bridge_vlan_aware")
|
||||||
|
body.BridgeVLANAware = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(toDelete) > 0 {
|
||||||
|
body.Delete = &toDelete
|
||||||
|
}
|
||||||
|
|
||||||
|
err := r.client.Node(plan.NodeName.ValueString()).UpdateNetworkInterface(ctx, plan.Name.ValueString(), body)
|
||||||
|
if err != nil {
|
||||||
|
resp.Diagnostics.AddError(
|
||||||
|
"Error updating Linux Bridge interface",
|
||||||
|
"Could not update Linux Bridge, unexpected error: "+err.Error(),
|
||||||
|
)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
r.read(ctx, &plan, &resp.Diagnostics)
|
||||||
|
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
resp.Diagnostics.Append(resp.State.Set(ctx, plan)...)
|
||||||
|
|
||||||
|
err = r.client.Node(state.NodeName.ValueString()).ReloadNetworkConfiguration(ctx)
|
||||||
|
if err != nil {
|
||||||
|
resp.Diagnostics.AddError(
|
||||||
|
"Error reloading network configuration",
|
||||||
|
fmt.Sprintf("Could not reload network configuration on node '%s', unexpected error: %s",
|
||||||
|
state.NodeName.ValueString(), err.Error()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete deletes a Linux Bridge interface.
|
||||||
|
//
|
||||||
|
//nolint:dupl
|
||||||
|
func (r *linuxBridgeResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
|
||||||
|
var state linuxBridgeResourceModel
|
||||||
|
diags := req.State.Get(ctx, &state)
|
||||||
|
resp.Diagnostics.Append(diags...)
|
||||||
|
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err := r.client.Node(state.NodeName.ValueString()).DeleteNetworkInterface(ctx, state.Name.ValueString())
|
||||||
|
if err != nil {
|
||||||
|
if strings.Contains(err.Error(), "interface does not exist") {
|
||||||
|
resp.Diagnostics.AddWarning(
|
||||||
|
"Linux Bridge interface does not exist",
|
||||||
|
fmt.Sprintf("Could not delete Linux Bridge '%s', interface does not exist, "+
|
||||||
|
"or has already been deleted outside of Terraform.", state.Name.ValueString()),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
resp.Diagnostics.AddError(
|
||||||
|
"Error deleting Linux Bridge interface",
|
||||||
|
fmt.Sprintf("Could not delete Linux Bridge '%s', unexpected error: %s",
|
||||||
|
state.Name.ValueString(), err.Error()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = r.client.Node(state.NodeName.ValueString()).ReloadNetworkConfiguration(ctx)
|
||||||
|
if err != nil {
|
||||||
|
resp.Diagnostics.AddError(
|
||||||
|
"Error reloading network configuration",
|
||||||
|
fmt.Sprintf("Could not reload network configuration on node '%s', unexpected error: %s",
|
||||||
|
state.NodeName.ValueString(), err.Error()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *linuxBridgeResource) ImportState(
|
||||||
|
ctx context.Context,
|
||||||
|
req resource.ImportStateRequest,
|
||||||
|
resp *resource.ImportStateResponse,
|
||||||
|
) {
|
||||||
|
idParts := strings.Split(req.ID, ":")
|
||||||
|
if len(idParts) != 2 || idParts[0] == "" || idParts[1] == "" {
|
||||||
|
resp.Diagnostics.AddError(
|
||||||
|
"Unexpected Import Identifier",
|
||||||
|
fmt.Sprintf("Expected import identifier with format: node_name:iface. Got: %q", req.ID),
|
||||||
|
)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
nodeName := idParts[0]
|
||||||
|
iface := idParts[1]
|
||||||
|
|
||||||
|
state := linuxBridgeResourceModel{
|
||||||
|
ID: types.StringValue(req.ID),
|
||||||
|
NodeName: types.StringValue(nodeName),
|
||||||
|
Name: types.StringValue(iface),
|
||||||
|
}
|
||||||
|
r.read(ctx, &state, &resp.Diagnostics)
|
||||||
|
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
diags := resp.State.Set(ctx, state)
|
||||||
|
resp.Diagnostics.Append(diags...)
|
||||||
|
}
|
451
internal/network/resource_linux_vlan.go
Normal file
451
internal/network/resource_linux_vlan.go
Normal file
@ -0,0 +1,451 @@
|
|||||||
|
/*
|
||||||
|
* 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 network
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/diag"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/resource"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||||
|
|
||||||
|
pvetypes "github.com/bpg/terraform-provider-proxmox/internal/types"
|
||||||
|
"github.com/bpg/terraform-provider-proxmox/proxmox"
|
||||||
|
"github.com/bpg/terraform-provider-proxmox/proxmox/nodes"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
_ resource.Resource = &linuxVLANResource{}
|
||||||
|
_ resource.ResourceWithConfigure = &linuxVLANResource{}
|
||||||
|
_ resource.ResourceWithImportState = &linuxVLANResource{}
|
||||||
|
)
|
||||||
|
|
||||||
|
type linuxVLANResourceModel struct {
|
||||||
|
// Base attributes
|
||||||
|
ID types.String `tfsdk:"id"`
|
||||||
|
NodeName types.String `tfsdk:"node_name"`
|
||||||
|
Name types.String `tfsdk:"name"`
|
||||||
|
Address pvetypes.IPCIDRValue `tfsdk:"address"`
|
||||||
|
Gateway pvetypes.IPAddrValue `tfsdk:"gateway"`
|
||||||
|
Address6 pvetypes.IPCIDRValue `tfsdk:"address6"`
|
||||||
|
Gateway6 pvetypes.IPAddrValue `tfsdk:"gateway6"`
|
||||||
|
Autostart types.Bool `tfsdk:"autostart"`
|
||||||
|
MTU types.Int64 `tfsdk:"mtu"`
|
||||||
|
Comment types.String `tfsdk:"comment"`
|
||||||
|
// Linux VLAN attributes
|
||||||
|
Interface types.String `tfsdk:"interface"`
|
||||||
|
VLAN types.Int64 `tfsdk:"vlan"`
|
||||||
|
}
|
||||||
|
|
||||||
|
//nolint:lll
|
||||||
|
func (m *linuxVLANResourceModel) exportToNetworkInterfaceCreateUpdateBody() *nodes.NetworkInterfaceCreateUpdateRequestBody {
|
||||||
|
body := &nodes.NetworkInterfaceCreateUpdateRequestBody{
|
||||||
|
Iface: m.Name.ValueString(),
|
||||||
|
Type: "vlan",
|
||||||
|
Autostart: pvetypes.CustomBool(m.Autostart.ValueBool()).Pointer(),
|
||||||
|
}
|
||||||
|
|
||||||
|
body.CIDR = m.Address.ValueStringPointer()
|
||||||
|
body.Gateway = m.Gateway.ValueStringPointer()
|
||||||
|
body.CIDR6 = m.Address6.ValueStringPointer()
|
||||||
|
body.Gateway6 = m.Gateway6.ValueStringPointer()
|
||||||
|
body.Comments = m.Comment.ValueStringPointer()
|
||||||
|
|
||||||
|
if !m.MTU.IsUnknown() {
|
||||||
|
body.MTU = m.MTU.ValueInt64Pointer()
|
||||||
|
}
|
||||||
|
|
||||||
|
if !m.Interface.IsUnknown() {
|
||||||
|
body.VLANRawDevice = m.Interface.ValueStringPointer()
|
||||||
|
}
|
||||||
|
|
||||||
|
if !m.VLAN.IsUnknown() {
|
||||||
|
body.VLANID = m.VLAN.ValueInt64Pointer()
|
||||||
|
}
|
||||||
|
|
||||||
|
return body
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *linuxVLANResourceModel) importFromNetworkInterfaceList(iface *nodes.NetworkInterfaceListResponseData) {
|
||||||
|
m.Address = pvetypes.NewIPCIDRPointerValue(iface.CIDR)
|
||||||
|
m.Gateway = pvetypes.NewIPAddrPointerValue(iface.Gateway)
|
||||||
|
m.Address6 = pvetypes.NewIPCIDRPointerValue(iface.CIDR6)
|
||||||
|
m.Gateway6 = pvetypes.NewIPAddrPointerValue(iface.Gateway6)
|
||||||
|
m.Autostart = types.BoolPointerValue(iface.Autostart.PointerBool())
|
||||||
|
|
||||||
|
if iface.MTU != nil {
|
||||||
|
if v, err := strconv.Atoi(*iface.MTU); err == nil {
|
||||||
|
m.MTU = types.Int64Value(int64(v))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
m.MTU = types.Int64Null()
|
||||||
|
}
|
||||||
|
|
||||||
|
if iface.Comments != nil {
|
||||||
|
m.Comment = types.StringValue(strings.TrimSpace(*iface.Comments))
|
||||||
|
} else {
|
||||||
|
m.Comment = types.StringNull()
|
||||||
|
}
|
||||||
|
|
||||||
|
if iface.VLANID != nil {
|
||||||
|
if v, err := strconv.Atoi(*iface.VLANID); err == nil {
|
||||||
|
m.VLAN = types.Int64Value(int64(v))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// in reality, this should never happen
|
||||||
|
m.VLAN = types.Int64Unknown()
|
||||||
|
}
|
||||||
|
|
||||||
|
if iface.VLANRawDevice != nil {
|
||||||
|
m.Interface = types.StringValue(strings.TrimSpace(*iface.VLANRawDevice))
|
||||||
|
} else {
|
||||||
|
m.Interface = types.StringNull()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewLinuxVLANResource creates a new resource for managing Linux VLAN network interfaces.
|
||||||
|
func NewLinuxVLANResource() resource.Resource {
|
||||||
|
return &linuxVLANResource{}
|
||||||
|
}
|
||||||
|
|
||||||
|
type linuxVLANResource struct {
|
||||||
|
client proxmox.Client
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *linuxVLANResource) Metadata(
|
||||||
|
_ context.Context,
|
||||||
|
req resource.MetadataRequest,
|
||||||
|
resp *resource.MetadataResponse,
|
||||||
|
) {
|
||||||
|
resp.TypeName = req.ProviderTypeName + "_network_linux_vlan"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Schema defines the schema for the resource.
|
||||||
|
func (r *linuxVLANResource) Schema(
|
||||||
|
_ context.Context,
|
||||||
|
_ resource.SchemaRequest,
|
||||||
|
resp *resource.SchemaResponse,
|
||||||
|
) {
|
||||||
|
resp.Schema = schema.Schema{
|
||||||
|
Description: "Manages a Linux VLAN network interface in a Proxmox VE node.",
|
||||||
|
Attributes: map[string]schema.Attribute{
|
||||||
|
// Base attributes
|
||||||
|
"id": schema.StringAttribute{
|
||||||
|
Computed: true,
|
||||||
|
PlanModifiers: []planmodifier.String{
|
||||||
|
stringplanmodifier.UseStateForUnknown(),
|
||||||
|
},
|
||||||
|
Description: "A unique identifier with format '<node name>:<iface>'",
|
||||||
|
},
|
||||||
|
"node_name": schema.StringAttribute{
|
||||||
|
Description: "The name of the node.",
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
"name": schema.StringAttribute{
|
||||||
|
Description: "The interface name.",
|
||||||
|
Required: true,
|
||||||
|
Validators: []validator.String{
|
||||||
|
stringvalidator.LengthAtLeast(3),
|
||||||
|
},
|
||||||
|
PlanModifiers: []planmodifier.String{
|
||||||
|
stringplanmodifier.RequiresReplace(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"address": schema.StringAttribute{
|
||||||
|
Description: "The interface IPv4/CIDR address.",
|
||||||
|
CustomType: pvetypes.IPCIDRType{},
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
"gateway": schema.StringAttribute{
|
||||||
|
Description: "Default gateway address.",
|
||||||
|
CustomType: pvetypes.IPAddrType{},
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
"address6": schema.StringAttribute{
|
||||||
|
Description: "The interface IPv6/CIDR address.",
|
||||||
|
CustomType: pvetypes.IPCIDRType{},
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
"gateway6": schema.StringAttribute{
|
||||||
|
Description: "Default IPv6 gateway address.",
|
||||||
|
CustomType: pvetypes.IPAddrType{},
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
"autostart": schema.BoolAttribute{
|
||||||
|
Description: "Automatically start interface on boot.",
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
Default: booldefault.StaticBool(true),
|
||||||
|
},
|
||||||
|
"mtu": schema.Int64Attribute{
|
||||||
|
Description: "The interface MTU.",
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"comment": schema.StringAttribute{
|
||||||
|
Description: "Comment for the interface.",
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
// Linux VLAN attributes
|
||||||
|
"interface": schema.StringAttribute{
|
||||||
|
// read-only
|
||||||
|
Description: "The VLAN raw device.",
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"vlan": schema.Int64Attribute{
|
||||||
|
// read-only
|
||||||
|
Description: "The VLAN tag",
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *linuxVLANResource) Configure(
|
||||||
|
_ context.Context,
|
||||||
|
req resource.ConfigureRequest,
|
||||||
|
resp *resource.ConfigureResponse,
|
||||||
|
) {
|
||||||
|
if req.ProviderData == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
client, ok := req.ProviderData.(proxmox.Client)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
resp.Diagnostics.AddError(
|
||||||
|
"Unexpected Resource Configure Type",
|
||||||
|
fmt.Sprintf("Expected *proxmox.Client, got: %T. Please report this issue to the provider developers.",
|
||||||
|
req.ProviderData),
|
||||||
|
)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
r.client = client
|
||||||
|
}
|
||||||
|
|
||||||
|
//nolint:dupl
|
||||||
|
func (r *linuxVLANResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
|
||||||
|
var plan linuxVLANResourceModel
|
||||||
|
diags := req.Plan.Get(ctx, &plan)
|
||||||
|
resp.Diagnostics.Append(diags...)
|
||||||
|
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
body := plan.exportToNetworkInterfaceCreateUpdateBody()
|
||||||
|
|
||||||
|
err := r.client.Node(plan.NodeName.ValueString()).CreateNetworkInterface(ctx, body)
|
||||||
|
if err != nil {
|
||||||
|
resp.Diagnostics.AddError(
|
||||||
|
"Error creating Linux VLAN interface",
|
||||||
|
"Could not create Linux VLAN, unexpected error: "+err.Error(),
|
||||||
|
)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
plan.ID = types.StringValue(plan.NodeName.ValueString() + ":" + plan.Name.ValueString())
|
||||||
|
|
||||||
|
r.read(ctx, &plan, &resp.Diagnostics)
|
||||||
|
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
resp.State.Set(ctx, plan)
|
||||||
|
resp.Diagnostics.Append(diags...)
|
||||||
|
|
||||||
|
err = r.client.Node(plan.NodeName.ValueString()).ReloadNetworkConfiguration(ctx)
|
||||||
|
if err != nil {
|
||||||
|
resp.Diagnostics.AddError(
|
||||||
|
"Error reloading network configuration",
|
||||||
|
fmt.Sprintf("Could not reload network configuration on node '%s', unexpected error: %s",
|
||||||
|
plan.NodeName.ValueString(), err.Error()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *linuxVLANResource) read(ctx context.Context, model *linuxVLANResourceModel, diags *diag.Diagnostics) {
|
||||||
|
ifaces, err := r.client.Node(model.NodeName.ValueString()).ListNetworkInterfaces(ctx)
|
||||||
|
if err != nil {
|
||||||
|
diags.AddError(
|
||||||
|
"Error listing network interfaces",
|
||||||
|
"Could not list network interfaces, unexpected error: "+err.Error(),
|
||||||
|
)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, iface := range ifaces {
|
||||||
|
if iface.Iface != model.Name.ValueString() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
model.importFromNetworkInterfaceList(iface)
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read reads a Linux VLAN interface.
|
||||||
|
func (r *linuxVLANResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
|
||||||
|
// Get current state
|
||||||
|
var state linuxVLANResourceModel
|
||||||
|
diags := req.State.Get(ctx, &state)
|
||||||
|
resp.Diagnostics.Append(diags...)
|
||||||
|
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
r.read(ctx, &state, &resp.Diagnostics)
|
||||||
|
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
diags = resp.State.Set(ctx, state)
|
||||||
|
resp.Diagnostics.Append(diags...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update updates a Linux VLAN interface.
|
||||||
|
func (r *linuxVLANResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
|
||||||
|
var plan, state linuxVLANResourceModel
|
||||||
|
|
||||||
|
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
|
||||||
|
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
|
||||||
|
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
body := plan.exportToNetworkInterfaceCreateUpdateBody()
|
||||||
|
|
||||||
|
var toDelete []string
|
||||||
|
|
||||||
|
if !plan.MTU.Equal(state.MTU) && (plan.MTU.IsUnknown() || plan.MTU.ValueInt64() == 0) {
|
||||||
|
toDelete = append(toDelete, "mtu")
|
||||||
|
body.MTU = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(toDelete) > 0 {
|
||||||
|
body.Delete = &toDelete
|
||||||
|
}
|
||||||
|
|
||||||
|
err := r.client.Node(plan.NodeName.ValueString()).UpdateNetworkInterface(ctx, plan.Name.ValueString(), body)
|
||||||
|
if err != nil {
|
||||||
|
resp.Diagnostics.AddError(
|
||||||
|
"Error updating Linux VLAN interface",
|
||||||
|
"Could not update Linux VLAN, unexpected error: "+err.Error(),
|
||||||
|
)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
r.read(ctx, &plan, &resp.Diagnostics)
|
||||||
|
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
resp.Diagnostics.Append(resp.State.Set(ctx, plan)...)
|
||||||
|
|
||||||
|
err = r.client.Node(state.NodeName.ValueString()).ReloadNetworkConfiguration(ctx)
|
||||||
|
if err != nil {
|
||||||
|
resp.Diagnostics.AddError(
|
||||||
|
"Error reloading network configuration",
|
||||||
|
fmt.Sprintf("Could not reload network configuration on node '%s', unexpected error: %s",
|
||||||
|
state.NodeName.ValueString(), err.Error()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete deletes a Linux VLAN interface.
|
||||||
|
//
|
||||||
|
//nolint:dupl
|
||||||
|
func (r *linuxVLANResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
|
||||||
|
var state linuxVLANResourceModel
|
||||||
|
diags := req.State.Get(ctx, &state)
|
||||||
|
resp.Diagnostics.Append(diags...)
|
||||||
|
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err := r.client.Node(state.NodeName.ValueString()).DeleteNetworkInterface(ctx, state.Name.ValueString())
|
||||||
|
if err != nil {
|
||||||
|
if strings.Contains(err.Error(), "interface does not exist") {
|
||||||
|
resp.Diagnostics.AddWarning(
|
||||||
|
"Linux VLAN interface does not exist",
|
||||||
|
fmt.Sprintf("Could not delete Linux VLAN '%s', interface does not exist, "+
|
||||||
|
"or has already been deleted outside of Terraform.", state.Name.ValueString()),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
resp.Diagnostics.AddError(
|
||||||
|
"Error deleting Linux VLAN interface",
|
||||||
|
fmt.Sprintf("Could not delete Linux VLAN '%s', unexpected error: %s",
|
||||||
|
state.Name.ValueString(), err.Error()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = r.client.Node(state.NodeName.ValueString()).ReloadNetworkConfiguration(ctx)
|
||||||
|
if err != nil {
|
||||||
|
resp.Diagnostics.AddError(
|
||||||
|
"Error reloading network configuration",
|
||||||
|
fmt.Sprintf("Could not reload network configuration on node '%s', unexpected error: %s",
|
||||||
|
state.NodeName.ValueString(), err.Error()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *linuxVLANResource) ImportState(
|
||||||
|
ctx context.Context,
|
||||||
|
req resource.ImportStateRequest,
|
||||||
|
resp *resource.ImportStateResponse,
|
||||||
|
) {
|
||||||
|
idParts := strings.Split(req.ID, ":")
|
||||||
|
if len(idParts) != 2 || idParts[0] == "" || idParts[1] == "" {
|
||||||
|
resp.Diagnostics.AddError(
|
||||||
|
"Unexpected Import Identifier",
|
||||||
|
fmt.Sprintf("Expected import identifier with format: node_name:iface. Got: %q", req.ID),
|
||||||
|
)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
nodeName := idParts[0]
|
||||||
|
iface := idParts[1]
|
||||||
|
|
||||||
|
state := linuxVLANResourceModel{
|
||||||
|
ID: types.StringValue(req.ID),
|
||||||
|
NodeName: types.StringValue(nodeName),
|
||||||
|
Name: types.StringValue(iface),
|
||||||
|
}
|
||||||
|
r.read(ctx, &state, &resp.Diagnostics)
|
||||||
|
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
diags := resp.State.Set(ctx, state)
|
||||||
|
resp.Diagnostics.Append(diags...)
|
||||||
|
}
|
401
internal/provider/provider.go
Normal file
401
internal/provider/provider.go
Normal file
@ -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 provider
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework-validators/listvalidator"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/datasource"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/path"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/provider"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/provider/schema"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/resource"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||||
|
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||||
|
|
||||||
|
"github.com/bpg/terraform-provider-proxmox/internal/network"
|
||||||
|
"github.com/bpg/terraform-provider-proxmox/proxmox"
|
||||||
|
"github.com/bpg/terraform-provider-proxmox/proxmox/api"
|
||||||
|
"github.com/bpg/terraform-provider-proxmox/proxmox/nodes"
|
||||||
|
"github.com/bpg/terraform-provider-proxmox/proxmox/ssh"
|
||||||
|
"github.com/bpg/terraform-provider-proxmox/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Ensure the implementation satisfies the expected interfaces.
|
||||||
|
var _ provider.Provider = &proxmoxProvider{}
|
||||||
|
|
||||||
|
// New is a helper function to simplify provider server and testing implementation.
|
||||||
|
func New(version string) func() provider.Provider {
|
||||||
|
return func() provider.Provider {
|
||||||
|
return &proxmoxProvider{
|
||||||
|
version: version,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type proxmoxProvider struct {
|
||||||
|
// version is set to the provider version on release, "dev" when the
|
||||||
|
// provider is built and ran locally, and "test" when running acceptance
|
||||||
|
// testing.
|
||||||
|
version string
|
||||||
|
}
|
||||||
|
|
||||||
|
// proxmoxProviderModel maps provider schema data.
|
||||||
|
type proxmoxProviderModel struct {
|
||||||
|
APIToken types.String `tfsdk:"api_token"`
|
||||||
|
Endpoint types.String `tfsdk:"endpoint"`
|
||||||
|
Insecure types.Bool `tfsdk:"insecure"`
|
||||||
|
OTP types.String `tfsdk:"otp"`
|
||||||
|
Username types.String `tfsdk:"username"`
|
||||||
|
Password types.String `tfsdk:"password"`
|
||||||
|
SSH []struct {
|
||||||
|
Agent types.Bool `tfsdk:"agent"`
|
||||||
|
AgentSocket types.String `tfsdk:"agent_socket"`
|
||||||
|
Password types.String `tfsdk:"password"`
|
||||||
|
Username types.String `tfsdk:"username"`
|
||||||
|
|
||||||
|
Nodes []struct {
|
||||||
|
Name types.String `tfsdk:"name"`
|
||||||
|
Address types.String `tfsdk:"address"`
|
||||||
|
} `tfsdk:"node"`
|
||||||
|
} `tfsdk:"ssh"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *proxmoxProvider) Metadata(_ context.Context, _ provider.MetadataRequest, resp *provider.MetadataResponse) {
|
||||||
|
// resp.TypeName = "proxmox"
|
||||||
|
resp.TypeName = "proxmox_virtual_environment"
|
||||||
|
resp.Version = p.version
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *proxmoxProvider) Schema(_ context.Context, _ provider.SchemaRequest, resp *provider.SchemaResponse) {
|
||||||
|
resp.Schema = schema.Schema{
|
||||||
|
// Attributes specified in alphabetical order.
|
||||||
|
Attributes: map[string]schema.Attribute{
|
||||||
|
"api_token": schema.StringAttribute{
|
||||||
|
Description: "The API token for the Proxmox VE API.",
|
||||||
|
Optional: true,
|
||||||
|
Sensitive: true,
|
||||||
|
Validators: []validator.String{
|
||||||
|
stringvalidator.RegexMatches(
|
||||||
|
regexp.MustCompile(`^\S+@\w+!\S+=([a-zA-Z0-9-]+)$`),
|
||||||
|
`must be a valid API token, e.g. 'USER@REALM!TOKENID=UUID'`,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"endpoint": schema.StringAttribute{
|
||||||
|
Description: "The endpoint for the Proxmox VE API.",
|
||||||
|
Optional: true,
|
||||||
|
Validators: []validator.String{
|
||||||
|
stringvalidator.LengthAtLeast(1),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"insecure": schema.BoolAttribute{
|
||||||
|
Description: "Whether to skip the TLS verification step.",
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
"otp": schema.StringAttribute{
|
||||||
|
Description: "The one-time password for the Proxmox VE API.",
|
||||||
|
Optional: true,
|
||||||
|
DeprecationMessage: "The `otp` attribute is deprecated and will be removed in a future release. " +
|
||||||
|
"Please use the `api_token` attribute instead.",
|
||||||
|
},
|
||||||
|
"password": schema.StringAttribute{
|
||||||
|
Description: "The password for the Proxmox VE API.",
|
||||||
|
Optional: true,
|
||||||
|
Sensitive: true,
|
||||||
|
},
|
||||||
|
"username": schema.StringAttribute{
|
||||||
|
Description: "The username for the Proxmox VE API.",
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Blocks: map[string]schema.Block{
|
||||||
|
// have to define it as a list due to backwards compatibility
|
||||||
|
"ssh": schema.ListNestedBlock{
|
||||||
|
Description: "The SSH configuration for the Proxmox nodes.",
|
||||||
|
Validators: []validator.List{
|
||||||
|
listvalidator.SizeAtMost(1),
|
||||||
|
},
|
||||||
|
NestedObject: schema.NestedBlockObject{
|
||||||
|
Attributes: map[string]schema.Attribute{
|
||||||
|
"agent": schema.BoolAttribute{
|
||||||
|
Description: "Whether to use the SSH agent for authentication. " +
|
||||||
|
"Defaults to `false`.",
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
"agent_socket": schema.StringAttribute{
|
||||||
|
Description: "The path to the SSH agent socket. " +
|
||||||
|
"Defaults to the value of the `SSH_AUTH_SOCK` " +
|
||||||
|
"environment variable.",
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
"password": schema.StringAttribute{
|
||||||
|
Description: "The password used for the SSH connection. " +
|
||||||
|
"Defaults to the value of the `password` field of the " +
|
||||||
|
"`provider` block.",
|
||||||
|
Optional: true,
|
||||||
|
Sensitive: true,
|
||||||
|
},
|
||||||
|
"username": schema.StringAttribute{
|
||||||
|
Description: "The username used for the SSH connection. " +
|
||||||
|
"Defaults to the value of the `username` field of the " +
|
||||||
|
"`provider` block.",
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Blocks: map[string]schema.Block{
|
||||||
|
"node": schema.ListNestedBlock{
|
||||||
|
Description: "Overrides for SSH connection configuration for a Proxmox VE node.",
|
||||||
|
NestedObject: schema.NestedBlockObject{
|
||||||
|
Attributes: map[string]schema.Attribute{
|
||||||
|
"name": schema.StringAttribute{
|
||||||
|
Description: "The name of the Proxmox VE node.",
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
"address": schema.StringAttribute{
|
||||||
|
Description: "The address of the Proxmox VE node.",
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *proxmoxProvider) Configure(
|
||||||
|
ctx context.Context,
|
||||||
|
req provider.ConfigureRequest,
|
||||||
|
resp *provider.ConfigureResponse,
|
||||||
|
) {
|
||||||
|
tflog.Info(ctx, "Configuring the Proxmox provider...")
|
||||||
|
|
||||||
|
// Retrieve provider data from configuration
|
||||||
|
var config proxmoxProviderModel
|
||||||
|
diags := req.Config.Get(ctx, &config)
|
||||||
|
resp.Diagnostics.Append(diags...)
|
||||||
|
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// If practitioner provided a configuration value for any of the
|
||||||
|
// attributes, it must be a known value.
|
||||||
|
|
||||||
|
if config.Endpoint.IsUnknown() {
|
||||||
|
resp.Diagnostics.AddAttributeError(
|
||||||
|
path.Root("endpoint"),
|
||||||
|
"Unknown Proxmox VE API Endpoint",
|
||||||
|
"The provider cannot create the Proxmox VE API client as there is an unknown configuration value "+
|
||||||
|
"for the API endpoint. Either target apply the source of the value first, set the value statically in "+
|
||||||
|
"the configuration, or use the PROXMOX_VE_ENDPOINT environment variable.",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default values to environment variables, but override
|
||||||
|
// with Terraform configuration value if set.
|
||||||
|
|
||||||
|
// Check environment variables
|
||||||
|
apiToken := utils.GetAnyStringEnv("PROXMOX_VE_API_TOKEN")
|
||||||
|
endpoint := utils.GetAnyStringEnv("PROXMOX_VE_ENDPOINT")
|
||||||
|
insecure := utils.GetAnyBoolEnv("PROXMOX_VE_INSECURE")
|
||||||
|
username := utils.GetAnyStringEnv("PROXMOX_VE_USERNAME")
|
||||||
|
password := utils.GetAnyStringEnv("PROXMOX_VE_PASSWORD")
|
||||||
|
|
||||||
|
if !config.APIToken.IsNull() {
|
||||||
|
apiToken = config.APIToken.ValueString()
|
||||||
|
}
|
||||||
|
|
||||||
|
if !config.Endpoint.IsNull() {
|
||||||
|
endpoint = config.Endpoint.ValueString()
|
||||||
|
}
|
||||||
|
|
||||||
|
if !config.Insecure.IsNull() {
|
||||||
|
insecure = config.Insecure.ValueBool()
|
||||||
|
}
|
||||||
|
|
||||||
|
if !config.Username.IsNull() {
|
||||||
|
username = config.Username.ValueString()
|
||||||
|
}
|
||||||
|
|
||||||
|
if !config.Password.IsNull() {
|
||||||
|
password = config.Password.ValueString()
|
||||||
|
}
|
||||||
|
|
||||||
|
if endpoint == "" {
|
||||||
|
resp.Diagnostics.AddAttributeError(
|
||||||
|
path.Root("endpoint"),
|
||||||
|
"Missing Proxmox VE API Endpoint",
|
||||||
|
"The provider cannot create the Proxmox VE API client as there is a missing or empty value for the API endpoint. "+
|
||||||
|
"Set the host value in the configuration or use the PROXMOX_VE_ENDPOINT environment variable. "+
|
||||||
|
"If either is already set, ensure the value is not empty.",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the Proxmox VE API client
|
||||||
|
|
||||||
|
creds, err := api.NewCredentials(username, password, "", apiToken)
|
||||||
|
if err != nil {
|
||||||
|
resp.Diagnostics.AddError(
|
||||||
|
"Unable to create Proxmox VE API credentials",
|
||||||
|
err.Error(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
conn, err := api.NewConnection(
|
||||||
|
endpoint,
|
||||||
|
insecure,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
resp.Diagnostics.AddError(
|
||||||
|
"Unable to create Proxmox VE API connection",
|
||||||
|
err.Error(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
apiClient, err := api.NewClient(creds, conn)
|
||||||
|
if err != nil {
|
||||||
|
resp.Diagnostics.AddError(
|
||||||
|
"Unable to create Proxmox VE API client",
|
||||||
|
err.Error(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
sshUsername := utils.GetAnyStringEnv("PROXMOX_VE_SSH_USERNAME")
|
||||||
|
sshPassword := utils.GetAnyStringEnv("PROXMOX_VE_SSH_PASSWORD")
|
||||||
|
sshAgent := utils.GetAnyBoolEnv("PROXMOX_VE_SSH_AGENT")
|
||||||
|
sshAgentSocket := utils.GetAnyStringEnv("SSH_AUTH_SOCK", "PROXMOX_VE_SSH_AUTH_SOCK")
|
||||||
|
nodeOverrides := map[string]string{}
|
||||||
|
|
||||||
|
if len(config.SSH) > 0 {
|
||||||
|
if !config.SSH[0].Username.IsNull() {
|
||||||
|
sshUsername = config.SSH[0].Username.ValueString()
|
||||||
|
}
|
||||||
|
|
||||||
|
if !config.SSH[0].Password.IsNull() {
|
||||||
|
sshPassword = config.SSH[0].Password.ValueString()
|
||||||
|
}
|
||||||
|
|
||||||
|
if !config.SSH[0].Agent.IsNull() {
|
||||||
|
sshAgent = config.SSH[0].Agent.ValueBool()
|
||||||
|
}
|
||||||
|
|
||||||
|
if !config.SSH[0].AgentSocket.IsNull() {
|
||||||
|
sshAgentSocket = config.SSH[0].AgentSocket.ValueString()
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, n := range config.SSH[0].Nodes {
|
||||||
|
nodeOverrides[n.Name.ValueString()] = n.Address.ValueString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if sshUsername == "" {
|
||||||
|
sshUsername = strings.Split(creds.Username, "@")[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
if sshPassword == "" {
|
||||||
|
sshPassword = creds.Password
|
||||||
|
}
|
||||||
|
|
||||||
|
sshClient, err := ssh.NewClient(
|
||||||
|
sshUsername, sshPassword, sshAgent, sshAgentSocket,
|
||||||
|
&apiResolverWithOverrides{
|
||||||
|
ar: apiResolver{c: apiClient},
|
||||||
|
overrides: nodeOverrides,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
resp.Diagnostics.AddError(
|
||||||
|
"Unable to create Proxmox VE SSH client",
|
||||||
|
err.Error(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
client := proxmox.NewClient(apiClient, sshClient)
|
||||||
|
|
||||||
|
resp.ResourceData = client
|
||||||
|
resp.DataSourceData = client
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *proxmoxProvider) Resources(_ context.Context) []func() resource.Resource {
|
||||||
|
return []func() resource.Resource{
|
||||||
|
network.NewLinuxBridgeResource,
|
||||||
|
network.NewLinuxVLANResource,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *proxmoxProvider) DataSources(_ context.Context) []func() datasource.DataSource {
|
||||||
|
return []func() datasource.DataSource{}
|
||||||
|
}
|
||||||
|
|
||||||
|
type apiResolver struct {
|
||||||
|
c api.Client
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *apiResolver) Resolve(ctx context.Context, nodeName string) (string, error) {
|
||||||
|
nc := &nodes.Client{Client: r.c, NodeName: nodeName}
|
||||||
|
|
||||||
|
networkDevices, err := nc.ListNetworkInterfaces(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("failed to list network devices of node \"%s\": %w", nc.NodeName, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
nodeAddress := ""
|
||||||
|
|
||||||
|
for _, d := range networkDevices {
|
||||||
|
if d.Address != nil {
|
||||||
|
nodeAddress = *d.Address
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if nodeAddress == "" {
|
||||||
|
return "", fmt.Errorf("failed to determine the IP address of node \"%s\"", nc.NodeName)
|
||||||
|
}
|
||||||
|
|
||||||
|
nodeAddressParts := strings.Split(nodeAddress, "/")
|
||||||
|
|
||||||
|
return nodeAddressParts[0], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type apiResolverWithOverrides struct {
|
||||||
|
ar apiResolver
|
||||||
|
overrides map[string]string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *apiResolverWithOverrides) Resolve(ctx context.Context, nodeName string) (string, error) {
|
||||||
|
if ip, ok := r.overrides[nodeName]; ok {
|
||||||
|
return ip, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return r.ar.Resolve(ctx, nodeName)
|
||||||
|
}
|
41
internal/test/provider_test.go
Normal file
41
internal/test/provider_test.go
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/providerserver"
|
||||||
|
"github.com/hashicorp/terraform-plugin-go/tfprotov6"
|
||||||
|
|
||||||
|
"github.com/bpg/terraform-provider-proxmox/internal/provider"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// ProviderConfig is a shared configuration to combine with the actual
|
||||||
|
// test configuration so the Proxmox VE client is properly configured.
|
||||||
|
// It is also possible to use the PROXMOX_VE_ environment variables instead,.
|
||||||
|
ProviderConfig = `
|
||||||
|
provider "proxmox" {
|
||||||
|
username = "root@pam"
|
||||||
|
password = "password"
|
||||||
|
insecure = true
|
||||||
|
ssh {
|
||||||
|
agent = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
// such as updating the Makefile and running the testing through that tool.
|
||||||
|
)
|
||||||
|
|
||||||
|
// AccTestProtoV6ProviderFactories are used to instantiate a provider during
|
||||||
|
// acceptance testing. The factory function will be invoked for every Terraform
|
||||||
|
// CLI command executed to create a provider server to which the CLI can
|
||||||
|
// reattach.
|
||||||
|
//
|
||||||
|
//nolint:gochecknoglobals
|
||||||
|
var AccTestProtoV6ProviderFactories = map[string]func() (tfprotov6.ProviderServer, error){
|
||||||
|
"proxmox": providerserver.NewProtocol6WithError(provider.New("test")()),
|
||||||
|
}
|
74
internal/test/resource_linux_bridge_test.go
Normal file
74
internal/test/resource_linux_bridge_test.go
Normal file
@ -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 test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_LinuxBridgeResource(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
resourceName := "proxmox_virtual_environment_network_linux_bridge.test"
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
ProtoV6ProviderFactories: AccTestProtoV6ProviderFactories,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
// Create and Read testing
|
||||||
|
{
|
||||||
|
Config: ProviderConfig + `
|
||||||
|
resource "proxmox_virtual_environment_network_linux_bridge" "test" {
|
||||||
|
node_name = "pve"
|
||||||
|
name = "vmbr99"
|
||||||
|
address = "3.3.3.3/24"
|
||||||
|
comment = "created by terraform"
|
||||||
|
mtu = 1499
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
Check: resource.ComposeAggregateTestCheckFunc(
|
||||||
|
resource.TestCheckResourceAttr(resourceName, "name", "vmbr99"),
|
||||||
|
resource.TestCheckResourceAttr(resourceName, "address", "3.3.3.3/24"),
|
||||||
|
resource.TestCheckResourceAttr(resourceName, "comment", "created by terraform"),
|
||||||
|
resource.TestCheckResourceAttr(resourceName, "vlan_aware", "true"),
|
||||||
|
resource.TestCheckResourceAttr(resourceName, "mtu", "1499"),
|
||||||
|
resource.TestCheckResourceAttrSet(resourceName, "id"),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
// ImportState testing
|
||||||
|
{
|
||||||
|
ResourceName: resourceName,
|
||||||
|
ImportState: true,
|
||||||
|
ImportStateVerify: true,
|
||||||
|
},
|
||||||
|
// Update testing
|
||||||
|
{
|
||||||
|
Config: ProviderConfig + `
|
||||||
|
resource "proxmox_virtual_environment_network_linux_bridge" "test" {
|
||||||
|
node_name = "pve"
|
||||||
|
name = "vmbr99"
|
||||||
|
address = "1.1.1.1/24"
|
||||||
|
address6 = "FE80:0000:0000:0000:0202:B3FF:FE1E:8329/64"
|
||||||
|
comment = "updated by terraform"
|
||||||
|
vlan_aware = false
|
||||||
|
mtu = null
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
Check: resource.ComposeAggregateTestCheckFunc(
|
||||||
|
resource.TestCheckResourceAttr(resourceName, "name", "vmbr99"),
|
||||||
|
resource.TestCheckResourceAttr(resourceName, "address", "1.1.1.1/24"),
|
||||||
|
resource.TestCheckResourceAttr(resourceName, "address6", "FE80:0000:0000:0000:0202:B3FF:FE1E:8329/64"),
|
||||||
|
resource.TestCheckResourceAttr(resourceName, "comment", "updated by terraform"),
|
||||||
|
resource.TestCheckResourceAttr(resourceName, "vlan_aware", "false"),
|
||||||
|
resource.TestCheckNoResourceAttr(resourceName, "mtu"),
|
||||||
|
resource.TestCheckResourceAttrSet(resourceName, "id"),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
72
internal/test/resource_linux_vlan_test.go
Normal file
72
internal/test/resource_linux_vlan_test.go
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* 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/resource"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_LinuxVLANResource(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
resourceName := "proxmox_virtual_environment_network_linux_vlan.test"
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
ProtoV6ProviderFactories: AccTestProtoV6ProviderFactories,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
// Create and Read testing
|
||||||
|
{
|
||||||
|
Config: ProviderConfig + `
|
||||||
|
resource "proxmox_virtual_environment_network_linux_vlan" "test" {
|
||||||
|
node_name = "pve"
|
||||||
|
name = "ens18.33"
|
||||||
|
comment = "created by terraform"
|
||||||
|
mtu = 1499
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
Check: resource.ComposeAggregateTestCheckFunc(
|
||||||
|
resource.TestCheckResourceAttr(resourceName, "name", "ens18.33"),
|
||||||
|
resource.TestCheckResourceAttr(resourceName, "comment", "created by terraform"),
|
||||||
|
resource.TestCheckResourceAttr(resourceName, "vlan", "33"),
|
||||||
|
resource.TestCheckResourceAttr(resourceName, "interface", "ens18"),
|
||||||
|
resource.TestCheckResourceAttrSet(resourceName, "id"),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
// ImportState testing
|
||||||
|
{
|
||||||
|
ResourceName: resourceName,
|
||||||
|
ImportState: true,
|
||||||
|
ImportStateVerify: true,
|
||||||
|
},
|
||||||
|
// Update testing
|
||||||
|
{
|
||||||
|
Config: ProviderConfig + `
|
||||||
|
resource "proxmox_virtual_environment_network_linux_vlan" "test" {
|
||||||
|
node_name = "pve"
|
||||||
|
name = "ens18.33"
|
||||||
|
address = "1.1.1.1/24"
|
||||||
|
address6 = "FE80:0000:0000:0000:0202:B3FF:FE1E:8329/64"
|
||||||
|
comment = "updated by terraform"
|
||||||
|
mtu = null
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
Check: resource.ComposeAggregateTestCheckFunc(
|
||||||
|
resource.TestCheckResourceAttr(resourceName, "name", "ens18.33"),
|
||||||
|
resource.TestCheckResourceAttr(resourceName, "address", "1.1.1.1/24"),
|
||||||
|
resource.TestCheckResourceAttr(resourceName, "address6", "FE80:0000:0000:0000:0202:B3FF:FE1E:8329/64"),
|
||||||
|
resource.TestCheckResourceAttr(resourceName, "comment", "updated by terraform"),
|
||||||
|
resource.TestCheckResourceAttr(resourceName, "vlan", "33"),
|
||||||
|
resource.TestCheckResourceAttr(resourceName, "interface", "ens18"),
|
||||||
|
resource.TestCheckNoResourceAttr(resourceName, "mtu"),
|
||||||
|
resource.TestCheckResourceAttrSet(resourceName, "id"),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
@ -53,6 +53,16 @@ func (r *CustomBool) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Pointer returns a pointers.
|
||||||
|
func (r CustomBool) Pointer() *CustomBool {
|
||||||
|
return &r
|
||||||
|
}
|
||||||
|
|
||||||
|
// PointerBool returns a pointer to a boolean.
|
||||||
|
func (r *CustomBool) PointerBool() *bool {
|
||||||
|
return (*bool)(r)
|
||||||
|
}
|
||||||
|
|
||||||
// MarshalJSON converts a boolean to a JSON value.
|
// MarshalJSON converts a boolean to a JSON value.
|
||||||
func (r *CustomCommaSeparatedList) MarshalJSON() ([]byte, error) {
|
func (r *CustomCommaSeparatedList) MarshalJSON() ([]byte, error) {
|
||||||
s := strings.Join(*r, ",")
|
s := strings.Join(*r, ",")
|
118
internal/types/ip_addr.go
Normal file
118
internal/types/ip_addr.go
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
/*
|
||||||
|
* 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 types
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/attr"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/diag"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/path"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
|
||||||
|
"github.com/hashicorp/terraform-plugin-go/tftypes"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Ensure the implementation satisfies the expected interfaces.
|
||||||
|
var _ basetypes.StringTypable = IPAddrType{}
|
||||||
|
|
||||||
|
// IPAddrType is a type that represents an IP address.
|
||||||
|
type IPAddrType struct {
|
||||||
|
basetypes.StringType
|
||||||
|
}
|
||||||
|
|
||||||
|
// Equal returns true if the two types are equal.
|
||||||
|
func (t IPAddrType) Equal(o attr.Type) bool {
|
||||||
|
other, ok := o.(IPAddrType)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return t.StringType.Equal(other.StringType)
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns a string representation of the type.
|
||||||
|
func (t IPAddrType) String() string {
|
||||||
|
return "IPAddrType"
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValueFromString converts a string value to a StringValuable.
|
||||||
|
func (t IPAddrType) ValueFromString(
|
||||||
|
_ context.Context, in basetypes.StringValue,
|
||||||
|
) (basetypes.StringValuable, diag.Diagnostics) {
|
||||||
|
value := IPAddrValue{
|
||||||
|
StringValue: in,
|
||||||
|
}
|
||||||
|
|
||||||
|
return value, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValueFromTerraform converts a Terraform value to a StringValuable.
|
||||||
|
func (t IPAddrType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) {
|
||||||
|
attrValue, err := t.StringType.ValueFromTerraform(ctx, in)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("unexpected error converting Terraform value to StringValue: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
stringValue, ok := attrValue.(basetypes.StringValue)
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("unexpected value type of %T", attrValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
stringValuable, diags := t.ValueFromString(ctx, stringValue)
|
||||||
|
if diags.HasError() {
|
||||||
|
return nil, fmt.Errorf("unexpected error converting StringValue to StringValuable: %v", diags)
|
||||||
|
}
|
||||||
|
|
||||||
|
return stringValuable, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValueType returns the underlying value type.
|
||||||
|
func (t IPAddrType) ValueType(_ context.Context) attr.Value {
|
||||||
|
return IPAddrValue{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate ensures the value is valid IP address.
|
||||||
|
func (t IPAddrType) Validate(_ context.Context, value tftypes.Value, valuePath path.Path) diag.Diagnostics {
|
||||||
|
if value.IsNull() || !value.IsKnown() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var diags diag.Diagnostics
|
||||||
|
|
||||||
|
var valueString string
|
||||||
|
|
||||||
|
if err := value.As(&valueString); err != nil {
|
||||||
|
diags.AddAttributeError(
|
||||||
|
valuePath,
|
||||||
|
"Invalid Terraform Value",
|
||||||
|
"An unexpected error occurred while attempting to convert a Terraform value to a string. "+
|
||||||
|
"This generally is an issue with the provider schema implementation. "+
|
||||||
|
"Please contact the provider developers.\n\n"+
|
||||||
|
"Path: "+valuePath.String()+"\n"+
|
||||||
|
"Error: "+err.Error(),
|
||||||
|
)
|
||||||
|
|
||||||
|
return diags
|
||||||
|
}
|
||||||
|
|
||||||
|
if ip := net.ParseIP(valueString); ip == nil {
|
||||||
|
diags.AddAttributeError(
|
||||||
|
valuePath,
|
||||||
|
"Invalid IP String Value",
|
||||||
|
"An unexpected error occurred while converting a string value that was expected to be IPv4/IPv6.\n\n"+
|
||||||
|
"Path: "+valuePath.String()+"\n"+
|
||||||
|
"Given Value: "+valueString,
|
||||||
|
)
|
||||||
|
|
||||||
|
return diags
|
||||||
|
}
|
||||||
|
|
||||||
|
return diags
|
||||||
|
}
|
122
internal/types/ip_addr_test.go
Normal file
122
internal/types/ip_addr_test.go
Normal file
@ -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 types
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/path"
|
||||||
|
"github.com/hashicorp/terraform-plugin-go/tftypes"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_IPAddrTypeValueFromTerraform(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
tests := map[string]struct {
|
||||||
|
val tftypes.Value
|
||||||
|
expected func(val IPAddrValue) bool
|
||||||
|
expectError bool
|
||||||
|
}{
|
||||||
|
"null value": {
|
||||||
|
val: tftypes.NewValue(tftypes.String, nil),
|
||||||
|
expected: func(val IPAddrValue) bool {
|
||||||
|
return val.IsNull()
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"unknown value": {
|
||||||
|
val: tftypes.NewValue(tftypes.String, tftypes.UnknownValue),
|
||||||
|
expected: func(val IPAddrValue) bool {
|
||||||
|
return val.IsUnknown()
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"valid IPv4": {
|
||||||
|
val: tftypes.NewValue(tftypes.String, "1.2.3.4"),
|
||||||
|
expected: func(val IPAddrValue) bool {
|
||||||
|
return val.ValueString() == "1.2.3.4"
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"valid IPv6": {
|
||||||
|
val: tftypes.NewValue(tftypes.String, "2001:0db8:85a3:0000:0000:8a2e:0370:7334"),
|
||||||
|
expected: func(val IPAddrValue) bool {
|
||||||
|
return val.ValueString() == "2001:0db8:85a3:0000:0000:8a2e:0370:7334"
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for name, test := range tests {
|
||||||
|
name, test := name, test
|
||||||
|
t.Run(name, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
ctx := context.TODO()
|
||||||
|
val, err := IPAddrType{}.ValueFromTerraform(ctx, test.val)
|
||||||
|
|
||||||
|
if err == nil && test.expectError {
|
||||||
|
t.Fatal("expected error, got no error")
|
||||||
|
}
|
||||||
|
if err != nil && !test.expectError {
|
||||||
|
t.Fatalf("got unexpected error: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !test.expected(val.(IPAddrValue)) {
|
||||||
|
t.Errorf("unexpected result")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_IPAddrTypeValidate(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
type testCase struct {
|
||||||
|
val tftypes.Value
|
||||||
|
expectError bool
|
||||||
|
}
|
||||||
|
|
||||||
|
tests := map[string]testCase{
|
||||||
|
"not a string": {
|
||||||
|
val: tftypes.NewValue(tftypes.Bool, true),
|
||||||
|
expectError: true,
|
||||||
|
},
|
||||||
|
"unknown string": {
|
||||||
|
val: tftypes.NewValue(tftypes.String, tftypes.UnknownValue),
|
||||||
|
},
|
||||||
|
"null string": {
|
||||||
|
val: tftypes.NewValue(tftypes.String, nil),
|
||||||
|
},
|
||||||
|
"valid IPv4 string": {
|
||||||
|
val: tftypes.NewValue(tftypes.String, "1.2.3.4"),
|
||||||
|
},
|
||||||
|
"valid IPv6 string": {
|
||||||
|
val: tftypes.NewValue(tftypes.String, "2001:0db8:85a3:0000:0000:8a2e:0370:7334"),
|
||||||
|
},
|
||||||
|
"invalid string": {
|
||||||
|
val: tftypes.NewValue(tftypes.String, "not ok"),
|
||||||
|
expectError: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for name, test := range tests {
|
||||||
|
name, test := name, test
|
||||||
|
t.Run(name, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
ctx := context.TODO()
|
||||||
|
|
||||||
|
diags := IPAddrType{}.Validate(ctx, test.val, path.Root("test"))
|
||||||
|
|
||||||
|
if !diags.HasError() && test.expectError {
|
||||||
|
t.Fatal("expected error, got no error")
|
||||||
|
}
|
||||||
|
|
||||||
|
if diags.HasError() && !test.expectError {
|
||||||
|
t.Fatalf("got unexpected error: %s", diags)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
46
internal/types/ip_addr_value.go
Normal file
46
internal/types/ip_addr_value.go
Normal file
@ -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 types
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/attr"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Ensure the implementation satisfies the expected interfaces.
|
||||||
|
var _ basetypes.StringValuable = IPAddrValue{}
|
||||||
|
|
||||||
|
// IPAddrValue is a type that represents an IP address value.
|
||||||
|
type IPAddrValue struct {
|
||||||
|
basetypes.StringValue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Equal returns true if the two values are equal.
|
||||||
|
func (v IPAddrValue) Equal(o attr.Value) bool {
|
||||||
|
other, ok := o.(IPAddrValue)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return v.StringValue.Equal(other.StringValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type returns the type of the value.
|
||||||
|
func (v IPAddrValue) Type(_ context.Context) attr.Type {
|
||||||
|
return IPAddrType{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewIPAddrPointerValue returns a new IPAddrValue from a string pointer.
|
||||||
|
func NewIPAddrPointerValue(value *string) IPAddrValue {
|
||||||
|
return IPAddrValue{
|
||||||
|
StringValue: types.StringPointerValue(value),
|
||||||
|
}
|
||||||
|
}
|
119
internal/types/ip_cidr.go
Normal file
119
internal/types/ip_cidr.go
Normal file
@ -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 types
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/attr"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/diag"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/path"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
|
||||||
|
"github.com/hashicorp/terraform-plugin-go/tftypes"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Ensure the implementation satisfies the expected interfaces.
|
||||||
|
var _ basetypes.StringTypable = IPCIDRType{}
|
||||||
|
|
||||||
|
// IPCIDRType is a type that represents an IP address in CIDR notation.
|
||||||
|
type IPCIDRType struct {
|
||||||
|
basetypes.StringType
|
||||||
|
}
|
||||||
|
|
||||||
|
// Equal returns true if the two types are equal.
|
||||||
|
func (t IPCIDRType) Equal(o attr.Type) bool {
|
||||||
|
other, ok := o.(IPCIDRType)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return t.StringType.Equal(other.StringType)
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns a string representation of the type.
|
||||||
|
func (t IPCIDRType) String() string {
|
||||||
|
return "IPCIDRType"
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValueFromString converts a string value to a StringValuable.
|
||||||
|
func (t IPCIDRType) ValueFromString(
|
||||||
|
_ context.Context, in basetypes.StringValue,
|
||||||
|
) (basetypes.StringValuable, diag.Diagnostics) {
|
||||||
|
value := IPCIDRValue{
|
||||||
|
StringValue: in,
|
||||||
|
}
|
||||||
|
|
||||||
|
return value, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValueFromTerraform converts a Terraform value to a StringValuable.
|
||||||
|
func (t IPCIDRType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) {
|
||||||
|
attrValue, err := t.StringType.ValueFromTerraform(ctx, in)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("unexpected error converting Terraform value to StringValue: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
stringValue, ok := attrValue.(basetypes.StringValue)
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("unexpected value type of %T", attrValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
stringValuable, diags := t.ValueFromString(ctx, stringValue)
|
||||||
|
if diags.HasError() {
|
||||||
|
return nil, fmt.Errorf("unexpected error converting StringValue to StringValuable: %v", diags)
|
||||||
|
}
|
||||||
|
|
||||||
|
return stringValuable, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValueType returns the underlying value type.
|
||||||
|
func (t IPCIDRType) ValueType(_ context.Context) attr.Value {
|
||||||
|
return IPCIDRValue{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate ensures the value is valid IP address in CIDR notation.
|
||||||
|
func (t IPCIDRType) Validate(_ context.Context, value tftypes.Value, valuePath path.Path) diag.Diagnostics {
|
||||||
|
if value.IsNull() || !value.IsKnown() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var diags diag.Diagnostics
|
||||||
|
|
||||||
|
var valueString string
|
||||||
|
|
||||||
|
if err := value.As(&valueString); err != nil {
|
||||||
|
diags.AddAttributeError(
|
||||||
|
valuePath,
|
||||||
|
"Invalid Terraform Value",
|
||||||
|
"An unexpected error occurred while attempting to convert a Terraform value to a string. "+
|
||||||
|
"This generally is an issue with the provider schema implementation. "+
|
||||||
|
"Please contact the provider developers.\n\n"+
|
||||||
|
"Path: "+valuePath.String()+"\n"+
|
||||||
|
"Error: "+err.Error(),
|
||||||
|
)
|
||||||
|
|
||||||
|
return diags
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, _, err := net.ParseCIDR(valueString); err != nil {
|
||||||
|
diags.AddAttributeError(
|
||||||
|
valuePath,
|
||||||
|
"Invalid IP/CIDR String Value",
|
||||||
|
"An unexpected error occurred while converting a string value that was expected to be IP/CIDR.\n\n"+
|
||||||
|
"Path: "+valuePath.String()+"\n"+
|
||||||
|
"Given Value: "+valueString+"\n"+
|
||||||
|
"Error: "+err.Error(),
|
||||||
|
)
|
||||||
|
|
||||||
|
return diags
|
||||||
|
}
|
||||||
|
|
||||||
|
return diags
|
||||||
|
}
|
130
internal/types/ip_cidr_test.go
Normal file
130
internal/types/ip_cidr_test.go
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
/*
|
||||||
|
* 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 types
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/path"
|
||||||
|
"github.com/hashicorp/terraform-plugin-go/tftypes"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_IPCIDRTypeValueFromTerraform(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
tests := map[string]struct {
|
||||||
|
val tftypes.Value
|
||||||
|
expected func(val IPCIDRValue) bool
|
||||||
|
expectError bool
|
||||||
|
}{
|
||||||
|
"null value": {
|
||||||
|
val: tftypes.NewValue(tftypes.String, nil),
|
||||||
|
expected: func(val IPCIDRValue) bool {
|
||||||
|
return val.IsNull()
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"unknown value": {
|
||||||
|
val: tftypes.NewValue(tftypes.String, tftypes.UnknownValue),
|
||||||
|
expected: func(val IPCIDRValue) bool {
|
||||||
|
return val.IsUnknown()
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"valid IPv4/CIDR": {
|
||||||
|
val: tftypes.NewValue(tftypes.String, "1.2.3.4/32"),
|
||||||
|
expected: func(val IPCIDRValue) bool {
|
||||||
|
return val.ValueString() == "1.2.3.4/32"
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"valid IPv6/CIDR": {
|
||||||
|
val: tftypes.NewValue(tftypes.String, "2001:db8::/32"),
|
||||||
|
expected: func(val IPCIDRValue) bool {
|
||||||
|
return val.ValueString() == "2001:db8::/32"
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for name, test := range tests {
|
||||||
|
name, test := name, test
|
||||||
|
t.Run(name, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
ctx := context.TODO()
|
||||||
|
val, err := IPCIDRType{}.ValueFromTerraform(ctx, test.val)
|
||||||
|
|
||||||
|
if err == nil && test.expectError {
|
||||||
|
t.Fatal("expected error, got no error")
|
||||||
|
}
|
||||||
|
if err != nil && !test.expectError {
|
||||||
|
t.Fatalf("got unexpected error: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !test.expected(val.(IPCIDRValue)) {
|
||||||
|
t.Errorf("unexpected result")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_IPCIDRTypeValidate(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
type testCase struct {
|
||||||
|
val tftypes.Value
|
||||||
|
expectError bool
|
||||||
|
}
|
||||||
|
|
||||||
|
tests := map[string]testCase{
|
||||||
|
"not a string": {
|
||||||
|
val: tftypes.NewValue(tftypes.Bool, true),
|
||||||
|
expectError: true,
|
||||||
|
},
|
||||||
|
"unknown string": {
|
||||||
|
val: tftypes.NewValue(tftypes.String, tftypes.UnknownValue),
|
||||||
|
},
|
||||||
|
"null string": {
|
||||||
|
val: tftypes.NewValue(tftypes.String, nil),
|
||||||
|
},
|
||||||
|
"valid IPv4 string": {
|
||||||
|
val: tftypes.NewValue(tftypes.String, "1.2.3.4/32"),
|
||||||
|
},
|
||||||
|
"valid IPv6 string": {
|
||||||
|
val: tftypes.NewValue(tftypes.String, "2001:db8::/32"),
|
||||||
|
},
|
||||||
|
"invalid string": {
|
||||||
|
val: tftypes.NewValue(tftypes.String, "not ok"),
|
||||||
|
expectError: true,
|
||||||
|
},
|
||||||
|
"invalid IPv4 string no CIDR": {
|
||||||
|
val: tftypes.NewValue(tftypes.String, "1.2.3.4"),
|
||||||
|
expectError: true,
|
||||||
|
},
|
||||||
|
"invalid IPv6 string no CIDR": {
|
||||||
|
val: tftypes.NewValue(tftypes.String, "2001:db8::"),
|
||||||
|
expectError: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for name, test := range tests {
|
||||||
|
name, test := name, test
|
||||||
|
t.Run(name, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
ctx := context.TODO()
|
||||||
|
|
||||||
|
diags := IPCIDRType{}.Validate(ctx, test.val, path.Root("test"))
|
||||||
|
|
||||||
|
if !diags.HasError() && test.expectError {
|
||||||
|
t.Fatal("expected error, got no error")
|
||||||
|
}
|
||||||
|
|
||||||
|
if diags.HasError() && !test.expectError {
|
||||||
|
t.Fatalf("got unexpected error: %s", diags)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
46
internal/types/ip_cidr_value.go
Normal file
46
internal/types/ip_cidr_value.go
Normal file
@ -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 types
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/attr"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Ensure the implementation satisfies the expected interfaces.
|
||||||
|
var _ basetypes.StringValuable = IPCIDRValue{}
|
||||||
|
|
||||||
|
// IPCIDRValue is a type that represents an IP address in CIDR notation.
|
||||||
|
type IPCIDRValue struct {
|
||||||
|
basetypes.StringValue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Equal returns true if the two values are equal.
|
||||||
|
func (v IPCIDRValue) Equal(o attr.Value) bool {
|
||||||
|
other, ok := o.(IPCIDRValue)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return v.StringValue.Equal(other.StringValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type returns the type of the value.
|
||||||
|
func (v IPCIDRValue) Type(_ context.Context) attr.Type {
|
||||||
|
return IPCIDRType{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewIPCIDRPointerValue returns a new IPCIDRValue from a string pointer.
|
||||||
|
func NewIPCIDRPointerValue(value *string) IPCIDRValue {
|
||||||
|
return IPCIDRValue{
|
||||||
|
StringValue: types.StringPointerValue(value),
|
||||||
|
}
|
||||||
|
}
|
67
main.go
67
main.go
@ -1,31 +1,80 @@
|
|||||||
/* 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
|
* 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 main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"flag"
|
"flag"
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/providerserver"
|
||||||
|
"github.com/hashicorp/terraform-plugin-go/tfprotov5"
|
||||||
|
"github.com/hashicorp/terraform-plugin-go/tfprotov6"
|
||||||
|
"github.com/hashicorp/terraform-plugin-go/tfprotov6/tf6server"
|
||||||
|
"github.com/hashicorp/terraform-plugin-mux/tf5to6server"
|
||||||
|
"github.com/hashicorp/terraform-plugin-mux/tf6muxserver"
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/v2/plugin"
|
|
||||||
|
|
||||||
|
newProvider "github.com/bpg/terraform-provider-proxmox/internal/provider"
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmoxtf/provider"
|
"github.com/bpg/terraform-provider-proxmox/proxmoxtf/provider"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// If you do not have terraform installed, you can remove the formatting command, but it's suggested to
|
||||||
|
// ensure the documentation is formatted properly.
|
||||||
|
//go:generate terraform fmt -recursive ./example/
|
||||||
|
|
||||||
|
// Run the docs generation tool, check its repository for more information on how it works and how docs
|
||||||
|
// can be customized.
|
||||||
|
//go:generate go run -modfile=tools/go.mod github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
var debug bool
|
var debug bool
|
||||||
|
|
||||||
flag.BoolVar(&debug, "debug", false, "set to true to run the provider with support for debuggers like delve")
|
flag.BoolVar(&debug, "debug", false, "set to true to run the provider with support for debuggers like delve")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
opts := &plugin.ServeOpts{
|
upgradedSdkServer, err := tf5to6server.UpgradeServer(
|
||||||
Debug: debug,
|
ctx,
|
||||||
ProviderAddr: "registry.terraform.io/bpg/proxmox",
|
func() tfprotov5.ProviderServer {
|
||||||
ProviderFunc: func() *schema.Provider {
|
return schema.NewGRPCProviderServer(
|
||||||
return provider.ProxmoxVirtualEnvironment()
|
provider.ProxmoxVirtualEnvironment(),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
providers := []func() tfprotov6.ProviderServer{
|
||||||
|
providerserver.NewProtocol6(newProvider.New("dev")()),
|
||||||
|
func() tfprotov6.ProviderServer {
|
||||||
|
return upgradedSdkServer
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
plugin.Serve(opts)
|
muxServer, err := tf6muxserver.NewMuxServer(ctx, providers...)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var serveOpts []tf6server.ServeOpt
|
||||||
|
|
||||||
|
if debug {
|
||||||
|
serveOpts = append(serveOpts, tf6server.WithManagedDebug())
|
||||||
|
}
|
||||||
|
|
||||||
|
err = tf6server.Serve(
|
||||||
|
"registry.terraform.io/bpg/proxmox",
|
||||||
|
muxServer.ProviderServer,
|
||||||
|
serveOpts...,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,9 @@
|
|||||||
|
|
||||||
package access
|
package access
|
||||||
|
|
||||||
import "github.com/bpg/terraform-provider-proxmox/proxmox/types"
|
import (
|
||||||
|
"github.com/bpg/terraform-provider-proxmox/internal/types"
|
||||||
|
)
|
||||||
|
|
||||||
// ACLGetResponseBody contains the body from an access control list response.
|
// ACLGetResponseBody contains the body from an access control list response.
|
||||||
type ACLGetResponseBody struct {
|
type ACLGetResponseBody struct {
|
||||||
|
@ -13,8 +13,8 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
|
"github.com/bpg/terraform-provider-proxmox/internal/types"
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox/api"
|
"github.com/bpg/terraform-provider-proxmox/proxmox/api"
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox/types"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c *Client) rolesPath() string {
|
func (c *Client) rolesPath() string {
|
||||||
|
@ -6,7 +6,9 @@
|
|||||||
|
|
||||||
package access
|
package access
|
||||||
|
|
||||||
import "github.com/bpg/terraform-provider-proxmox/proxmox/types"
|
import (
|
||||||
|
"github.com/bpg/terraform-provider-proxmox/internal/types"
|
||||||
|
)
|
||||||
|
|
||||||
// RoleCreateRequestBody contains the data for an access group create request.
|
// RoleCreateRequestBody contains the data for an access group create request.
|
||||||
type RoleCreateRequestBody struct {
|
type RoleCreateRequestBody struct {
|
||||||
|
@ -14,8 +14,8 @@ import (
|
|||||||
"sort"
|
"sort"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/bpg/terraform-provider-proxmox/internal/types"
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox/api"
|
"github.com/bpg/terraform-provider-proxmox/proxmox/api"
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox/types"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c *Client) usersPath() string {
|
func (c *Client) usersPath() string {
|
||||||
|
@ -6,7 +6,9 @@
|
|||||||
|
|
||||||
package access
|
package access
|
||||||
|
|
||||||
import "github.com/bpg/terraform-provider-proxmox/proxmox/types"
|
import (
|
||||||
|
"github.com/bpg/terraform-provider-proxmox/internal/types"
|
||||||
|
)
|
||||||
|
|
||||||
// UserChangePasswordRequestBody contains the data for a user password change request.
|
// UserChangePasswordRequestBody contains the data for a user password change request.
|
||||||
type UserChangePasswordRequestBody struct {
|
type UserChangePasswordRequestBody struct {
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -18,5 +19,5 @@ type Authenticator interface {
|
|||||||
IsRoot() bool
|
IsRoot() bool
|
||||||
|
|
||||||
// AuthenticateRequest adds authentication data to a new request.
|
// AuthenticateRequest adds authentication data to a new request.
|
||||||
AuthenticateRequest(req *http.Request) error
|
AuthenticateRequest(ctx context.Context, req *http.Request) error
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/google/go-querystring/query"
|
"github.com/google/go-querystring/query"
|
||||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||||
@ -29,7 +30,9 @@ import (
|
|||||||
var ErrNoDataObjectInResponse = errors.New("the server did not include a data object in the response")
|
var ErrNoDataObjectInResponse = errors.New("the server did not include a data object in the response")
|
||||||
|
|
||||||
const (
|
const (
|
||||||
basePathJSONAPI = "api2/json"
|
// the large timeout is to allow for large file uploads.
|
||||||
|
httpClientTimeout = 5 * time.Minute
|
||||||
|
basePathJSONAPI = "api2/json"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Client is an interface for performing requests against the Proxmox API.
|
// Client is an interface for performing requests against the Proxmox API.
|
||||||
@ -83,8 +86,11 @@ func NewConnection(endpoint string, insecure bool) (*Connection, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return &Connection{
|
return &Connection{
|
||||||
endpoint: strings.TrimRight(u.String(), "/"),
|
endpoint: strings.TrimRight(u.String(), "/"),
|
||||||
httpClient: &http.Client{Transport: transport},
|
httpClient: &http.Client{
|
||||||
|
Transport: transport,
|
||||||
|
Timeout: httpClientTimeout,
|
||||||
|
},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,7 +101,7 @@ type client struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewClient creates and initializes a VirtualEnvironmentClient instance.
|
// NewClient creates and initializes a VirtualEnvironmentClient instance.
|
||||||
func NewClient(ctx context.Context, creds *Credentials, conn *Connection) (Client, error) {
|
func NewClient(creds *Credentials, conn *Connection) (Client, error) {
|
||||||
if creds == nil {
|
if creds == nil {
|
||||||
return nil, errors.New("credentials must not be nil")
|
return nil, errors.New("credentials must not be nil")
|
||||||
}
|
}
|
||||||
@ -111,7 +117,7 @@ func NewClient(ctx context.Context, creds *Credentials, conn *Connection) (Clien
|
|||||||
if creds.APIToken != nil {
|
if creds.APIToken != nil {
|
||||||
auth, err = NewTokenAuthenticator(*creds.APIToken)
|
auth, err = NewTokenAuthenticator(*creds.APIToken)
|
||||||
} else {
|
} else {
|
||||||
auth, err = NewTicketAuthenticator(ctx, conn, creds)
|
auth, err = NewTicketAuthenticator(conn, creds)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -202,7 +208,7 @@ func (c *client) DoRequest(
|
|||||||
req.Header.Add("Content-Type", reqBodyType)
|
req.Header.Add("Content-Type", reqBodyType)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = c.auth.AuthenticateRequest(req)
|
err = c.auth.AuthenticateRequest(ctx, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to authenticate HTTP %s request (path: %s) - Reason: %w",
|
return fmt.Errorf("failed to authenticate HTTP %s request (path: %s) - Reason: %w",
|
||||||
method,
|
method,
|
||||||
@ -228,6 +234,7 @@ func (c *client) DoRequest(
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//nolint:nestif
|
||||||
if responseBody != nil {
|
if responseBody != nil {
|
||||||
err = json.NewDecoder(res.Body).Decode(responseBody)
|
err = json.NewDecoder(res.Body).Decode(responseBody)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -248,14 +255,27 @@ func (c *client) DoRequest(
|
|||||||
err,
|
err,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
tflog.Warn(ctx, "unhandled HTTP response body", map[string]interface{}{
|
if len(data) > 0 {
|
||||||
"data": string(data),
|
dr := dataResponse{}
|
||||||
})
|
|
||||||
|
if err2 := json.NewDecoder(bytes.NewReader(data)).Decode(&dr); err2 == nil {
|
||||||
|
if dr.Data == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tflog.Warn(ctx, "unhandled HTTP response body", map[string]interface{}{
|
||||||
|
"data": dr.Data,
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type dataResponse struct {
|
||||||
|
Data interface{} `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
// ExpandPath expands the given path to an absolute path.
|
// ExpandPath expands the given path to an absolute path.
|
||||||
func (c *client) ExpandPath(path string) string {
|
func (c *client) ExpandPath(path string) string {
|
||||||
return path
|
return path
|
||||||
|
@ -21,12 +21,14 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type ticketAuthenticator struct {
|
type ticketAuthenticator struct {
|
||||||
authenticationData *AuthenticationResponseData
|
conn *Connection
|
||||||
|
authRequest string
|
||||||
|
authData *AuthenticationResponseData
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewTicketAuthenticator returns a new ticket authenticator.
|
// NewTicketAuthenticator returns a new ticket authenticator.
|
||||||
func NewTicketAuthenticator(ctx context.Context, conn *Connection, creds *Credentials) (Authenticator, error) {
|
func NewTicketAuthenticator(conn *Connection, creds *Credentials) (Authenticator, error) {
|
||||||
reqStr := fmt.Sprintf(
|
authRequest := fmt.Sprintf(
|
||||||
"username=%s&password=%s",
|
"username=%s&password=%s",
|
||||||
url.QueryEscape(creds.Username),
|
url.QueryEscape(creds.Username),
|
||||||
url.QueryEscape(creds.Password),
|
url.QueryEscape(creds.Password),
|
||||||
@ -34,14 +36,25 @@ func NewTicketAuthenticator(ctx context.Context, conn *Connection, creds *Creden
|
|||||||
|
|
||||||
// OTP is optional, and probably doesn't make much sense for most provider users.
|
// OTP is optional, and probably doesn't make much sense for most provider users.
|
||||||
if creds.OTP != nil {
|
if creds.OTP != nil {
|
||||||
reqStr = fmt.Sprintf("%s&otp=%s", reqStr, url.QueryEscape(*creds.OTP))
|
authRequest = fmt.Sprintf("%s&otp=%s", authRequest, url.QueryEscape(*creds.OTP))
|
||||||
|
}
|
||||||
|
|
||||||
|
return &ticketAuthenticator{
|
||||||
|
conn: conn,
|
||||||
|
authRequest: authRequest,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *ticketAuthenticator) authenticate(ctx context.Context) (*AuthenticationResponseData, error) {
|
||||||
|
if t.authData != nil {
|
||||||
|
return t.authData, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
req, err := http.NewRequestWithContext(
|
req, err := http.NewRequestWithContext(
|
||||||
ctx,
|
ctx,
|
||||||
http.MethodPost,
|
http.MethodPost,
|
||||||
fmt.Sprintf("%s/%s/access/ticket", conn.endpoint, basePathJSONAPI),
|
fmt.Sprintf("%s/%s/access/ticket", t.conn.endpoint, basePathJSONAPI),
|
||||||
bytes.NewBufferString(reqStr),
|
bytes.NewBufferString(t.authRequest),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to create authentication request: %w", err)
|
return nil, fmt.Errorf("failed to create authentication request: %w", err)
|
||||||
@ -49,12 +62,12 @@ func NewTicketAuthenticator(ctx context.Context, conn *Connection, creds *Creden
|
|||||||
|
|
||||||
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
|
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
|
||||||
|
|
||||||
tflog.Debug(ctx, "sending authentication request", map[string]interface{}{
|
tflog.Debug(ctx, "Sending authentication request", map[string]interface{}{
|
||||||
"path": req.URL.Path,
|
"path": req.URL.Path,
|
||||||
})
|
})
|
||||||
|
|
||||||
//nolint:bodyclose
|
//nolint:bodyclose
|
||||||
res, err := conn.httpClient.Do(req)
|
res, err := t.conn.httpClient.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to retrieve authentication response: %w", err)
|
return nil, fmt.Errorf("failed to retrieve authentication response: %w", err)
|
||||||
}
|
}
|
||||||
@ -91,28 +104,29 @@ func NewTicketAuthenticator(ctx context.Context, conn *Connection, creds *Creden
|
|||||||
return nil, errors.New("the server did not include the username in the authentication response")
|
return nil, errors.New("the server did not include the username in the authentication response")
|
||||||
}
|
}
|
||||||
|
|
||||||
return &ticketAuthenticator{
|
t.authData = resBody.Data
|
||||||
authenticationData: resBody.Data,
|
|
||||||
}, nil
|
return resBody.Data, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *ticketAuthenticator) IsRoot() bool {
|
func (t *ticketAuthenticator) IsRoot() bool {
|
||||||
return t.authenticationData.Username == rootUsername
|
return t.authData != nil && t.authData.Username == rootUsername
|
||||||
}
|
}
|
||||||
|
|
||||||
// AuthenticateRequest adds authentication data to a new request.
|
// AuthenticateRequest adds authentication data to a new request.
|
||||||
func (t *ticketAuthenticator) AuthenticateRequest(req *http.Request) error {
|
func (t *ticketAuthenticator) AuthenticateRequest(ctx context.Context, req *http.Request) error {
|
||||||
if t.authenticationData == nil {
|
a, err := t.authenticate(ctx)
|
||||||
return errors.New("failed to authenticate: no ticket")
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to authenticate: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
req.AddCookie(&http.Cookie{
|
req.AddCookie(&http.Cookie{
|
||||||
Name: "PVEAuthCookie",
|
Name: "PVEAuthCookie",
|
||||||
Value: *t.authenticationData.Ticket,
|
Value: *a.Ticket,
|
||||||
})
|
})
|
||||||
|
|
||||||
if req.Method != http.MethodGet {
|
if req.Method != http.MethodGet {
|
||||||
req.Header.Add("CSRFPreventionToken", *t.authenticationData.CSRFPreventionToken)
|
req.Header.Add("CSRFPreventionToken", *a.CSRFPreventionToken)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -6,7 +6,9 @@
|
|||||||
|
|
||||||
package api
|
package api
|
||||||
|
|
||||||
import "github.com/bpg/terraform-provider-proxmox/proxmox/types"
|
import (
|
||||||
|
"github.com/bpg/terraform-provider-proxmox/internal/types"
|
||||||
|
)
|
||||||
|
|
||||||
// AuthenticationResponseBody contains the body from an authentication response.
|
// AuthenticationResponseBody contains the body from an authentication response.
|
||||||
type AuthenticationResponseBody struct {
|
type AuthenticationResponseBody struct {
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
@ -29,7 +30,7 @@ func (t *tokenAuthenticator) IsRoot() bool {
|
|||||||
return t.username == rootUsername
|
return t.username == rootUsername
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *tokenAuthenticator) AuthenticateRequest(req *http.Request) error {
|
func (t *tokenAuthenticator) AuthenticateRequest(_ context.Context, req *http.Request) error {
|
||||||
req.Header.Set("Authorization", "PVEAPIToken="+t.token)
|
req.Header.Set("Authorization", "PVEAPIToken="+t.token)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,14 @@
|
|||||||
/* 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
|
* 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 cluster
|
package cluster
|
||||||
|
|
||||||
import "github.com/bpg/terraform-provider-proxmox/proxmox/types"
|
import (
|
||||||
|
"github.com/bpg/terraform-provider-proxmox/internal/types"
|
||||||
|
)
|
||||||
|
|
||||||
// NextIDRequestBody contains the data for a cluster next id request.
|
// NextIDRequestBody contains the data for a cluster next id request.
|
||||||
type NextIDRequestBody struct {
|
type NextIDRequestBody struct {
|
||||||
|
@ -13,7 +13,7 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox/types"
|
"github.com/bpg/terraform-provider-proxmox/internal/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
// OptionsPutRequestBody is the request body for the PUT /cluster/firewall/options API call.
|
// OptionsPutRequestBody is the request body for the PUT /cluster/firewall/options API call.
|
||||||
|
@ -6,7 +6,9 @@
|
|||||||
|
|
||||||
package firewall
|
package firewall
|
||||||
|
|
||||||
import "github.com/bpg/terraform-provider-proxmox/proxmox/types"
|
import (
|
||||||
|
"github.com/bpg/terraform-provider-proxmox/internal/types"
|
||||||
|
)
|
||||||
|
|
||||||
// IPSetListResponseBody contains the data from an IPSet get response.
|
// IPSetListResponseBody contains the data from an IPSet get response.
|
||||||
type IPSetListResponseBody struct {
|
type IPSetListResponseBody struct {
|
||||||
|
@ -6,7 +6,9 @@
|
|||||||
|
|
||||||
package firewall
|
package firewall
|
||||||
|
|
||||||
import "github.com/bpg/terraform-provider-proxmox/proxmox/types"
|
import (
|
||||||
|
"github.com/bpg/terraform-provider-proxmox/internal/types"
|
||||||
|
)
|
||||||
|
|
||||||
// OptionsPutRequestBody is the request body for the PUT /cluster/firewall/options API call.
|
// OptionsPutRequestBody is the request body for the PUT /cluster/firewall/options API call.
|
||||||
type OptionsPutRequestBody struct {
|
type OptionsPutRequestBody struct {
|
||||||
|
@ -14,8 +14,8 @@ import (
|
|||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
|
||||||
|
"github.com/bpg/terraform-provider-proxmox/internal/types"
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox/api"
|
"github.com/bpg/terraform-provider-proxmox/proxmox/api"
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox/types"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Rule is an interface for the Proxmox firewall rule API.
|
// Rule is an interface for the Proxmox firewall rule API.
|
||||||
|
@ -26,9 +26,9 @@ type RuleGetResponseData struct {
|
|||||||
BaseRule
|
BaseRule
|
||||||
|
|
||||||
// NOTE: This is `int` in the PVE API docs, but it's actually a string in the response.
|
// NOTE: This is `int` in the PVE API docs, but it's actually a string in the response.
|
||||||
Pos string `json:"pos" url:"pos"`
|
Pos string `json:"pos" url:"pos"`
|
||||||
Action string `json:"action" url:"action"`
|
Action string `json:"action" url:"action"`
|
||||||
Type string `json:"type" url:"type"`
|
Type string `json:"type" url:"type"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// RuleListResponseBody contains the data from a firewall rule get response.
|
// RuleListResponseBody contains the data from a firewall rule get response.
|
||||||
|
@ -6,7 +6,9 @@
|
|||||||
|
|
||||||
package nodes
|
package nodes
|
||||||
|
|
||||||
import "github.com/bpg/terraform-provider-proxmox/proxmox/types"
|
import (
|
||||||
|
"github.com/bpg/terraform-provider-proxmox/internal/types"
|
||||||
|
)
|
||||||
|
|
||||||
// CertificateDeleteRequestBody contains the data for a custom certificate delete request.
|
// CertificateDeleteRequestBody contains the data for a custom certificate delete request.
|
||||||
type CertificateDeleteRequestBody struct {
|
type CertificateDeleteRequestBody struct {
|
||||||
|
@ -12,6 +12,7 @@ import (
|
|||||||
|
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox/api"
|
"github.com/bpg/terraform-provider-proxmox/proxmox/api"
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox/nodes/containers"
|
"github.com/bpg/terraform-provider-proxmox/proxmox/nodes/containers"
|
||||||
|
"github.com/bpg/terraform-provider-proxmox/proxmox/nodes/tasks"
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox/nodes/vms"
|
"github.com/bpg/terraform-provider-proxmox/proxmox/nodes/vms"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -41,3 +42,10 @@ func (c *Client) VM(vmID int) *vms.Client {
|
|||||||
VMID: vmID,
|
VMID: vmID,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tasks returns a client for managing VM tasks.
|
||||||
|
func (c *Client) Tasks() *tasks.Client {
|
||||||
|
return &tasks.Client{
|
||||||
|
Client: c,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -13,26 +13,27 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
types2 "github.com/bpg/terraform-provider-proxmox/internal/types"
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox/types"
|
"github.com/bpg/terraform-provider-proxmox/proxmox/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CloneRequestBody contains the data for an container clone request.
|
// CloneRequestBody contains the data for an container clone request.
|
||||||
type CloneRequestBody struct {
|
type CloneRequestBody struct {
|
||||||
BandwidthLimit *int `json:"bwlimit,omitempty" url:"bwlimit,omitempty"`
|
BandwidthLimit *int `json:"bwlimit,omitempty" url:"bwlimit,omitempty"`
|
||||||
Description *string `json:"description,omitempty" url:"description,omitempty"`
|
Description *string `json:"description,omitempty" url:"description,omitempty"`
|
||||||
FullCopy *types.CustomBool `json:"full,omitempty" url:"full,omitempty,int"`
|
FullCopy *types2.CustomBool `json:"full,omitempty" url:"full,omitempty,int"`
|
||||||
Hostname *string `json:"hostname,omitempty" url:"hostname,omitempty"`
|
Hostname *string `json:"hostname,omitempty" url:"hostname,omitempty"`
|
||||||
PoolID *string `json:"pool,omitempty" url:"pool,omitempty"`
|
PoolID *string `json:"pool,omitempty" url:"pool,omitempty"`
|
||||||
SnapshotName *string `json:"snapname,omitempty" url:"snapname,omitempty"`
|
SnapshotName *string `json:"snapname,omitempty" url:"snapname,omitempty"`
|
||||||
TargetNodeName *string `json:"target,omitempty" url:"target,omitempty"`
|
TargetNodeName *string `json:"target,omitempty" url:"target,omitempty"`
|
||||||
TargetStorage *string `json:"storage,omitempty" url:"storage,omitempty"`
|
TargetStorage *string `json:"storage,omitempty" url:"storage,omitempty"`
|
||||||
VMIDNew int `json:"newid" url:"newid"`
|
VMIDNew int `json:"newid" url:"newid"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateRequestBody contains the data for a user create request.
|
// CreateRequestBody contains the data for a user create request.
|
||||||
type CreateRequestBody struct {
|
type CreateRequestBody struct {
|
||||||
BandwidthLimit *float64 `json:"bwlimit,omitempty" url:"bwlimit,omitempty"`
|
BandwidthLimit *float64 `json:"bwlimit,omitempty" url:"bwlimit,omitempty"`
|
||||||
ConsoleEnabled *types.CustomBool `json:"console,omitempty" url:"console,omitempty,int"`
|
ConsoleEnabled *types2.CustomBool `json:"console,omitempty" url:"console,omitempty,int"`
|
||||||
ConsoleMode *string `json:"cmode,omitempty" url:"cmode,omitempty"`
|
ConsoleMode *string `json:"cmode,omitempty" url:"cmode,omitempty"`
|
||||||
CPUArchitecture *string `json:"arch,omitempty" url:"arch,omitempty"`
|
CPUArchitecture *string `json:"arch,omitempty" url:"arch,omitempty"`
|
||||||
CPUCores *int `json:"cores,omitempty" url:"cores,omitempty"`
|
CPUCores *int `json:"cores,omitempty" url:"cores,omitempty"`
|
||||||
@ -45,10 +46,10 @@ type CreateRequestBody struct {
|
|||||||
DNSDomain *string `json:"searchdomain,omitempty" url:"searchdomain,omitempty"`
|
DNSDomain *string `json:"searchdomain,omitempty" url:"searchdomain,omitempty"`
|
||||||
DNSServer *string `json:"nameserver,omitempty" url:"nameserver,omitempty"`
|
DNSServer *string `json:"nameserver,omitempty" url:"nameserver,omitempty"`
|
||||||
Features *CustomFeatures `json:"features,omitempty" url:"features,omitempty"`
|
Features *CustomFeatures `json:"features,omitempty" url:"features,omitempty"`
|
||||||
Force *types.CustomBool `json:"force,omitempty" url:"force,omitempty,int"`
|
Force *types2.CustomBool `json:"force,omitempty" url:"force,omitempty,int"`
|
||||||
HookScript *string `json:"hookscript,omitempty" url:"hookscript,omitempty"`
|
HookScript *string `json:"hookscript,omitempty" url:"hookscript,omitempty"`
|
||||||
Hostname *string `json:"hostname,omitempty" url:"hostname,omitempty"`
|
Hostname *string `json:"hostname,omitempty" url:"hostname,omitempty"`
|
||||||
IgnoreUnpackErrors *types.CustomBool `json:"ignore-unpack-errors,omitempty" url:"force,omitempty,int"`
|
IgnoreUnpackErrors *types2.CustomBool `json:"ignore-unpack-errors,omitempty" url:"force,omitempty,int"`
|
||||||
Lock *string `json:"lock,omitempty" url:"lock,omitempty,int"`
|
Lock *string `json:"lock,omitempty" url:"lock,omitempty,int"`
|
||||||
MountPoints CustomMountPointArray `json:"mp,omitempty" url:"mp,omitempty,numbered"`
|
MountPoints CustomMountPointArray `json:"mp,omitempty" url:"mp,omitempty,numbered"`
|
||||||
NetworkInterfaces CustomNetworkInterfaceArray `json:"net,omitempty" url:"net,omitempty,numbered"`
|
NetworkInterfaces CustomNetworkInterfaceArray `json:"net,omitempty" url:"net,omitempty,numbered"`
|
||||||
@ -56,43 +57,43 @@ type CreateRequestBody struct {
|
|||||||
OSType *string `json:"ostype,omitempty" url:"ostype,omitempty"`
|
OSType *string `json:"ostype,omitempty" url:"ostype,omitempty"`
|
||||||
Password *string `json:"password,omitempty" url:"password,omitempty"`
|
Password *string `json:"password,omitempty" url:"password,omitempty"`
|
||||||
PoolID *string `json:"pool,omitempty" url:"pool,omitempty"`
|
PoolID *string `json:"pool,omitempty" url:"pool,omitempty"`
|
||||||
Protection *types.CustomBool `json:"protection,omitempty" url:"protection,omitempty,int"`
|
Protection *types2.CustomBool `json:"protection,omitempty" url:"protection,omitempty,int"`
|
||||||
Restore *types.CustomBool `json:"restore,omitempty" url:"restore,omitempty,int"`
|
Restore *types2.CustomBool `json:"restore,omitempty" url:"restore,omitempty,int"`
|
||||||
RootFS *CustomRootFS `json:"rootfs,omitempty" url:"rootfs,omitempty"`
|
RootFS *CustomRootFS `json:"rootfs,omitempty" url:"rootfs,omitempty"`
|
||||||
SSHKeys *CustomSSHKeys `json:"ssh-public-keys,omitempty" url:"ssh-public-keys,omitempty"`
|
SSHKeys *CustomSSHKeys `json:"ssh-public-keys,omitempty" url:"ssh-public-keys,omitempty"`
|
||||||
Start *types.CustomBool `json:"start,omitempty" url:"start,omitempty,int"`
|
Start *types2.CustomBool `json:"start,omitempty" url:"start,omitempty,int"`
|
||||||
StartOnBoot *types.CustomBool `json:"onboot,omitempty" url:"onboot,omitempty,int"`
|
StartOnBoot *types2.CustomBool `json:"onboot,omitempty" url:"onboot,omitempty,int"`
|
||||||
StartupBehavior *CustomStartupBehavior `json:"startup,omitempty" url:"startup,omitempty"`
|
StartupBehavior *CustomStartupBehavior `json:"startup,omitempty" url:"startup,omitempty"`
|
||||||
Swap *int `json:"swap,omitempty" url:"swap,omitempty"`
|
Swap *int `json:"swap,omitempty" url:"swap,omitempty"`
|
||||||
Tags *string `json:"tags,omitempty" url:"tags,omitempty"`
|
Tags *string `json:"tags,omitempty" url:"tags,omitempty"`
|
||||||
Template *types.CustomBool `json:"template,omitempty" url:"template,omitempty,int"`
|
Template *types2.CustomBool `json:"template,omitempty" url:"template,omitempty,int"`
|
||||||
TTY *int `json:"tty,omitempty" url:"tty,omitempty"`
|
TTY *int `json:"tty,omitempty" url:"tty,omitempty"`
|
||||||
Unique *types.CustomBool `json:"unique,omitempty" url:"unique,omitempty,int"`
|
Unique *types2.CustomBool `json:"unique,omitempty" url:"unique,omitempty,int"`
|
||||||
Unprivileged *types.CustomBool `json:"unprivileged,omitempty" url:"unprivileged,omitempty,int"`
|
Unprivileged *types2.CustomBool `json:"unprivileged,omitempty" url:"unprivileged,omitempty,int"`
|
||||||
VMID *int `json:"vmid,omitempty" url:"vmid,omitempty"`
|
VMID *int `json:"vmid,omitempty" url:"vmid,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// CustomFeatures contains the values for the "features" property.
|
// CustomFeatures contains the values for the "features" property.
|
||||||
type CustomFeatures struct {
|
type CustomFeatures struct {
|
||||||
FUSE *types.CustomBool `json:"fuse,omitempty" url:"fuse,omitempty,int"`
|
FUSE *types2.CustomBool `json:"fuse,omitempty" url:"fuse,omitempty,int"`
|
||||||
KeyControl *types.CustomBool `json:"keyctl,omitempty" url:"keyctl,omitempty,int"`
|
KeyControl *types2.CustomBool `json:"keyctl,omitempty" url:"keyctl,omitempty,int"`
|
||||||
MountTypes *[]string `json:"mount,omitempty" url:"mount,omitempty"`
|
MountTypes *[]string `json:"mount,omitempty" url:"mount,omitempty"`
|
||||||
Nesting *types.CustomBool `json:"nesting,omitempty" url:"nesting,omitempty,int"`
|
Nesting *types2.CustomBool `json:"nesting,omitempty" url:"nesting,omitempty,int"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// CustomMountPoint contains the values for the "mp[n]" properties.
|
// CustomMountPoint contains the values for the "mp[n]" properties.
|
||||||
type CustomMountPoint struct {
|
type CustomMountPoint struct {
|
||||||
ACL *types.CustomBool `json:"acl,omitempty" url:"acl,omitempty,int"`
|
ACL *types2.CustomBool `json:"acl,omitempty" url:"acl,omitempty,int"`
|
||||||
Backup *types.CustomBool `json:"backup,omitempty" url:"backup,omitempty,int"`
|
Backup *types2.CustomBool `json:"backup,omitempty" url:"backup,omitempty,int"`
|
||||||
DiskSize *string `json:"size,omitempty" url:"size,omitempty"`
|
DiskSize *string `json:"size,omitempty" url:"size,omitempty"`
|
||||||
Enabled bool `json:"-" url:"-"`
|
Enabled bool `json:"-" url:"-"`
|
||||||
MountOptions *[]string `json:"mountoptions,omitempty" url:"mountoptions,omitempty"`
|
MountOptions *[]string `json:"mountoptions,omitempty" url:"mountoptions,omitempty"`
|
||||||
MountPoint string `json:"mp" url:"mp"`
|
MountPoint string `json:"mp" url:"mp"`
|
||||||
Quota *types.CustomBool `json:"quota,omitempty" url:"quota,omitempty,int"`
|
Quota *types2.CustomBool `json:"quota,omitempty" url:"quota,omitempty,int"`
|
||||||
ReadOnly *types.CustomBool `json:"ro,omitempty" url:"ro,omitempty,int"`
|
ReadOnly *types2.CustomBool `json:"ro,omitempty" url:"ro,omitempty,int"`
|
||||||
Replicate *types.CustomBool `json:"replicate,omitempty" url:"replicate,omitempty,int"`
|
Replicate *types2.CustomBool `json:"replicate,omitempty" url:"replicate,omitempty,int"`
|
||||||
Shared *types.CustomBool `json:"shared,omitempty" url:"shared,omitempty,int"`
|
Shared *types2.CustomBool `json:"shared,omitempty" url:"shared,omitempty,int"`
|
||||||
Volume string `json:"volume" url:"volume"`
|
Volume string `json:"volume" url:"volume"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// CustomMountPointArray is an array of CustomMountPoint.
|
// CustomMountPointArray is an array of CustomMountPoint.
|
||||||
@ -100,20 +101,20 @@ type CustomMountPointArray []CustomMountPoint
|
|||||||
|
|
||||||
// CustomNetworkInterface contains the values for the "net[n]" properties.
|
// CustomNetworkInterface contains the values for the "net[n]" properties.
|
||||||
type CustomNetworkInterface struct {
|
type CustomNetworkInterface struct {
|
||||||
Bridge *string `json:"bridge,omitempty" url:"bridge,omitempty"`
|
Bridge *string `json:"bridge,omitempty" url:"bridge,omitempty"`
|
||||||
Enabled bool `json:"-" url:"-"`
|
Enabled bool `json:"-" url:"-"`
|
||||||
Firewall *types.CustomBool `json:"firewall,omitempty" url:"firewall,omitempty,int"`
|
Firewall *types2.CustomBool `json:"firewall,omitempty" url:"firewall,omitempty,int"`
|
||||||
IPv4Address *string `json:"ip,omitempty" url:"ip,omitempty"`
|
IPv4Address *string `json:"ip,omitempty" url:"ip,omitempty"`
|
||||||
IPv4Gateway *string `json:"gw,omitempty" url:"gw,omitempty"`
|
IPv4Gateway *string `json:"gw,omitempty" url:"gw,omitempty"`
|
||||||
IPv6Address *string `json:"ip6,omitempty" url:"ip6,omitempty"`
|
IPv6Address *string `json:"ip6,omitempty" url:"ip6,omitempty"`
|
||||||
IPv6Gateway *string `json:"gw6,omitempty" url:"gw6,omitempty"`
|
IPv6Gateway *string `json:"gw6,omitempty" url:"gw6,omitempty"`
|
||||||
MACAddress *string `json:"hwaddr,omitempty" url:"hwaddr,omitempty"`
|
MACAddress *string `json:"hwaddr,omitempty" url:"hwaddr,omitempty"`
|
||||||
MTU *int `json:"mtu,omitempty" url:"mtu,omitempty"`
|
MTU *int `json:"mtu,omitempty" url:"mtu,omitempty"`
|
||||||
Name string `json:"name" url:"name"`
|
Name string `json:"name" url:"name"`
|
||||||
RateLimit *float64 `json:"rate,omitempty" url:"rate,omitempty"`
|
RateLimit *float64 `json:"rate,omitempty" url:"rate,omitempty"`
|
||||||
Tag *int `json:"tag,omitempty" url:"tag,omitempty"`
|
Tag *int `json:"tag,omitempty" url:"tag,omitempty"`
|
||||||
Trunks *[]int `json:"trunks,omitempty" url:"trunks,omitempty"`
|
Trunks *[]int `json:"trunks,omitempty" url:"trunks,omitempty"`
|
||||||
Type *string `json:"type,omitempty" url:"type,omitempty"`
|
Type *string `json:"type,omitempty" url:"type,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// CustomNetworkInterfaceArray is an array of CustomNetworkInterface.
|
// CustomNetworkInterfaceArray is an array of CustomNetworkInterface.
|
||||||
@ -121,14 +122,14 @@ type CustomNetworkInterfaceArray []CustomNetworkInterface
|
|||||||
|
|
||||||
// CustomRootFS contains the values for the "rootfs" property.
|
// CustomRootFS contains the values for the "rootfs" property.
|
||||||
type CustomRootFS struct {
|
type CustomRootFS struct {
|
||||||
ACL *types.CustomBool `json:"acl,omitempty" url:"acl,omitempty,int"`
|
ACL *types2.CustomBool `json:"acl,omitempty" url:"acl,omitempty,int"`
|
||||||
Size *types.DiskSize `json:"size,omitempty" url:"size,omitempty"`
|
Size *types.DiskSize `json:"size,omitempty" url:"size,omitempty"`
|
||||||
MountOptions *[]string `json:"mountoptions,omitempty" url:"mountoptions,omitempty"`
|
MountOptions *[]string `json:"mountoptions,omitempty" url:"mountoptions,omitempty"`
|
||||||
Quota *types.CustomBool `json:"quota,omitempty" url:"quota,omitempty,int"`
|
Quota *types2.CustomBool `json:"quota,omitempty" url:"quota,omitempty,int"`
|
||||||
ReadOnly *types.CustomBool `json:"ro,omitempty" url:"ro,omitempty,int"`
|
ReadOnly *types2.CustomBool `json:"ro,omitempty" url:"ro,omitempty,int"`
|
||||||
Replicate *types.CustomBool `json:"replicate,omitempty" url:"replicate,omitempty,int"`
|
Replicate *types2.CustomBool `json:"replicate,omitempty" url:"replicate,omitempty,int"`
|
||||||
Shared *types.CustomBool `json:"shared,omitempty" url:"shared,omitempty,int"`
|
Shared *types2.CustomBool `json:"shared,omitempty" url:"shared,omitempty,int"`
|
||||||
Volume string `json:"volume" url:"volume"`
|
Volume string `json:"volume" url:"volume"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// CustomSSHKeys contains the values for the "ssh-public-keys" property.
|
// CustomSSHKeys contains the values for the "ssh-public-keys" property.
|
||||||
@ -148,7 +149,7 @@ type GetResponseBody struct {
|
|||||||
|
|
||||||
// GetResponseData contains the data from a user get response.
|
// GetResponseData contains the data from a user get response.
|
||||||
type GetResponseData struct {
|
type GetResponseData struct {
|
||||||
ConsoleEnabled *types.CustomBool `json:"console,omitempty"`
|
ConsoleEnabled *types2.CustomBool `json:"console,omitempty"`
|
||||||
ConsoleMode *string `json:"cmode,omitempty"`
|
ConsoleMode *string `json:"cmode,omitempty"`
|
||||||
CPUArchitecture *string `json:"arch,omitempty"`
|
CPUArchitecture *string `json:"arch,omitempty"`
|
||||||
CPUCores *int `json:"cores,omitempty"`
|
CPUCores *int `json:"cores,omitempty"`
|
||||||
@ -162,7 +163,7 @@ type GetResponseData struct {
|
|||||||
Features *CustomFeatures `json:"features,omitempty"`
|
Features *CustomFeatures `json:"features,omitempty"`
|
||||||
HookScript *string `json:"hookscript,omitempty"`
|
HookScript *string `json:"hookscript,omitempty"`
|
||||||
Hostname *string `json:"hostname,omitempty"`
|
Hostname *string `json:"hostname,omitempty"`
|
||||||
Lock *types.CustomBool `json:"lock,omitempty"`
|
Lock *types2.CustomBool `json:"lock,omitempty"`
|
||||||
LXCConfiguration *[][2]string `json:"lxc,omitempty"`
|
LXCConfiguration *[][2]string `json:"lxc,omitempty"`
|
||||||
MountPoint0 CustomMountPoint `json:"mp0,omitempty"`
|
MountPoint0 CustomMountPoint `json:"mp0,omitempty"`
|
||||||
MountPoint1 CustomMountPoint `json:"mp1,omitempty"`
|
MountPoint1 CustomMountPoint `json:"mp1,omitempty"`
|
||||||
@ -177,15 +178,15 @@ type GetResponseData struct {
|
|||||||
NetworkInterface6 *CustomNetworkInterface `json:"net6,omitempty"`
|
NetworkInterface6 *CustomNetworkInterface `json:"net6,omitempty"`
|
||||||
NetworkInterface7 *CustomNetworkInterface `json:"net7,omitempty"`
|
NetworkInterface7 *CustomNetworkInterface `json:"net7,omitempty"`
|
||||||
OSType *string `json:"ostype,omitempty"`
|
OSType *string `json:"ostype,omitempty"`
|
||||||
Protection *types.CustomBool `json:"protection,omitempty"`
|
Protection *types2.CustomBool `json:"protection,omitempty"`
|
||||||
RootFS *CustomRootFS `json:"rootfs,omitempty"`
|
RootFS *CustomRootFS `json:"rootfs,omitempty"`
|
||||||
StartOnBoot *types.CustomBool `json:"onboot,omitempty"`
|
StartOnBoot *types2.CustomBool `json:"onboot,omitempty"`
|
||||||
StartupBehavior *CustomStartupBehavior `json:"startup,omitempty"`
|
StartupBehavior *CustomStartupBehavior `json:"startup,omitempty"`
|
||||||
Swap *int `json:"swap,omitempty"`
|
Swap *int `json:"swap,omitempty"`
|
||||||
Tags *string `json:"tags,omitempty"`
|
Tags *string `json:"tags,omitempty"`
|
||||||
Template *types.CustomBool `json:"template,omitempty"`
|
Template *types2.CustomBool `json:"template,omitempty"`
|
||||||
TTY *int `json:"tty,omitempty"`
|
TTY *int `json:"tty,omitempty"`
|
||||||
Unprivileged *types.CustomBool `json:"unprivileged,omitempty"`
|
Unprivileged *types2.CustomBool `json:"unprivileged,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetStatusResponseBody contains the body from a container get status response.
|
// GetStatusResponseBody contains the body from a container get status response.
|
||||||
@ -214,8 +215,8 @@ type RebootRequestBody struct {
|
|||||||
|
|
||||||
// ShutdownRequestBody contains the body for a container shutdown request.
|
// ShutdownRequestBody contains the body for a container shutdown request.
|
||||||
type ShutdownRequestBody struct {
|
type ShutdownRequestBody struct {
|
||||||
ForceStop *types.CustomBool `json:"forceStop,omitempty" url:"forceStop,omitempty,int"`
|
ForceStop *types2.CustomBool `json:"forceStop,omitempty" url:"forceStop,omitempty,int"`
|
||||||
Timeout *int `json:"timeout,omitempty" url:"timeout,omitempty"`
|
Timeout *int `json:"timeout,omitempty" url:"timeout,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateRequestBody contains the data for an user update request.
|
// UpdateRequestBody contains the data for an user update request.
|
||||||
@ -550,10 +551,10 @@ func (r *CustomFeatures) UnmarshalJSON(b []byte) error {
|
|||||||
if len(v) == 2 {
|
if len(v) == 2 {
|
||||||
switch v[0] {
|
switch v[0] {
|
||||||
case "fuse":
|
case "fuse":
|
||||||
bv := types.CustomBool(v[1] == "1")
|
bv := types2.CustomBool(v[1] == "1")
|
||||||
r.FUSE = &bv
|
r.FUSE = &bv
|
||||||
case "keyctl":
|
case "keyctl":
|
||||||
bv := types.CustomBool(v[1] == "1")
|
bv := types2.CustomBool(v[1] == "1")
|
||||||
r.KeyControl = &bv
|
r.KeyControl = &bv
|
||||||
case "mount":
|
case "mount":
|
||||||
if v[1] != "" {
|
if v[1] != "" {
|
||||||
@ -564,7 +565,7 @@ func (r *CustomFeatures) UnmarshalJSON(b []byte) error {
|
|||||||
r.MountTypes = &a
|
r.MountTypes = &a
|
||||||
}
|
}
|
||||||
case "nesting":
|
case "nesting":
|
||||||
bv := types.CustomBool(v[1] == "1")
|
bv := types2.CustomBool(v[1] == "1")
|
||||||
r.Nesting = &bv
|
r.Nesting = &bv
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -592,10 +593,10 @@ func (r *CustomMountPoint) UnmarshalJSON(b []byte) error {
|
|||||||
} else if len(v) == 2 {
|
} else if len(v) == 2 {
|
||||||
switch v[0] {
|
switch v[0] {
|
||||||
case "acl":
|
case "acl":
|
||||||
bv := types.CustomBool(v[1] == "1")
|
bv := types2.CustomBool(v[1] == "1")
|
||||||
r.ACL = &bv
|
r.ACL = &bv
|
||||||
case "backup":
|
case "backup":
|
||||||
bv := types.CustomBool(v[1] == "1")
|
bv := types2.CustomBool(v[1] == "1")
|
||||||
r.Backup = &bv
|
r.Backup = &bv
|
||||||
case "mountoptions":
|
case "mountoptions":
|
||||||
if v[1] != "" {
|
if v[1] != "" {
|
||||||
@ -608,16 +609,16 @@ func (r *CustomMountPoint) UnmarshalJSON(b []byte) error {
|
|||||||
case "mp":
|
case "mp":
|
||||||
r.MountPoint = v[1]
|
r.MountPoint = v[1]
|
||||||
case "quota":
|
case "quota":
|
||||||
bv := types.CustomBool(v[1] == "1")
|
bv := types2.CustomBool(v[1] == "1")
|
||||||
r.Quota = &bv
|
r.Quota = &bv
|
||||||
case "ro":
|
case "ro":
|
||||||
bv := types.CustomBool(v[1] == "1")
|
bv := types2.CustomBool(v[1] == "1")
|
||||||
r.ReadOnly = &bv
|
r.ReadOnly = &bv
|
||||||
case "replicate":
|
case "replicate":
|
||||||
bv := types.CustomBool(v[1] == "1")
|
bv := types2.CustomBool(v[1] == "1")
|
||||||
r.Replicate = &bv
|
r.Replicate = &bv
|
||||||
case "shared":
|
case "shared":
|
||||||
bv := types.CustomBool(v[1] == "1")
|
bv := types2.CustomBool(v[1] == "1")
|
||||||
r.Shared = &bv
|
r.Shared = &bv
|
||||||
case "size":
|
case "size":
|
||||||
r.DiskSize = &v[1]
|
r.DiskSize = &v[1]
|
||||||
@ -650,7 +651,7 @@ func (r *CustomNetworkInterface) UnmarshalJSON(b []byte) error {
|
|||||||
case "bridge":
|
case "bridge":
|
||||||
r.Bridge = &v[1]
|
r.Bridge = &v[1]
|
||||||
case "firewall":
|
case "firewall":
|
||||||
bv := types.CustomBool(v[1] == "1")
|
bv := types2.CustomBool(v[1] == "1")
|
||||||
r.Firewall = &bv
|
r.Firewall = &bv
|
||||||
case "gw":
|
case "gw":
|
||||||
r.IPv4Gateway = &v[1]
|
r.IPv4Gateway = &v[1]
|
||||||
@ -731,7 +732,7 @@ func (r *CustomRootFS) UnmarshalJSON(b []byte) error {
|
|||||||
} else if len(v) == 2 {
|
} else if len(v) == 2 {
|
||||||
switch v[0] {
|
switch v[0] {
|
||||||
case "acl":
|
case "acl":
|
||||||
bv := types.CustomBool(v[1] == "1")
|
bv := types2.CustomBool(v[1] == "1")
|
||||||
r.ACL = &bv
|
r.ACL = &bv
|
||||||
case "mountoptions":
|
case "mountoptions":
|
||||||
if v[1] != "" {
|
if v[1] != "" {
|
||||||
@ -742,16 +743,16 @@ func (r *CustomRootFS) UnmarshalJSON(b []byte) error {
|
|||||||
r.MountOptions = &a
|
r.MountOptions = &a
|
||||||
}
|
}
|
||||||
case "quota":
|
case "quota":
|
||||||
bv := types.CustomBool(v[1] == "1")
|
bv := types2.CustomBool(v[1] == "1")
|
||||||
r.Quota = &bv
|
r.Quota = &bv
|
||||||
case "ro":
|
case "ro":
|
||||||
bv := types.CustomBool(v[1] == "1")
|
bv := types2.CustomBool(v[1] == "1")
|
||||||
r.ReadOnly = &bv
|
r.ReadOnly = &bv
|
||||||
case "replicate":
|
case "replicate":
|
||||||
bv := types.CustomBool(v[1] == "1")
|
bv := types2.CustomBool(v[1] == "1")
|
||||||
r.Replicate = &bv
|
r.Replicate = &bv
|
||||||
case "shared":
|
case "shared":
|
||||||
bv := types.CustomBool(v[1] == "1")
|
bv := types2.CustomBool(v[1] == "1")
|
||||||
r.Shared = &bv
|
r.Shared = &bv
|
||||||
case "size":
|
case "size":
|
||||||
r.Size = new(types.DiskSize)
|
r.Size = new(types.DiskSize)
|
||||||
|
125
proxmox/nodes/network.go
Normal file
125
proxmox/nodes/network.go
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
/*
|
||||||
|
* 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 nodes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"sort"
|
||||||
|
|
||||||
|
"github.com/bpg/terraform-provider-proxmox/proxmox/api"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
networkReloadTimeoutSec = 5
|
||||||
|
)
|
||||||
|
|
||||||
|
// ListNetworkInterfaces retrieves a list of network interfaces for a specific nodes.
|
||||||
|
func (c *Client) ListNetworkInterfaces(ctx context.Context) ([]*NetworkInterfaceListResponseData, error) {
|
||||||
|
resBody := &NetworkInterfaceListResponseBody{}
|
||||||
|
|
||||||
|
err := c.DoRequest(ctx, http.MethodGet, c.ExpandPath("network"), nil, resBody)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to get network interfaces for node \"%s\": %w", c.NodeName, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if resBody.Data == nil {
|
||||||
|
return nil, api.ErrNoDataObjectInResponse
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Slice(resBody.Data, func(i, j int) bool {
|
||||||
|
return resBody.Data[i].Priority < resBody.Data[j].Priority
|
||||||
|
})
|
||||||
|
|
||||||
|
return resBody.Data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateNetworkInterface creates a network interface for a specific node.
|
||||||
|
func (c *Client) CreateNetworkInterface(ctx context.Context, d *NetworkInterfaceCreateUpdateRequestBody) error {
|
||||||
|
err := c.DoRequest(ctx, http.MethodPost, c.ExpandPath("network"), d, nil)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf(
|
||||||
|
"failed to create network interface \"%s\" for node \"%s\": %w",
|
||||||
|
d.Iface, c.NodeName, err,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReloadNetworkConfiguration reloads the network configuration for a specific node.
|
||||||
|
func (c *Client) ReloadNetworkConfiguration(ctx context.Context) error {
|
||||||
|
resBody := &ReloadNetworkResponseBody{}
|
||||||
|
|
||||||
|
err := c.DoRequest(ctx, http.MethodPut, c.ExpandPath("network"), nil, resBody)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to reload network configuration for node \"%s\": %w", c.NodeName, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if resBody.Data == nil {
|
||||||
|
return api.ErrNoDataObjectInResponse
|
||||||
|
}
|
||||||
|
|
||||||
|
err = c.Tasks().WaitForTask(ctx, *resBody.Data, networkReloadTimeoutSec, 1)
|
||||||
|
if err == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RevertNetworkConfiguration reverts the network configuration changes for a specific node.
|
||||||
|
func (c *Client) RevertNetworkConfiguration(ctx context.Context) error {
|
||||||
|
err := c.DoRequest(ctx, http.MethodDelete, c.ExpandPath("network"), nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to revert network configuration for node \"%s\": %w", c.NodeName, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateNetworkInterface updates a network interface for a specific node.
|
||||||
|
func (c *Client) UpdateNetworkInterface(
|
||||||
|
ctx context.Context,
|
||||||
|
iface string,
|
||||||
|
d *NetworkInterfaceCreateUpdateRequestBody,
|
||||||
|
) error {
|
||||||
|
err := c.DoRequest(
|
||||||
|
ctx,
|
||||||
|
http.MethodPut,
|
||||||
|
c.ExpandPath(fmt.Sprintf("network/%s", url.PathEscape(iface))),
|
||||||
|
d,
|
||||||
|
nil,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to update network interface \"%s\" for node \"%s\": %w",
|
||||||
|
d.Iface, c.NodeName, err,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteNetworkInterface deletes a network interface configuration for a specific node.
|
||||||
|
func (c *Client) DeleteNetworkInterface(ctx context.Context, iface string) error {
|
||||||
|
err := c.DoRequest(
|
||||||
|
ctx,
|
||||||
|
http.MethodDelete,
|
||||||
|
c.ExpandPath(fmt.Sprintf("network/%s", url.PathEscape(iface))),
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to delete network interface \"%s\" for node \"%s\": %w",
|
||||||
|
iface, c.NodeName, err,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
83
proxmox/nodes/network_types.go
Normal file
83
proxmox/nodes/network_types.go
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* 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 nodes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/bpg/terraform-provider-proxmox/internal/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NetworkInterfaceListResponseBody contains the body from a node network interface list response.
|
||||||
|
type NetworkInterfaceListResponseBody struct {
|
||||||
|
Data []*NetworkInterfaceListResponseData `json:"data,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NetworkInterfaceListResponseData contains the data from a node network interface list response.
|
||||||
|
type NetworkInterfaceListResponseData struct {
|
||||||
|
Active *types.CustomBool `json:"active,omitempty"`
|
||||||
|
Address *string `json:"address,omitempty"`
|
||||||
|
Address6 *string `json:"address6,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"`
|
||||||
|
BridgeVIDs *string `json:"bridge_vids,omitempty"`
|
||||||
|
BridgeVLANAware *types.CustomBool `json:"bridge_vlan_aware,omitempty"`
|
||||||
|
CIDR *string `json:"cidr,omitempty"`
|
||||||
|
CIDR6 *string `json:"cidr6,omitempty"`
|
||||||
|
Comments *string `json:"comments,omitempty"`
|
||||||
|
Exists *types.CustomBool `json:"exists,omitempty"`
|
||||||
|
Families *[]string `json:"families,omitempty"`
|
||||||
|
Gateway *string `json:"gateway,omitempty"`
|
||||||
|
Gateway6 *string `json:"gateway6,omitempty"`
|
||||||
|
Iface string `json:"iface"`
|
||||||
|
MethodIPv4 *string `json:"method,omitempty"`
|
||||||
|
MethodIPv6 *string `json:"method6,omitempty"`
|
||||||
|
MTU *string `json:"mtu,omitempty"`
|
||||||
|
Netmask *string `json:"netmask,omitempty"`
|
||||||
|
VLANID *string `json:"vlan-id,omitempty"`
|
||||||
|
VLANRawDevice *string `json:"vlan-raw-device,omitempty"`
|
||||||
|
Priority int `json:"priority"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NetworkInterfaceCreateUpdateRequestBody contains the body for a node network interface create / update request.
|
||||||
|
type NetworkInterfaceCreateUpdateRequestBody struct {
|
||||||
|
Iface string `json:"iface" url:"iface"`
|
||||||
|
Type string `json:"type" url:"type"`
|
||||||
|
|
||||||
|
Address *string `json:"address,omitempty" url:"address,omitempty"`
|
||||||
|
Address6 *string `json:"address6,omitempty" url:"address6,omitempty"`
|
||||||
|
Autostart *types.CustomBool `json:"autostart,omitempty" url:"autostart,omitempty,int"`
|
||||||
|
BondPrimary *string `json:"bond-primary,omitempty" url:"bond-primary,omitempty"`
|
||||||
|
BondMode *string `json:"bond_mode,omitempty" url:"bond_mode,omitempty"`
|
||||||
|
BondXmitHashPolicy *string `json:"bond_xmit_hash_policy,omitempty" url:"bond_xmit_hash_policy,omitempty"`
|
||||||
|
BridgePorts *string `json:"bridge_ports,omitempty" url:"bridge_ports,omitempty"`
|
||||||
|
BridgeVLANAware *types.CustomBool `json:"bridge_vlan_aware,omitempty" url:"bridge_vlan_aware,omitempty,int"`
|
||||||
|
CIDR *string `json:"cidr,omitempty" url:"cidr,omitempty"`
|
||||||
|
CIDR6 *string `json:"cidr6,omitempty" url:"cidr6,omitempty"`
|
||||||
|
Comments *string `json:"comments,omitempty" url:"comments,omitempty"`
|
||||||
|
Comments6 *string `json:"comments6,omitempty" url:"comments6,omitempty"`
|
||||||
|
Gateway *string `json:"gateway,omitempty" url:"gateway,omitempty"`
|
||||||
|
Gateway6 *string `json:"gateway6,omitempty" url:"gateway6,omitempty"`
|
||||||
|
Delete *[]string `json:"delete,omitempty" url:"delete,omitempty"`
|
||||||
|
MTU *int64 `json:"mtu,omitempty" url:"mtu,omitempty"`
|
||||||
|
Netmask *string `json:"netmask,omitempty" url:"netmask,omitempty"`
|
||||||
|
Netmask6 *string `json:"netmask6,omitempty" url:"netmask6,omitempty"`
|
||||||
|
OVSBonds *string `json:"ovs_bonds,omitempty" url:"ovs_bonds,omitempty"`
|
||||||
|
OVSBridge *string `json:"ovs_bridge,omitempty" url:"ovs_bridge,omitempty"`
|
||||||
|
OVSOptions *string `json:"ovs_options,omitempty" url:"ovs_options,omitempty"`
|
||||||
|
OVSPorts *string `json:"ovs_ports,omitempty" url:"ovs_ports,omitempty"`
|
||||||
|
OVSTag *string `json:"ovs_tag,omitempty" url:"ovs_tag,omitempty"`
|
||||||
|
Slaves *string `json:"slaves,omitempty" url:"slaves,omitempty"`
|
||||||
|
VLANID *int64 `json:"vlan_id,omitempty" url:"vlan_id,omitempty"`
|
||||||
|
VLANRawDevice *string `json:"vlan-raw-device,omitempty" url:"vlan-raw-device,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReloadNetworkResponseBody contains the body from a node network reload response.
|
||||||
|
type ReloadNetworkResponseBody struct {
|
||||||
|
Data *string `json:"data,omitempty"`
|
||||||
|
}
|
@ -11,72 +11,10 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox/api"
|
"github.com/bpg/terraform-provider-proxmox/proxmox/api"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetIP retrieves the IP address of a node.
|
|
||||||
func (c *Client) GetIP(ctx context.Context) (string, error) {
|
|
||||||
networkDevices, err := c.ListNetworkDevices(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
nodeAddress := ""
|
|
||||||
|
|
||||||
for _, d := range networkDevices {
|
|
||||||
if d.Address != nil {
|
|
||||||
nodeAddress = *d.Address
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if nodeAddress == "" {
|
|
||||||
return "", fmt.Errorf("failed to determine the IP address of node \"%s\"", c.NodeName)
|
|
||||||
}
|
|
||||||
|
|
||||||
nodeAddressParts := strings.Split(nodeAddress, "/")
|
|
||||||
|
|
||||||
return nodeAddressParts[0], nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetTime retrieves the time information for a node.
|
|
||||||
func (c *Client) GetTime(ctx context.Context) (*GetTimeResponseData, error) {
|
|
||||||
resBody := &GetTimeResponseBody{}
|
|
||||||
|
|
||||||
err := c.DoRequest(ctx, http.MethodGet, c.ExpandPath("time"), nil, resBody)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to get time information for node \"%s\": %w", c.NodeName, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if resBody.Data == nil {
|
|
||||||
return nil, api.ErrNoDataObjectInResponse
|
|
||||||
}
|
|
||||||
|
|
||||||
return resBody.Data, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ListNetworkDevices retrieves a list of network devices for a specific nodes.
|
|
||||||
func (c *Client) ListNetworkDevices(ctx context.Context) ([]*NetworkDeviceListResponseData, error) {
|
|
||||||
resBody := &NetworkDeviceListResponseBody{}
|
|
||||||
|
|
||||||
err := c.DoRequest(ctx, http.MethodGet, c.ExpandPath("network"), nil, resBody)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to get network devices for node \"%s\": %w", c.NodeName, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if resBody.Data == nil {
|
|
||||||
return nil, api.ErrNoDataObjectInResponse
|
|
||||||
}
|
|
||||||
|
|
||||||
sort.Slice(resBody.Data, func(i, j int) bool {
|
|
||||||
return resBody.Data[i].Priority < resBody.Data[j].Priority
|
|
||||||
})
|
|
||||||
|
|
||||||
return resBody.Data, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ListNodes retrieves a list of nodes.
|
// ListNodes retrieves a list of nodes.
|
||||||
func (c *Client) ListNodes(ctx context.Context) ([]*ListResponseData, error) {
|
func (c *Client) ListNodes(ctx context.Context) ([]*ListResponseData, error) {
|
||||||
resBody := &ListResponseBody{}
|
resBody := &ListResponseBody{}
|
||||||
@ -97,6 +35,22 @@ func (c *Client) ListNodes(ctx context.Context) ([]*ListResponseData, error) {
|
|||||||
return resBody.Data, nil
|
return resBody.Data, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetTime retrieves the time information for a node.
|
||||||
|
func (c *Client) GetTime(ctx context.Context) (*GetTimeResponseData, error) {
|
||||||
|
resBody := &GetTimeResponseBody{}
|
||||||
|
|
||||||
|
err := c.DoRequest(ctx, http.MethodGet, c.ExpandPath("time"), nil, resBody)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to get time information for node \"%s\": %w", c.NodeName, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if resBody.Data == nil {
|
||||||
|
return nil, api.ErrNoDataObjectInResponse
|
||||||
|
}
|
||||||
|
|
||||||
|
return resBody.Data, nil
|
||||||
|
}
|
||||||
|
|
||||||
// UpdateTime updates the time on a node.
|
// UpdateTime updates the time on a node.
|
||||||
func (c *Client) UpdateTime(ctx context.Context, d *UpdateTimeRequestBody) error {
|
func (c *Client) UpdateTime(ctx context.Context, d *UpdateTimeRequestBody) error {
|
||||||
err := c.DoRequest(ctx, http.MethodPut, c.ExpandPath("time"), d, nil)
|
err := c.DoRequest(ctx, http.MethodPut, c.ExpandPath("time"), d, nil)
|
||||||
|
@ -11,7 +11,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox/types"
|
"github.com/bpg/terraform-provider-proxmox/internal/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CustomCommands contains an array of commands to execute.
|
// CustomCommands contains an array of commands to execute.
|
||||||
@ -52,31 +52,6 @@ type ListResponseData struct {
|
|||||||
Uptime *int `json:"uptime"`
|
Uptime *int `json:"uptime"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// NetworkDeviceListResponseBody contains the body from a node network device list response.
|
|
||||||
type NetworkDeviceListResponseBody struct {
|
|
||||||
Data []*NetworkDeviceListResponseData `json:"data,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// NetworkDeviceListResponseData contains the data from a node network device list response.
|
|
||||||
type NetworkDeviceListResponseData struct {
|
|
||||||
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"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateTimeRequestBody contains the body for a node time update request.
|
// UpdateTimeRequestBody contains the body for a node time update request.
|
||||||
type UpdateTimeRequestBody struct {
|
type UpdateTimeRequestBody struct {
|
||||||
TimeZone string `json:"timezone" url:"timezone"`
|
TimeZone string `json:"timezone" url:"timezone"`
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
package nodes
|
package nodes
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox/types"
|
"github.com/bpg/terraform-provider-proxmox/internal/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DatastoreFileListResponseBody contains the body from a datastore content list response.
|
// DatastoreFileListResponseBody contains the body from a datastore content list response.
|
||||||
|
@ -39,9 +39,9 @@ func (c *Client) GetTaskStatus(ctx context.Context, upid string) (*GetTaskStatus
|
|||||||
}
|
}
|
||||||
|
|
||||||
// WaitForTask waits for a specific task to complete.
|
// WaitForTask waits for a specific task to complete.
|
||||||
func (c *Client) WaitForTask(ctx context.Context, upid string, timeout, delay int) error {
|
func (c *Client) WaitForTask(ctx context.Context, upid string, timeoutSec, delaySec int) error {
|
||||||
timeDelay := int64(delay)
|
timeDelay := int64(delaySec)
|
||||||
timeMax := float64(timeout)
|
timeMax := float64(timeoutSec)
|
||||||
timeStart := time.Now()
|
timeStart := time.Now()
|
||||||
timeElapsed := timeStart.Sub(timeStart)
|
timeElapsed := timeStart.Sub(timeStart)
|
||||||
|
|
||||||
@ -80,7 +80,7 @@ func (c *Client) WaitForTask(ctx context.Context, upid string, timeout, delay in
|
|||||||
}
|
}
|
||||||
|
|
||||||
return fmt.Errorf(
|
return fmt.Errorf(
|
||||||
"timeout while waiting for task \"%s\" to complete",
|
"timeoutSec while waiting for task \"%s\" to complete",
|
||||||
upid,
|
upid,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -15,14 +15,15 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
types2 "github.com/bpg/terraform-provider-proxmox/internal/types"
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox/types"
|
"github.com/bpg/terraform-provider-proxmox/proxmox/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CustomAgent handles QEMU agent parameters.
|
// CustomAgent handles QEMU agent parameters.
|
||||||
type CustomAgent struct {
|
type CustomAgent struct {
|
||||||
Enabled *types.CustomBool `json:"enabled,omitempty" url:"enabled,int"`
|
Enabled *types2.CustomBool `json:"enabled,omitempty" url:"enabled,int"`
|
||||||
TrimClonedDisks *types.CustomBool `json:"fstrim_cloned_disks" url:"fstrim_cloned_disks,int"`
|
TrimClonedDisks *types2.CustomBool `json:"fstrim_cloned_disks" url:"fstrim_cloned_disks,int"`
|
||||||
Type *string `json:"type" url:"type"`
|
Type *string `json:"type" url:"type"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// CustomAudioDevice handles QEMU audio parameters.
|
// CustomAudioDevice handles QEMU audio parameters.
|
||||||
@ -73,10 +74,10 @@ type CustomCloudInitSSHKeys []string
|
|||||||
|
|
||||||
// CustomCPUEmulation handles QEMU CPU emulation parameters.
|
// CustomCPUEmulation handles QEMU CPU emulation parameters.
|
||||||
type CustomCPUEmulation struct {
|
type CustomCPUEmulation struct {
|
||||||
Flags *[]string `json:"flags,omitempty" url:"flags,omitempty,semicolon"`
|
Flags *[]string `json:"flags,omitempty" url:"flags,omitempty,semicolon"`
|
||||||
Hidden *types.CustomBool `json:"hidden,omitempty" url:"hidden,omitempty,int"`
|
Hidden *types2.CustomBool `json:"hidden,omitempty" url:"hidden,omitempty,int"`
|
||||||
HVVendorID *string `json:"hv-vendor-id,omitempty" url:"hv-vendor-id,omitempty"`
|
HVVendorID *string `json:"hv-vendor-id,omitempty" url:"hv-vendor-id,omitempty"`
|
||||||
Type string `json:"cputype,omitempty" url:"cputype,omitempty"`
|
Type string `json:"cputype,omitempty" url:"cputype,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// CustomEFIDisk handles QEMU EFI disk parameters.
|
// CustomEFIDisk handles QEMU EFI disk parameters.
|
||||||
@ -88,17 +89,17 @@ type CustomEFIDisk struct {
|
|||||||
|
|
||||||
// CustomNetworkDevice handles QEMU network device parameters.
|
// CustomNetworkDevice handles QEMU network device parameters.
|
||||||
type CustomNetworkDevice struct {
|
type CustomNetworkDevice struct {
|
||||||
Model string `json:"model" url:"model"`
|
Model string `json:"model" url:"model"`
|
||||||
Bridge *string `json:"bridge,omitempty" url:"bridge,omitempty"`
|
Bridge *string `json:"bridge,omitempty" url:"bridge,omitempty"`
|
||||||
Enabled bool `json:"-" url:"-"`
|
Enabled bool `json:"-" url:"-"`
|
||||||
Firewall *types.CustomBool `json:"firewall,omitempty" url:"firewall,omitempty,int"`
|
Firewall *types2.CustomBool `json:"firewall,omitempty" url:"firewall,omitempty,int"`
|
||||||
LinkDown *types.CustomBool `json:"link_down,omitempty" url:"link_down,omitempty,int"`
|
LinkDown *types2.CustomBool `json:"link_down,omitempty" url:"link_down,omitempty,int"`
|
||||||
MACAddress *string `json:"macaddr,omitempty" url:"macaddr,omitempty"`
|
MACAddress *string `json:"macaddr,omitempty" url:"macaddr,omitempty"`
|
||||||
Queues *int `json:"queues,omitempty" url:"queues,omitempty"`
|
Queues *int `json:"queues,omitempty" url:"queues,omitempty"`
|
||||||
RateLimit *float64 `json:"rate,omitempty" url:"rate,omitempty"`
|
RateLimit *float64 `json:"rate,omitempty" url:"rate,omitempty"`
|
||||||
Tag *int `json:"tag,omitempty" url:"tag,omitempty"`
|
Tag *int `json:"tag,omitempty" url:"tag,omitempty"`
|
||||||
MTU *int `json:"mtu,omitempty" url:"mtu,omitempty"`
|
MTU *int `json:"mtu,omitempty" url:"mtu,omitempty"`
|
||||||
Trunks []int `json:"trunks,omitempty" url:"trunks,omitempty"`
|
Trunks []int `json:"trunks,omitempty" url:"trunks,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// CustomNetworkDevices handles QEMU network device parameters.
|
// CustomNetworkDevices handles QEMU network device parameters.
|
||||||
@ -117,12 +118,12 @@ type CustomNUMADevices []CustomNUMADevice
|
|||||||
|
|
||||||
// CustomPCIDevice handles QEMU host PCI device mapping parameters.
|
// CustomPCIDevice handles QEMU host PCI device mapping parameters.
|
||||||
type CustomPCIDevice struct {
|
type CustomPCIDevice struct {
|
||||||
DeviceIDs []string `json:"host" url:"host,semicolon"`
|
DeviceIDs []string `json:"host" url:"host,semicolon"`
|
||||||
MDev *string `json:"mdev,omitempty" url:"mdev,omitempty"`
|
MDev *string `json:"mdev,omitempty" url:"mdev,omitempty"`
|
||||||
PCIExpress *types.CustomBool `json:"pcie,omitempty" url:"pcie,omitempty,int"`
|
PCIExpress *types2.CustomBool `json:"pcie,omitempty" url:"pcie,omitempty,int"`
|
||||||
ROMBAR *types.CustomBool `json:"rombar,omitempty" url:"rombar,omitempty,int"`
|
ROMBAR *types2.CustomBool `json:"rombar,omitempty" url:"rombar,omitempty,int"`
|
||||||
ROMFile *string `json:"romfile,omitempty" url:"romfile,omitempty"`
|
ROMFile *string `json:"romfile,omitempty" url:"romfile,omitempty"`
|
||||||
XVGA *types.CustomBool `json:"x-vga,omitempty" url:"x-vga,omitempty,int"`
|
XVGA *types2.CustomBool `json:"x-vga,omitempty" url:"x-vga,omitempty,int"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// CustomPCIDevices handles QEMU host PCI device mapping parameters.
|
// CustomPCIDevices handles QEMU host PCI device mapping parameters.
|
||||||
@ -139,20 +140,20 @@ type CustomSharedMemory struct {
|
|||||||
|
|
||||||
// CustomSMBIOS handles QEMU SMBIOS parameters.
|
// CustomSMBIOS handles QEMU SMBIOS parameters.
|
||||||
type CustomSMBIOS struct {
|
type CustomSMBIOS struct {
|
||||||
Base64 *types.CustomBool `json:"base64,omitempty" url:"base64,omitempty"`
|
Base64 *types2.CustomBool `json:"base64,omitempty" url:"base64,omitempty"`
|
||||||
Family *string `json:"family,omitempty" url:"family,omitempty"`
|
Family *string `json:"family,omitempty" url:"family,omitempty"`
|
||||||
Manufacturer *string `json:"manufacturer,omitempty" url:"manufacturer,omitempty"`
|
Manufacturer *string `json:"manufacturer,omitempty" url:"manufacturer,omitempty"`
|
||||||
Product *string `json:"product,omitempty" url:"product,omitempty"`
|
Product *string `json:"product,omitempty" url:"product,omitempty"`
|
||||||
Serial *string `json:"serial,omitempty" url:"serial,omitempty"`
|
Serial *string `json:"serial,omitempty" url:"serial,omitempty"`
|
||||||
SKU *string `json:"sku,omitempty" url:"sku,omitempty"`
|
SKU *string `json:"sku,omitempty" url:"sku,omitempty"`
|
||||||
UUID *string `json:"uuid,omitempty" url:"uuid,omitempty"`
|
UUID *string `json:"uuid,omitempty" url:"uuid,omitempty"`
|
||||||
Version *string `json:"version,omitempty" url:"version,omitempty"`
|
Version *string `json:"version,omitempty" url:"version,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// CustomSpiceEnhancements handles QEMU spice enhancement parameters.
|
// CustomSpiceEnhancements handles QEMU spice enhancement parameters.
|
||||||
type CustomSpiceEnhancements struct {
|
type CustomSpiceEnhancements struct {
|
||||||
FolderSharing *types.CustomBool `json:"foldersharing,omitempty" url:"foldersharing,omitempty"`
|
FolderSharing *types2.CustomBool `json:"foldersharing,omitempty" url:"foldersharing,omitempty"`
|
||||||
VideoStreaming *string `json:"videostreaming,omitempty" url:"videostreaming,omitempty"`
|
VideoStreaming *string `json:"videostreaming,omitempty" url:"videostreaming,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// CustomStartupOrder handles QEMU startup order parameters.
|
// CustomStartupOrder handles QEMU startup order parameters.
|
||||||
@ -164,20 +165,20 @@ type CustomStartupOrder struct {
|
|||||||
|
|
||||||
// CustomStorageDevice handles QEMU SATA device parameters.
|
// CustomStorageDevice handles QEMU SATA device parameters.
|
||||||
type CustomStorageDevice struct {
|
type CustomStorageDevice struct {
|
||||||
AIO *string `json:"aio,omitempty" url:"aio,omitempty"`
|
AIO *string `json:"aio,omitempty" url:"aio,omitempty"`
|
||||||
BackupEnabled *types.CustomBool `json:"backup,omitempty" url:"backup,omitempty,int"`
|
BackupEnabled *types2.CustomBool `json:"backup,omitempty" url:"backup,omitempty,int"`
|
||||||
BurstableReadSpeedMbps *int `json:"mbps_rd_max,omitempty" url:"mbps_rd_max,omitempty"`
|
BurstableReadSpeedMbps *int `json:"mbps_rd_max,omitempty" url:"mbps_rd_max,omitempty"`
|
||||||
BurstableWriteSpeedMbps *int `json:"mbps_wr_max,omitempty" url:"mbps_wr_max,omitempty"`
|
BurstableWriteSpeedMbps *int `json:"mbps_wr_max,omitempty" url:"mbps_wr_max,omitempty"`
|
||||||
Discard *string `json:"discard,omitempty" url:"discard,omitempty"`
|
Discard *string `json:"discard,omitempty" url:"discard,omitempty"`
|
||||||
Enabled bool `json:"-" url:"-"`
|
Enabled bool `json:"-" url:"-"`
|
||||||
FileVolume string `json:"file" url:"file"`
|
FileVolume string `json:"file" url:"file"`
|
||||||
Format *string `json:"format,omitempty" url:"format,omitempty"`
|
Format *string `json:"format,omitempty" url:"format,omitempty"`
|
||||||
IOThread *types.CustomBool `json:"iothread,omitempty" url:"iothread,omitempty,int"`
|
IOThread *types2.CustomBool `json:"iothread,omitempty" url:"iothread,omitempty,int"`
|
||||||
SSD *types.CustomBool `json:"ssd,omitempty" url:"ssd,omitempty,int"`
|
SSD *types2.CustomBool `json:"ssd,omitempty" url:"ssd,omitempty,int"`
|
||||||
MaxReadSpeedMbps *int `json:"mbps_rd,omitempty" url:"mbps_rd,omitempty"`
|
MaxReadSpeedMbps *int `json:"mbps_rd,omitempty" url:"mbps_rd,omitempty"`
|
||||||
MaxWriteSpeedMbps *int `json:"mbps_wr,omitempty" url:"mbps_wr,omitempty"`
|
MaxWriteSpeedMbps *int `json:"mbps_wr,omitempty" url:"mbps_wr,omitempty"`
|
||||||
Media *string `json:"media,omitempty" url:"media,omitempty"`
|
Media *string `json:"media,omitempty" url:"media,omitempty"`
|
||||||
Size *types.DiskSize `json:"size,omitempty" url:"size,omitempty"`
|
Size *types.DiskSize `json:"size,omitempty" url:"size,omitempty"`
|
||||||
Interface *string
|
Interface *string
|
||||||
ID *string
|
ID *string
|
||||||
FileID *string
|
FileID *string
|
||||||
@ -189,8 +190,8 @@ type CustomStorageDevices map[string]CustomStorageDevice
|
|||||||
|
|
||||||
// CustomUSBDevice handles QEMU USB device parameters.
|
// CustomUSBDevice handles QEMU USB device parameters.
|
||||||
type CustomUSBDevice struct {
|
type CustomUSBDevice struct {
|
||||||
HostDevice string `json:"host" url:"host"`
|
HostDevice string `json:"host" url:"host"`
|
||||||
USB3 *types.CustomBool `json:"usb3,omitempty" url:"usb3,omitempty,int"`
|
USB3 *types2.CustomBool `json:"usb3,omitempty" url:"usb3,omitempty,int"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// CustomUSBDevices handles QEMU USB device parameters.
|
// CustomUSBDevices handles QEMU USB device parameters.
|
||||||
@ -204,10 +205,10 @@ type CustomVGADevice struct {
|
|||||||
|
|
||||||
// CustomVirtualIODevice handles QEMU VirtIO device parameters.
|
// CustomVirtualIODevice handles QEMU VirtIO device parameters.
|
||||||
type CustomVirtualIODevice struct {
|
type CustomVirtualIODevice struct {
|
||||||
AIO *string `json:"aio,omitempty" url:"aio,omitempty"`
|
AIO *string `json:"aio,omitempty" url:"aio,omitempty"`
|
||||||
BackupEnabled *types.CustomBool `json:"backup,omitempty" url:"backup,omitempty,int"`
|
BackupEnabled *types2.CustomBool `json:"backup,omitempty" url:"backup,omitempty,int"`
|
||||||
Enabled bool `json:"-" url:"-"`
|
Enabled bool `json:"-" url:"-"`
|
||||||
FileVolume string `json:"file" url:"file"`
|
FileVolume string `json:"file" url:"file"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// CustomVirtualIODevices handles QEMU VirtIO device parameters.
|
// CustomVirtualIODevices handles QEMU VirtIO device parameters.
|
||||||
@ -221,89 +222,89 @@ type CustomWatchdogDevice struct {
|
|||||||
|
|
||||||
// CloneRequestBody contains the data for an virtual machine clone request.
|
// CloneRequestBody contains the data for an virtual machine clone request.
|
||||||
type CloneRequestBody struct {
|
type CloneRequestBody struct {
|
||||||
BandwidthLimit *int `json:"bwlimit,omitempty" url:"bwlimit,omitempty"`
|
BandwidthLimit *int `json:"bwlimit,omitempty" url:"bwlimit,omitempty"`
|
||||||
Description *string `json:"description,omitempty" url:"description,omitempty"`
|
Description *string `json:"description,omitempty" url:"description,omitempty"`
|
||||||
FullCopy *types.CustomBool `json:"full,omitempty" url:"full,omitempty,int"`
|
FullCopy *types2.CustomBool `json:"full,omitempty" url:"full,omitempty,int"`
|
||||||
Name *string `json:"name,omitempty" url:"name,omitempty"`
|
Name *string `json:"name,omitempty" url:"name,omitempty"`
|
||||||
PoolID *string `json:"pool,omitempty" url:"pool,omitempty"`
|
PoolID *string `json:"pool,omitempty" url:"pool,omitempty"`
|
||||||
SnapshotName *string `json:"snapname,omitempty" url:"snapname,omitempty"`
|
SnapshotName *string `json:"snapname,omitempty" url:"snapname,omitempty"`
|
||||||
TargetNodeName *string `json:"target,omitempty" url:"target,omitempty"`
|
TargetNodeName *string `json:"target,omitempty" url:"target,omitempty"`
|
||||||
TargetStorage *string `json:"storage,omitempty" url:"storage,omitempty"`
|
TargetStorage *string `json:"storage,omitempty" url:"storage,omitempty"`
|
||||||
TargetStorageFormat *string `json:"format,omitempty" url:"format,omitempty"`
|
TargetStorageFormat *string `json:"format,omitempty" url:"format,omitempty"`
|
||||||
VMIDNew int `json:"newid" url:"newid"`
|
VMIDNew int `json:"newid" url:"newid"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateRequestBody contains the data for a virtual machine create request.
|
// CreateRequestBody contains the data for a virtual machine create request.
|
||||||
type CreateRequestBody struct {
|
type CreateRequestBody struct {
|
||||||
ACPI *types.CustomBool `json:"acpi,omitempty" url:"acpi,omitempty,int"`
|
ACPI *types2.CustomBool `json:"acpi,omitempty" url:"acpi,omitempty,int"`
|
||||||
Agent *CustomAgent `json:"agent,omitempty" url:"agent,omitempty"`
|
Agent *CustomAgent `json:"agent,omitempty" url:"agent,omitempty"`
|
||||||
AllowReboot *types.CustomBool `json:"reboot,omitempty" url:"reboot,omitempty,int"`
|
AllowReboot *types2.CustomBool `json:"reboot,omitempty" url:"reboot,omitempty,int"`
|
||||||
AudioDevices CustomAudioDevices `json:"audio,omitempty" url:"audio,omitempty"`
|
AudioDevices CustomAudioDevices `json:"audio,omitempty" url:"audio,omitempty"`
|
||||||
Autostart *types.CustomBool `json:"autostart,omitempty" url:"autostart,omitempty,int"`
|
Autostart *types2.CustomBool `json:"autostart,omitempty" url:"autostart,omitempty,int"`
|
||||||
BackupFile *string `json:"archive,omitempty" url:"archive,omitempty"`
|
BackupFile *string `json:"archive,omitempty" url:"archive,omitempty"`
|
||||||
BandwidthLimit *int `json:"bwlimit,omitempty" url:"bwlimit,omitempty"`
|
BandwidthLimit *int `json:"bwlimit,omitempty" url:"bwlimit,omitempty"`
|
||||||
BIOS *string `json:"bios,omitempty" url:"bios,omitempty"`
|
BIOS *string `json:"bios,omitempty" url:"bios,omitempty"`
|
||||||
Boot *CustomBoot `json:"boot,omitempty" url:"boot,omitempty"`
|
Boot *CustomBoot `json:"boot,omitempty" url:"boot,omitempty"`
|
||||||
CDROM *string `json:"cdrom,omitempty" url:"cdrom,omitempty"`
|
CDROM *string `json:"cdrom,omitempty" url:"cdrom,omitempty"`
|
||||||
CloudInitConfig *CustomCloudInitConfig `json:"cloudinit,omitempty" url:"cloudinit,omitempty"`
|
CloudInitConfig *CustomCloudInitConfig `json:"cloudinit,omitempty" url:"cloudinit,omitempty"`
|
||||||
CPUArchitecture *string `json:"arch,omitempty" url:"arch,omitempty"`
|
CPUArchitecture *string `json:"arch,omitempty" url:"arch,omitempty"`
|
||||||
CPUCores *int `json:"cores,omitempty" url:"cores,omitempty"`
|
CPUCores *int `json:"cores,omitempty" url:"cores,omitempty"`
|
||||||
CPUEmulation *CustomCPUEmulation `json:"cpu,omitempty" url:"cpu,omitempty"`
|
CPUEmulation *CustomCPUEmulation `json:"cpu,omitempty" url:"cpu,omitempty"`
|
||||||
CPULimit *int `json:"cpulimit,omitempty" url:"cpulimit,omitempty"`
|
CPULimit *int `json:"cpulimit,omitempty" url:"cpulimit,omitempty"`
|
||||||
CPUSockets *int `json:"sockets,omitempty" url:"sockets,omitempty"`
|
CPUSockets *int `json:"sockets,omitempty" url:"sockets,omitempty"`
|
||||||
CPUUnits *int `json:"cpuunits,omitempty" url:"cpuunits,omitempty"`
|
CPUUnits *int `json:"cpuunits,omitempty" url:"cpuunits,omitempty"`
|
||||||
DedicatedMemory *int `json:"memory,omitempty" url:"memory,omitempty"`
|
DedicatedMemory *int `json:"memory,omitempty" url:"memory,omitempty"`
|
||||||
Delete []string `json:"delete,omitempty" url:"delete,omitempty,comma"`
|
Delete []string `json:"delete,omitempty" url:"delete,omitempty,comma"`
|
||||||
DeletionProtection *types.CustomBool `json:"protection,omitempty" url:"force,omitempty,int"`
|
DeletionProtection *types2.CustomBool `json:"protection,omitempty" url:"force,omitempty,int"`
|
||||||
Description *string `json:"description,omitempty" url:"description,omitempty"`
|
Description *string `json:"description,omitempty" url:"description,omitempty"`
|
||||||
EFIDisk *CustomEFIDisk `json:"efidisk0,omitempty" url:"efidisk0,omitempty"`
|
EFIDisk *CustomEFIDisk `json:"efidisk0,omitempty" url:"efidisk0,omitempty"`
|
||||||
FloatingMemory *int `json:"balloon,omitempty" url:"balloon,omitempty"`
|
FloatingMemory *int `json:"balloon,omitempty" url:"balloon,omitempty"`
|
||||||
FloatingMemoryShares *int `json:"shares,omitempty" url:"shares,omitempty"`
|
FloatingMemoryShares *int `json:"shares,omitempty" url:"shares,omitempty"`
|
||||||
Freeze *types.CustomBool `json:"freeze,omitempty" url:"freeze,omitempty,int"`
|
Freeze *types2.CustomBool `json:"freeze,omitempty" url:"freeze,omitempty,int"`
|
||||||
HookScript *string `json:"hookscript,omitempty" url:"hookscript,omitempty"`
|
HookScript *string `json:"hookscript,omitempty" url:"hookscript,omitempty"`
|
||||||
Hotplug types.CustomCommaSeparatedList `json:"hotplug,omitempty" url:"hotplug,omitempty,comma"`
|
Hotplug types2.CustomCommaSeparatedList `json:"hotplug,omitempty" url:"hotplug,omitempty,comma"`
|
||||||
Hugepages *string `json:"hugepages,omitempty" url:"hugepages,omitempty"`
|
Hugepages *string `json:"hugepages,omitempty" url:"hugepages,omitempty"`
|
||||||
IDEDevices CustomStorageDevices `json:"ide,omitempty" url:",omitempty"`
|
IDEDevices CustomStorageDevices `json:"ide,omitempty" url:",omitempty"`
|
||||||
KeyboardLayout *string `json:"keyboard,omitempty" url:"keyboard,omitempty"`
|
KeyboardLayout *string `json:"keyboard,omitempty" url:"keyboard,omitempty"`
|
||||||
KVMArguments *string `json:"args,omitempty" url:"args,omitempty,space"`
|
KVMArguments *string `json:"args,omitempty" url:"args,omitempty,space"`
|
||||||
KVMEnabled *types.CustomBool `json:"kvm,omitempty" url:"kvm,omitempty,int"`
|
KVMEnabled *types2.CustomBool `json:"kvm,omitempty" url:"kvm,omitempty,int"`
|
||||||
LocalTime *types.CustomBool `json:"localtime,omitempty" url:"localtime,omitempty,int"`
|
LocalTime *types2.CustomBool `json:"localtime,omitempty" url:"localtime,omitempty,int"`
|
||||||
Lock *string `json:"lock,omitempty" url:"lock,omitempty"`
|
Lock *string `json:"lock,omitempty" url:"lock,omitempty"`
|
||||||
Machine *string `json:"machine,omitempty" url:"machine,omitempty"`
|
Machine *string `json:"machine,omitempty" url:"machine,omitempty"`
|
||||||
MigrateDowntime *float64 `json:"migrate_downtime,omitempty" url:"migrate_downtime,omitempty"`
|
MigrateDowntime *float64 `json:"migrate_downtime,omitempty" url:"migrate_downtime,omitempty"`
|
||||||
MigrateSpeed *int `json:"migrate_speed,omitempty" url:"migrate_speed,omitempty"`
|
MigrateSpeed *int `json:"migrate_speed,omitempty" url:"migrate_speed,omitempty"`
|
||||||
Name *string `json:"name,omitempty" url:"name,omitempty"`
|
Name *string `json:"name,omitempty" url:"name,omitempty"`
|
||||||
NetworkDevices CustomNetworkDevices `json:"net,omitempty" url:"net,omitempty"`
|
NetworkDevices CustomNetworkDevices `json:"net,omitempty" url:"net,omitempty"`
|
||||||
NUMADevices CustomNUMADevices `json:"numa_devices,omitempty" url:"numa,omitempty"`
|
NUMADevices CustomNUMADevices `json:"numa_devices,omitempty" url:"numa,omitempty"`
|
||||||
NUMAEnabled *types.CustomBool `json:"numa,omitempty" url:"numa,omitempty,int"`
|
NUMAEnabled *types2.CustomBool `json:"numa,omitempty" url:"numa,omitempty,int"`
|
||||||
OSType *string `json:"ostype,omitempty" url:"ostype,omitempty"`
|
OSType *string `json:"ostype,omitempty" url:"ostype,omitempty"`
|
||||||
Overwrite *types.CustomBool `json:"force,omitempty" url:"force,omitempty,int"`
|
Overwrite *types2.CustomBool `json:"force,omitempty" url:"force,omitempty,int"`
|
||||||
PCIDevices CustomPCIDevices `json:"hostpci,omitempty" url:"hostpci,omitempty"`
|
PCIDevices CustomPCIDevices `json:"hostpci,omitempty" url:"hostpci,omitempty"`
|
||||||
PoolID *string `json:"pool,omitempty" url:"pool,omitempty"`
|
PoolID *string `json:"pool,omitempty" url:"pool,omitempty"`
|
||||||
Revert *string `json:"revert,omitempty" url:"revert,omitempty"`
|
Revert *string `json:"revert,omitempty" url:"revert,omitempty"`
|
||||||
SATADevices CustomStorageDevices `json:"sata,omitempty" url:"sata,omitempty"`
|
SATADevices CustomStorageDevices `json:"sata,omitempty" url:"sata,omitempty"`
|
||||||
SCSIDevices CustomStorageDevices `json:"scsi,omitempty" url:"scsi,omitempty"`
|
SCSIDevices CustomStorageDevices `json:"scsi,omitempty" url:"scsi,omitempty"`
|
||||||
SCSIHardware *string `json:"scsihw,omitempty" url:"scsihw,omitempty"`
|
SCSIHardware *string `json:"scsihw,omitempty" url:"scsihw,omitempty"`
|
||||||
SerialDevices CustomSerialDevices `json:"serial,omitempty" url:"serial,omitempty"`
|
SerialDevices CustomSerialDevices `json:"serial,omitempty" url:"serial,omitempty"`
|
||||||
SharedMemory *CustomSharedMemory `json:"ivshmem,omitempty" url:"ivshmem,omitempty"`
|
SharedMemory *CustomSharedMemory `json:"ivshmem,omitempty" url:"ivshmem,omitempty"`
|
||||||
SkipLock *types.CustomBool `json:"skiplock,omitempty" url:"skiplock,omitempty,int"`
|
SkipLock *types2.CustomBool `json:"skiplock,omitempty" url:"skiplock,omitempty,int"`
|
||||||
SMBIOS *CustomSMBIOS `json:"smbios1,omitempty" url:"smbios1,omitempty"`
|
SMBIOS *CustomSMBIOS `json:"smbios1,omitempty" url:"smbios1,omitempty"`
|
||||||
SpiceEnhancements *CustomSpiceEnhancements `json:"spice_enhancements,omitempty" url:"spice_enhancements,omitempty"`
|
SpiceEnhancements *CustomSpiceEnhancements `json:"spice_enhancements,omitempty" url:"spice_enhancements,omitempty"`
|
||||||
StartDate *string `json:"startdate,omitempty" url:"startdate,omitempty"`
|
StartDate *string `json:"startdate,omitempty" url:"startdate,omitempty"`
|
||||||
StartOnBoot *types.CustomBool `json:"onboot,omitempty" url:"onboot,omitempty,int"`
|
StartOnBoot *types2.CustomBool `json:"onboot,omitempty" url:"onboot,omitempty,int"`
|
||||||
StartupOrder *CustomStartupOrder `json:"startup,omitempty" url:"startup,omitempty"`
|
StartupOrder *CustomStartupOrder `json:"startup,omitempty" url:"startup,omitempty"`
|
||||||
TabletDeviceEnabled *types.CustomBool `json:"tablet,omitempty" url:"tablet,omitempty,int"`
|
TabletDeviceEnabled *types2.CustomBool `json:"tablet,omitempty" url:"tablet,omitempty,int"`
|
||||||
Tags *string `json:"tags,omitempty" url:"tags,omitempty"`
|
Tags *string `json:"tags,omitempty" url:"tags,omitempty"`
|
||||||
Template *types.CustomBool `json:"template,omitempty" url:"template,omitempty,int"`
|
Template *types2.CustomBool `json:"template,omitempty" url:"template,omitempty,int"`
|
||||||
TimeDriftFixEnabled *types.CustomBool `json:"tdf,omitempty" url:"tdf,omitempty,int"`
|
TimeDriftFixEnabled *types2.CustomBool `json:"tdf,omitempty" url:"tdf,omitempty,int"`
|
||||||
USBDevices CustomUSBDevices `json:"usb,omitempty" url:"usb,omitempty"`
|
USBDevices CustomUSBDevices `json:"usb,omitempty" url:"usb,omitempty"`
|
||||||
VGADevice *CustomVGADevice `json:"vga,omitempty" url:"vga,omitempty"`
|
VGADevice *CustomVGADevice `json:"vga,omitempty" url:"vga,omitempty"`
|
||||||
VirtualCPUCount *int `json:"vcpus,omitempty" url:"vcpus,omitempty"`
|
VirtualCPUCount *int `json:"vcpus,omitempty" url:"vcpus,omitempty"`
|
||||||
VirtualIODevices CustomStorageDevices `json:"virtio,omitempty" url:"virtio,omitempty"`
|
VirtualIODevices CustomStorageDevices `json:"virtio,omitempty" url:"virtio,omitempty"`
|
||||||
VMGenerationID *string `json:"vmgenid,omitempty" url:"vmgenid,omitempty"`
|
VMGenerationID *string `json:"vmgenid,omitempty" url:"vmgenid,omitempty"`
|
||||||
VMID *int `json:"vmid,omitempty" url:"vmid,omitempty"`
|
VMID *int `json:"vmid,omitempty" url:"vmid,omitempty"`
|
||||||
VMStateDatastoreID *string `json:"vmstatestorage,omitempty" url:"vmstatestorage,omitempty"`
|
VMStateDatastoreID *string `json:"vmstatestorage,omitempty" url:"vmstatestorage,omitempty"`
|
||||||
WatchdogDevice *CustomWatchdogDevice `json:"watchdog,omitempty" url:"watchdog,omitempty"`
|
WatchdogDevice *CustomWatchdogDevice `json:"watchdog,omitempty" url:"watchdog,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateResponseBody contains the body from a create response.
|
// CreateResponseBody contains the body from a create response.
|
||||||
@ -355,137 +356,137 @@ type GetResponseBody struct {
|
|||||||
|
|
||||||
// GetResponseData contains the data from an virtual machine get response.
|
// GetResponseData contains the data from an virtual machine get response.
|
||||||
type GetResponseData struct {
|
type GetResponseData struct {
|
||||||
ACPI *types.CustomBool `json:"acpi,omitempty"`
|
ACPI *types2.CustomBool `json:"acpi,omitempty"`
|
||||||
Agent *CustomAgent `json:"agent,omitempty"`
|
Agent *CustomAgent `json:"agent,omitempty"`
|
||||||
AllowReboot *types.CustomBool `json:"reboot,omitempty"`
|
AllowReboot *types2.CustomBool `json:"reboot,omitempty"`
|
||||||
AudioDevice *CustomAudioDevice `json:"audio0,omitempty"`
|
AudioDevice *CustomAudioDevice `json:"audio0,omitempty"`
|
||||||
Autostart *types.CustomBool `json:"autostart,omitempty"`
|
Autostart *types2.CustomBool `json:"autostart,omitempty"`
|
||||||
BackupFile *string `json:"archive,omitempty"`
|
BackupFile *string `json:"archive,omitempty"`
|
||||||
BandwidthLimit *int `json:"bwlimit,omitempty"`
|
BandwidthLimit *int `json:"bwlimit,omitempty"`
|
||||||
BIOS *string `json:"bios,omitempty"`
|
BIOS *string `json:"bios,omitempty"`
|
||||||
BootDisk *string `json:"bootdisk,omitempty"`
|
BootDisk *string `json:"bootdisk,omitempty"`
|
||||||
BootOrder *string `json:"boot,omitempty"`
|
BootOrder *string `json:"boot,omitempty"`
|
||||||
CDROM *string `json:"cdrom,omitempty"`
|
CDROM *string `json:"cdrom,omitempty"`
|
||||||
CloudInitDNSDomain *string `json:"searchdomain,omitempty"`
|
CloudInitDNSDomain *string `json:"searchdomain,omitempty"`
|
||||||
CloudInitDNSServer *string `json:"nameserver,omitempty"`
|
CloudInitDNSServer *string `json:"nameserver,omitempty"`
|
||||||
CloudInitFiles *CustomCloudInitFiles `json:"cicustom,omitempty"`
|
CloudInitFiles *CustomCloudInitFiles `json:"cicustom,omitempty"`
|
||||||
CloudInitPassword *string `json:"cipassword,omitempty"`
|
CloudInitPassword *string `json:"cipassword,omitempty"`
|
||||||
CloudInitSSHKeys *CustomCloudInitSSHKeys `json:"sshkeys,omitempty"`
|
CloudInitSSHKeys *CustomCloudInitSSHKeys `json:"sshkeys,omitempty"`
|
||||||
CloudInitType *string `json:"citype,omitempty"`
|
CloudInitType *string `json:"citype,omitempty"`
|
||||||
CloudInitUsername *string `json:"ciuser,omitempty"`
|
CloudInitUsername *string `json:"ciuser,omitempty"`
|
||||||
CPUArchitecture *string `json:"arch,omitempty"`
|
CPUArchitecture *string `json:"arch,omitempty"`
|
||||||
CPUCores *int `json:"cores,omitempty"`
|
CPUCores *int `json:"cores,omitempty"`
|
||||||
CPUEmulation *CustomCPUEmulation `json:"cpu,omitempty"`
|
CPUEmulation *CustomCPUEmulation `json:"cpu,omitempty"`
|
||||||
CPULimit *int `json:"cpulimit,omitempty"`
|
CPULimit *int `json:"cpulimit,omitempty"`
|
||||||
CPUSockets *int `json:"sockets,omitempty"`
|
CPUSockets *int `json:"sockets,omitempty"`
|
||||||
CPUUnits *int `json:"cpuunits,omitempty"`
|
CPUUnits *int `json:"cpuunits,omitempty"`
|
||||||
DedicatedMemory *int `json:"memory,omitempty"`
|
DedicatedMemory *int `json:"memory,omitempty"`
|
||||||
DeletionProtection *types.CustomBool `json:"protection,omitempty"`
|
DeletionProtection *types2.CustomBool `json:"protection,omitempty"`
|
||||||
Description *string `json:"description,omitempty"`
|
Description *string `json:"description,omitempty"`
|
||||||
EFIDisk *CustomEFIDisk `json:"efidisk0,omitempty"`
|
EFIDisk *CustomEFIDisk `json:"efidisk0,omitempty"`
|
||||||
FloatingMemory *int `json:"balloon,omitempty"`
|
FloatingMemory *int `json:"balloon,omitempty"`
|
||||||
FloatingMemoryShares *int `json:"shares,omitempty"`
|
FloatingMemoryShares *int `json:"shares,omitempty"`
|
||||||
Freeze *types.CustomBool `json:"freeze,omitempty"`
|
Freeze *types2.CustomBool `json:"freeze,omitempty"`
|
||||||
HookScript *string `json:"hookscript,omitempty"`
|
HookScript *string `json:"hookscript,omitempty"`
|
||||||
Hotplug *types.CustomCommaSeparatedList `json:"hotplug,omitempty"`
|
Hotplug *types2.CustomCommaSeparatedList `json:"hotplug,omitempty"`
|
||||||
Hugepages *string `json:"hugepages,omitempty"`
|
Hugepages *string `json:"hugepages,omitempty"`
|
||||||
IDEDevice0 *CustomStorageDevice `json:"ide0,omitempty"`
|
IDEDevice0 *CustomStorageDevice `json:"ide0,omitempty"`
|
||||||
IDEDevice1 *CustomStorageDevice `json:"ide1,omitempty"`
|
IDEDevice1 *CustomStorageDevice `json:"ide1,omitempty"`
|
||||||
IDEDevice2 *CustomStorageDevice `json:"ide2,omitempty"`
|
IDEDevice2 *CustomStorageDevice `json:"ide2,omitempty"`
|
||||||
IDEDevice3 *CustomStorageDevice `json:"ide3,omitempty"`
|
IDEDevice3 *CustomStorageDevice `json:"ide3,omitempty"`
|
||||||
IPConfig0 *CustomCloudInitIPConfig `json:"ipconfig0,omitempty"`
|
IPConfig0 *CustomCloudInitIPConfig `json:"ipconfig0,omitempty"`
|
||||||
IPConfig1 *CustomCloudInitIPConfig `json:"ipconfig1,omitempty"`
|
IPConfig1 *CustomCloudInitIPConfig `json:"ipconfig1,omitempty"`
|
||||||
IPConfig2 *CustomCloudInitIPConfig `json:"ipconfig2,omitempty"`
|
IPConfig2 *CustomCloudInitIPConfig `json:"ipconfig2,omitempty"`
|
||||||
IPConfig3 *CustomCloudInitIPConfig `json:"ipconfig3,omitempty"`
|
IPConfig3 *CustomCloudInitIPConfig `json:"ipconfig3,omitempty"`
|
||||||
IPConfig4 *CustomCloudInitIPConfig `json:"ipconfig4,omitempty"`
|
IPConfig4 *CustomCloudInitIPConfig `json:"ipconfig4,omitempty"`
|
||||||
IPConfig5 *CustomCloudInitIPConfig `json:"ipconfig5,omitempty"`
|
IPConfig5 *CustomCloudInitIPConfig `json:"ipconfig5,omitempty"`
|
||||||
IPConfig6 *CustomCloudInitIPConfig `json:"ipconfig6,omitempty"`
|
IPConfig6 *CustomCloudInitIPConfig `json:"ipconfig6,omitempty"`
|
||||||
IPConfig7 *CustomCloudInitIPConfig `json:"ipconfig7,omitempty"`
|
IPConfig7 *CustomCloudInitIPConfig `json:"ipconfig7,omitempty"`
|
||||||
KeyboardLayout *string `json:"keyboard,omitempty"`
|
KeyboardLayout *string `json:"keyboard,omitempty"`
|
||||||
KVMArguments *string `json:"args,omitempty"`
|
KVMArguments *string `json:"args,omitempty"`
|
||||||
KVMEnabled *types.CustomBool `json:"kvm,omitempty"`
|
KVMEnabled *types2.CustomBool `json:"kvm,omitempty"`
|
||||||
LocalTime *types.CustomBool `json:"localtime,omitempty"`
|
LocalTime *types2.CustomBool `json:"localtime,omitempty"`
|
||||||
Lock *string `json:"lock,omitempty"`
|
Lock *string `json:"lock,omitempty"`
|
||||||
Machine *string `json:"machine,omitempty"`
|
Machine *string `json:"machine,omitempty"`
|
||||||
MigrateDowntime *float64 `json:"migrate_downtime,omitempty"`
|
MigrateDowntime *float64 `json:"migrate_downtime,omitempty"`
|
||||||
MigrateSpeed *int `json:"migrate_speed,omitempty"`
|
MigrateSpeed *int `json:"migrate_speed,omitempty"`
|
||||||
Name *string `json:"name,omitempty"`
|
Name *string `json:"name,omitempty"`
|
||||||
NetworkDevice0 *CustomNetworkDevice `json:"net0,omitempty"`
|
NetworkDevice0 *CustomNetworkDevice `json:"net0,omitempty"`
|
||||||
NetworkDevice1 *CustomNetworkDevice `json:"net1,omitempty"`
|
NetworkDevice1 *CustomNetworkDevice `json:"net1,omitempty"`
|
||||||
NetworkDevice2 *CustomNetworkDevice `json:"net2,omitempty"`
|
NetworkDevice2 *CustomNetworkDevice `json:"net2,omitempty"`
|
||||||
NetworkDevice3 *CustomNetworkDevice `json:"net3,omitempty"`
|
NetworkDevice3 *CustomNetworkDevice `json:"net3,omitempty"`
|
||||||
NetworkDevice4 *CustomNetworkDevice `json:"net4,omitempty"`
|
NetworkDevice4 *CustomNetworkDevice `json:"net4,omitempty"`
|
||||||
NetworkDevice5 *CustomNetworkDevice `json:"net5,omitempty"`
|
NetworkDevice5 *CustomNetworkDevice `json:"net5,omitempty"`
|
||||||
NetworkDevice6 *CustomNetworkDevice `json:"net6,omitempty"`
|
NetworkDevice6 *CustomNetworkDevice `json:"net6,omitempty"`
|
||||||
NetworkDevice7 *CustomNetworkDevice `json:"net7,omitempty"`
|
NetworkDevice7 *CustomNetworkDevice `json:"net7,omitempty"`
|
||||||
NUMADevices *CustomNUMADevices `json:"numa_devices,omitempty"`
|
NUMADevices *CustomNUMADevices `json:"numa_devices,omitempty"`
|
||||||
NUMAEnabled *types.CustomBool `json:"numa,omitempty"`
|
NUMAEnabled *types2.CustomBool `json:"numa,omitempty"`
|
||||||
OSType *string `json:"ostype,omitempty"`
|
OSType *string `json:"ostype,omitempty"`
|
||||||
Overwrite *types.CustomBool `json:"force,omitempty"`
|
Overwrite *types2.CustomBool `json:"force,omitempty"`
|
||||||
PCIDevice0 *CustomPCIDevice `json:"hostpci0,omitempty"`
|
PCIDevice0 *CustomPCIDevice `json:"hostpci0,omitempty"`
|
||||||
PCIDevice1 *CustomPCIDevice `json:"hostpci1,omitempty"`
|
PCIDevice1 *CustomPCIDevice `json:"hostpci1,omitempty"`
|
||||||
PCIDevice2 *CustomPCIDevice `json:"hostpci2,omitempty"`
|
PCIDevice2 *CustomPCIDevice `json:"hostpci2,omitempty"`
|
||||||
PCIDevice3 *CustomPCIDevice `json:"hostpci3,omitempty"`
|
PCIDevice3 *CustomPCIDevice `json:"hostpci3,omitempty"`
|
||||||
PoolID *string `json:"pool,omitempty" url:"pool,omitempty"`
|
PoolID *string `json:"pool,omitempty" url:"pool,omitempty"`
|
||||||
Revert *string `json:"revert,omitempty"`
|
Revert *string `json:"revert,omitempty"`
|
||||||
SATADevice0 *CustomStorageDevice `json:"sata0,omitempty"`
|
SATADevice0 *CustomStorageDevice `json:"sata0,omitempty"`
|
||||||
SATADevice1 *CustomStorageDevice `json:"sata1,omitempty"`
|
SATADevice1 *CustomStorageDevice `json:"sata1,omitempty"`
|
||||||
SATADevice2 *CustomStorageDevice `json:"sata2,omitempty"`
|
SATADevice2 *CustomStorageDevice `json:"sata2,omitempty"`
|
||||||
SATADevice3 *CustomStorageDevice `json:"sata3,omitempty"`
|
SATADevice3 *CustomStorageDevice `json:"sata3,omitempty"`
|
||||||
SATADevice4 *CustomStorageDevice `json:"sata4,omitempty"`
|
SATADevice4 *CustomStorageDevice `json:"sata4,omitempty"`
|
||||||
SATADevice5 *CustomStorageDevice `json:"sata5,omitempty"`
|
SATADevice5 *CustomStorageDevice `json:"sata5,omitempty"`
|
||||||
SCSIDevice0 *CustomStorageDevice `json:"scsi0,omitempty"`
|
SCSIDevice0 *CustomStorageDevice `json:"scsi0,omitempty"`
|
||||||
SCSIDevice1 *CustomStorageDevice `json:"scsi1,omitempty"`
|
SCSIDevice1 *CustomStorageDevice `json:"scsi1,omitempty"`
|
||||||
SCSIDevice2 *CustomStorageDevice `json:"scsi2,omitempty"`
|
SCSIDevice2 *CustomStorageDevice `json:"scsi2,omitempty"`
|
||||||
SCSIDevice3 *CustomStorageDevice `json:"scsi3,omitempty"`
|
SCSIDevice3 *CustomStorageDevice `json:"scsi3,omitempty"`
|
||||||
SCSIDevice4 *CustomStorageDevice `json:"scsi4,omitempty"`
|
SCSIDevice4 *CustomStorageDevice `json:"scsi4,omitempty"`
|
||||||
SCSIDevice5 *CustomStorageDevice `json:"scsi5,omitempty"`
|
SCSIDevice5 *CustomStorageDevice `json:"scsi5,omitempty"`
|
||||||
SCSIDevice6 *CustomStorageDevice `json:"scsi6,omitempty"`
|
SCSIDevice6 *CustomStorageDevice `json:"scsi6,omitempty"`
|
||||||
SCSIDevice7 *CustomStorageDevice `json:"scsi7,omitempty"`
|
SCSIDevice7 *CustomStorageDevice `json:"scsi7,omitempty"`
|
||||||
SCSIDevice8 *CustomStorageDevice `json:"scsi8,omitempty"`
|
SCSIDevice8 *CustomStorageDevice `json:"scsi8,omitempty"`
|
||||||
SCSIDevice9 *CustomStorageDevice `json:"scsi9,omitempty"`
|
SCSIDevice9 *CustomStorageDevice `json:"scsi9,omitempty"`
|
||||||
SCSIDevice10 *CustomStorageDevice `json:"scsi10,omitempty"`
|
SCSIDevice10 *CustomStorageDevice `json:"scsi10,omitempty"`
|
||||||
SCSIDevice11 *CustomStorageDevice `json:"scsi11,omitempty"`
|
SCSIDevice11 *CustomStorageDevice `json:"scsi11,omitempty"`
|
||||||
SCSIDevice12 *CustomStorageDevice `json:"scsi12,omitempty"`
|
SCSIDevice12 *CustomStorageDevice `json:"scsi12,omitempty"`
|
||||||
SCSIDevice13 *CustomStorageDevice `json:"scsi13,omitempty"`
|
SCSIDevice13 *CustomStorageDevice `json:"scsi13,omitempty"`
|
||||||
SCSIHardware *string `json:"scsihw,omitempty"`
|
SCSIHardware *string `json:"scsihw,omitempty"`
|
||||||
SerialDevice0 *string `json:"serial0,omitempty"`
|
SerialDevice0 *string `json:"serial0,omitempty"`
|
||||||
SerialDevice1 *string `json:"serial1,omitempty"`
|
SerialDevice1 *string `json:"serial1,omitempty"`
|
||||||
SerialDevice2 *string `json:"serial2,omitempty"`
|
SerialDevice2 *string `json:"serial2,omitempty"`
|
||||||
SerialDevice3 *string `json:"serial3,omitempty"`
|
SerialDevice3 *string `json:"serial3,omitempty"`
|
||||||
SharedMemory *CustomSharedMemory `json:"ivshmem,omitempty"`
|
SharedMemory *CustomSharedMemory `json:"ivshmem,omitempty"`
|
||||||
SkipLock *types.CustomBool `json:"skiplock,omitempty"`
|
SkipLock *types2.CustomBool `json:"skiplock,omitempty"`
|
||||||
SMBIOS *CustomSMBIOS `json:"smbios1,omitempty"`
|
SMBIOS *CustomSMBIOS `json:"smbios1,omitempty"`
|
||||||
SpiceEnhancements *CustomSpiceEnhancements `json:"spice_enhancements,omitempty"`
|
SpiceEnhancements *CustomSpiceEnhancements `json:"spice_enhancements,omitempty"`
|
||||||
StartDate *string `json:"startdate,omitempty"`
|
StartDate *string `json:"startdate,omitempty"`
|
||||||
StartOnBoot *types.CustomBool `json:"onboot,omitempty"`
|
StartOnBoot *types2.CustomBool `json:"onboot,omitempty"`
|
||||||
StartupOrder *CustomStartupOrder `json:"startup,omitempty"`
|
StartupOrder *CustomStartupOrder `json:"startup,omitempty"`
|
||||||
TabletDeviceEnabled *types.CustomBool `json:"tablet,omitempty"`
|
TabletDeviceEnabled *types2.CustomBool `json:"tablet,omitempty"`
|
||||||
Tags *string `json:"tags,omitempty"`
|
Tags *string `json:"tags,omitempty"`
|
||||||
Template *types.CustomBool `json:"template,omitempty"`
|
Template *types2.CustomBool `json:"template,omitempty"`
|
||||||
TimeDriftFixEnabled *types.CustomBool `json:"tdf,omitempty"`
|
TimeDriftFixEnabled *types2.CustomBool `json:"tdf,omitempty"`
|
||||||
USBDevices *CustomUSBDevices `json:"usb,omitempty"`
|
USBDevices *CustomUSBDevices `json:"usb,omitempty"`
|
||||||
VGADevice *CustomVGADevice `json:"vga,omitempty"`
|
VGADevice *CustomVGADevice `json:"vga,omitempty"`
|
||||||
VirtualCPUCount *int `json:"vcpus,omitempty"`
|
VirtualCPUCount *int `json:"vcpus,omitempty"`
|
||||||
VirtualIODevice0 *CustomStorageDevice `json:"virtio0,omitempty"`
|
VirtualIODevice0 *CustomStorageDevice `json:"virtio0,omitempty"`
|
||||||
VirtualIODevice1 *CustomStorageDevice `json:"virtio1,omitempty"`
|
VirtualIODevice1 *CustomStorageDevice `json:"virtio1,omitempty"`
|
||||||
VirtualIODevice2 *CustomStorageDevice `json:"virtio2,omitempty"`
|
VirtualIODevice2 *CustomStorageDevice `json:"virtio2,omitempty"`
|
||||||
VirtualIODevice3 *CustomStorageDevice `json:"virtio3,omitempty"`
|
VirtualIODevice3 *CustomStorageDevice `json:"virtio3,omitempty"`
|
||||||
VirtualIODevice4 *CustomStorageDevice `json:"virtio4,omitempty"`
|
VirtualIODevice4 *CustomStorageDevice `json:"virtio4,omitempty"`
|
||||||
VirtualIODevice5 *CustomStorageDevice `json:"virtio5,omitempty"`
|
VirtualIODevice5 *CustomStorageDevice `json:"virtio5,omitempty"`
|
||||||
VirtualIODevice6 *CustomStorageDevice `json:"virtio6,omitempty"`
|
VirtualIODevice6 *CustomStorageDevice `json:"virtio6,omitempty"`
|
||||||
VirtualIODevice7 *CustomStorageDevice `json:"virtio7,omitempty"`
|
VirtualIODevice7 *CustomStorageDevice `json:"virtio7,omitempty"`
|
||||||
VirtualIODevice8 *CustomStorageDevice `json:"virtio8,omitempty"`
|
VirtualIODevice8 *CustomStorageDevice `json:"virtio8,omitempty"`
|
||||||
VirtualIODevice9 *CustomStorageDevice `json:"virtio9,omitempty"`
|
VirtualIODevice9 *CustomStorageDevice `json:"virtio9,omitempty"`
|
||||||
VirtualIODevice10 *CustomStorageDevice `json:"virtio10,omitempty"`
|
VirtualIODevice10 *CustomStorageDevice `json:"virtio10,omitempty"`
|
||||||
VirtualIODevice11 *CustomStorageDevice `json:"virtio11,omitempty"`
|
VirtualIODevice11 *CustomStorageDevice `json:"virtio11,omitempty"`
|
||||||
VirtualIODevice12 *CustomStorageDevice `json:"virtio12,omitempty"`
|
VirtualIODevice12 *CustomStorageDevice `json:"virtio12,omitempty"`
|
||||||
VirtualIODevice13 *CustomStorageDevice `json:"virtio13,omitempty"`
|
VirtualIODevice13 *CustomStorageDevice `json:"virtio13,omitempty"`
|
||||||
VirtualIODevice14 *CustomStorageDevice `json:"virtio14,omitempty"`
|
VirtualIODevice14 *CustomStorageDevice `json:"virtio14,omitempty"`
|
||||||
VirtualIODevice15 *CustomStorageDevice `json:"virtio15,omitempty"`
|
VirtualIODevice15 *CustomStorageDevice `json:"virtio15,omitempty"`
|
||||||
VMGenerationID *string `json:"vmgenid,omitempty"`
|
VMGenerationID *string `json:"vmgenid,omitempty"`
|
||||||
VMStateDatastoreID *string `json:"vmstatestorage,omitempty"`
|
VMStateDatastoreID *string `json:"vmstatestorage,omitempty"`
|
||||||
WatchdogDevice *CustomWatchdogDevice `json:"watchdog,omitempty"`
|
WatchdogDevice *CustomWatchdogDevice `json:"watchdog,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetStatusResponseBody contains the body from a VM get status response.
|
// GetStatusResponseBody contains the body from a VM get status response.
|
||||||
@ -495,19 +496,19 @@ type GetStatusResponseBody struct {
|
|||||||
|
|
||||||
// GetStatusResponseData contains the data from a VM get status response.
|
// GetStatusResponseData contains the data from a VM get status response.
|
||||||
type GetStatusResponseData struct {
|
type GetStatusResponseData struct {
|
||||||
AgentEnabled *types.CustomBool `json:"agent,omitempty"`
|
AgentEnabled *types2.CustomBool `json:"agent,omitempty"`
|
||||||
CPUCount *float64 `json:"cpus,omitempty"`
|
CPUCount *float64 `json:"cpus,omitempty"`
|
||||||
Lock *string `json:"lock,omitempty"`
|
Lock *string `json:"lock,omitempty"`
|
||||||
MemoryAllocation *int `json:"maxmem,omitempty"`
|
MemoryAllocation *int `json:"maxmem,omitempty"`
|
||||||
Name *string `json:"name,omitempty"`
|
Name *string `json:"name,omitempty"`
|
||||||
PID *int `json:"pid,omitempty"`
|
PID *int `json:"pid,omitempty"`
|
||||||
QMPStatus *string `json:"qmpstatus,omitempty"`
|
QMPStatus *string `json:"qmpstatus,omitempty"`
|
||||||
RootDiskSize *int `json:"maxdisk,omitempty"`
|
RootDiskSize *int `json:"maxdisk,omitempty"`
|
||||||
SpiceSupport *types.CustomBool `json:"spice,omitempty"`
|
SpiceSupport *types2.CustomBool `json:"spice,omitempty"`
|
||||||
Status string `json:"status,omitempty"`
|
Status string `json:"status,omitempty"`
|
||||||
Tags *string `json:"tags,omitempty"`
|
Tags *string `json:"tags,omitempty"`
|
||||||
Uptime *int `json:"uptime,omitempty"`
|
Uptime *int `json:"uptime,omitempty"`
|
||||||
VMID *int `json:"vmid,omitempty"`
|
VMID *int `json:"vmid,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListResponseBody contains the body from a virtual machine list response.
|
// ListResponseBody contains the body from a virtual machine list response.
|
||||||
@ -524,10 +525,10 @@ type ListResponseData struct {
|
|||||||
|
|
||||||
// MigrateRequestBody contains the body for a VM migration request.
|
// MigrateRequestBody contains the body for a VM migration request.
|
||||||
type MigrateRequestBody struct {
|
type MigrateRequestBody struct {
|
||||||
OnlineMigration *types.CustomBool `json:"online,omitempty" url:"online,omitempty"`
|
OnlineMigration *types2.CustomBool `json:"online,omitempty" url:"online,omitempty"`
|
||||||
TargetNode string `json:"target" url:"target"`
|
TargetNode string `json:"target" url:"target"`
|
||||||
TargetStorage *string `json:"targetstorage,omitempty" url:"targetstorage,omitempty"`
|
TargetStorage *string `json:"targetstorage,omitempty" url:"targetstorage,omitempty"`
|
||||||
WithLocalDisks *types.CustomBool `json:"with-local-disks,omitempty" url:"with-local-disks,omitempty,int"`
|
WithLocalDisks *types2.CustomBool `json:"with-local-disks,omitempty" url:"with-local-disks,omitempty,int"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// MigrateResponseBody contains the body from a VM migrate response.
|
// MigrateResponseBody contains the body from a VM migrate response.
|
||||||
@ -537,12 +538,12 @@ type MigrateResponseBody struct {
|
|||||||
|
|
||||||
// MoveDiskRequestBody contains the body for a VM move disk request.
|
// MoveDiskRequestBody contains the body for a VM move disk request.
|
||||||
type MoveDiskRequestBody struct {
|
type MoveDiskRequestBody struct {
|
||||||
BandwidthLimit *int `json:"bwlimit,omitempty" url:"bwlimit,omitempty"`
|
BandwidthLimit *int `json:"bwlimit,omitempty" url:"bwlimit,omitempty"`
|
||||||
DeleteOriginalDisk *types.CustomBool `json:"delete,omitempty" url:"delete,omitempty,int"`
|
DeleteOriginalDisk *types2.CustomBool `json:"delete,omitempty" url:"delete,omitempty,int"`
|
||||||
Digest *string `json:"digest,omitempty" url:"digest,omitempty"`
|
Digest *string `json:"digest,omitempty" url:"digest,omitempty"`
|
||||||
Disk string `json:"disk" url:"disk"`
|
Disk string `json:"disk" url:"disk"`
|
||||||
TargetStorage string `json:"storage" url:"storage"`
|
TargetStorage string `json:"storage" url:"storage"`
|
||||||
TargetStorageFormat *string `json:"format,omitempty" url:"format,omitempty"`
|
TargetStorageFormat *string `json:"format,omitempty" url:"format,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// MoveDiskResponseBody contains the body from a VM move disk response.
|
// MoveDiskResponseBody contains the body from a VM move disk response.
|
||||||
@ -562,18 +563,18 @@ type RebootResponseBody struct {
|
|||||||
|
|
||||||
// ResizeDiskRequestBody contains the body for a VM resize disk request.
|
// ResizeDiskRequestBody contains the body for a VM resize disk request.
|
||||||
type ResizeDiskRequestBody struct {
|
type ResizeDiskRequestBody struct {
|
||||||
Digest *string `json:"digest,omitempty" url:"digest,omitempty"`
|
Digest *string `json:"digest,omitempty" url:"digest,omitempty"`
|
||||||
Disk string `json:"disk" url:"disk"`
|
Disk string `json:"disk" url:"disk"`
|
||||||
Size types.DiskSize `json:"size" url:"size"`
|
Size types.DiskSize `json:"size" url:"size"`
|
||||||
SkipLock *types.CustomBool `json:"skiplock,omitempty" url:"skiplock,omitempty,int"`
|
SkipLock *types2.CustomBool `json:"skiplock,omitempty" url:"skiplock,omitempty,int"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ShutdownRequestBody contains the body for a VM shutdown request.
|
// ShutdownRequestBody contains the body for a VM shutdown request.
|
||||||
type ShutdownRequestBody struct {
|
type ShutdownRequestBody struct {
|
||||||
ForceStop *types.CustomBool `json:"forceStop,omitempty" url:"forceStop,omitempty,int"`
|
ForceStop *types2.CustomBool `json:"forceStop,omitempty" url:"forceStop,omitempty,int"`
|
||||||
KeepActive *types.CustomBool `json:"keepActive,omitempty" url:"keepActive,omitempty,int"`
|
KeepActive *types2.CustomBool `json:"keepActive,omitempty" url:"keepActive,omitempty,int"`
|
||||||
SkipLock *types.CustomBool `json:"skipLock,omitempty" url:"skipLock,omitempty,int"`
|
SkipLock *types2.CustomBool `json:"skipLock,omitempty" url:"skipLock,omitempty,int"`
|
||||||
Timeout *int `json:"timeout,omitempty" url:"timeout,omitempty"`
|
Timeout *int `json:"timeout,omitempty" url:"timeout,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ShutdownResponseBody contains the body from a VM shutdown response.
|
// ShutdownResponseBody contains the body from a VM shutdown response.
|
||||||
@ -1267,15 +1268,15 @@ func (r *CustomAgent) UnmarshalJSON(b []byte) error {
|
|||||||
v := strings.Split(strings.TrimSpace(p), "=")
|
v := strings.Split(strings.TrimSpace(p), "=")
|
||||||
|
|
||||||
if len(v) == 1 {
|
if len(v) == 1 {
|
||||||
enabled := types.CustomBool(v[0] == "1")
|
enabled := types2.CustomBool(v[0] == "1")
|
||||||
r.Enabled = &enabled
|
r.Enabled = &enabled
|
||||||
} else if len(v) == 2 {
|
} else if len(v) == 2 {
|
||||||
switch v[0] {
|
switch v[0] {
|
||||||
case "enabled":
|
case "enabled":
|
||||||
enabled := types.CustomBool(v[1] == "1")
|
enabled := types2.CustomBool(v[1] == "1")
|
||||||
r.Enabled = &enabled
|
r.Enabled = &enabled
|
||||||
case "fstrim_cloned_disks":
|
case "fstrim_cloned_disks":
|
||||||
fstrim := types.CustomBool(v[1] == "1")
|
fstrim := types2.CustomBool(v[1] == "1")
|
||||||
r.TrimClonedDisks = &fstrim
|
r.TrimClonedDisks = &fstrim
|
||||||
case "type":
|
case "type":
|
||||||
r.Type = &v[1]
|
r.Type = &v[1]
|
||||||
@ -1450,7 +1451,7 @@ func (r *CustomCPUEmulation) UnmarshalJSON(b []byte) error {
|
|||||||
r.Flags = &f
|
r.Flags = &f
|
||||||
}
|
}
|
||||||
case "hidden":
|
case "hidden":
|
||||||
bv := types.CustomBool(v[1] == "1")
|
bv := types2.CustomBool(v[1] == "1")
|
||||||
r.Hidden = &bv
|
r.Hidden = &bv
|
||||||
case "hv-vendor-id":
|
case "hv-vendor-id":
|
||||||
r.HVVendorID = &v[1]
|
r.HVVendorID = &v[1]
|
||||||
@ -1513,10 +1514,10 @@ func (r *CustomNetworkDevice) UnmarshalJSON(b []byte) error {
|
|||||||
case "bridge":
|
case "bridge":
|
||||||
r.Bridge = &v[1]
|
r.Bridge = &v[1]
|
||||||
case "firewall":
|
case "firewall":
|
||||||
bv := types.CustomBool(v[1] == "1")
|
bv := types2.CustomBool(v[1] == "1")
|
||||||
r.Firewall = &bv
|
r.Firewall = &bv
|
||||||
case "link_down":
|
case "link_down":
|
||||||
bv := types.CustomBool(v[1] == "1")
|
bv := types2.CustomBool(v[1] == "1")
|
||||||
r.LinkDown = &bv
|
r.LinkDown = &bv
|
||||||
case "macaddr":
|
case "macaddr":
|
||||||
r.MACAddress = &v[1]
|
r.MACAddress = &v[1]
|
||||||
@ -1597,15 +1598,15 @@ func (r *CustomPCIDevice) UnmarshalJSON(b []byte) error {
|
|||||||
case "mdev":
|
case "mdev":
|
||||||
r.MDev = &v[1]
|
r.MDev = &v[1]
|
||||||
case "pcie":
|
case "pcie":
|
||||||
bv := types.CustomBool(v[1] == "1")
|
bv := types2.CustomBool(v[1] == "1")
|
||||||
r.PCIExpress = &bv
|
r.PCIExpress = &bv
|
||||||
case "rombar":
|
case "rombar":
|
||||||
bv := types.CustomBool(v[1] == "1")
|
bv := types2.CustomBool(v[1] == "1")
|
||||||
r.ROMBAR = &bv
|
r.ROMBAR = &bv
|
||||||
case "romfile":
|
case "romfile":
|
||||||
r.ROMFile = &v[1]
|
r.ROMFile = &v[1]
|
||||||
case "x-vga":
|
case "x-vga":
|
||||||
bv := types.CustomBool(v[1] == "1")
|
bv := types2.CustomBool(v[1] == "1")
|
||||||
r.XVGA = &bv
|
r.XVGA = &bv
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1661,7 +1662,7 @@ func (r *CustomSMBIOS) UnmarshalJSON(b []byte) error {
|
|||||||
if len(v) == 2 {
|
if len(v) == 2 {
|
||||||
switch v[0] {
|
switch v[0] {
|
||||||
case "base64":
|
case "base64":
|
||||||
base64 := types.CustomBool(v[1] == "1")
|
base64 := types2.CustomBool(v[1] == "1")
|
||||||
r.Base64 = &base64
|
r.Base64 = &base64
|
||||||
case "family":
|
case "family":
|
||||||
r.Family = &v[1]
|
r.Family = &v[1]
|
||||||
@ -1711,7 +1712,7 @@ func (r *CustomStorageDevice) UnmarshalJSON(b []byte) error {
|
|||||||
case "aio":
|
case "aio":
|
||||||
r.AIO = &v[1]
|
r.AIO = &v[1]
|
||||||
case "backup":
|
case "backup":
|
||||||
bv := types.CustomBool(v[1] == "1")
|
bv := types2.CustomBool(v[1] == "1")
|
||||||
r.BackupEnabled = &bv
|
r.BackupEnabled = &bv
|
||||||
case "file":
|
case "file":
|
||||||
r.FileVolume = v[1]
|
r.FileVolume = v[1]
|
||||||
@ -1754,10 +1755,10 @@ func (r *CustomStorageDevice) UnmarshalJSON(b []byte) error {
|
|||||||
case "format":
|
case "format":
|
||||||
r.Format = &v[1]
|
r.Format = &v[1]
|
||||||
case "iothread":
|
case "iothread":
|
||||||
bv := types.CustomBool(v[1] == "1")
|
bv := types2.CustomBool(v[1] == "1")
|
||||||
r.IOThread = &bv
|
r.IOThread = &bv
|
||||||
case "ssd":
|
case "ssd":
|
||||||
bv := types.CustomBool(v[1] == "1")
|
bv := types2.CustomBool(v[1] == "1")
|
||||||
r.SSD = &bv
|
r.SSD = &bv
|
||||||
case "discard":
|
case "discard":
|
||||||
r.Discard = &v[1]
|
r.Discard = &v[1]
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
package storage
|
package storage
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox/types"
|
"github.com/bpg/terraform-provider-proxmox/internal/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DatastoreGetResponseBody contains the body from a datastore get response.
|
// DatastoreGetResponseBody contains the body from a datastore get response.
|
||||||
|
@ -6,13 +6,15 @@
|
|||||||
|
|
||||||
package types
|
package types
|
||||||
|
|
||||||
|
import "github.com/bpg/terraform-provider-proxmox/internal/types"
|
||||||
|
|
||||||
// StrPtr returns a pointer to a string.
|
// StrPtr returns a pointer to a string.
|
||||||
func StrPtr(s string) *string {
|
func StrPtr(s string) *string {
|
||||||
return &s
|
return &s
|
||||||
}
|
}
|
||||||
|
|
||||||
// BoolPtr returns a pointer to a bool.
|
// BoolPtr returns a pointer to a bool.
|
||||||
func BoolPtr(s bool) *CustomBool {
|
func BoolPtr(s bool) *types.CustomBool {
|
||||||
customBool := CustomBool(s)
|
customBool := types.CustomBool(s)
|
||||||
return &customBool
|
return &customBool
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ func ProxmoxVirtualEnvironment() *schema.Provider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func providerConfigure(ctx context.Context, d *schema.ResourceData) (interface{}, diag.Diagnostics) {
|
func providerConfigure(_ context.Context, d *schema.ResourceData) (interface{}, diag.Diagnostics) {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
var diags diag.Diagnostics
|
var diags diag.Diagnostics
|
||||||
@ -43,44 +43,25 @@ func providerConfigure(ctx context.Context, d *schema.ResourceData) (interface{}
|
|||||||
|
|
||||||
var conn *api.Connection
|
var conn *api.Connection
|
||||||
|
|
||||||
// Legacy configuration, wrapped in the deprecated `virtual_environment` block
|
creds, err = api.NewCredentials(
|
||||||
veConfigBlock := d.Get(mkProviderVirtualEnvironment).([]interface{})
|
d.Get(mkProviderUsername).(string),
|
||||||
if len(veConfigBlock) > 0 {
|
d.Get(mkProviderPassword).(string),
|
||||||
veConfig := veConfigBlock[0].(map[string]interface{})
|
d.Get(mkProviderOTP).(string),
|
||||||
creds, err = api.NewCredentials(
|
d.Get(mkProviderAPIToken).(string),
|
||||||
veConfig[mkProviderUsername].(string),
|
)
|
||||||
veConfig[mkProviderPassword].(string),
|
diags = append(diags, diag.FromErr(err)...)
|
||||||
veConfig[mkProviderOTP].(string),
|
|
||||||
"",
|
|
||||||
)
|
|
||||||
diags = append(diags, diag.FromErr(err)...)
|
|
||||||
|
|
||||||
conn, err = api.NewConnection(
|
conn, err = api.NewConnection(
|
||||||
veConfig[mkProviderEndpoint].(string),
|
d.Get(mkProviderEndpoint).(string),
|
||||||
veConfig[mkProviderInsecure].(bool),
|
d.Get(mkProviderInsecure).(bool),
|
||||||
)
|
)
|
||||||
diags = append(diags, diag.FromErr(err)...)
|
diags = append(diags, diag.FromErr(err)...)
|
||||||
} else {
|
|
||||||
creds, err = api.NewCredentials(
|
|
||||||
d.Get(mkProviderUsername).(string),
|
|
||||||
d.Get(mkProviderPassword).(string),
|
|
||||||
d.Get(mkProviderOTP).(string),
|
|
||||||
d.Get(mkProviderAPIToken).(string),
|
|
||||||
)
|
|
||||||
diags = append(diags, diag.FromErr(err)...)
|
|
||||||
|
|
||||||
conn, err = api.NewConnection(
|
|
||||||
d.Get(mkProviderEndpoint).(string),
|
|
||||||
d.Get(mkProviderInsecure).(bool),
|
|
||||||
)
|
|
||||||
diags = append(diags, diag.FromErr(err)...)
|
|
||||||
}
|
|
||||||
|
|
||||||
if diags.HasError() {
|
if diags.HasError() {
|
||||||
return nil, diags
|
return nil, diags
|
||||||
}
|
}
|
||||||
|
|
||||||
apiClient, err = api.NewClient(ctx, creds, conn)
|
apiClient, err = api.NewClient(creds, conn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, diag.Errorf("error creating virtual environment client: %s", err)
|
return nil, diag.Errorf("error creating virtual environment client: %s", err)
|
||||||
}
|
}
|
||||||
@ -145,12 +126,27 @@ type apiResolver struct {
|
|||||||
func (r *apiResolver) Resolve(ctx context.Context, nodeName string) (string, error) {
|
func (r *apiResolver) Resolve(ctx context.Context, nodeName string) (string, error) {
|
||||||
nc := &nodes.Client{Client: r.c, NodeName: nodeName}
|
nc := &nodes.Client{Client: r.c, NodeName: nodeName}
|
||||||
|
|
||||||
ip, err := nc.GetIP(ctx)
|
networkDevices, err := nc.ListNetworkInterfaces(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("failed to get node IP: %w", err)
|
return "", fmt.Errorf("failed to list network devices of node \"%s\": %w", nc.NodeName, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return ip, nil
|
nodeAddress := ""
|
||||||
|
|
||||||
|
for _, d := range networkDevices {
|
||||||
|
if d.Address != nil {
|
||||||
|
nodeAddress = *d.Address
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if nodeAddress == "" {
|
||||||
|
return "", fmt.Errorf("failed to determine the IP address of node \"%s\"", nc.NodeName)
|
||||||
|
}
|
||||||
|
|
||||||
|
nodeAddressParts := strings.Split(nodeAddress, "/")
|
||||||
|
|
||||||
|
return nodeAddressParts[0], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type apiResolverWithOverrides struct {
|
type apiResolverWithOverrides struct {
|
||||||
|
@ -33,7 +33,6 @@ func TestProviderSchema(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
test.AssertOptionalArguments(t, s, []string{
|
test.AssertOptionalArguments(t, s, []string{
|
||||||
mkProviderVirtualEnvironment,
|
|
||||||
mkProviderUsername,
|
mkProviderUsername,
|
||||||
mkProviderPassword,
|
mkProviderPassword,
|
||||||
mkProviderEndpoint,
|
mkProviderEndpoint,
|
||||||
@ -42,32 +41,11 @@ func TestProviderSchema(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
test.AssertValueTypes(t, s, map[string]schema.ValueType{
|
test.AssertValueTypes(t, s, map[string]schema.ValueType{
|
||||||
mkProviderVirtualEnvironment: schema.TypeList,
|
mkProviderUsername: schema.TypeString,
|
||||||
mkProviderUsername: schema.TypeString,
|
mkProviderPassword: schema.TypeString,
|
||||||
mkProviderPassword: schema.TypeString,
|
|
||||||
mkProviderEndpoint: schema.TypeString,
|
|
||||||
mkProviderInsecure: schema.TypeBool,
|
|
||||||
mkProviderOTP: schema.TypeString,
|
|
||||||
})
|
|
||||||
|
|
||||||
veSchema := test.AssertNestedSchemaExistence(t, s, mkProviderVirtualEnvironment)
|
|
||||||
|
|
||||||
test.AssertOptionalArguments(t, veSchema, []string{
|
|
||||||
mkProviderEndpoint,
|
|
||||||
mkProviderInsecure,
|
|
||||||
mkProviderOTP,
|
|
||||||
mkProviderPassword,
|
|
||||||
mkProviderUsername,
|
|
||||||
mkProviderSSH,
|
|
||||||
})
|
|
||||||
|
|
||||||
test.AssertValueTypes(t, veSchema, map[string]schema.ValueType{
|
|
||||||
mkProviderEndpoint: schema.TypeString,
|
mkProviderEndpoint: schema.TypeString,
|
||||||
mkProviderInsecure: schema.TypeBool,
|
mkProviderInsecure: schema.TypeBool,
|
||||||
mkProviderOTP: schema.TypeString,
|
mkProviderOTP: schema.TypeString,
|
||||||
mkProviderPassword: schema.TypeString,
|
|
||||||
mkProviderUsername: schema.TypeString,
|
|
||||||
mkProviderSSH: schema.TypeList,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
providerSSHSchema := test.AssertNestedSchemaExistence(t, s, mkProviderSSH)
|
providerSSHSchema := test.AssertNestedSchemaExistence(t, s, mkProviderSSH)
|
||||||
|
@ -17,21 +17,22 @@ import (
|
|||||||
func createResourceMap() map[string]*schema.Resource {
|
func createResourceMap() map[string]*schema.Resource {
|
||||||
return map[string]*schema.Resource{
|
return map[string]*schema.Resource{
|
||||||
"proxmox_virtual_environment_certificate": resource.Certificate(),
|
"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_cluster_firewall": clusterfirewall.Firewall(),
|
||||||
|
"proxmox_virtual_environment_cluster_firewall_security_group": clusterfirewall.SecurityGroup(),
|
||||||
"proxmox_virtual_environment_container": resource.Container(),
|
"proxmox_virtual_environment_container": resource.Container(),
|
||||||
"proxmox_virtual_environment_dns": resource.DNS(),
|
"proxmox_virtual_environment_dns": resource.DNS(),
|
||||||
"proxmox_virtual_environment_file": resource.File(),
|
"proxmox_virtual_environment_file": resource.File(),
|
||||||
|
"proxmox_virtual_environment_firewall_alias": firewall.Alias(),
|
||||||
|
"proxmox_virtual_environment_firewall_ipset": firewall.IPSet(),
|
||||||
|
"proxmox_virtual_environment_firewall_options": firewall.Options(),
|
||||||
|
"proxmox_virtual_environment_firewall_rules": firewall.Rules(),
|
||||||
"proxmox_virtual_environment_group": resource.Group(),
|
"proxmox_virtual_environment_group": resource.Group(),
|
||||||
"proxmox_virtual_environment_hosts": resource.Hosts(),
|
"proxmox_virtual_environment_hosts": resource.Hosts(),
|
||||||
"proxmox_virtual_environment_pool": resource.Pool(),
|
// "proxmox_virtual_environment_network_linux_bridge": resource.NetworkLinuxBridge(),
|
||||||
"proxmox_virtual_environment_role": resource.Role(),
|
"proxmox_virtual_environment_pool": resource.Pool(),
|
||||||
"proxmox_virtual_environment_time": resource.Time(),
|
"proxmox_virtual_environment_role": resource.Role(),
|
||||||
"proxmox_virtual_environment_user": resource.User(),
|
"proxmox_virtual_environment_time": resource.Time(),
|
||||||
"proxmox_virtual_environment_vm": resource.VM(),
|
"proxmox_virtual_environment_user": resource.User(),
|
||||||
|
"proxmox_virtual_environment_vm": resource.VM(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,6 @@
|
|||||||
package provider
|
package provider
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"os"
|
"os"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
|
||||||
@ -16,19 +15,18 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
dvProviderOTP = ""
|
dvProviderOTP = ""
|
||||||
mkProviderVirtualEnvironment = "virtual_environment"
|
mkProviderEndpoint = "endpoint"
|
||||||
mkProviderEndpoint = "endpoint"
|
mkProviderInsecure = "insecure"
|
||||||
mkProviderInsecure = "insecure"
|
mkProviderOTP = "otp"
|
||||||
mkProviderOTP = "otp"
|
mkProviderPassword = "password"
|
||||||
mkProviderPassword = "password"
|
mkProviderUsername = "username"
|
||||||
mkProviderUsername = "username"
|
mkProviderAPIToken = "api_token"
|
||||||
mkProviderAPIToken = "api_token"
|
mkProviderSSH = "ssh"
|
||||||
mkProviderSSH = "ssh"
|
mkProviderSSHUsername = "username"
|
||||||
mkProviderSSHUsername = "username"
|
mkProviderSSHPassword = "password"
|
||||||
mkProviderSSHPassword = "password"
|
mkProviderSSHAgent = "agent"
|
||||||
mkProviderSSHAgent = "agent"
|
mkProviderSSHAgentSocket = "agent_socket"
|
||||||
mkProviderSSHAgentSocket = "agent_socket"
|
|
||||||
|
|
||||||
mkProviderSSHNode = "node"
|
mkProviderSSHNode = "node"
|
||||||
mkProviderSSHNodeName = "name"
|
mkProviderSSHNodeName = "name"
|
||||||
@ -36,40 +34,21 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func createSchema() map[string]*schema.Schema {
|
func createSchema() map[string]*schema.Schema {
|
||||||
providerSchema := nestedProviderSchema()
|
|
||||||
providerSchema[mkProviderVirtualEnvironment] = &schema.Schema{
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Optional: true,
|
|
||||||
Elem: &schema.Resource{
|
|
||||||
Schema: nestedProviderSchema(),
|
|
||||||
},
|
|
||||||
MaxItems: 1,
|
|
||||||
Deprecated: "Move attributes out of virtual_environment block",
|
|
||||||
}
|
|
||||||
|
|
||||||
return providerSchema
|
|
||||||
}
|
|
||||||
|
|
||||||
func nestedProviderSchema() map[string]*schema.Schema {
|
|
||||||
return map[string]*schema.Schema{
|
return map[string]*schema.Schema{
|
||||||
mkProviderEndpoint: {
|
mkProviderEndpoint: {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
Description: "The endpoint for the Proxmox Virtual Environment API",
|
Description: "The endpoint for the Proxmox VE API.",
|
||||||
DefaultFunc: schema.MultiEnvDefaultFunc(
|
DefaultFunc: schema.MultiEnvDefaultFunc(
|
||||||
[]string{"PROXMOX_VE_ENDPOINT", "PM_VE_ENDPOINT"},
|
[]string{"PROXMOX_VE_ENDPOINT", "PM_VE_ENDPOINT"},
|
||||||
nil,
|
nil,
|
||||||
),
|
),
|
||||||
AtLeastOneOf: []string{
|
|
||||||
mkProviderEndpoint,
|
|
||||||
fmt.Sprintf("%s.0.%s", mkProviderVirtualEnvironment, mkProviderEndpoint),
|
|
||||||
},
|
|
||||||
ValidateFunc: validation.IsURLWithHTTPorHTTPS,
|
ValidateFunc: validation.IsURLWithHTTPorHTTPS,
|
||||||
},
|
},
|
||||||
mkProviderInsecure: {
|
mkProviderInsecure: {
|
||||||
Type: schema.TypeBool,
|
Type: schema.TypeBool,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
Description: "Whether to skip the TLS verification step",
|
Description: "Whether to skip the TLS verification step.",
|
||||||
DefaultFunc: func() (interface{}, error) {
|
DefaultFunc: func() (interface{}, error) {
|
||||||
for _, k := range []string{"PROXMOX_VE_INSECURE", "PM_VE_INSECURE"} {
|
for _, k := range []string{"PROXMOX_VE_INSECURE", "PM_VE_INSECURE"} {
|
||||||
v := os.Getenv(k)
|
v := os.Getenv(k)
|
||||||
@ -85,24 +64,25 @@ func nestedProviderSchema() map[string]*schema.Schema {
|
|||||||
mkProviderOTP: {
|
mkProviderOTP: {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
Description: "The one-time password for the Proxmox Virtual Environment API",
|
Description: "The one-time password for the Proxmox VE API.",
|
||||||
|
Deprecated: "The `otp` attribute is deprecated and will be removed in a future release. " +
|
||||||
|
"Please use the `api_token` attribute instead.",
|
||||||
DefaultFunc: schema.MultiEnvDefaultFunc(
|
DefaultFunc: schema.MultiEnvDefaultFunc(
|
||||||
[]string{"PROXMOX_VE_OTP", "PM_VE_OTP"},
|
[]string{"PROXMOX_VE_OTP", "PM_VE_OTP"},
|
||||||
dvProviderOTP,
|
nil,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
mkProviderPassword: {
|
mkProviderPassword: {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
Sensitive: true,
|
Sensitive: true,
|
||||||
Description: "The password for the Proxmox Virtual Environment API",
|
Description: "The password for the Proxmox VE API.",
|
||||||
DefaultFunc: schema.MultiEnvDefaultFunc(
|
DefaultFunc: schema.MultiEnvDefaultFunc(
|
||||||
[]string{"PROXMOX_VE_PASSWORD", "PM_VE_PASSWORD"},
|
[]string{"PROXMOX_VE_PASSWORD", "PM_VE_PASSWORD"},
|
||||||
nil,
|
nil,
|
||||||
),
|
),
|
||||||
AtLeastOneOf: []string{
|
AtLeastOneOf: []string{
|
||||||
mkProviderPassword,
|
mkProviderPassword,
|
||||||
fmt.Sprintf("%s.0.%s", mkProviderVirtualEnvironment, mkProviderPassword),
|
|
||||||
mkProviderAPIToken,
|
mkProviderAPIToken,
|
||||||
},
|
},
|
||||||
ValidateFunc: validation.StringIsNotEmpty,
|
ValidateFunc: validation.StringIsNotEmpty,
|
||||||
@ -110,14 +90,13 @@ func nestedProviderSchema() map[string]*schema.Schema {
|
|||||||
mkProviderUsername: {
|
mkProviderUsername: {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
Description: "The username for the Proxmox Virtual Environment API",
|
Description: "The username for the Proxmox VE API.",
|
||||||
DefaultFunc: schema.MultiEnvDefaultFunc(
|
DefaultFunc: schema.MultiEnvDefaultFunc(
|
||||||
[]string{"PROXMOX_VE_USERNAME", "PM_VE_USERNAME"},
|
[]string{"PROXMOX_VE_USERNAME", "PM_VE_USERNAME"},
|
||||||
nil,
|
nil,
|
||||||
),
|
),
|
||||||
AtLeastOneOf: []string{
|
AtLeastOneOf: []string{
|
||||||
mkProviderUsername,
|
mkProviderUsername,
|
||||||
fmt.Sprintf("%s.0.%s", mkProviderVirtualEnvironment, mkProviderUsername),
|
|
||||||
mkProviderAPIToken,
|
mkProviderAPIToken,
|
||||||
},
|
},
|
||||||
ValidateFunc: validation.StringIsNotEmpty,
|
ValidateFunc: validation.StringIsNotEmpty,
|
||||||
@ -126,7 +105,7 @@ func nestedProviderSchema() map[string]*schema.Schema {
|
|||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
Sensitive: true,
|
Sensitive: true,
|
||||||
Description: "The API token for the Proxmox Virtual Environment API",
|
Description: "The API token for the Proxmox VE API.",
|
||||||
DefaultFunc: schema.MultiEnvDefaultFunc(
|
DefaultFunc: schema.MultiEnvDefaultFunc(
|
||||||
[]string{"PROXMOX_VE_API_TOKEN", "PM_VE_API_TOKEN"},
|
[]string{"PROXMOX_VE_API_TOKEN", "PM_VE_API_TOKEN"},
|
||||||
nil,
|
nil,
|
||||||
@ -140,14 +119,15 @@ func nestedProviderSchema() map[string]*schema.Schema {
|
|||||||
Type: schema.TypeList,
|
Type: schema.TypeList,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
MaxItems: 1,
|
MaxItems: 1,
|
||||||
Description: "The SSH connection configuration to a Proxmox node",
|
Description: "The SSH configuration for the Proxmox nodes.",
|
||||||
Elem: &schema.Resource{
|
Elem: &schema.Resource{
|
||||||
Schema: map[string]*schema.Schema{
|
Schema: map[string]*schema.Schema{
|
||||||
mkProviderSSHUsername: {
|
mkProviderSSHUsername: {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
Description: fmt.Sprintf("The username used for the SSH connection, "+
|
Description: "The username used for the SSH connection. " +
|
||||||
"defaults to the user specified in '%s'", mkProviderUsername),
|
"Defaults to the value of the `username` field of the " +
|
||||||
|
"`provider` block.",
|
||||||
DefaultFunc: schema.MultiEnvDefaultFunc(
|
DefaultFunc: schema.MultiEnvDefaultFunc(
|
||||||
[]string{"PROXMOX_VE_SSH_USERNAME", "PM_VE_SSH_USERNAME"},
|
[]string{"PROXMOX_VE_SSH_USERNAME", "PM_VE_SSH_USERNAME"},
|
||||||
nil,
|
nil,
|
||||||
@ -158,8 +138,9 @@ func nestedProviderSchema() map[string]*schema.Schema {
|
|||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
Sensitive: true,
|
Sensitive: true,
|
||||||
Description: fmt.Sprintf("The password used for the SSH connection, "+
|
Description: "The password used for the SSH connection. " +
|
||||||
"defaults to the password specified in '%s'", mkProviderPassword),
|
"Defaults to the value of the `password` field of the " +
|
||||||
|
"`provider` block.",
|
||||||
DefaultFunc: schema.MultiEnvDefaultFunc(
|
DefaultFunc: schema.MultiEnvDefaultFunc(
|
||||||
[]string{"PROXMOX_VE_SSH_PASSWORD", "PM_VE_SSH_PASSWORD"},
|
[]string{"PROXMOX_VE_SSH_PASSWORD", "PM_VE_SSH_PASSWORD"},
|
||||||
nil,
|
nil,
|
||||||
@ -167,9 +148,10 @@ func nestedProviderSchema() map[string]*schema.Schema {
|
|||||||
ValidateFunc: validation.StringIsNotEmpty,
|
ValidateFunc: validation.StringIsNotEmpty,
|
||||||
},
|
},
|
||||||
mkProviderSSHAgent: {
|
mkProviderSSHAgent: {
|
||||||
Type: schema.TypeBool,
|
Type: schema.TypeBool,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
Description: "Whether to use the SSH agent for the SSH authentication. Defaults to false",
|
Description: "Whether to use the SSH agent for authentication. " +
|
||||||
|
"Defaults to `false`.",
|
||||||
DefaultFunc: func() (interface{}, error) {
|
DefaultFunc: func() (interface{}, error) {
|
||||||
for _, k := range []string{"PROXMOX_VE_SSH_AGENT", "PM_VE_SSH_AGENT"} {
|
for _, k := range []string{"PROXMOX_VE_SSH_AGENT", "PM_VE_SSH_AGENT"} {
|
||||||
v := os.Getenv(k)
|
v := os.Getenv(k)
|
||||||
@ -186,7 +168,7 @@ func nestedProviderSchema() map[string]*schema.Schema {
|
|||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
Description: "The path to the SSH agent socket. Defaults to the value of the `SSH_AUTH_SOCK` " +
|
Description: "The path to the SSH agent socket. Defaults to the value of the `SSH_AUTH_SOCK` " +
|
||||||
"environment variable",
|
"environment variable.",
|
||||||
DefaultFunc: schema.MultiEnvDefaultFunc(
|
DefaultFunc: schema.MultiEnvDefaultFunc(
|
||||||
[]string{"SSH_AUTH_SOCK", "PROXMOX_VE_SSH_AUTH_SOCK", "PM_VE_SSH_AUTH_SOCK"},
|
[]string{"SSH_AUTH_SOCK", "PROXMOX_VE_SSH_AUTH_SOCK", "PM_VE_SSH_AUTH_SOCK"},
|
||||||
nil,
|
nil,
|
||||||
@ -197,19 +179,19 @@ func nestedProviderSchema() map[string]*schema.Schema {
|
|||||||
Type: schema.TypeList,
|
Type: schema.TypeList,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
MinItems: 0,
|
MinItems: 0,
|
||||||
Description: "Overrides for SSH connection configuration to a Proxmox node",
|
Description: "Overrides for SSH connection configuration for a Proxmox VE node.",
|
||||||
Elem: &schema.Resource{
|
Elem: &schema.Resource{
|
||||||
Schema: map[string]*schema.Schema{
|
Schema: map[string]*schema.Schema{
|
||||||
mkProviderSSHNodeName: {
|
mkProviderSSHNodeName: {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Required: true,
|
Required: true,
|
||||||
Description: "The name of the node to connect to",
|
Description: "The name of the Proxmox VE node.",
|
||||||
ValidateFunc: validation.StringIsNotEmpty,
|
ValidateFunc: validation.StringIsNotEmpty,
|
||||||
},
|
},
|
||||||
mkProviderSSHNodeAddress: {
|
mkProviderSSHNodeAddress: {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Required: true,
|
Required: true,
|
||||||
Description: "The address that should be used to connect to the node",
|
Description: "The address of the Proxmox VE node.",
|
||||||
ValidateFunc: validation.IsIPAddress,
|
ValidateFunc: validation.IsIPAddress,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -15,8 +15,8 @@ import (
|
|||||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
"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/schema"
|
||||||
|
|
||||||
|
"github.com/bpg/terraform-provider-proxmox/internal/types"
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox/nodes"
|
"github.com/bpg/terraform-provider-proxmox/proxmox/nodes"
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox/types"
|
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmoxtf"
|
"github.com/bpg/terraform-provider-proxmox/proxmoxtf"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -12,8 +12,8 @@ import (
|
|||||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
"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/schema"
|
||||||
|
|
||||||
|
"github.com/bpg/terraform-provider-proxmox/internal/types"
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox/cluster/firewall"
|
"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"
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmoxtf/resource/validator"
|
"github.com/bpg/terraform-provider-proxmox/proxmoxtf/resource/validator"
|
||||||
)
|
)
|
||||||
|
@ -17,8 +17,8 @@ import (
|
|||||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
|
||||||
|
|
||||||
|
"github.com/bpg/terraform-provider-proxmox/internal/types"
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox/nodes/containers"
|
"github.com/bpg/terraform-provider-proxmox/proxmox/nodes/containers"
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox/types"
|
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmoxtf"
|
"github.com/bpg/terraform-provider-proxmox/proxmoxtf"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -13,8 +13,8 @@ import (
|
|||||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
"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/schema"
|
||||||
|
|
||||||
|
"github.com/bpg/terraform-provider-proxmox/internal/types"
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox/firewall"
|
"github.com/bpg/terraform-provider-proxmox/proxmox/firewall"
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox/types"
|
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmoxtf/structure"
|
"github.com/bpg/terraform-provider-proxmox/proxmoxtf/structure"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -12,8 +12,8 @@ import (
|
|||||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
"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/schema"
|
||||||
|
|
||||||
|
"github.com/bpg/terraform-provider-proxmox/internal/types"
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox/firewall"
|
"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/resource/validator"
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmoxtf/structure"
|
"github.com/bpg/terraform-provider-proxmox/proxmoxtf/structure"
|
||||||
)
|
)
|
||||||
|
@ -15,8 +15,8 @@ import (
|
|||||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
|
||||||
|
|
||||||
|
"github.com/bpg/terraform-provider-proxmox/internal/types"
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox/firewall"
|
"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/resource/validator"
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmoxtf/structure"
|
"github.com/bpg/terraform-provider-proxmox/proxmoxtf/structure"
|
||||||
)
|
)
|
||||||
|
@ -13,8 +13,8 @@ import (
|
|||||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
"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/schema"
|
||||||
|
|
||||||
|
"github.com/bpg/terraform-provider-proxmox/internal/types"
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox/access"
|
"github.com/bpg/terraform-provider-proxmox/proxmox/access"
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox/types"
|
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmoxtf"
|
"github.com/bpg/terraform-provider-proxmox/proxmoxtf"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -13,8 +13,8 @@ import (
|
|||||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
"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/schema"
|
||||||
|
|
||||||
|
"github.com/bpg/terraform-provider-proxmox/internal/types"
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox/access"
|
"github.com/bpg/terraform-provider-proxmox/proxmox/access"
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox/types"
|
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmoxtf"
|
"github.com/bpg/terraform-provider-proxmox/proxmoxtf"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -15,8 +15,8 @@ import (
|
|||||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
|
||||||
|
|
||||||
|
"github.com/bpg/terraform-provider-proxmox/internal/types"
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox/access"
|
"github.com/bpg/terraform-provider-proxmox/proxmox/access"
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox/types"
|
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmoxtf"
|
"github.com/bpg/terraform-provider-proxmox/proxmoxtf"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -352,39 +352,6 @@ func getSCSIHardwareValidator() schema.SchemaValidateDiagFunc {
|
|||||||
}, false))
|
}, false))
|
||||||
}
|
}
|
||||||
|
|
||||||
//nolint:unused
|
|
||||||
func getVLANIDsValidator() schema.SchemaValidateDiagFunc {
|
|
||||||
return validation.ToDiagFunc(func(i interface{}, k string) (ws []string, es []error) {
|
|
||||||
min := 1
|
|
||||||
max := 4094
|
|
||||||
|
|
||||||
list, ok := i.([]interface{})
|
|
||||||
|
|
||||||
if !ok {
|
|
||||||
es = append(es, fmt.Errorf("expected type of %s to be []interface{}", k))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for li, lv := range list {
|
|
||||||
v, ok := lv.(int)
|
|
||||||
|
|
||||||
if !ok {
|
|
||||||
es = append(es, fmt.Errorf("expected type of %s[%d] to be int", k, li))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if v != -1 {
|
|
||||||
if v < min || v > max {
|
|
||||||
es = append(es, fmt.Errorf("expected %s[%d] to be in the range (%d - %d), got %d", k, li, min, max, v))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func getVMIDValidator() schema.SchemaValidateDiagFunc {
|
func getVMIDValidator() schema.SchemaValidateDiagFunc {
|
||||||
return validation.ToDiagFunc(func(i interface{}, k string) (ws []string, es []error) {
|
return validation.ToDiagFunc(func(i interface{}, k string) (ws []string, es []error) {
|
||||||
min := 100
|
min := 100
|
||||||
|
76
proxmoxtf/resource/validator/network.go
Normal file
76
proxmoxtf/resource/validator/network.go
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
* 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 (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
|
||||||
|
)
|
||||||
|
|
||||||
|
// VLANIDsValidator returns a schema validation function for VLAN IDs.
|
||||||
|
func VLANIDsValidator() schema.SchemaValidateDiagFunc {
|
||||||
|
return validation.ToDiagFunc(func(i interface{}, k string) ([]string, []error) {
|
||||||
|
min := 1
|
||||||
|
max := 4094
|
||||||
|
|
||||||
|
var ws []string
|
||||||
|
var es []error
|
||||||
|
|
||||||
|
list, ok := i.([]interface{})
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
es = append(es, fmt.Errorf("expected type of %s to be []interface{}", k))
|
||||||
|
return ws, es
|
||||||
|
}
|
||||||
|
|
||||||
|
for li, lv := range list {
|
||||||
|
v, ok := lv.(int)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
es = append(es, fmt.Errorf("expected type of %s[%d] to be int", k, li))
|
||||||
|
return ws, es
|
||||||
|
}
|
||||||
|
|
||||||
|
if v != -1 {
|
||||||
|
if v < min || v > max {
|
||||||
|
es = append(es, fmt.Errorf("expected %s[%d] to be in the range (%d - %d), got %d", k, li, min, max, v))
|
||||||
|
return ws, es
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ws, es
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// NodeNetworkInterfaceBondingModes returns a schema validation function for a node network interface bonding mode.
|
||||||
|
func NodeNetworkInterfaceBondingModes() schema.SchemaValidateDiagFunc {
|
||||||
|
return validation.ToDiagFunc(validation.StringInSlice([]string{
|
||||||
|
"balance-rr",
|
||||||
|
"active-backup",
|
||||||
|
"balance-xor",
|
||||||
|
"broadcast",
|
||||||
|
"802.3ad",
|
||||||
|
"balance-tlb",
|
||||||
|
"balance-alb",
|
||||||
|
"balance-slb",
|
||||||
|
"lacp-balance-slb",
|
||||||
|
"lacp-balance-tcp",
|
||||||
|
}, false))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NodeNetworkInterfaceBondingTransmitHashPolicies returns a schema validation function for a node network interface
|
||||||
|
// bonding transmit hash policy.
|
||||||
|
func NodeNetworkInterfaceBondingTransmitHashPolicies() schema.SchemaValidateDiagFunc {
|
||||||
|
return validation.ToDiagFunc(validation.StringInSlice([]string{
|
||||||
|
"layer2",
|
||||||
|
"layer2+3",
|
||||||
|
"layer3+4",
|
||||||
|
}, false))
|
||||||
|
}
|
@ -20,6 +20,7 @@ import (
|
|||||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
|
||||||
|
|
||||||
|
types2 "github.com/bpg/terraform-provider-proxmox/internal/types"
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox/nodes/vms"
|
"github.com/bpg/terraform-provider-proxmox/proxmox/nodes/vms"
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox/types"
|
"github.com/bpg/terraform-provider-proxmox/proxmox/types"
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmoxtf"
|
"github.com/bpg/terraform-provider-proxmox/proxmoxtf"
|
||||||
@ -1311,7 +1312,7 @@ func vmCreateClone(ctx context.Context, d *schema.ResourceData, m interface{}) d
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fullCopy := types.CustomBool(cloneFull)
|
fullCopy := types2.CustomBool(cloneFull)
|
||||||
|
|
||||||
cloneBody := &vms.CloneRequestBody{
|
cloneBody := &vms.CloneRequestBody{
|
||||||
FullCopy: &fullCopy,
|
FullCopy: &fullCopy,
|
||||||
@ -1392,7 +1393,7 @@ func vmCreateClone(ctx context.Context, d *schema.ResourceData, m interface{}) d
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Migrate to target node
|
// Migrate to target node
|
||||||
withLocalDisks := types.CustomBool(true)
|
withLocalDisks := types2.CustomBool(true)
|
||||||
migrateBody := &vms.MigrateRequestBody{
|
migrateBody := &vms.MigrateRequestBody{
|
||||||
TargetNode: nodeName,
|
TargetNode: nodeName,
|
||||||
WithLocalDisks: &withLocalDisks,
|
WithLocalDisks: &withLocalDisks,
|
||||||
@ -1426,7 +1427,7 @@ func vmCreateClone(ctx context.Context, d *schema.ResourceData, m interface{}) d
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Now that the virtual machine has been cloned, we need to perform some modifications.
|
// Now that the virtual machine has been cloned, we need to perform some modifications.
|
||||||
acpi := types.CustomBool(d.Get(mkResourceVirtualEnvironmentVMACPI).(bool))
|
acpi := types2.CustomBool(d.Get(mkResourceVirtualEnvironmentVMACPI).(bool))
|
||||||
agent := d.Get(mkResourceVirtualEnvironmentVMAgent).([]interface{})
|
agent := d.Get(mkResourceVirtualEnvironmentVMAgent).([]interface{})
|
||||||
audioDevices := vmGetAudioDeviceList(d)
|
audioDevices := vmGetAudioDeviceList(d)
|
||||||
|
|
||||||
@ -1442,9 +1443,9 @@ func vmCreateClone(ctx context.Context, d *schema.ResourceData, m interface{}) d
|
|||||||
networkDevice := d.Get(mkResourceVirtualEnvironmentVMNetworkDevice).([]interface{})
|
networkDevice := d.Get(mkResourceVirtualEnvironmentVMNetworkDevice).([]interface{})
|
||||||
operatingSystem := d.Get(mkResourceVirtualEnvironmentVMOperatingSystem).([]interface{})
|
operatingSystem := d.Get(mkResourceVirtualEnvironmentVMOperatingSystem).([]interface{})
|
||||||
serialDevice := d.Get(mkResourceVirtualEnvironmentVMSerialDevice).([]interface{})
|
serialDevice := d.Get(mkResourceVirtualEnvironmentVMSerialDevice).([]interface{})
|
||||||
onBoot := types.CustomBool(d.Get(mkResourceVirtualEnvironmentVMOnBoot).(bool))
|
onBoot := types2.CustomBool(d.Get(mkResourceVirtualEnvironmentVMOnBoot).(bool))
|
||||||
tabletDevice := types.CustomBool(d.Get(mkResourceVirtualEnvironmentVMTabletDevice).(bool))
|
tabletDevice := types2.CustomBool(d.Get(mkResourceVirtualEnvironmentVMTabletDevice).(bool))
|
||||||
template := types.CustomBool(d.Get(mkResourceVirtualEnvironmentVMTemplate).(bool))
|
template := types2.CustomBool(d.Get(mkResourceVirtualEnvironmentVMTemplate).(bool))
|
||||||
vga := d.Get(mkResourceVirtualEnvironmentVMVGA).([]interface{})
|
vga := d.Get(mkResourceVirtualEnvironmentVMVGA).([]interface{})
|
||||||
|
|
||||||
updateBody := &vms.UpdateRequestBody{
|
updateBody := &vms.UpdateRequestBody{
|
||||||
@ -1463,10 +1464,10 @@ func vmCreateClone(ctx context.Context, d *schema.ResourceData, m interface{}) d
|
|||||||
if len(agent) > 0 {
|
if len(agent) > 0 {
|
||||||
agentBlock := agent[0].(map[string]interface{})
|
agentBlock := agent[0].(map[string]interface{})
|
||||||
|
|
||||||
agentEnabled := types.CustomBool(
|
agentEnabled := types2.CustomBool(
|
||||||
agentBlock[mkResourceVirtualEnvironmentVMAgentEnabled].(bool),
|
agentBlock[mkResourceVirtualEnvironmentVMAgentEnabled].(bool),
|
||||||
)
|
)
|
||||||
agentTrim := types.CustomBool(agentBlock[mkResourceVirtualEnvironmentVMAgentTrim].(bool))
|
agentTrim := types2.CustomBool(agentBlock[mkResourceVirtualEnvironmentVMAgentTrim].(bool))
|
||||||
agentType := agentBlock[mkResourceVirtualEnvironmentVMAgentType].(string)
|
agentType := agentBlock[mkResourceVirtualEnvironmentVMAgentType].(string)
|
||||||
|
|
||||||
updateBody.Agent = &vms.CustomAgent{
|
updateBody.Agent = &vms.CustomAgent{
|
||||||
@ -1753,7 +1754,7 @@ func vmCreateClone(ctx context.Context, d *schema.ResourceData, m interface{}) d
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteOriginalDisk := types.CustomBool(true)
|
deleteOriginalDisk := types2.CustomBool(true)
|
||||||
|
|
||||||
diskMoveBody := &vms.MoveDiskRequestBody{
|
diskMoveBody := &vms.MoveDiskRequestBody{
|
||||||
DeleteOriginalDisk: &deleteOriginalDisk,
|
DeleteOriginalDisk: &deleteOriginalDisk,
|
||||||
@ -1806,7 +1807,7 @@ func vmCreateCustom(ctx context.Context, d *schema.ResourceData, m interface{})
|
|||||||
|
|
||||||
resource := VM()
|
resource := VM()
|
||||||
|
|
||||||
acpi := types.CustomBool(d.Get(mkResourceVirtualEnvironmentVMACPI).(bool))
|
acpi := types2.CustomBool(d.Get(mkResourceVirtualEnvironmentVMACPI).(bool))
|
||||||
|
|
||||||
agentBlock, err := getSchemaBlock(
|
agentBlock, err := getSchemaBlock(
|
||||||
resource,
|
resource,
|
||||||
@ -1819,10 +1820,10 @@ func vmCreateCustom(ctx context.Context, d *schema.ResourceData, m interface{})
|
|||||||
return diag.FromErr(err)
|
return diag.FromErr(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
agentEnabled := types.CustomBool(
|
agentEnabled := types2.CustomBool(
|
||||||
agentBlock[mkResourceVirtualEnvironmentVMAgentEnabled].(bool),
|
agentBlock[mkResourceVirtualEnvironmentVMAgentEnabled].(bool),
|
||||||
)
|
)
|
||||||
agentTrim := types.CustomBool(agentBlock[mkResourceVirtualEnvironmentVMAgentTrim].(bool))
|
agentTrim := types2.CustomBool(agentBlock[mkResourceVirtualEnvironmentVMAgentTrim].(bool))
|
||||||
agentType := agentBlock[mkResourceVirtualEnvironmentVMAgentType].(string)
|
agentType := agentBlock[mkResourceVirtualEnvironmentVMAgentType].(string)
|
||||||
|
|
||||||
kvmArguments := d.Get(mkResourceVirtualEnvironmentVMKVMArguments).(string)
|
kvmArguments := d.Get(mkResourceVirtualEnvironmentVMKVMArguments).(string)
|
||||||
@ -1936,9 +1937,9 @@ func vmCreateCustom(ctx context.Context, d *schema.ResourceData, m interface{})
|
|||||||
|
|
||||||
serialDevices := vmGetSerialDeviceList(d)
|
serialDevices := vmGetSerialDeviceList(d)
|
||||||
|
|
||||||
onBoot := types.CustomBool(d.Get(mkResourceVirtualEnvironmentVMOnBoot).(bool))
|
onBoot := types2.CustomBool(d.Get(mkResourceVirtualEnvironmentVMOnBoot).(bool))
|
||||||
tabletDevice := types.CustomBool(d.Get(mkResourceVirtualEnvironmentVMTabletDevice).(bool))
|
tabletDevice := types2.CustomBool(d.Get(mkResourceVirtualEnvironmentVMTabletDevice).(bool))
|
||||||
template := types.CustomBool(d.Get(mkResourceVirtualEnvironmentVMTemplate).(bool))
|
template := types2.CustomBool(d.Get(mkResourceVirtualEnvironmentVMTemplate).(bool))
|
||||||
|
|
||||||
vgaDevice, err := vmGetVGADeviceObject(d)
|
vgaDevice, err := vmGetVGADeviceObject(d)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -2161,8 +2162,8 @@ func vmCreateCustomDisks(ctx context.Context, d *schema.ResourceData, m interfac
|
|||||||
size, _ := block[mkResourceVirtualEnvironmentVMDiskSize].(int)
|
size, _ := block[mkResourceVirtualEnvironmentVMDiskSize].(int)
|
||||||
speed := block[mkResourceVirtualEnvironmentVMDiskSpeed].([]interface{})
|
speed := block[mkResourceVirtualEnvironmentVMDiskSpeed].([]interface{})
|
||||||
diskInterface, _ := block[mkResourceVirtualEnvironmentVMDiskInterface].(string)
|
diskInterface, _ := block[mkResourceVirtualEnvironmentVMDiskInterface].(string)
|
||||||
ioThread := types.CustomBool(block[mkResourceVirtualEnvironmentVMDiskIOThread].(bool))
|
ioThread := types2.CustomBool(block[mkResourceVirtualEnvironmentVMDiskIOThread].(bool))
|
||||||
ssd := types.CustomBool(block[mkResourceVirtualEnvironmentVMDiskSSD].(bool))
|
ssd := types2.CustomBool(block[mkResourceVirtualEnvironmentVMDiskSSD].(bool))
|
||||||
discard, _ := block[mkResourceVirtualEnvironmentVMDiskDiscard].(string)
|
discard, _ := block[mkResourceVirtualEnvironmentVMDiskDiscard].(string)
|
||||||
|
|
||||||
if fileFormat == "" {
|
if fileFormat == "" {
|
||||||
@ -2510,8 +2511,8 @@ func vmGetDiskDeviceObjects(
|
|||||||
fileID, _ := block[mkResourceVirtualEnvironmentVMDiskFileID].(string)
|
fileID, _ := block[mkResourceVirtualEnvironmentVMDiskFileID].(string)
|
||||||
size, _ := block[mkResourceVirtualEnvironmentVMDiskSize].(int)
|
size, _ := block[mkResourceVirtualEnvironmentVMDiskSize].(int)
|
||||||
diskInterface, _ := block[mkResourceVirtualEnvironmentVMDiskInterface].(string)
|
diskInterface, _ := block[mkResourceVirtualEnvironmentVMDiskInterface].(string)
|
||||||
ioThread := types.CustomBool(block[mkResourceVirtualEnvironmentVMDiskIOThread].(bool))
|
ioThread := types2.CustomBool(block[mkResourceVirtualEnvironmentVMDiskIOThread].(bool))
|
||||||
ssd := types.CustomBool(block[mkResourceVirtualEnvironmentVMDiskSSD].(bool))
|
ssd := types2.CustomBool(block[mkResourceVirtualEnvironmentVMDiskSSD].(bool))
|
||||||
discard := block[mkResourceVirtualEnvironmentVMDiskDiscard].(string)
|
discard := block[mkResourceVirtualEnvironmentVMDiskDiscard].(string)
|
||||||
|
|
||||||
speedBlock, err := getSchemaBlock(
|
speedBlock, err := getSchemaBlock(
|
||||||
@ -2601,12 +2602,12 @@ func vmGetHostPCIDeviceObjects(d *schema.ResourceData) vms.CustomPCIDevices {
|
|||||||
|
|
||||||
ids, _ := block[mkResourceVirtualEnvironmentVMHostPCIDeviceID].(string)
|
ids, _ := block[mkResourceVirtualEnvironmentVMHostPCIDeviceID].(string)
|
||||||
mdev, _ := block[mkResourceVirtualEnvironmentVMHostPCIDeviceMDev].(string)
|
mdev, _ := block[mkResourceVirtualEnvironmentVMHostPCIDeviceMDev].(string)
|
||||||
pcie := types.CustomBool(block[mkResourceVirtualEnvironmentVMHostPCIDevicePCIE].(bool))
|
pcie := types2.CustomBool(block[mkResourceVirtualEnvironmentVMHostPCIDevicePCIE].(bool))
|
||||||
rombar := types.CustomBool(
|
rombar := types2.CustomBool(
|
||||||
block[mkResourceVirtualEnvironmentVMHostPCIDeviceROMBAR].(bool),
|
block[mkResourceVirtualEnvironmentVMHostPCIDeviceROMBAR].(bool),
|
||||||
)
|
)
|
||||||
romfile, _ := block[mkResourceVirtualEnvironmentVMHostPCIDeviceROMFile].(string)
|
romfile, _ := block[mkResourceVirtualEnvironmentVMHostPCIDeviceROMFile].(string)
|
||||||
xvga := types.CustomBool(block[mkResourceVirtualEnvironmentVMHostPCIDeviceXVGA].(bool))
|
xvga := types2.CustomBool(block[mkResourceVirtualEnvironmentVMHostPCIDeviceXVGA].(bool))
|
||||||
|
|
||||||
device := vms.CustomPCIDevice{
|
device := vms.CustomPCIDevice{
|
||||||
DeviceIDs: strings.Split(ids, ";"),
|
DeviceIDs: strings.Split(ids, ";"),
|
||||||
@ -2641,7 +2642,7 @@ func vmGetNetworkDeviceObjects(d *schema.ResourceData) vms.CustomNetworkDevices
|
|||||||
|
|
||||||
bridge := block[mkResourceVirtualEnvironmentVMNetworkDeviceBridge].(string)
|
bridge := block[mkResourceVirtualEnvironmentVMNetworkDeviceBridge].(string)
|
||||||
enabled := block[mkResourceVirtualEnvironmentVMNetworkDeviceEnabled].(bool)
|
enabled := block[mkResourceVirtualEnvironmentVMNetworkDeviceEnabled].(bool)
|
||||||
firewall := types.CustomBool(block[mkResourceVirtualEnvironmentVMNetworkDeviceFirewall].(bool))
|
firewall := types2.CustomBool(block[mkResourceVirtualEnvironmentVMNetworkDeviceFirewall].(bool))
|
||||||
macAddress := block[mkResourceVirtualEnvironmentVMNetworkDeviceMACAddress].(string)
|
macAddress := block[mkResourceVirtualEnvironmentVMNetworkDeviceMACAddress].(string)
|
||||||
model := block[mkResourceVirtualEnvironmentVMNetworkDeviceModel].(string)
|
model := block[mkResourceVirtualEnvironmentVMNetworkDeviceModel].(string)
|
||||||
rateLimit := block[mkResourceVirtualEnvironmentVMNetworkDeviceRateLimit].(float64)
|
rateLimit := block[mkResourceVirtualEnvironmentVMNetworkDeviceRateLimit].(float64)
|
||||||
@ -2757,7 +2758,7 @@ func vmGetVGADeviceObject(d *schema.ResourceData) (*vms.CustomVGADevice, error)
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
vgaEnabled := types.CustomBool(vgaBlock[mkResourceVirtualEnvironmentVMAgentEnabled].(bool))
|
vgaEnabled := types2.CustomBool(vgaBlock[mkResourceVirtualEnvironmentVMAgentEnabled].(bool))
|
||||||
vgaMemory := vgaBlock[mkResourceVirtualEnvironmentVMVGAMemory].(int)
|
vgaMemory := vgaBlock[mkResourceVirtualEnvironmentVMVGAMemory].(int)
|
||||||
vgaType := vgaBlock[mkResourceVirtualEnvironmentVMVGAType].(string)
|
vgaType := vgaBlock[mkResourceVirtualEnvironmentVMVGAType].(string)
|
||||||
|
|
||||||
@ -4008,7 +4009,7 @@ func vmUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.D
|
|||||||
|
|
||||||
// Prepare the new primitive configuration values.
|
// Prepare the new primitive configuration values.
|
||||||
if d.HasChange(mkResourceVirtualEnvironmentVMACPI) {
|
if d.HasChange(mkResourceVirtualEnvironmentVMACPI) {
|
||||||
acpi := types.CustomBool(d.Get(mkResourceVirtualEnvironmentVMACPI).(bool))
|
acpi := types2.CustomBool(d.Get(mkResourceVirtualEnvironmentVMACPI).(bool))
|
||||||
updateBody.ACPI = &acpi
|
updateBody.ACPI = &acpi
|
||||||
rebootRequired = true
|
rebootRequired = true
|
||||||
}
|
}
|
||||||
@ -4031,7 +4032,7 @@ func vmUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.D
|
|||||||
}
|
}
|
||||||
|
|
||||||
if d.HasChange(mkResourceVirtualEnvironmentVMOnBoot) {
|
if d.HasChange(mkResourceVirtualEnvironmentVMOnBoot) {
|
||||||
startOnBoot := types.CustomBool(d.Get(mkResourceVirtualEnvironmentVMOnBoot).(bool))
|
startOnBoot := types2.CustomBool(d.Get(mkResourceVirtualEnvironmentVMOnBoot).(bool))
|
||||||
updateBody.StartOnBoot = &startOnBoot
|
updateBody.StartOnBoot = &startOnBoot
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4061,12 +4062,12 @@ func vmUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.D
|
|||||||
}
|
}
|
||||||
|
|
||||||
if d.HasChange(mkResourceVirtualEnvironmentVMTabletDevice) {
|
if d.HasChange(mkResourceVirtualEnvironmentVMTabletDevice) {
|
||||||
tabletDevice := types.CustomBool(d.Get(mkResourceVirtualEnvironmentVMTabletDevice).(bool))
|
tabletDevice := types2.CustomBool(d.Get(mkResourceVirtualEnvironmentVMTabletDevice).(bool))
|
||||||
updateBody.TabletDeviceEnabled = &tabletDevice
|
updateBody.TabletDeviceEnabled = &tabletDevice
|
||||||
rebootRequired = true
|
rebootRequired = true
|
||||||
}
|
}
|
||||||
|
|
||||||
template := types.CustomBool(d.Get(mkResourceVirtualEnvironmentVMTemplate).(bool))
|
template := types2.CustomBool(d.Get(mkResourceVirtualEnvironmentVMTemplate).(bool))
|
||||||
|
|
||||||
if d.HasChange(mkResourceVirtualEnvironmentVMTemplate) {
|
if d.HasChange(mkResourceVirtualEnvironmentVMTemplate) {
|
||||||
updateBody.Template = &template
|
updateBody.Template = &template
|
||||||
@ -4086,10 +4087,10 @@ func vmUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.D
|
|||||||
return diag.FromErr(err)
|
return diag.FromErr(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
agentEnabled := types.CustomBool(
|
agentEnabled := types2.CustomBool(
|
||||||
agentBlock[mkResourceVirtualEnvironmentVMAgentEnabled].(bool),
|
agentBlock[mkResourceVirtualEnvironmentVMAgentEnabled].(bool),
|
||||||
)
|
)
|
||||||
agentTrim := types.CustomBool(agentBlock[mkResourceVirtualEnvironmentVMAgentTrim].(bool))
|
agentTrim := types2.CustomBool(agentBlock[mkResourceVirtualEnvironmentVMAgentTrim].(bool))
|
||||||
agentType := agentBlock[mkResourceVirtualEnvironmentVMAgentType].(string)
|
agentType := agentBlock[mkResourceVirtualEnvironmentVMAgentType].(string)
|
||||||
|
|
||||||
updateBody.Agent = &vms.CustomAgent{
|
updateBody.Agent = &vms.CustomAgent{
|
||||||
@ -4436,7 +4437,7 @@ func vmUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.D
|
|||||||
return diag.FromErr(e)
|
return diag.FromErr(e)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
forceStop := types.CustomBool(true)
|
forceStop := types2.CustomBool(true)
|
||||||
shutdownTimeout := d.Get(mkResourceVirtualEnvironmentVMTimeoutShutdownVM).(int)
|
shutdownTimeout := d.Get(mkResourceVirtualEnvironmentVMTimeoutShutdownVM).(int)
|
||||||
|
|
||||||
e = vmAPI.ShutdownVM(ctx, &vms.ShutdownRequestBody{
|
e = vmAPI.ShutdownVM(ctx, &vms.ShutdownRequestBody{
|
||||||
@ -4518,7 +4519,7 @@ func vmUpdateDiskLocationAndSize(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if *oldDisk.ID != *diskNewEntries[prefix][oldKey].ID {
|
if *oldDisk.ID != *diskNewEntries[prefix][oldKey].ID {
|
||||||
deleteOriginalDisk := types.CustomBool(true)
|
deleteOriginalDisk := types2.CustomBool(true)
|
||||||
|
|
||||||
diskMoveBodies = append(
|
diskMoveBodies = append(
|
||||||
diskMoveBodies,
|
diskMoveBodies,
|
||||||
@ -4546,7 +4547,7 @@ func vmUpdateDiskLocationAndSize(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if shutdownForDisksRequired && !template {
|
if shutdownForDisksRequired && !template {
|
||||||
forceStop := types.CustomBool(true)
|
forceStop := types2.CustomBool(true)
|
||||||
shutdownTimeout := d.Get(mkResourceVirtualEnvironmentVMTimeoutShutdownVM).(int)
|
shutdownTimeout := d.Get(mkResourceVirtualEnvironmentVMTimeoutShutdownVM).(int)
|
||||||
|
|
||||||
err = vmAPI.ShutdownVM(
|
err = vmAPI.ShutdownVM(
|
||||||
@ -4630,7 +4631,7 @@ func vmDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.D
|
|||||||
}
|
}
|
||||||
|
|
||||||
if status.Status != "stopped" {
|
if status.Status != "stopped" {
|
||||||
forceStop := types.CustomBool(true)
|
forceStop := types2.CustomBool(true)
|
||||||
shutdownTimeout := d.Get(mkResourceVirtualEnvironmentVMTimeoutShutdownVM).(int)
|
shutdownTimeout := d.Get(mkResourceVirtualEnvironmentVMTimeoutShutdownVM).(int)
|
||||||
|
|
||||||
err = vmAPI.ShutdownVM(
|
err = vmAPI.ShutdownVM(
|
||||||
|
32
tools/go.mod
32
tools/go.mod
@ -5,6 +5,7 @@ go 1.20
|
|||||||
require (
|
require (
|
||||||
github.com/golangci/golangci-lint v1.53.3
|
github.com/golangci/golangci-lint v1.53.3
|
||||||
github.com/goreleaser/goreleaser v1.18.2
|
github.com/goreleaser/goreleaser v1.18.2
|
||||||
|
github.com/hashicorp/terraform-plugin-docs v0.15.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
@ -46,15 +47,18 @@ require (
|
|||||||
github.com/Masterminds/semver v1.5.0 // indirect
|
github.com/Masterminds/semver v1.5.0 // indirect
|
||||||
github.com/Masterminds/semver/v3 v3.2.1 // indirect
|
github.com/Masterminds/semver/v3 v3.2.1 // indirect
|
||||||
github.com/Masterminds/sprig v2.22.0+incompatible // indirect
|
github.com/Masterminds/sprig v2.22.0+incompatible // indirect
|
||||||
|
github.com/Masterminds/sprig/v3 v3.2.2 // indirect
|
||||||
github.com/Microsoft/go-winio v0.6.0 // indirect
|
github.com/Microsoft/go-winio v0.6.0 // indirect
|
||||||
github.com/OpenPeeDeeP/depguard/v2 v2.1.0 // indirect
|
github.com/OpenPeeDeeP/depguard/v2 v2.1.0 // indirect
|
||||||
github.com/ProtonMail/go-crypto v0.0.0-20211112122917-428f8eabeeb3 // indirect
|
github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 // indirect
|
||||||
github.com/ProtonMail/go-mime v0.0.0-20220302105931-303f85f7fe0f // indirect
|
github.com/ProtonMail/go-mime v0.0.0-20220302105931-303f85f7fe0f // indirect
|
||||||
github.com/acomagu/bufpipe v1.0.3 // indirect
|
github.com/acomagu/bufpipe v1.0.4 // indirect
|
||||||
github.com/alessio/shellescape v1.4.1 // indirect
|
github.com/alessio/shellescape v1.4.1 // indirect
|
||||||
github.com/alexkohler/nakedret/v2 v2.0.2 // indirect
|
github.com/alexkohler/nakedret/v2 v2.0.2 // indirect
|
||||||
github.com/alexkohler/prealloc v1.0.0 // indirect
|
github.com/alexkohler/prealloc v1.0.0 // indirect
|
||||||
github.com/alingse/asasalint v0.0.11 // indirect
|
github.com/alingse/asasalint v0.0.11 // indirect
|
||||||
|
github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
|
||||||
|
github.com/armon/go-radix v1.0.0 // indirect
|
||||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
|
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
|
||||||
github.com/ashanbrown/forbidigo v1.5.3 // indirect
|
github.com/ashanbrown/forbidigo v1.5.3 // indirect
|
||||||
github.com/ashanbrown/makezero v1.1.1 // indirect
|
github.com/ashanbrown/makezero v1.1.1 // indirect
|
||||||
@ -85,6 +89,7 @@ require (
|
|||||||
github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20220517224237-e6f29200ae04 // indirect
|
github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20220517224237-e6f29200ae04 // indirect
|
||||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
|
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
|
||||||
github.com/beorn7/perks v1.0.1 // indirect
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
|
github.com/bgentry/speakeasy v0.1.0 // indirect
|
||||||
github.com/bkielbasa/cyclop v1.2.1 // indirect
|
github.com/bkielbasa/cyclop v1.2.1 // indirect
|
||||||
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb // indirect
|
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb // indirect
|
||||||
github.com/blizzy78/varnamelen v0.8.0 // indirect
|
github.com/blizzy78/varnamelen v0.8.0 // indirect
|
||||||
@ -106,6 +111,7 @@ require (
|
|||||||
github.com/charmbracelet/lipgloss v0.7.1 // indirect
|
github.com/charmbracelet/lipgloss v0.7.1 // indirect
|
||||||
github.com/chavacava/garif v0.0.0-20230227094218-b8c73b2037b8 // indirect
|
github.com/chavacava/garif v0.0.0-20230227094218-b8c73b2037b8 // indirect
|
||||||
github.com/chrismellard/docker-credential-acr-env v0.0.0-20220327082430-c57b701bfc08 // indirect
|
github.com/chrismellard/docker-credential-acr-env v0.0.0-20220327082430-c57b701bfc08 // indirect
|
||||||
|
github.com/cloudflare/circl v1.3.3 // indirect
|
||||||
github.com/containerd/stargz-snapshotter/estargz v0.14.3 // indirect
|
github.com/containerd/stargz-snapshotter/estargz v0.14.3 // indirect
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
|
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
|
||||||
github.com/curioswitch/go-reassign v0.2.0 // indirect
|
github.com/curioswitch/go-reassign v0.2.0 // indirect
|
||||||
@ -127,7 +133,7 @@ require (
|
|||||||
github.com/docker/go-connections v0.4.0 // indirect
|
github.com/docker/go-connections v0.4.0 // indirect
|
||||||
github.com/docker/go-units v0.5.0 // indirect
|
github.com/docker/go-units v0.5.0 // indirect
|
||||||
github.com/elliotchance/orderedmap/v2 v2.2.0 // indirect
|
github.com/elliotchance/orderedmap/v2 v2.2.0 // indirect
|
||||||
github.com/emirpasic/gods v1.12.0 // indirect
|
github.com/emirpasic/gods v1.18.1 // indirect
|
||||||
github.com/esimonov/ifshort v1.0.4 // indirect
|
github.com/esimonov/ifshort v1.0.4 // indirect
|
||||||
github.com/ettle/strcase v0.1.1 // indirect
|
github.com/ettle/strcase v0.1.1 // indirect
|
||||||
github.com/evanphx/json-patch/v5 v5.6.0 // indirect
|
github.com/evanphx/json-patch/v5 v5.6.0 // indirect
|
||||||
@ -138,8 +144,8 @@ require (
|
|||||||
github.com/fzipp/gocyclo v0.6.0 // indirect
|
github.com/fzipp/gocyclo v0.6.0 // indirect
|
||||||
github.com/go-critic/go-critic v0.8.1 // indirect
|
github.com/go-critic/go-critic v0.8.1 // indirect
|
||||||
github.com/go-git/gcfg v1.5.0 // indirect
|
github.com/go-git/gcfg v1.5.0 // indirect
|
||||||
github.com/go-git/go-billy/v5 v5.3.1 // indirect
|
github.com/go-git/go-billy/v5 v5.4.1 // indirect
|
||||||
github.com/go-git/go-git/v5 v5.4.2 // indirect
|
github.com/go-git/go-git/v5 v5.6.1 // indirect
|
||||||
github.com/go-openapi/analysis v0.21.4 // indirect
|
github.com/go-openapi/analysis v0.21.4 // indirect
|
||||||
github.com/go-openapi/errors v0.20.3 // indirect
|
github.com/go-openapi/errors v0.20.3 // indirect
|
||||||
github.com/go-openapi/jsonpointer v0.19.5 // indirect
|
github.com/go-openapi/jsonpointer v0.19.5 // indirect
|
||||||
@ -195,11 +201,16 @@ require (
|
|||||||
github.com/gostaticanalysis/forcetypeassert v0.1.0 // indirect
|
github.com/gostaticanalysis/forcetypeassert v0.1.0 // indirect
|
||||||
github.com/gostaticanalysis/nilerr v0.1.1 // indirect
|
github.com/gostaticanalysis/nilerr v0.1.1 // indirect
|
||||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||||
|
github.com/hashicorp/go-checkpoint v0.5.0 // indirect
|
||||||
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
||||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||||
github.com/hashicorp/go-retryablehttp v0.7.2 // indirect
|
github.com/hashicorp/go-retryablehttp v0.7.2 // indirect
|
||||||
|
github.com/hashicorp/go-uuid v1.0.3 // indirect
|
||||||
github.com/hashicorp/go-version v1.6.0 // indirect
|
github.com/hashicorp/go-version v1.6.0 // indirect
|
||||||
|
github.com/hashicorp/hc-install v0.5.2 // indirect
|
||||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||||
|
github.com/hashicorp/terraform-exec v0.18.1 // indirect
|
||||||
|
github.com/hashicorp/terraform-json v0.16.0 // indirect
|
||||||
github.com/hexops/gotextdiff v1.0.3 // indirect
|
github.com/hexops/gotextdiff v1.0.3 // indirect
|
||||||
github.com/huandu/xstrings v1.3.2 // indirect
|
github.com/huandu/xstrings v1.3.2 // indirect
|
||||||
github.com/iancoleman/orderedmap v0.2.0 // indirect
|
github.com/iancoleman/orderedmap v0.2.0 // indirect
|
||||||
@ -213,7 +224,7 @@ require (
|
|||||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||||
github.com/josharian/intern v1.0.0 // indirect
|
github.com/josharian/intern v1.0.0 // indirect
|
||||||
github.com/julz/importas v0.1.0 // indirect
|
github.com/julz/importas v0.1.0 // indirect
|
||||||
github.com/kevinburke/ssh_config v1.1.0 // indirect
|
github.com/kevinburke/ssh_config v1.2.0 // indirect
|
||||||
github.com/kisielk/errcheck v1.6.3 // indirect
|
github.com/kisielk/errcheck v1.6.3 // indirect
|
||||||
github.com/kisielk/gotool v1.0.0 // indirect
|
github.com/kisielk/gotool v1.0.0 // indirect
|
||||||
github.com/kkHAIKE/contextcheck v1.1.4 // indirect
|
github.com/kkHAIKE/contextcheck v1.1.4 // indirect
|
||||||
@ -241,6 +252,7 @@ require (
|
|||||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
|
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
|
||||||
github.com/mbilski/exhaustivestruct v1.2.0 // indirect
|
github.com/mbilski/exhaustivestruct v1.2.0 // indirect
|
||||||
github.com/mgechev/revive v1.3.2 // indirect
|
github.com/mgechev/revive v1.3.2 // indirect
|
||||||
|
github.com/mitchellh/cli v1.1.5 // indirect
|
||||||
github.com/mitchellh/copystructure v1.2.0 // indirect
|
github.com/mitchellh/copystructure v1.2.0 // indirect
|
||||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||||
@ -263,10 +275,12 @@ require (
|
|||||||
github.com/opencontainers/image-spec v1.1.0-rc2 // indirect
|
github.com/opencontainers/image-spec v1.1.0-rc2 // indirect
|
||||||
github.com/pelletier/go-toml v1.9.5 // indirect
|
github.com/pelletier/go-toml v1.9.5 // indirect
|
||||||
github.com/pelletier/go-toml/v2 v2.0.6 // indirect
|
github.com/pelletier/go-toml/v2 v2.0.6 // indirect
|
||||||
|
github.com/pjbgf/sha1cd v0.3.0 // indirect
|
||||||
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect
|
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect
|
||||||
github.com/pkg/errors v0.9.1 // indirect
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
github.com/polyfloyd/go-errorlint v1.4.2 // indirect
|
github.com/polyfloyd/go-errorlint v1.4.2 // indirect
|
||||||
|
github.com/posener/complete v1.2.3 // indirect
|
||||||
github.com/prometheus/client_golang v1.15.1 // indirect
|
github.com/prometheus/client_golang v1.15.1 // indirect
|
||||||
github.com/prometheus/client_model v0.4.0 // indirect
|
github.com/prometheus/client_model v0.4.0 // indirect
|
||||||
github.com/prometheus/common v0.42.0 // indirect
|
github.com/prometheus/common v0.42.0 // indirect
|
||||||
@ -276,6 +290,7 @@ require (
|
|||||||
github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 // indirect
|
github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 // indirect
|
||||||
github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect
|
github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect
|
||||||
github.com/rivo/uniseg v0.4.2 // indirect
|
github.com/rivo/uniseg v0.4.2 // indirect
|
||||||
|
github.com/russross/blackfriday v1.6.0 // indirect
|
||||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||||
github.com/ryancurrah/gomodguard v1.3.0 // indirect
|
github.com/ryancurrah/gomodguard v1.3.0 // indirect
|
||||||
github.com/ryanrolds/sqlclosecheck v0.4.0 // indirect
|
github.com/ryanrolds/sqlclosecheck v0.4.0 // indirect
|
||||||
@ -286,6 +301,7 @@ require (
|
|||||||
github.com/securego/gosec/v2 v2.16.0 // indirect
|
github.com/securego/gosec/v2 v2.16.0 // indirect
|
||||||
github.com/sergi/go-diff v1.2.0 // indirect
|
github.com/sergi/go-diff v1.2.0 // indirect
|
||||||
github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c // indirect
|
github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c // indirect
|
||||||
|
github.com/shopspring/decimal v1.3.1 // indirect
|
||||||
github.com/sigstore/cosign/v2 v2.0.0 // indirect
|
github.com/sigstore/cosign/v2 v2.0.0 // indirect
|
||||||
github.com/sigstore/rekor v1.2.0 // indirect
|
github.com/sigstore/rekor v1.2.0 // indirect
|
||||||
github.com/sigstore/sigstore v1.6.4 // indirect
|
github.com/sigstore/sigstore v1.6.4 // indirect
|
||||||
@ -293,6 +309,7 @@ require (
|
|||||||
github.com/sivchari/containedctx v1.0.3 // indirect
|
github.com/sivchari/containedctx v1.0.3 // indirect
|
||||||
github.com/sivchari/nosnakecase v1.7.0 // indirect
|
github.com/sivchari/nosnakecase v1.7.0 // indirect
|
||||||
github.com/sivchari/tenv v1.7.1 // indirect
|
github.com/sivchari/tenv v1.7.1 // indirect
|
||||||
|
github.com/skeema/knownhosts v1.1.0 // indirect
|
||||||
github.com/slack-go/slack v0.12.2 // indirect
|
github.com/slack-go/slack v0.12.2 // indirect
|
||||||
github.com/sonatard/noctx v0.0.2 // indirect
|
github.com/sonatard/noctx v0.0.2 // indirect
|
||||||
github.com/sourcegraph/go-diff v0.7.0 // indirect
|
github.com/sourcegraph/go-diff v0.7.0 // indirect
|
||||||
@ -325,11 +342,12 @@ require (
|
|||||||
github.com/vbatts/tar-split v0.11.2 // indirect
|
github.com/vbatts/tar-split v0.11.2 // indirect
|
||||||
github.com/withfig/autocomplete-tools/integrations/cobra v1.2.1 // indirect
|
github.com/withfig/autocomplete-tools/integrations/cobra v1.2.1 // indirect
|
||||||
github.com/xanzy/go-gitlab v0.83.0 // indirect
|
github.com/xanzy/go-gitlab v0.83.0 // indirect
|
||||||
github.com/xanzy/ssh-agent v0.3.1 // indirect
|
github.com/xanzy/ssh-agent v0.3.3 // indirect
|
||||||
github.com/xen0n/gosmopolitan v1.2.1 // indirect
|
github.com/xen0n/gosmopolitan v1.2.1 // indirect
|
||||||
github.com/yagipy/maintidx v1.0.0 // indirect
|
github.com/yagipy/maintidx v1.0.0 // indirect
|
||||||
github.com/yeya24/promlinter v0.2.0 // indirect
|
github.com/yeya24/promlinter v0.2.0 // indirect
|
||||||
github.com/ykadowak/zerologlint v0.1.2 // indirect
|
github.com/ykadowak/zerologlint v0.1.2 // indirect
|
||||||
|
github.com/zclconf/go-cty v1.13.2 // indirect
|
||||||
gitlab.com/bosi/decorder v0.2.3 // indirect
|
gitlab.com/bosi/decorder v0.2.3 // indirect
|
||||||
gitlab.com/digitalxero/go-conventional-commit v1.0.7 // indirect
|
gitlab.com/digitalxero/go-conventional-commit v1.0.7 // indirect
|
||||||
go.mongodb.org/mongo-driver v1.11.3 // indirect
|
go.mongodb.org/mongo-driver v1.11.3 // indirect
|
||||||
|
100
tools/go.sum
100
tools/go.sum
@ -535,6 +535,9 @@ github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0
|
|||||||
github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
|
github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
|
||||||
github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60=
|
github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60=
|
||||||
github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=
|
github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=
|
||||||
|
github.com/Masterminds/sprig/v3 v3.2.1/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk=
|
||||||
|
github.com/Masterminds/sprig/v3 v3.2.2 h1:17jRggJu518dr3QaafizSXOjKYp94wKfABxUmyxvxX8=
|
||||||
|
github.com/Masterminds/sprig/v3 v3.2.2/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk=
|
||||||
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
|
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
|
||||||
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
|
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
|
||||||
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
|
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
|
||||||
@ -543,8 +546,8 @@ github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugX
|
|||||||
github.com/Microsoft/go-winio v0.4.17-0.20210211115548-6eac466e5fa3/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
|
github.com/Microsoft/go-winio v0.4.17-0.20210211115548-6eac466e5fa3/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
|
||||||
github.com/Microsoft/go-winio v0.4.17-0.20210324224401-5516f17a5958/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
|
github.com/Microsoft/go-winio v0.4.17-0.20210324224401-5516f17a5958/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
|
||||||
github.com/Microsoft/go-winio v0.4.17/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
|
github.com/Microsoft/go-winio v0.4.17/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
|
||||||
github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
|
|
||||||
github.com/Microsoft/go-winio v0.5.1/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
|
github.com/Microsoft/go-winio v0.5.1/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
|
||||||
|
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
|
||||||
github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg=
|
github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg=
|
||||||
github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE=
|
github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE=
|
||||||
github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg=
|
github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg=
|
||||||
@ -566,9 +569,8 @@ github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEV
|
|||||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||||
github.com/OpenPeeDeeP/depguard/v2 v2.1.0 h1:aQl70G173h/GZYhWf36aE5H0KaujXfVMnn/f1kSDVYY=
|
github.com/OpenPeeDeeP/depguard/v2 v2.1.0 h1:aQl70G173h/GZYhWf36aE5H0KaujXfVMnn/f1kSDVYY=
|
||||||
github.com/OpenPeeDeeP/depguard/v2 v2.1.0/go.mod h1:PUBgk35fX4i7JDmwzlJwJ+GMe6NfO1723wmJMgPThNQ=
|
github.com/OpenPeeDeeP/depguard/v2 v2.1.0/go.mod h1:PUBgk35fX4i7JDmwzlJwJ+GMe6NfO1723wmJMgPThNQ=
|
||||||
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo=
|
github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 h1:wPbRQzjjwFc0ih8puEVAOFGELsn1zoIIYdxvML7mDxA=
|
||||||
github.com/ProtonMail/go-crypto v0.0.0-20211112122917-428f8eabeeb3 h1:XcF0cTDJeiuZ5NU8w7WUDge0HRwwNRmxj/GGk6KSA6g=
|
github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8/go.mod h1:I0gYDMZ6Z5GRU7l58bNFSkPTFN6Yl12dsUlAZ8xy98g=
|
||||||
github.com/ProtonMail/go-crypto v0.0.0-20211112122917-428f8eabeeb3/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo=
|
|
||||||
github.com/ProtonMail/go-mime v0.0.0-20220302105931-303f85f7fe0f h1:CGq7OieOz3wyQJ1fO8S0eO9TCW1JyvLrf8fhzz1i8ko=
|
github.com/ProtonMail/go-mime v0.0.0-20220302105931-303f85f7fe0f h1:CGq7OieOz3wyQJ1fO8S0eO9TCW1JyvLrf8fhzz1i8ko=
|
||||||
github.com/ProtonMail/go-mime v0.0.0-20220302105931-303f85f7fe0f/go.mod h1:NYt+V3/4rEeDuaev/zw1zCq8uqVEuPHzDPo3OZrlGJ4=
|
github.com/ProtonMail/go-mime v0.0.0-20220302105931-303f85f7fe0f/go.mod h1:NYt+V3/4rEeDuaev/zw1zCq8uqVEuPHzDPo3OZrlGJ4=
|
||||||
github.com/ProtonMail/gopenpgp/v2 v2.2.2 h1:u2m7xt+CZWj88qK1UUNBoXeJCFJwJCZ/Ff4ymGoxEXs=
|
github.com/ProtonMail/gopenpgp/v2 v2.2.2 h1:u2m7xt+CZWj88qK1UUNBoXeJCFJwJCZ/Ff4ymGoxEXs=
|
||||||
@ -580,8 +582,8 @@ github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:H
|
|||||||
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
||||||
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
||||||
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
|
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
|
||||||
github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk=
|
github.com/acomagu/bufpipe v1.0.4 h1:e3H4WUzM3npvo5uv95QuJM3cQspFNtFBzvJ2oNjKIDQ=
|
||||||
github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4=
|
github.com/acomagu/bufpipe v1.0.4/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4=
|
||||||
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
|
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
|
||||||
github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=
|
github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=
|
||||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||||
@ -600,9 +602,11 @@ github.com/alexkohler/prealloc v1.0.0 h1:Hbq0/3fJPQhNkN0dR95AVrr6R7tou91y0uHG5pO
|
|||||||
github.com/alexkohler/prealloc v1.0.0/go.mod h1:VetnK3dIgFBBKmg0YnD9F9x6Icjd+9cvfHR56wJVlKE=
|
github.com/alexkohler/prealloc v1.0.0/go.mod h1:VetnK3dIgFBBKmg0YnD9F9x6Icjd+9cvfHR56wJVlKE=
|
||||||
github.com/alingse/asasalint v0.0.11 h1:SFwnQXJ49Kx/1GghOFz1XGqHYKp21Kq1nHad/0WQRnw=
|
github.com/alingse/asasalint v0.0.11 h1:SFwnQXJ49Kx/1GghOFz1XGqHYKp21Kq1nHad/0WQRnw=
|
||||||
github.com/alingse/asasalint v0.0.11/go.mod h1:nCaoMhw7a9kSJObvQyVzNTPBDbNpdocqrSP7t/cW5+I=
|
github.com/alingse/asasalint v0.0.11/go.mod h1:nCaoMhw7a9kSJObvQyVzNTPBDbNpdocqrSP7t/cW5+I=
|
||||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA=
|
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
|
||||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
|
||||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||||
|
github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw=
|
||||||
|
github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo=
|
||||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
||||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
||||||
@ -610,6 +614,7 @@ github.com/armon/go-metrics v0.3.3/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4
|
|||||||
github.com/armon/go-metrics v0.3.9/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc=
|
github.com/armon/go-metrics v0.3.9/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc=
|
||||||
github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc=
|
github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc=
|
||||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||||
|
github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI=
|
||||||
github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
|
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
|
||||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
||||||
@ -726,6 +731,7 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24
|
|||||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||||
|
github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY=
|
||||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||||
github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA=
|
github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA=
|
||||||
github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
|
github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
|
||||||
@ -755,6 +761,7 @@ github.com/butuzov/ireturn v0.2.0 h1:kCHi+YzC150GE98WFuZQu9yrTn6GEydO2AuPLbTgnO4
|
|||||||
github.com/butuzov/ireturn v0.2.0/go.mod h1:Wh6Zl3IMtTpaIKbmwzqi6olnM9ptYQxxVacMsOEFPoc=
|
github.com/butuzov/ireturn v0.2.0/go.mod h1:Wh6Zl3IMtTpaIKbmwzqi6olnM9ptYQxxVacMsOEFPoc=
|
||||||
github.com/butuzov/mirror v1.1.0 h1:ZqX54gBVMXu78QLoiqdwpl2mgmoOJTk7s4p4o+0avZI=
|
github.com/butuzov/mirror v1.1.0 h1:ZqX54gBVMXu78QLoiqdwpl2mgmoOJTk7s4p4o+0avZI=
|
||||||
github.com/butuzov/mirror v1.1.0/go.mod h1:8Q0BdQU6rC6WILDiBM60DBfvV78OLJmMmixe7GF45AE=
|
github.com/butuzov/mirror v1.1.0/go.mod h1:8Q0BdQU6rC6WILDiBM60DBfvV78OLJmMmixe7GF45AE=
|
||||||
|
github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
|
||||||
github.com/caarlos0/ctrlc v1.2.0 h1:AtbThhmbeYx1WW3WXdWrd94EHKi+0NPRGS4/4pzrjwk=
|
github.com/caarlos0/ctrlc v1.2.0 h1:AtbThhmbeYx1WW3WXdWrd94EHKi+0NPRGS4/4pzrjwk=
|
||||||
github.com/caarlos0/ctrlc v1.2.0/go.mod h1:n3gDlSjsXZ7rbD9/RprIR040b7oaLfNStikPd4gFago=
|
github.com/caarlos0/ctrlc v1.2.0/go.mod h1:n3gDlSjsXZ7rbD9/RprIR040b7oaLfNStikPd4gFago=
|
||||||
github.com/caarlos0/env/v8 v8.0.0 h1:POhxHhSpuxrLMIdvTGARuZqR4Jjm8AYmoi/JKlcScs0=
|
github.com/caarlos0/env/v8 v8.0.0 h1:POhxHhSpuxrLMIdvTGARuZqR4Jjm8AYmoi/JKlcScs0=
|
||||||
@ -816,6 +823,9 @@ github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6D
|
|||||||
github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
|
github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
|
||||||
github.com/clbanning/mxj v1.8.4/go.mod h1:BVjHeAH+rl9rs6f+QIpeRl0tfu10SXn1pUSa5PVGJng=
|
github.com/clbanning/mxj v1.8.4/go.mod h1:BVjHeAH+rl9rs6f+QIpeRl0tfu10SXn1pUSa5PVGJng=
|
||||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||||
|
github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I=
|
||||||
|
github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs=
|
||||||
|
github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
|
||||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||||
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||||
@ -1049,8 +1059,8 @@ github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb
|
|||||||
github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
|
github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
|
||||||
github.com/emicklei/go-restful/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
|
github.com/emicklei/go-restful/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
|
||||||
github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
|
github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
|
||||||
github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg=
|
github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
|
||||||
github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o=
|
github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||||
@ -1091,7 +1101,6 @@ github.com/felixge/httpsnoop v1.0.2/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSw
|
|||||||
github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||||
github.com/firefart/nonamedreturns v1.0.4 h1:abzI1p7mAEPYuR4A+VLKn4eNDOycjYo2phmY9sfv40Y=
|
github.com/firefart/nonamedreturns v1.0.4 h1:abzI1p7mAEPYuR4A+VLKn4eNDOycjYo2phmY9sfv40Y=
|
||||||
github.com/firefart/nonamedreturns v1.0.4/go.mod h1:TDhe/tjI1BXo48CmYbUduTV7BdIga8MAO/xbKdcVsGI=
|
github.com/firefart/nonamedreturns v1.0.4/go.mod h1:TDhe/tjI1BXo48CmYbUduTV7BdIga8MAO/xbKdcVsGI=
|
||||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
|
||||||
github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
|
github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
|
||||||
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
|
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
|
||||||
github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
|
github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
|
||||||
@ -1118,19 +1127,19 @@ github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeME
|
|||||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||||
github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
|
github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
|
||||||
github.com/gin-gonic/gin v1.7.7/go.mod h1:axIBovoeJpVj8S3BwE0uPMTeReE4+AfFtqpqaZ1qq1U=
|
github.com/gin-gonic/gin v1.7.7/go.mod h1:axIBovoeJpVj8S3BwE0uPMTeReE4+AfFtqpqaZ1qq1U=
|
||||||
github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0=
|
github.com/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY=
|
||||||
github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
|
github.com/gliderlabs/ssh v0.3.5/go.mod h1:8XB4KraRrX39qHhT6yxPsHedjA08I/uBVwj4xC+/+z4=
|
||||||
github.com/go-critic/go-critic v0.8.1 h1:16omCF1gN3gTzt4j4J6fKI/HnRojhEp+Eks6EuKw3vw=
|
github.com/go-critic/go-critic v0.8.1 h1:16omCF1gN3gTzt4j4J6fKI/HnRojhEp+Eks6EuKw3vw=
|
||||||
github.com/go-critic/go-critic v0.8.1/go.mod h1:kpzXl09SIJX1cr9TB/g/sAG+eFEl7ZS9f9cqvZtyNl0=
|
github.com/go-critic/go-critic v0.8.1/go.mod h1:kpzXl09SIJX1cr9TB/g/sAG+eFEl7ZS9f9cqvZtyNl0=
|
||||||
github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4=
|
github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4=
|
||||||
github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E=
|
github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E=
|
||||||
github.com/go-git/go-billy/v5 v5.2.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
|
|
||||||
github.com/go-git/go-billy/v5 v5.3.1 h1:CPiOUAzKtMRvolEKw+bG1PLRpT7D3LIs3/3ey4Aiu34=
|
|
||||||
github.com/go-git/go-billy/v5 v5.3.1/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
|
github.com/go-git/go-billy/v5 v5.3.1/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
|
||||||
github.com/go-git/go-git-fixtures/v4 v4.2.1 h1:n9gGL1Ct/yIw+nfsfr8s4+sbhT+Ncu2SubfXjIWgci8=
|
github.com/go-git/go-billy/v5 v5.4.1 h1:Uwp5tDRkPr+l/TnbHOQzp+tmJfLceOlbVucgpTz8ix4=
|
||||||
github.com/go-git/go-git-fixtures/v4 v4.2.1/go.mod h1:K8zd3kDUAykwTdDCr+I0per6Y6vMiRR/nnVTBtavnB0=
|
github.com/go-git/go-billy/v5 v5.4.1/go.mod h1:vjbugF6Fz7JIflbVpl1hJsGjSHNltrSw45YK/ukIvQg=
|
||||||
github.com/go-git/go-git/v5 v5.4.2 h1:BXyZu9t0VkbiHtqrsvdq39UDhGJTl1h55VW6CSC4aY4=
|
github.com/go-git/go-git-fixtures/v4 v4.3.1 h1:y5z6dd3qi8Hl+stezc8p3JxDkoTRqMAlKnXHuzrfjTQ=
|
||||||
github.com/go-git/go-git/v5 v5.4.2/go.mod h1:gQ1kArt6d+n+BGd+/B/I74HwRTLhth2+zti4ihgckDc=
|
github.com/go-git/go-git-fixtures/v4 v4.3.1/go.mod h1:8LHG1a3SRW71ettAD/jW13h8c6AqjVSeL11RAdgaqpo=
|
||||||
|
github.com/go-git/go-git/v5 v5.6.1 h1:q4ZRqQl4pR/ZJHc1L5CFjGA1a10u76aV1iC+nh+bHsk=
|
||||||
|
github.com/go-git/go-git/v5 v5.6.1/go.mod h1:mvyoL6Unz0PiTQrGQfSfiLFhBH1c1e84ylC2MDs4ee8=
|
||||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||||
@ -1535,6 +1544,8 @@ github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FK
|
|||||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||||
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
|
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
|
||||||
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||||
|
github.com/hashicorp/go-checkpoint v0.5.0 h1:MFYpPZCnQqQTE18jFwSII6eUQrD/oxMFp3mlgcqk5mU=
|
||||||
|
github.com/hashicorp/go-checkpoint v0.5.0/go.mod h1:7nfLNL10NsxqO4iWuW6tWW0HjZuDrwkBuEQsVcpCOgg=
|
||||||
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
||||||
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
||||||
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
|
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
|
||||||
@ -1566,6 +1577,8 @@ github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdv
|
|||||||
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||||
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||||
github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||||
|
github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
|
||||||
|
github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||||
github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||||
github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek=
|
github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek=
|
||||||
github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||||
@ -1574,6 +1587,8 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ
|
|||||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||||
github.com/hashicorp/golang-lru v0.6.0/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
github.com/hashicorp/golang-lru v0.6.0/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||||
|
github.com/hashicorp/hc-install v0.5.2 h1:SfwMFnEXVVirpwkDuSF5kymUOhrUxrTq3udEseZdOD0=
|
||||||
|
github.com/hashicorp/hc-install v0.5.2/go.mod h1:9QISwe6newMWIfEiXpzuu1k9HAGtQYgnSH8H9T8wmoI=
|
||||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||||
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
|
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
|
||||||
@ -1591,6 +1606,12 @@ github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKEN
|
|||||||
github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4=
|
github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4=
|
||||||
github.com/hashicorp/serf v0.9.7/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4=
|
github.com/hashicorp/serf v0.9.7/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4=
|
||||||
github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4=
|
github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4=
|
||||||
|
github.com/hashicorp/terraform-exec v0.18.1 h1:LAbfDvNQU1l0NOQlTuudjczVhHj061fNX5H8XZxHlH4=
|
||||||
|
github.com/hashicorp/terraform-exec v0.18.1/go.mod h1:58wg4IeuAJ6LVsLUeD2DWZZoc/bYi6dzhLHzxM41980=
|
||||||
|
github.com/hashicorp/terraform-json v0.16.0 h1:UKkeWRWb23do5LNAFlh/K3N0ymn1qTOO8c+85Albo3s=
|
||||||
|
github.com/hashicorp/terraform-json v0.16.0/go.mod h1:v0Ufk9jJnk6tcIZvScHvetlKfiNTC+WS21mnXIlc0B0=
|
||||||
|
github.com/hashicorp/terraform-plugin-docs v0.15.0 h1:W5xYB5kCUBqO7lyjE2UMmUBh95c0aAf4jwO0Xuuw2Ec=
|
||||||
|
github.com/hashicorp/terraform-plugin-docs v0.15.0/go.mod h1:K5Taof1Y7sL4dw6Ie0qMFyQnHN0W+RSVMD0iIyFDFJc=
|
||||||
github.com/hetznercloud/hcloud-go v1.33.1/go.mod h1:XX/TQub3ge0yWR2yHWmnDVIrB+MQbda1pHxkUmDlUME=
|
github.com/hetznercloud/hcloud-go v1.33.1/go.mod h1:XX/TQub3ge0yWR2yHWmnDVIrB+MQbda1pHxkUmDlUME=
|
||||||
github.com/hetznercloud/hcloud-go v1.39.0/go.mod h1:mepQwR6va27S3UQthaEPGS86jtzSY9xWL1e9dyxXpgA=
|
github.com/hetznercloud/hcloud-go v1.39.0/go.mod h1:mepQwR6va27S3UQthaEPGS86jtzSY9xWL1e9dyxXpgA=
|
||||||
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
|
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
|
||||||
@ -1598,6 +1619,7 @@ github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSo
|
|||||||
github.com/honeycombio/beeline-go v1.10.0 h1:cUDe555oqvw8oD76BQJ8alk7FP0JZ/M/zXpNvOEDLDc=
|
github.com/honeycombio/beeline-go v1.10.0 h1:cUDe555oqvw8oD76BQJ8alk7FP0JZ/M/zXpNvOEDLDc=
|
||||||
github.com/honeycombio/libhoney-go v1.16.0 h1:kPpqoz6vbOzgp7jC6SR7SkNj7rua7rgxvznI6M3KdHc=
|
github.com/honeycombio/libhoney-go v1.16.0 h1:kPpqoz6vbOzgp7jC6SR7SkNj7rua7rgxvznI6M3KdHc=
|
||||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||||
|
github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
|
||||||
github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw=
|
github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw=
|
||||||
github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
|
github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
|
||||||
github.com/hudl/fargo v1.4.0/go.mod h1:9Ai6uvFy5fQNq6VPKtg+Ceq1+eTY4nKUlR2JElEOcDo=
|
github.com/hudl/fargo v1.4.0/go.mod h1:9Ai6uvFy5fQNq6VPKtg+Ceq1+eTY4nKUlR2JElEOcDo=
|
||||||
@ -1615,6 +1637,7 @@ github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJ
|
|||||||
github.com/imdario/mergo v0.3.10/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
github.com/imdario/mergo v0.3.10/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||||
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||||
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||||
|
github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg=
|
||||||
github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM=
|
github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM=
|
||||||
github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
|
github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
|
||||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||||
@ -1713,9 +1736,8 @@ github.com/julz/importas v0.1.0/go.mod h1:oSFU2R4XK/P7kNBrnL/FEQlDGN1/6WoxXEjSSX
|
|||||||
github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
|
github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
|
||||||
github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4=
|
github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4=
|
||||||
github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA=
|
github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA=
|
||||||
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=
|
||||||
github.com/kevinburke/ssh_config v1.1.0 h1:pH/t1WS9NzT8go394IqZeJTMHVm6Cr6ZJ6AQ+mdNo/o=
|
github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
||||||
github.com/kevinburke/ssh_config v1.1.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
|
||||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||||
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
||||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||||
@ -1865,6 +1887,9 @@ github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLT
|
|||||||
github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4=
|
github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4=
|
||||||
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
||||||
github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI=
|
github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI=
|
||||||
|
github.com/mitchellh/cli v1.1.5 h1:OxRIeJXpAMztws/XHlN2vu6imG5Dpq+j61AzAX5fLng=
|
||||||
|
github.com/mitchellh/cli v1.1.5/go.mod h1:v8+iFts2sPIKUV1ltktPXMCC8fumSKFItNcD2cLtRR4=
|
||||||
|
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
|
||||||
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
|
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
|
||||||
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
|
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
|
||||||
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||||
@ -1884,8 +1909,10 @@ github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR
|
|||||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||||
github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A=
|
github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A=
|
||||||
|
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
||||||
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
|
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
|
||||||
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
||||||
|
github.com/mmcloughlin/avo v0.5.0/go.mod h1:ChHFdoV7ql95Wi7vuq2YT1bwCJqiWdZrQ1im3VujLYM=
|
||||||
github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc=
|
github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc=
|
||||||
github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
|
github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
|
||||||
github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
|
github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
|
||||||
@ -2052,6 +2079,8 @@ github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha
|
|||||||
github.com/performancecopilot/speed/v4 v4.0.0/go.mod h1:qxrSyuDGrTOWfV+uKRFhfxw6h/4HXRGUiZiufxo49BM=
|
github.com/performancecopilot/speed/v4 v4.0.0/go.mod h1:qxrSyuDGrTOWfV+uKRFhfxw6h/4HXRGUiZiufxo49BM=
|
||||||
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
||||||
github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
|
github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
|
||||||
|
github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4=
|
||||||
|
github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI=
|
||||||
github.com/pkg/browser v0.0.0-20210115035449-ce105d075bb4/go.mod h1:N6UoU20jOqggOuDwUaBQpluzLNDqif3kq9z2wpdYEfQ=
|
github.com/pkg/browser v0.0.0-20210115035449-ce105d075bb4/go.mod h1:N6UoU20jOqggOuDwUaBQpluzLNDqif3kq9z2wpdYEfQ=
|
||||||
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU=
|
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU=
|
||||||
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
|
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
|
||||||
@ -2069,6 +2098,7 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
|
|||||||
github.com/polyfloyd/go-errorlint v1.4.2 h1:CU+O4181IxFDdPH6t/HT7IiDj1I7zxNi1RIUxYwn8d0=
|
github.com/polyfloyd/go-errorlint v1.4.2 h1:CU+O4181IxFDdPH6t/HT7IiDj1I7zxNi1RIUxYwn8d0=
|
||||||
github.com/polyfloyd/go-errorlint v1.4.2/go.mod h1:k6fU/+fQe38ednoZS51T7gSIGQW1y94d6TkSr35OzH8=
|
github.com/polyfloyd/go-errorlint v1.4.2/go.mod h1:k6fU/+fQe38ednoZS51T7gSIGQW1y94d6TkSr35OzH8=
|
||||||
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
||||||
|
github.com/posener/complete v1.2.3 h1:NP0eAhjcjImqslEwo/1hq7gpajME0fTLTezBKDqfXqo=
|
||||||
github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s=
|
github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s=
|
||||||
github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
|
github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
|
||||||
github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
|
github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
|
||||||
@ -2163,6 +2193,8 @@ github.com/rs/cors v1.8.2/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
|
|||||||
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
|
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
|
||||||
github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
|
github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
|
||||||
github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
|
github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
|
||||||
|
github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww=
|
||||||
|
github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY=
|
||||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
@ -2201,6 +2233,8 @@ github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAx
|
|||||||
github.com/shoenig/test v0.6.0/go.mod h1:xYtyGBC5Q3kzCNyJg/SjgNpfAa2kvmgA0i5+lQso8x0=
|
github.com/shoenig/test v0.6.0/go.mod h1:xYtyGBC5Q3kzCNyJg/SjgNpfAa2kvmgA0i5+lQso8x0=
|
||||||
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
|
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
|
||||||
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
||||||
|
github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
|
||||||
|
github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
||||||
github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
|
github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
|
||||||
github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ=
|
github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ=
|
||||||
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
|
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
|
||||||
@ -2229,6 +2263,8 @@ github.com/sivchari/nosnakecase v1.7.0 h1:7QkpWIRMe8x25gckkFd2A5Pi6Ymo0qgr4JrhGt
|
|||||||
github.com/sivchari/nosnakecase v1.7.0/go.mod h1:CwDzrzPea40/GB6uynrNLiorAlgFRvRbFSgJx2Gs+QY=
|
github.com/sivchari/nosnakecase v1.7.0/go.mod h1:CwDzrzPea40/GB6uynrNLiorAlgFRvRbFSgJx2Gs+QY=
|
||||||
github.com/sivchari/tenv v1.7.1 h1:PSpuD4bu6fSmtWMxSGWcvqUUgIn7k3yOJhOIzVWn8Ak=
|
github.com/sivchari/tenv v1.7.1 h1:PSpuD4bu6fSmtWMxSGWcvqUUgIn7k3yOJhOIzVWn8Ak=
|
||||||
github.com/sivchari/tenv v1.7.1/go.mod h1:64yStXKSOxDfX47NlhVwND4dHwfZDdbp2Lyl018Icvg=
|
github.com/sivchari/tenv v1.7.1/go.mod h1:64yStXKSOxDfX47NlhVwND4dHwfZDdbp2Lyl018Icvg=
|
||||||
|
github.com/skeema/knownhosts v1.1.0 h1:Wvr9V0MxhjRbl3f9nMnKnFfiWTJmtECJ9Njkea3ysW0=
|
||||||
|
github.com/skeema/knownhosts v1.1.0/go.mod h1:sKFq3RD6/TKZkSWn8boUbDC7Qkgcv+8XXijpFO6roag=
|
||||||
github.com/slack-go/slack v0.12.2 h1:x3OppyMyGIbbiyFhsBmpf9pwkUzMhthJMRNmNlA4LaQ=
|
github.com/slack-go/slack v0.12.2 h1:x3OppyMyGIbbiyFhsBmpf9pwkUzMhthJMRNmNlA4LaQ=
|
||||||
github.com/slack-go/slack v0.12.2/go.mod h1:hlGi5oXA+Gt+yWTPP0plCdRKmjsDxecdHxYQdlMQKOw=
|
github.com/slack-go/slack v0.12.2/go.mod h1:hlGi5oXA+Gt+yWTPP0plCdRKmjsDxecdHxYQdlMQKOw=
|
||||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||||
@ -2386,9 +2422,8 @@ github.com/withfig/autocomplete-tools/integrations/cobra v1.2.1 h1:+dBg5k7nuTE38
|
|||||||
github.com/withfig/autocomplete-tools/integrations/cobra v1.2.1/go.mod h1:nmuySobZb4kFgFy6BptpXp/BBw+xFSyvVPP6auoJB4k=
|
github.com/withfig/autocomplete-tools/integrations/cobra v1.2.1/go.mod h1:nmuySobZb4kFgFy6BptpXp/BBw+xFSyvVPP6auoJB4k=
|
||||||
github.com/xanzy/go-gitlab v0.83.0 h1:37p0MpTPNbsTMKX/JnmJtY8Ch1sFiJzVF342+RvZEGw=
|
github.com/xanzy/go-gitlab v0.83.0 h1:37p0MpTPNbsTMKX/JnmJtY8Ch1sFiJzVF342+RvZEGw=
|
||||||
github.com/xanzy/go-gitlab v0.83.0/go.mod h1:5ryv+MnpZStBH8I/77HuQBsMbBGANtVpLWC15qOjWAw=
|
github.com/xanzy/go-gitlab v0.83.0/go.mod h1:5ryv+MnpZStBH8I/77HuQBsMbBGANtVpLWC15qOjWAw=
|
||||||
github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0=
|
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
|
||||||
github.com/xanzy/ssh-agent v0.3.1 h1:AmzO1SSWxw73zxFZPRwaMN1MohDw8UyHnmuxyceTEGo=
|
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
|
||||||
github.com/xanzy/ssh-agent v0.3.1/go.mod h1:QIE4lCeL7nkC25x+yA3LBIYfwCc1TFziCtG7cBAac6w=
|
|
||||||
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
|
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
|
||||||
github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs=
|
github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs=
|
||||||
github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g=
|
github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g=
|
||||||
@ -2423,6 +2458,8 @@ github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5t
|
|||||||
github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs=
|
github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs=
|
||||||
github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA=
|
github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA=
|
||||||
github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg=
|
github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg=
|
||||||
|
github.com/zclconf/go-cty v1.13.2 h1:4GvrUxe/QUDYuJKAav4EYqdM47/kZa672LwmXFmEKT0=
|
||||||
|
github.com/zclconf/go-cty v1.13.2/go.mod h1:YKQzy/7pZ7iq2jNFzy5go57xdxdWoLLpaEp4u238AE0=
|
||||||
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
|
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
|
||||||
gitlab.com/bosi/decorder v0.2.3 h1:gX4/RgK16ijY8V+BRQHAySfQAb354T7/xQpDB2n10P0=
|
gitlab.com/bosi/decorder v0.2.3 h1:gX4/RgK16ijY8V+BRQHAySfQAb354T7/xQpDB2n10P0=
|
||||||
gitlab.com/bosi/decorder v0.2.3/go.mod h1:9K1RB5+VPNQYtXtTDAzd2OEftsZb1oV0IrJrzChSdGE=
|
gitlab.com/bosi/decorder v0.2.3/go.mod h1:9K1RB5+VPNQYtXtTDAzd2OEftsZb1oV0IrJrzChSdGE=
|
||||||
@ -2546,11 +2583,11 @@ go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=
|
|||||||
go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=
|
go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=
|
||||||
gocloud.dev v0.29.0 h1:fBy0jwJSmxs0IjT0fE32MO+Mj+307VZQwyHaTyFZbC4=
|
gocloud.dev v0.29.0 h1:fBy0jwJSmxs0IjT0fE32MO+Mj+307VZQwyHaTyFZbC4=
|
||||||
gocloud.dev v0.29.0/go.mod h1:E3dAjji80g+lIkq4CQeF/BTWqv1CBeTftmOb+gpyapQ=
|
gocloud.dev v0.29.0/go.mod h1:E3dAjji80g+lIkq4CQeF/BTWqv1CBeTftmOb+gpyapQ=
|
||||||
|
golang.org/x/arch v0.1.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||||
golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/crypto v0.0.0-20181009213950-7c1a557ab941/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20181009213950-7c1a557ab941/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
||||||
golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
||||||
@ -2563,8 +2600,10 @@ golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3
|
|||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
|
golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
|
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||||
@ -2584,8 +2623,10 @@ golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0
|
|||||||
golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/crypto v0.0.0-20220511200225-c6db032c6c88/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20220511200225-c6db032c6c88/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
|
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
|
golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/crypto v0.0.0-20221012134737-56aed061732a/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20221012134737-56aed061732a/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
|
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
|
||||||
@ -2699,7 +2740,6 @@ golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v
|
|||||||
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
|
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
|
||||||
golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k=
|
|
||||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||||
golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8=
|
golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8=
|
||||||
golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM=
|
golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM=
|
||||||
@ -2727,6 +2767,7 @@ golang.org/x/net v0.0.0-20220617184016-355a448f1bc9/go.mod h1:XRhObCWvk6IyKnWLug
|
|||||||
golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
golang.org/x/net v0.0.0-20220805013720-a33c5aa5df48/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
golang.org/x/net v0.0.0-20220805013720-a33c5aa5df48/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||||
|
golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||||
golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||||
golang.org/x/net v0.0.0-20220921155015-db77216a4ee9/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
golang.org/x/net v0.0.0-20220921155015-db77216a4ee9/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||||
golang.org/x/net v0.0.0-20221012135044-0b7e1fb9d458/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
golang.org/x/net v0.0.0-20221012135044-0b7e1fb9d458/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||||
@ -2738,6 +2779,7 @@ golang.org/x/net v0.3.1-0.20221206200815-1e63c2f08a10/go.mod h1:MBQ8lrhLObU/6UmL
|
|||||||
golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
|
golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
|
||||||
golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
|
golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
|
||||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||||
|
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||||
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
|
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
|
||||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
@ -2890,7 +2932,6 @@ golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210502180810-71e4cd670f79/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210503080704-8803ae5d1324/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210503080704-8803ae5d1324/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
@ -2940,6 +2981,7 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||||||
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220731174439-a90be440212d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220731174439-a90be440212d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220919091848-fb04ddd9f9c8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220919091848-fb04ddd9f9c8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
@ -2954,6 +2996,7 @@ golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9sn
|
|||||||
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
|
golang.org/x/term v0.0.0-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
|
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
|
||||||
golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
|
golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
|
||||||
@ -3436,6 +3479,7 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C
|
|||||||
gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
||||||
|
@ -1,6 +1,12 @@
|
|||||||
//go:build tools
|
//go:build tools
|
||||||
// +build tools
|
// +build tools
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
package tools
|
package tools
|
||||||
|
|
||||||
// Manage tool dependencies via go.mod.
|
// Manage tool dependencies via go.mod.
|
||||||
@ -10,4 +16,5 @@ package tools
|
|||||||
import (
|
import (
|
||||||
_ "github.com/golangci/golangci-lint/cmd/golangci-lint"
|
_ "github.com/golangci/golangci-lint/cmd/golangci-lint"
|
||||||
_ "github.com/goreleaser/goreleaser"
|
_ "github.com/goreleaser/goreleaser"
|
||||||
|
_ "github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs"
|
||||||
)
|
)
|
||||||
|
34
utils/env.go
Normal file
34
utils/env.go
Normal file
@ -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 utils
|
||||||
|
|
||||||
|
import "os"
|
||||||
|
|
||||||
|
// GetAnyStringEnv returns the first non-empty string value from the environment variables.
|
||||||
|
func GetAnyStringEnv(ks ...string) string {
|
||||||
|
for _, k := range ks {
|
||||||
|
if v := os.Getenv(k); v != "" {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAnyBoolEnv returns the first non-empty boolean value from the environment variables.
|
||||||
|
func GetAnyBoolEnv(ks ...string) bool {
|
||||||
|
val := ""
|
||||||
|
|
||||||
|
for _, k := range ks {
|
||||||
|
if v := os.Getenv(k); v != "" {
|
||||||
|
val = v
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return val == "true" || val == "1"
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user