0
0
mirror of https://github.com/bpg/terraform-provider-proxmox.git synced 2025-08-23 03:48:35 +00:00

Upgrade the provider codebase to use Terraform SDK v2 (#91)

* Update TF SDK using `tf-sdk-migrator v2upgrade`
Address some linter issues
Clean up `resource_virtual_environment_file.go` (still, error handling is not ideal)

* few minor cleanups

* Clean up, add context and diagnostics to `resource_virtual_environment_vm.go`

* Clean up, add context and diagnostics to `resource_virtual_environment_container.go`

* Clean up, add context and diagnostics to `resource_virtual_environment_container.go`

* Update remaining resources and data sources

* fix `make example`... now it actually uses the built provider 🤦

* propagate Context everywhere
use tflog.* for logging

* add support for debug flag

* fix old issues with:
- setting `resource_virtual_environment_file.changed` attribute
- setting `resource_virtual_environment_cluster_ipset.cidr` attributes
- setting `data_source_virtual_environment_user.groups` and `.keys` attributes

* bump dependencies

* minor cleanups

* Bump Go to v1.18
Dropped support for TF v0.x

* more cleanups

* update README.md

* update PR template

* update release.yml
This commit is contained in:
Pavel Boldyrev 2022-07-14 12:20:30 -04:00 committed by GitHub
parent 3234451213
commit 192cbd5e3d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
94 changed files with 2389 additions and 2838 deletions

View File

@ -8,9 +8,4 @@
<!--- If your PR fully resolves and should automatically close the linked issue, use Closes. Otherwise, use Relates ---> <!--- If your PR fully resolves and should automatically close the linked issue, use Closes. Otherwise, use Relates --->
Relates OR Closes #0000 Relates OR Closes #0000
Release note for [CHANGELOG](https://github.com/bpg/terraform-provider-proxmox/blob/main/CHANGELOG.md): <!--- Release note for [CHANGELOG](https://github.com/bpg/terraform-provider-proxmox/blob/main/CHANGELOG.md) will be created automatically using the PR's title and labels, update them accordingly. --->
<!-- If change is not user facing, just write "NONE" in the release-note block below. -->
```release-note
```

View File

@ -1,14 +1,11 @@
# This GitHub action can publish assets for release when a tag is created. # This GitHub action can publish assets for release when a tag is created.
# Currently its setup to run on any tag that matches the pattern "v*" (ie. v0.1.0). # Currently its setup to run on any tag that matches the pattern "v*" (ie. v0.1.0).
# #
# This uses an action (hashicorp/ghaction-import-gpg) that assumes you set your # This uses an action (crazy-max/ghaction-import-gpg) that assumes you set your
# private key in the `GPG_PRIVATE_KEY` secret and passphrase in the `PASSPHRASE` # private key in the `GPG_PRIVATE_KEY` secret and passphrase in the `PASSPHRASE`
# secret. If you would rather own your own GPG handling, please fork this action # secret. If you would rather own your own GPG handling, please fork this action
# or use an alternative one for key handling. # or use an alternative one for key handling.
# #
# You will need to pass the `--batch` flag to `gpg` in your signing step
# in `goreleaser` to indicate this is being used in a non-interactive mode.
#
name: release name: release
on: on:
push: push:
@ -27,7 +24,7 @@ jobs:
- name: Set up Go - name: Set up Go
uses: actions/setup-go@v3 uses: actions/setup-go@v3
with: with:
go-version: 1.16 go-version: 1.18
- name: Import GPG key - name: Import GPG key
id: import_gpg id: import_gpg

View File

@ -20,7 +20,7 @@ jobs:
- name: Set up Go - name: Set up Go
uses: actions/setup-go@v3 uses: actions/setup-go@v3
with: with:
go-version: '1.16' go-version: '1.18'
id: go id: go
- name: Check out code into the Go module directory - name: Check out code into the Go module directory
@ -43,15 +43,15 @@ jobs:
matrix: matrix:
# list whatever Terraform versions here you would like to support # list whatever Terraform versions here you would like to support
terraform: terraform:
- '0.14.11' - '1.0.1'
- '0.15.5' - '1.1.9'
- '1.1.7' - '1.2.5'
steps: steps:
- name: Set up Go - name: Set up Go
uses: actions/setup-go@v3 uses: actions/setup-go@v3
with: with:
go-version: '1.16' go-version: '1.18'
id: go id: go
- name: Check out code into the Go module directory - name: Check out code into the Go module directory

View File

@ -10,7 +10,7 @@ ifeq ($(OS),Windows_NT)
TERRAFORM_PLUGIN_CACHE_DIRECTORY=$$(cygpath -u "$(shell pwd -P)")/cache/plugins TERRAFORM_PLUGIN_CACHE_DIRECTORY=$$(cygpath -u "$(shell pwd -P)")/cache/plugins
TERRAFORM_PLUGIN_EXTENSION=.exe TERRAFORM_PLUGIN_EXTENSION=.exe
else else
TERRAFORM_PLATFORM=$$(terraform -version | awk 'FNR == 2 {print $2}') TERRAFORM_PLATFORM=$$(terraform -version | awk 'FNR == 2 {print $$2}')
TERRAFORM_PLUGIN_CACHE_DIRECTORY=$(shell pwd -P)/cache/plugins TERRAFORM_PLUGIN_CACHE_DIRECTORY=$(shell pwd -P)/cache/plugins
endif endif

View File

@ -18,9 +18,9 @@ VM deployment in Proxmox v7.0, and a few other enhancements.
| 7.x | 0.4.x \> 0.4.4 <br>0.5.x | | 7.x | 0.4.x \> 0.4.4 <br>0.5.x |
## Requirements ## Requirements
- [Terraform](https://www.terraform.io/downloads.html) 0.14+ - [Terraform](https://www.terraform.io/downloads.html) 1.0+
- [Go](https://golang.org/doc/install) 1.16+ (to build the provider plugin) - [Go](https://golang.org/doc/install) 1.18+ (to build the provider plugin)
- [GoReleaser](https://goreleaser.com/install/) 0.155+ (to build the provider plugin) - [GoReleaser](https://goreleaser.com/install/) v1.10+ (to build the provider plugin)
## Table of Contents ## Table of Contents
- [Building the provider](#building-the-provider) - [Building the provider](#building-the-provider)
@ -56,6 +56,25 @@ $ make test
Tests are limited to regression tests, ensuring backwards compatibility. Tests are limited to regression tests, ensuring backwards compatibility.
## Deploying the example resources
There are number of TF examples in the `examples` directory, which can be used to deploy a Container, VM, or other Proxmox resources on your test Proxmox cluster.
The following assumptions are made about the test Proxmox cluster:
- It has one node named `pve`
- The node has local storages named `local` and `local-lvm`
Create `examples/terraform.tfvars` with the following variables:
```sh
virtual_environment_username = "root@pam"
virtual_environment_password = "put-your-password-here"
virtual_environment_endpoint = "https://<your-cluster-endpoint>:8006/"
```
Then run `make example` to deploy the example resources.
## Known issues ## Known issues
### Disk images cannot be imported by non-PAM accounts ### Disk images cannot be imported by non-PAM accounts
@ -78,7 +97,7 @@ resource "proxmox_virtual_environment_file" "vmdk_disk_image" {
} }
resource "proxmox_virtual_environment_vm" "example" { resource "proxmox_virtual_environment_vm" "example" {
... //...
disk { disk {
datastore_id = "datastore-id" datastore_id = "datastore-id"
@ -87,7 +106,7 @@ resource "proxmox_virtual_environment_vm" "example" {
file_id = "${proxmox_virtual_environment_file.vmdk_disk_image.id}" file_id = "${proxmox_virtual_environment_file.vmdk_disk_image.id}"
} }
... //...
} }
``` ```

View File

@ -1,7 +1,7 @@
GEM GEM
remote: https://rubygems.org/ remote: https://rubygems.org/
specs: specs:
activesupport (6.0.5) activesupport (6.0.5.1)
concurrent-ruby (~> 1.0, >= 1.0.2) concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 0.7, < 2) i18n (>= 0.7, < 2)
minitest (~> 5.1) minitest (~> 5.1)
@ -14,7 +14,7 @@ GEM
execjs execjs
coffee-script-source (1.11.1) coffee-script-source (1.11.1)
colorator (1.1.0) colorator (1.1.0)
commonmarker (0.23.4) commonmarker (0.23.5)
concurrent-ruby (1.1.10) concurrent-ruby (1.1.10)
dnsruby (1.61.9) dnsruby (1.61.9)
simpleidn (~> 0.1) simpleidn (~> 0.1)
@ -34,7 +34,7 @@ GEM
ffi (1.15.5-x64-mingw32) ffi (1.15.5-x64-mingw32)
forwardable-extended (2.6.0) forwardable-extended (2.6.0)
gemoji (3.0.1) gemoji (3.0.1)
github-pages (226) github-pages (227)
github-pages-health-check (= 1.17.9) github-pages-health-check (= 1.17.9)
jekyll (= 3.9.2) jekyll (= 3.9.2)
jekyll-avatar (= 0.7.0) jekyll-avatar (= 0.7.0)
@ -76,7 +76,7 @@ GEM
liquid (= 4.0.3) liquid (= 4.0.3)
mercenary (~> 0.3) mercenary (~> 0.3)
minima (= 2.5.1) minima (= 2.5.1)
nokogiri (>= 1.13.4, < 2.0) nokogiri (>= 1.13.6, < 2.0)
rouge (= 3.26.0) rouge (= 3.26.0)
terminal-table (~> 1.4) terminal-table (~> 1.4)
github-pages-health-check (1.17.9) github-pages-health-check (1.17.9)
@ -85,7 +85,7 @@ GEM
octokit (~> 4.0) octokit (~> 4.0)
public_suffix (>= 3.0, < 5.0) public_suffix (>= 3.0, < 5.0)
typhoeus (~> 1.3) typhoeus (~> 1.3)
html-pipeline (2.14.1) html-pipeline (2.14.2)
activesupport (>= 2) activesupport (>= 2)
nokogiri (>= 1.4) nokogiri (>= 1.4)
http_parser.rb (0.8.0) http_parser.rb (0.8.0)
@ -212,20 +212,16 @@ GEM
rb-fsevent (~> 0.10, >= 0.10.3) rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10) rb-inotify (~> 0.9, >= 0.9.10)
mercenary (0.3.6) mercenary (0.3.6)
mini_portile2 (2.8.0)
minima (2.5.1) minima (2.5.1)
jekyll (>= 3.5, < 5.0) jekyll (>= 3.5, < 5.0)
jekyll-feed (~> 0.9) jekyll-feed (~> 0.9)
jekyll-seo-tag (~> 2.1) jekyll-seo-tag (~> 2.1)
minitest (5.15.0) minitest (5.16.2)
nokogiri (1.13.6-arm64-darwin) nokogiri (1.13.7)
mini_portile2 (~> 2.8.0)
racc (~> 1.4) racc (~> 1.4)
nokogiri (1.13.6-x64-mingw32) octokit (4.25.1)
racc (~> 1.4)
nokogiri (1.13.6-x86_64-darwin)
racc (~> 1.4)
nokogiri (1.13.6-x86_64-linux)
racc (~> 1.4)
octokit (4.25.0)
faraday (>= 1, < 3) faraday (>= 1, < 3)
sawyer (~> 0.9) sawyer (~> 0.9)
pathutil (0.16.2) pathutil (0.16.2)
@ -265,7 +261,7 @@ GEM
unf_ext (0.0.8.2) unf_ext (0.0.8.2)
unicode-display_width (1.8.0) unicode-display_width (1.8.0)
webrick (1.7.0) webrick (1.7.0)
zeitwerk (2.5.4) zeitwerk (2.6.0)
PLATFORMS PLATFORMS
universal-darwin-21 universal-darwin-21

66
go.mod
View File

@ -1,47 +1,55 @@
module github.com/bpg/terraform-provider-proxmox module github.com/bpg/terraform-provider-proxmox
go 1.16 go 1.18
require ( require (
cloud.google.com/go v0.102.0 // indirect
github.com/Masterminds/sprig/v3 v3.2.2 // indirect
github.com/agext/levenshtein v1.2.3 // indirect
github.com/aws/aws-sdk-go v1.44.26 // indirect
github.com/fatih/color v1.13.0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/google/go-querystring v1.1.0 github.com/google/go-querystring v1.1.0
github.com/google/martian/v3 v3.3.2 // indirect github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320
github.com/google/uuid v1.3.0 // indirect github.com/hashicorp/go-multierror v1.1.1
github.com/hashicorp/terraform-plugin-log v0.5.0
github.com/hashicorp/terraform-plugin-sdk/v2 v2.18.0
github.com/pkg/sftp v1.13.5
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d
)
require (
github.com/agext/levenshtein v1.2.3 // indirect
github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
github.com/fatih/color v1.13.0 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/google/go-cmp v0.5.8 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-getter v1.6.1 // indirect github.com/hashicorp/go-hclog v1.2.1 // indirect
github.com/hashicorp/go-hclog v1.2.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/go-plugin v1.4.4 // indirect github.com/hashicorp/go-plugin v1.4.4 // 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.5.0 // indirect github.com/hashicorp/go-version v1.6.0 // indirect
github.com/hashicorp/hcl/v2 v2.12.0 // indirect github.com/hashicorp/hcl/v2 v2.13.0 // indirect
github.com/hashicorp/terraform-plugin-sdk v1.17.2 github.com/hashicorp/logutils v1.0.0 // indirect
github.com/hashicorp/terraform-plugin-go v0.11.0 // indirect
github.com/hashicorp/terraform-registry-address v0.0.0-20220623143253-7d51757b572c // indirect
github.com/hashicorp/terraform-svchost v0.0.0-20200729002733-f050f53b9734 // indirect
github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87 // indirect github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87 // indirect
github.com/klauspost/compress v1.15.5 // indirect github.com/kr/fs v0.1.0 // indirect
github.com/kr/pretty v0.2.1 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/mattn/go-colorable v0.1.12 // indirect github.com/mattn/go-colorable v0.1.12 // indirect
github.com/mitchellh/cli v1.1.3 // indirect github.com/mattn/go-isatty v0.0.14 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/go-testing-interface v1.14.1 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect
github.com/mitchellh/go-wordwrap v1.0.1 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/oklog/run v1.1.0 // indirect github.com/oklog/run v1.1.0 // indirect
github.com/pkg/sftp v1.13.5 github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect
github.com/posener/complete v1.2.3 // indirect github.com/vmihailenco/msgpack/v4 v4.3.12 // indirect
github.com/shopspring/decimal v1.3.1 // indirect
github.com/spf13/afero v1.8.2 // indirect
github.com/spf13/cast v1.4.1 // indirect
github.com/ulikunitz/xz v0.5.10 // indirect
github.com/vmihailenco/tagparser v0.1.2 // indirect github.com/vmihailenco/tagparser v0.1.2 // indirect
github.com/zclconf/go-cty v1.10.0 // indirect github.com/zclconf/go-cty v1.10.0 // indirect
golang.org/x/crypto v0.0.0-20220507011949-2cf3adece122 golang.org/x/net v0.0.0-20220708220712-1185a9018129 // indirect
golang.org/x/net v0.0.0-20220531201128-c960675eff93 // indirect golang.org/x/sys v0.0.0-20220712014510-0a85c31ab51e // indirect
google.golang.org/api v0.82.0 // indirect golang.org/x/text v0.3.7 // indirect
google.golang.org/genproto v0.0.0-20220601144221-27df5f98adab // indirect google.golang.org/appengine v1.6.7 // indirect
google.golang.org/grpc v1.47.0 // indirect google.golang.org/genproto v0.0.0-20220713161829-9c7dac0a6568 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect google.golang.org/grpc v1.48.0 // indirect
google.golang.org/protobuf v1.28.0 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
) )

750
go.sum
View File

@ -1,127 +1,20 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY=
cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg=
cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8=
cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0=
cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY=
cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM=
cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY=
cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ=
cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI=
cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4=
cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc=
cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA=
cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A=
cloud.google.com/go v0.102.0 h1:DAq3r8y4mDgyB/ZPJ9v/5VJNqjgJAxTn6ZYLlUywOu8=
cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow=
cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM=
cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M=
cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s=
cloud.google.com/go/compute v1.6.1 h1:2sMmt8prCn7DPaG4Pmh0N3Inmc8cT8ae5k1M6VJ9Wqc=
cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
cloud.google.com/go/iam v0.3.0 h1:exkAomrVUuzx9kWFI1wm3KI0uoDeUFPB4kKGzx6x+Gc=
cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo=
cloud.google.com/go/storage v1.22.1 h1:F6IlQJZrZM++apn9V5/VfS3gbTUYg98PS3EMQAzqtfg=
cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
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/v3 v3.2.0/go.mod h1:tWhwTbUTndesPNeF0C900vKoq283u6zp4APT9vaF3SI=
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.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
github.com/agext/levenshtein v1.2.2/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
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/agl/ed25519 v0.0.0-20170116200512-5312a6153412/go.mod h1:WPjqKcmVOxf0XSf3YxCJs6N6AOSrOx3obionmG7T0y0=
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs=
github.com/andybalholm/crlf v0.0.0-20171020200849-670099aa064f/go.mod h1:k8feO4+kXDxro6ErPXBRTJ/ro2mf0SsFG8s7doP9kJE=
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
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-cidr v1.1.0 h1:2mAhrMoF+nhXqxTzSZMUzDHkLjmIHC+Zzn4tdgBZjnU=
github.com/apparentlymart/go-cidr v1.1.0/go.mod h1:EBcsNrHc3zQeuaeCeCtQruQm+n9/YjEn/vI25Lg7Gwc=
github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM=
github.com/apparentlymart/go-dump v0.0.0-20190214190832-042adf3cf4a0 h1:MzVXffFUye+ZcSR6opIgz9Co7WcDx6ZcY+RjfFHoA0I= github.com/apparentlymart/go-dump v0.0.0-20190214190832-042adf3cf4a0 h1:MzVXffFUye+ZcSR6opIgz9Co7WcDx6ZcY+RjfFHoA0I=
github.com/apparentlymart/go-dump v0.0.0-20190214190832-042adf3cf4a0/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM=
github.com/apparentlymart/go-textseg v1.0.0 h1:rRmlIsPEEhUTIKQb7T++Nz/A5Q6C9IuX2wFoYVvnCs0=
github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk= 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/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-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/aws/aws-sdk-go v1.15.78/go.mod h1:E3/ieXAlvM0XWO57iftYVDLLvQ824smPP3ATZkfNZeM=
github.com/aws/aws-sdk-go v1.37.0/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
github.com/aws/aws-sdk-go v1.44.26 h1:fOvltAUcUA3IFe0ddPSlmCBSwPKifsXJf4beI0f8XS0=
github.com/aws/aws-sdk-go v1.44.26/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas=
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4=
github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cheggaaa/pb v1.0.27/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
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-20201120205902-5459f2c99403/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-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
@ -129,56 +22,24 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3
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.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o=
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=
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E=
github.com/go-git/go-billy/v5 v5.0.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
github.com/go-git/go-billy/v5 v5.1.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw=
github.com/go-git/go-git/v5 v5.3.0/go.mod h1:xdX4bWJ48aOrdhnl2XqHYstHbbp6+LFS4r4X+lNVprw=
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-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
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/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
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.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.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
@ -188,151 +49,56 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
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.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
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=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk=
github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw=
github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0=
github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM=
github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM=
github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM=
github.com/googleapis/gax-go/v2 v2.4.0 h1:dS9eYAjhrE2RjmzYw2XAPvcXfmcQLtFEQWn0CR82awk=
github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c=
github.com/googleapis/go-type-adapters v1.0.0 h1:9XdMn+d/G57qq1s8dNc5IesGCXHf6V2HZ2JwRxfA2tA=
github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4=
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
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/go.mod h1:7nfLNL10NsxqO4iWuW6tWW0HjZuDrwkBuEQsVcpCOgg=
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-cty v1.4.1-0.20200414143053-d3edf31b6320 h1:1/D3zfFHttUKaCaGKZ/dR2roBXv0vKbSCnssIldfQdI=
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/go.mod h1:EiZBMaudVLy8fmjf9Npq1dq9RalhveqZG5w/yz3mHWs=
github.com/hashicorp/go-getter v1.5.3/go.mod h1:BrrV/1clo8cCYu6mxvboYg+KutTiFnXjMEgDD8+i7ZI= github.com/hashicorp/go-hclog v1.2.1 h1:YQsLlGDJgwhXFpucSPyVbCBviQtjlHv3jLTlp8YmtEw=
github.com/hashicorp/go-getter v1.6.1 h1:NASsgP4q6tL94WH6nJxKWj8As2H/2kop/bB1d8JMyRY= github.com/hashicorp/go-hclog v1.2.1/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
github.com/hashicorp/go-getter v1.6.1/go.mod h1:IZCrswsZPeWv9IkVnLElzRU/gz/QPi6pZHn4tv6vbwA=
github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI=
github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
github.com/hashicorp/go-hclog v0.14.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
github.com/hashicorp/go-hclog v1.2.0 h1:La19f8d7WIlm4ogzNHB0JGqs5AUDAZ2UfCY4sJXcJdM=
github.com/hashicorp/go-hclog v1.2.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
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.3.0/go.mod h1:F9eH4LrE/ZsRdbwhfjs9k9HoDUwAHnYtXdgmf1AVNs0=
github.com/hashicorp/go-plugin v1.4.4 h1:NVdrSdFRt3SkZtNckJ6tog7gbpRrcbOjQi/rgF7JYWQ= github.com/hashicorp/go-plugin v1.4.4 h1:NVdrSdFRt3SkZtNckJ6tog7gbpRrcbOjQi/rgF7JYWQ=
github.com/hashicorp/go-plugin v1.4.4/go.mod h1:viDMjcLJuDui6pXb8U4HVfb8AamCWhHGUjr2IrTF67s= github.com/hashicorp/go-plugin v1.4.4/go.mod h1:viDMjcLJuDui6pXb8U4HVfb8AamCWhHGUjr2IrTF67s=
github.com/hashicorp/go-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo=
github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I=
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.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.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go-version v1.3.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek=
github.com/hashicorp/go-version v1.5.0 h1:O293SZ2Eg+AAYijkVK3jR786Am1bhDEh2GHT0tIVE5E= github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go-version v1.5.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/hcl/v2 v2.13.0 h1:0Apadu1w6M11dyGFxWnmhhcMjkbAiKCv7G1r/2QgCNc=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl/v2 v2.13.0/go.mod h1:e4z5nxYlWNPdDSNYX+ph14EvWYMFm3eP0zIUqPc2jr0=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/hcl v0.0.0-20170504190234-a4b07c25de5f h1:UdxlrJz4JOnY8W+DbLISwf2B8WXEolNRA8BGCwI9jws=
github.com/hashicorp/hcl v0.0.0-20170504190234-a4b07c25de5f/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w=
github.com/hashicorp/hcl/v2 v2.0.0/go.mod h1:oVVDG71tEinNGYCxinCYadcmKU9bglqW9pV3txagJ90=
github.com/hashicorp/hcl/v2 v2.8.2/go.mod h1:bQTN5mpo+jewjJgh8jr0JUguIi7qPHUF6yIfAEN3jqY=
github.com/hashicorp/hcl/v2 v2.12.0 h1:PsYxySWpMD4KPaoJLnsHwtK5Qptvj/4Q6s0t4sUxZf4=
github.com/hashicorp/hcl/v2 v2.12.0/go.mod h1:FwWsfWEjyV/CMj8s/gqAuiviY72rJ1/oayI9WftqcKg=
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-config-inspect v0.0.0-20191212124732-c6ae6269b9d7 h1:Pc5TCv9mbxFN6UVX0LH6CpQrdTM5YjbVI2w15237Pjk= github.com/hashicorp/terraform-plugin-go v0.11.0 h1:YXsvSCx7GbQO5jIUQd77FesqmIBxgSvYAtAX1NqErTk=
github.com/hashicorp/terraform-config-inspect v0.0.0-20191212124732-c6ae6269b9d7/go.mod h1:p+ivJws3dpqbp1iP84+npOyAmTTOLMgCzrXd3GSdn/A= github.com/hashicorp/terraform-plugin-go v0.11.0/go.mod h1:aphXBG8qtQH0yF1waMRlaw/3G+ZFlR/6Artnvt1QEDE=
github.com/hashicorp/terraform-exec v0.13.3/go.mod h1:SSg6lbUsVB3DmFyCPjBPklqf6EYGX0TlQ6QTxOlikDU= github.com/hashicorp/terraform-plugin-log v0.5.0 h1:2/5mE8+e0152+cxZ4QqZ2Ai8o0LPvXS9ZPTIPCvsg1g=
github.com/hashicorp/terraform-json v0.10.0/go.mod h1:3defM4kkMfttwiE7VakJDwCd4R+umhSQnvJwORXbprE= github.com/hashicorp/terraform-plugin-log v0.5.0/go.mod h1:p4R1jWBXRTvL4odmEkFfDdhUjHf9zcs/BCoNHAc7IK4=
github.com/hashicorp/terraform-plugin-sdk v1.17.2 h1:V7DUR3yBWFrVB9z3ddpY7kiYVSsq4NYR67NiTs93NQo= github.com/hashicorp/terraform-plugin-sdk/v2 v2.18.0 h1:/cdI5di5XA+N80gXzXF4YcHq36DprBskubk6Z8i26ZQ=
github.com/hashicorp/terraform-plugin-sdk v1.17.2/go.mod h1:wkvldbraEMkz23NxkkAsFS88A1R9eUiooiaUZyS6TLw= github.com/hashicorp/terraform-plugin-sdk/v2 v2.18.0/go.mod h1:L3SHkD/Q8zPVgXviQmpVwy9nKwpXXZscVIpVEnQ/T50=
github.com/hashicorp/terraform-plugin-test/v2 v2.2.1/go.mod h1:eZ9JL3O69Cb71Skn6OhHyj17sLmHRb+H6VrDcJjKrYU= github.com/hashicorp/terraform-registry-address v0.0.0-20220623143253-7d51757b572c h1:D8aRO6+mTqHfLsK/BC3j5OAoogv1WLRWzY1AaTo3rBg=
github.com/hashicorp/terraform-registry-address v0.0.0-20220623143253-7d51757b572c/go.mod h1:Wn3Na71knbXc1G8Lh+yu/dQWWJeFQEpDeJMtWMtlmNI=
github.com/hashicorp/terraform-svchost v0.0.0-20200729002733-f050f53b9734 h1:HKLsbzeOsfXmKNpr3GiT18XAblV0BjCbzL8KQAMZGa0= github.com/hashicorp/terraform-svchost v0.0.0-20200729002733-f050f53b9734 h1:HKLsbzeOsfXmKNpr3GiT18XAblV0BjCbzL8KQAMZGa0=
github.com/hashicorp/terraform-svchost v0.0.0-20200729002733-f050f53b9734/go.mod h1:kNDNcF7sN4DocDLBkQYz73HGKwN1ANB1blq4lIYLYvg= github.com/hashicorp/terraform-svchost v0.0.0-20200729002733-f050f53b9734/go.mod h1:kNDNcF7sN4DocDLBkQYz73HGKwN1ANB1blq4lIYLYvg=
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87 h1:xixZ2bWeofWV68J+x6AzmKuVM/JWCQwkWm6GW/MUR6I= github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87 h1:xixZ2bWeofWV68J+x6AzmKuVM/JWCQwkWm6GW/MUR6I=
github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ=
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/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
github.com/jhump/protoreflect v1.6.0 h1:h5jfMVslIg6l29nsMs0D8Wj17RDVdNYti0vDN/PZZoE= github.com/jhump/protoreflect v1.6.0 h1:h5jfMVslIg6l29nsMs0D8Wj17RDVdNYti0vDN/PZZoE=
github.com/jhump/protoreflect v1.6.0/go.mod h1:eaTn3RZAmMBcV0fifFvlm6VHNz3wSkYyXYWUh7ymB74=
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
github.com/keybase/go-crypto v0.0.0-20161004153544-93f5b35093ba/go.mod h1:ghbZscTyKdM07+Fw3KSi0hcJm+AlEUWj8QLlPtijN/M=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.11.2/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.15.5 h1:qyCLMz2JCrKADihKOh9FxnW3houKeNsp2h5OEz0QSEA=
github.com/klauspost/compress v1.15.5/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
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=
@ -344,180 +110,57 @@ 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 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/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
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 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mitchellh/cli v1.1.2/go.mod h1:6iaV0fGdElS6dPBx0EApTxHrcWvmJphyh2n8YBLPPZ4=
github.com/mitchellh/cli v1.1.3 h1:xrX6lWnp1wgXZ65TGY2SB5URdQYcXu6VILdxDf5NttQ=
github.com/mitchellh/cli v1.1.3/go.mod h1:vTLESy5mRhKOs9KDp0/RATawxP1UqBmdrpVRMnpcvKQ=
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw=
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.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
github.com/mitchellh/go-testing-interface v1.0.4/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU=
github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8=
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0=
github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
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/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/mitchellh/reflectwalk v1.0.1/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/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nsf/jsondiff v0.0.0-20200515183724-f29ed568f4ce h1:RPclfga2SEJmgMmz2k+Mg7cowZ8yv4Trqw9UsJby758=
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
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/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=
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/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/posener/complete v1.2.1/go.mod h1:6gapUrK/U1TAN7ciCoNRIdVC5sbdBTUh1DKN0g6uH7E=
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/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
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/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
github.com/spf13/afero v1.8.2 h1:xehSyVa0YnHWsJ49JFljMpg1HX19V6NDZ1fkm1Xznbo=
github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo=
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cast v1.4.1 h1:s0hze+J0196ZfEMTs80N7UlFt0BDuQ7Q+JDnHiMWKdA=
github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
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/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
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/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s=
github.com/ulikunitz/xz v0.5.10 h1:t92gobL9l3HE202wg3rlk19F6X+JOxl9BBrCCMYEYd8= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
github.com/vmihailenco/msgpack v3.3.3+incompatible h1:wapg9xDUZDzGCNFlwc5SqI1rvcciqcxEHac4CYj89xI=
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/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
github.com/vmihailenco/msgpack/v4 v4.3.12 h1:07s4sz9IReOgdikxLTKNbBdqDMLsjPKXwvCazn8G65U= github.com/vmihailenco/msgpack/v4 v4.3.12 h1:07s4sz9IReOgdikxLTKNbBdqDMLsjPKXwvCazn8G65U=
github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4= github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4=
github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI=
github.com/vmihailenco/tagparser v0.1.2 h1:gnjoVuB/kljJ5wICEEOpx98oXMWPLj22G67Vbd1qPqc= github.com/vmihailenco/tagparser v0.1.2 h1:gnjoVuB/kljJ5wICEEOpx98oXMWPLj22G67Vbd1qPqc=
github.com/vmihailenco/tagparser v0.1.2/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= github.com/vmihailenco/tagparser v0.1.2/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI=
github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/zclconf/go-cty v1.0.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s=
github.com/zclconf/go-cty v1.1.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s= github.com/zclconf/go-cty v1.1.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s=
github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8=
github.com/zclconf/go-cty v1.2.1/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8=
github.com/zclconf/go-cty v1.8.0/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk=
github.com/zclconf/go-cty v1.8.2/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk=
github.com/zclconf/go-cty v1.10.0 h1:mp9ZXQeIcN8kAwuqorjH+Q+njbJKjLrvB2yIh4q7U+0= github.com/zclconf/go-cty v1.10.0 h1:mp9ZXQeIcN8kAwuqorjH+Q+njbJKjLrvB2yIh4q7U+0=
github.com/zclconf/go-cty v1.10.0/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk= github.com/zclconf/go-cty v1.10.0/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk=
github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8=
github.com/zclconf/go-cty-yaml v1.0.2 h1:dNyg4QLTrv2IfJpm7Wtxi55ed5gLGOlPrZ6kMd51hY0=
github.com/zclconf/go-cty-yaml v1.0.2/go.mod h1:IP3Ylp0wQpYm50IHK8OZWKMu6sPJIUgKa8XhiVHura0=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M=
go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
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-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
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-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/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.0.0-20220507011949-2cf3adece122 h1:NvGWuYG8dkDHFSKksI1P9faiVJ9rayE6l0+ouWVIDs8= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d h1:sK3txAijHtOK88l68nt020reeT1ZdKLIYetKl95FzVY=
golang.org/x/crypto v0.0.0-20220507011949-2cf3adece122/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20180530234432-1e491301e022/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -525,391 +168,78 @@ golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73r
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
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-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/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-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191009170851-d66e71096ffb/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191009170851-d66e71096ffb/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
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-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-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
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.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220708220712-1185a9018129 h1:vucSRfWwTsoXro7P+3Cjlr6flUMtzCwzlvkxEQtHHB0=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220708220712-1185a9018129/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220526153639-5463443f8c37/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.0.0-20220531201128-c960675eff93 h1:MYimHLfoXEpOhqd/zgoA/uoXzHB86AEky4LAx5ij9xA=
golang.org/x/net v0.0.0-20220531201128-c960675eff93/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
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=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
golang.org/x/oauth2 v0.0.0-20220524215830-622c5d57e401 h1:zwrSfklXn0gxyLRX/aR+q6cgHbV/ItVyzbPlbA+dkAw=
golang.org/x/oauth2 v0.0.0-20220524215830-622c5d57e401/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
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-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220513210516-0976fa681c29/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/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-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
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-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/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=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
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-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-20210603125802-9665404d3644/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-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/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-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/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-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211210111614-af8b64212486/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-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/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-20220517195934-5e4e11fc645e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220712014510-0a85c31ab51e h1:NHvCuwuS43lGnYhten69ZWqi2QOj/CiDNcKbVqwVoew=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k= golang.org/x/sys v0.0.0-20220712014510-0a85c31ab51e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
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/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
golang.org/x/tools v0.0.0-20201028111035-eafbe7b904eb/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
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=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df h1:5Pf6pFKu98ODmgnpvkJ3kFUOQGGLIzLIkbzUHp47618=
golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
google.golang.org/api v0.34.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=
google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=
google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo=
google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4=
google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw=
google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU=
google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k=
google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE=
google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE=
google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI=
google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I=
google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo=
google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g=
google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA=
google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8=
google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs=
google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA=
google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw=
google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg=
google.golang.org/api v0.82.0 h1:h6EGeZuzhoKSS7BUznzkW+2wHZ+4Ubd6rsVvvh3dRkw=
google.golang.org/api v0.82.0/go.mod h1:Ld58BeTlL9DIYr2M2ajvoSqmGLei0BMn+kVBmkam1os=
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.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.6/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-20170818010345-ee236bd376b0/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20220713161829-9c7dac0a6568 h1:iKx0VcikTdB4xj9Ho1Opn9AKzWFknYDE7oW/KBWZf9g=
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20220713161829-9c7dac0a6568/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A=
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24=
google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k=
google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k=
google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48=
google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48=
google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w=
google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=
google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=
google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=
google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=
google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E=
google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
google.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
google.golang.org/genproto v0.0.0-20220527130721-00d5c0f3be58/go.mod h1:yKyY4AMRwFiC8yMMNaMi+RkCnjZJt9LoWuvhXjMs+To=
google.golang.org/genproto v0.0.0-20220601144221-27df5f98adab h1:YYs5818GyaApJxN5iyBnJxr7FUDrKpcXX+GaPrv0Cms=
google.golang.org/genproto v0.0.0-20220601144221-27df5f98adab/go.mod h1:yKyY4AMRwFiC8yMMNaMi+RkCnjZJt9LoWuvhXjMs+To=
google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=
google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=
google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
google.golang.org/grpc v1.47.0 h1:9n77onPX5F3qfFCqjy9dhn8PbNQsIKeVU04J9G7umt8=
google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/grpc v1.48.0 h1:rQOsyJ/8+ufEDJd/Gdsz7HG220Mh9HAhFHRGnIjda0w=
google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@ -918,7 +248,6 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
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=
@ -927,29 +256,12 @@ google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscL
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.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/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-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/cheggaaa/pb.v1 v1.0.27/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
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=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=

20
main.go
View File

@ -5,15 +5,25 @@
package main package main
import ( import (
"flag"
"github.com/bpg/terraform-provider-proxmox/proxmoxtf" "github.com/bpg/terraform-provider-proxmox/proxmoxtf"
"github.com/hashicorp/terraform-plugin-sdk/plugin" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/terraform" "github.com/hashicorp/terraform-plugin-sdk/v2/plugin"
) )
func main() { func main() {
plugin.Serve(&plugin.ServeOpts{ var debug bool
ProviderFunc: func() terraform.ResourceProvider {
flag.BoolVar(&debug, "debug", false, "set to true to run the provider with support for debuggers like delve")
flag.Parse()
opts := &plugin.ServeOpts{
Debug: debug,
ProviderAddr: "registry.terraform.io/example-namespace/example",
ProviderFunc: func() *schema.Provider {
return proxmoxtf.Provider() return proxmoxtf.Provider()
}, },
}) }
plugin.Serve(opts)
} }

View File

@ -46,7 +46,7 @@ func (r CustomBool) MarshalJSON() ([]byte, error) {
// UnmarshalJSON converts a JSON value to a boolean. // UnmarshalJSON converts a JSON value to a boolean.
func (r *CustomBool) UnmarshalJSON(b []byte) error { func (r *CustomBool) UnmarshalJSON(b []byte) error {
s := string(b) s := string(b)
*r = CustomBool(s == "1" || s == "true") *r = s == "1" || s == "true"
return nil return nil
} }

View File

@ -5,21 +5,22 @@
package proxmox package proxmox
import ( import (
"context"
"errors" "errors"
"sort" "sort"
) )
// GetACL retrieves the access control list. // GetACL retrieves the access control list.
func (c *VirtualEnvironmentClient) GetACL() ([]*VirtualEnvironmentACLGetResponseData, error) { func (c *VirtualEnvironmentClient) GetACL(ctx context.Context) ([]*VirtualEnvironmentACLGetResponseData, error) {
resBody := &VirtualEnvironmentACLGetResponseBody{} resBody := &VirtualEnvironmentACLGetResponseBody{}
err := c.DoRequest(hmGET, "access/acl", nil, resBody) err := c.DoRequest(ctx, hmGET, "access/acl", nil, resBody)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if resBody.Data == nil { if resBody.Data == nil {
return nil, errors.New("The server did not include a data object in the response") return nil, errors.New("the server did not include a data object in the response")
} }
sort.Slice(resBody.Data, func(i, j int) bool { sort.Slice(resBody.Data, func(i, j int) bool {
@ -30,6 +31,6 @@ func (c *VirtualEnvironmentClient) GetACL() ([]*VirtualEnvironmentACLGetResponse
} }
// UpdateACL updates the access control list. // UpdateACL updates the access control list.
func (c *VirtualEnvironmentClient) UpdateACL(d *VirtualEnvironmentACLUpdateRequestBody) error { func (c *VirtualEnvironmentClient) UpdateACL(ctx context.Context, d *VirtualEnvironmentACLUpdateRequestBody) error {
return c.DoRequest(hmPUT, "access/acl", d, nil) return c.DoRequest(ctx, hmPUT, "access/acl", d, nil)
} }

View File

@ -44,7 +44,7 @@ func (c *VirtualEnvironmentClient) Authenticate(reset bool) error {
req, err := http.NewRequest(hmPOST, fmt.Sprintf("%s/%s/access/ticket", c.Endpoint, basePathJSONAPI), reqBody) req, err := http.NewRequest(hmPOST, fmt.Sprintf("%s/%s/access/ticket", c.Endpoint, basePathJSONAPI), reqBody)
if err != nil { if err != nil {
return errors.New("Failed to create authentication request") return errors.New("failed to create authentication request")
} }
req.Header.Add("Content-Type", "application/x-www-form-urlencoded") req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
@ -52,7 +52,7 @@ func (c *VirtualEnvironmentClient) Authenticate(reset bool) error {
res, err := c.httpClient.Do(req) res, err := c.httpClient.Do(req)
if err != nil { if err != nil {
return errors.New("Failed to retrieve authentication response") return errors.New("failed to retrieve authentication response")
} }
err = c.ValidateResponseCode(res) err = c.ValidateResponseCode(res)
@ -65,23 +65,23 @@ func (c *VirtualEnvironmentClient) Authenticate(reset bool) error {
err = json.NewDecoder(res.Body).Decode(&resBody) err = json.NewDecoder(res.Body).Decode(&resBody)
if err != nil { if err != nil {
return errors.New("Failed to decode authentication response") return errors.New("failed to decode authentication response")
} }
if resBody.Data == nil { if resBody.Data == nil {
return errors.New("The server did not include a data object in the authentication response") return errors.New("the server did not include a data object in the authentication response")
} }
if resBody.Data.CSRFPreventionToken == nil { if resBody.Data.CSRFPreventionToken == nil {
return errors.New("The server did not include a CSRF prevention token in the authentication response") return errors.New("the server did not include a CSRF prevention token in the authentication response")
} }
if resBody.Data.Ticket == nil { if resBody.Data.Ticket == nil {
return errors.New("The server did not include a ticket in the authentication response") return errors.New("the server did not include a ticket in the authentication response")
} }
if resBody.Data.Username == "" { if resBody.Data.Username == "" {
return errors.New("The server did not include the username in the authentication response") return errors.New("the server did not include the username in the authentication response")
} }
c.authenticationData = resBody.Data c.authenticationData = resBody.Data

View File

@ -5,33 +5,34 @@
package proxmox package proxmox
import ( import (
"context"
"errors" "errors"
"fmt" "fmt"
"net/url" "net/url"
) )
// DeleteCertificate deletes the custom certificate for a node. // DeleteCertificate deletes the custom certificate for a node.
func (c *VirtualEnvironmentClient) DeleteCertificate(nodeName string, d *VirtualEnvironmentCertificateDeleteRequestBody) error { func (c *VirtualEnvironmentClient) DeleteCertificate(ctx context.Context, nodeName string, d *VirtualEnvironmentCertificateDeleteRequestBody) error {
return c.DoRequest(hmDELETE, fmt.Sprintf("nodes/%s/certificates/custom", url.PathEscape(nodeName)), d, nil) return c.DoRequest(ctx, hmDELETE, fmt.Sprintf("nodes/%s/certificates/custom", url.PathEscape(nodeName)), d, nil)
} }
// ListCertificates retrieves the list of certificates for a node. // ListCertificates retrieves the list of certificates for a node.
func (c *VirtualEnvironmentClient) ListCertificates(nodeName string) (*[]VirtualEnvironmentCertificateListResponseData, error) { func (c *VirtualEnvironmentClient) ListCertificates(ctx context.Context, nodeName string) (*[]VirtualEnvironmentCertificateListResponseData, error) {
resBody := &VirtualEnvironmentCertificateListResponseBody{} resBody := &VirtualEnvironmentCertificateListResponseBody{}
err := c.DoRequest(hmGET, fmt.Sprintf("nodes/%s/certificates/info", url.PathEscape(nodeName)), nil, resBody) err := c.DoRequest(ctx, hmGET, fmt.Sprintf("nodes/%s/certificates/info", url.PathEscape(nodeName)), nil, resBody)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if resBody.Data == nil { if resBody.Data == nil {
return nil, errors.New("The server did not include a data object in the response") return nil, errors.New("the server did not include a data object in the response")
} }
return resBody.Data, nil return resBody.Data, nil
} }
// UpdateCertificate updates the custom certificate for a node. // UpdateCertificate updates the custom certificate for a node.
func (c *VirtualEnvironmentClient) UpdateCertificate(nodeName string, d *VirtualEnvironmentCertificateUpdateRequestBody) error { func (c *VirtualEnvironmentClient) UpdateCertificate(ctx context.Context, nodeName string, d *VirtualEnvironmentCertificateUpdateRequestBody) error {
return c.DoRequest(hmPOST, fmt.Sprintf("nodes/%s/certificates/custom", url.PathEscape(nodeName)), d, nil) return c.DoRequest(ctx, hmPOST, fmt.Sprintf("nodes/%s/certificates/custom", url.PathEscape(nodeName)), d, nil)
} }

View File

@ -6,13 +6,14 @@ package proxmox
import ( import (
"bytes" "bytes"
"context"
"crypto/tls" "crypto/tls"
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"github.com/hashicorp/terraform-plugin-log/tflog"
"io" "io"
"io/ioutil" "io/ioutil"
"log"
"net/http" "net/http"
"net/url" "net/url"
"strings" "strings"
@ -22,22 +23,22 @@ import (
// NewVirtualEnvironmentClient creates and initializes a VirtualEnvironmentClient instance. // NewVirtualEnvironmentClient creates and initializes a VirtualEnvironmentClient instance.
func NewVirtualEnvironmentClient(endpoint, username, password, otp string, insecure bool) (*VirtualEnvironmentClient, error) { func NewVirtualEnvironmentClient(endpoint, username, password, otp string, insecure bool) (*VirtualEnvironmentClient, error) {
url, err := url.ParseRequestURI(endpoint) u, err := url.ParseRequestURI(endpoint)
if err != nil { if err != nil {
return nil, errors.New("You must specify a valid endpoint for the Proxmox Virtual Environment API (valid: https://host:port/)") return nil, errors.New("you must specify a valid endpoint for the Proxmox Virtual Environment API (valid: https://host:port/)")
} }
if url.Scheme != "https" { if u.Scheme != "https" {
return nil, errors.New("You must specify a secure endpoint for the Proxmox Virtual Environment API (valid: https://host:port/)") return nil, errors.New("you must specify a secure endpoint for the Proxmox Virtual Environment API (valid: https://host:port/)")
} }
if password == "" { if password == "" {
return nil, errors.New("You must specify a password for the Proxmox Virtual Environment API") return nil, errors.New("you must specify a password for the Proxmox Virtual Environment API")
} }
if username == "" { if username == "" {
return nil, errors.New("You must specify a username for the Proxmox Virtual Environment API") return nil, errors.New("you must specify a username for the Proxmox Virtual Environment API")
} }
var pOTP *string var pOTP *string
@ -55,7 +56,7 @@ func NewVirtualEnvironmentClient(endpoint, username, password, otp string, insec
} }
return &VirtualEnvironmentClient{ return &VirtualEnvironmentClient{
Endpoint: strings.TrimRight(url.String(), "/"), Endpoint: strings.TrimRight(u.String(), "/"),
Insecure: insecure, Insecure: insecure,
OTP: pOTP, OTP: pOTP,
Password: password, Password: password,
@ -65,11 +66,14 @@ func NewVirtualEnvironmentClient(endpoint, username, password, otp string, insec
} }
// DoRequest performs a HTTP request against a JSON API endpoint. // DoRequest performs a HTTP request against a JSON API endpoint.
func (c *VirtualEnvironmentClient) DoRequest(method, path string, requestBody interface{}, responseBody interface{}) error { func (c *VirtualEnvironmentClient) DoRequest(ctx context.Context, method, path string, requestBody, responseBody interface{}) error {
var reqBodyReader io.Reader var reqBodyReader io.Reader
var reqContentLength *int64 var reqContentLength *int64
log.Printf("[DEBUG] Performing HTTP %s request (path: %s)", method, path) tflog.Debug(ctx, "performing HTTP request", map[string]interface{}{
"method": method,
"path": path,
})
modifiedPath := path modifiedPath := path
reqBodyType := "" reqBodyType := ""
@ -83,17 +87,24 @@ func (c *VirtualEnvironmentClient) DoRequest(method, path string, requestBody in
reqBodyType = fmt.Sprintf("multipart/form-data; boundary=%s", multipartData.Boundary) reqBodyType = fmt.Sprintf("multipart/form-data; boundary=%s", multipartData.Boundary)
reqContentLength = multipartData.Size reqContentLength = multipartData.Size
log.Printf("[DEBUG] Added multipart request body to HTTP %s request (path: %s)", method, modifiedPath) tflog.Debug(ctx, "added multipart request body to HTTP request", map[string]interface{}{
"method": method,
"path": modifiedPath,
})
} else if pipedBody { } else if pipedBody {
reqBodyReader = pipedBodyReader reqBodyReader = pipedBodyReader
log.Printf("[DEBUG] Added piped request body to HTTP %s request (path: %s)", method, modifiedPath) tflog.Debug(ctx, "added piped request body to HTTP request", map[string]interface{}{
"method": method,
"path": modifiedPath,
})
} else { } else {
v, err := query.Values(requestBody) v, err := query.Values(requestBody)
if err != nil { if err != nil {
fErr := fmt.Errorf("Failed to encode HTTP %s request (path: %s) - Reason: %s", method, modifiedPath, err.Error()) fErr := fmt.Errorf("failed to encode HTTP %s request (path: %s) - Reason: %s", method, modifiedPath, err.Error())
log.Printf("[DEBUG] WARNING: %s", fErr.Error()) tflog.Warn(ctx, fErr.Error())
return fErr return fErr
} }
@ -111,7 +122,11 @@ func (c *VirtualEnvironmentClient) DoRequest(method, path string, requestBody in
reqBodyType = "application/x-www-form-urlencoded" reqBodyType = "application/x-www-form-urlencoded"
} }
log.Printf("[DEBUG] Added request body to HTTP %s request (path: %s) - Body: %s", method, modifiedPath, encodedValues) tflog.Debug(ctx, "added request body to HTTP request", map[string]interface{}{
"method": method,
"path": modifiedPath,
"encodedValues": encodedValues,
})
} }
} }
} else { } else {
@ -121,8 +136,8 @@ func (c *VirtualEnvironmentClient) DoRequest(method, path string, requestBody in
req, err := http.NewRequest(method, fmt.Sprintf("%s/%s/%s", c.Endpoint, basePathJSONAPI, modifiedPath), reqBodyReader) req, err := http.NewRequest(method, fmt.Sprintf("%s/%s/%s", c.Endpoint, basePathJSONAPI, modifiedPath), reqBodyReader)
if err != nil { if err != nil {
fErr := fmt.Errorf("Failed to create HTTP %s request (path: %s) - Reason: %s", method, modifiedPath, err.Error()) fErr := fmt.Errorf("failed to create HTTP %s request (path: %s) - Reason: %s", method, modifiedPath, err.Error())
log.Printf("[DEBUG] WARNING: %s", fErr.Error()) tflog.Warn(ctx, fErr.Error())
return fErr return fErr
} }
@ -139,24 +154,30 @@ func (c *VirtualEnvironmentClient) DoRequest(method, path string, requestBody in
err = c.AuthenticateRequest(req) err = c.AuthenticateRequest(req)
if err != nil { if err != nil {
log.Printf("[DEBUG] WARNING: %s", err.Error()) tflog.Warn(ctx, err.Error())
return err return err
} }
res, err := c.httpClient.Do(req) res, err := c.httpClient.Do(req)
if err != nil { if err != nil {
fErr := fmt.Errorf("Failed to perform HTTP %s request (path: %s) - Reason: %s", method, modifiedPath, err.Error()) fErr := fmt.Errorf("failed to perform HTTP %s request (path: %s) - Reason: %s", method, modifiedPath, err.Error())
log.Printf("[DEBUG] WARNING: %s", fErr.Error()) tflog.Warn(ctx, fErr.Error())
return fErr return fErr
} }
defer res.Body.Close() defer func(Body io.ReadCloser) {
err := Body.Close()
if err != nil {
tflog.Error(ctx, "failed to close the response body", map[string]interface{}{
"error": err.Error(),
})
}
}(res.Body)
err = c.ValidateResponseCode(res) err = c.ValidateResponseCode(res)
if err != nil { if err != nil {
log.Printf("[DEBUG] WARNING: %s", err.Error()) tflog.Warn(ctx, err.Error())
return err return err
} }
@ -164,13 +185,15 @@ func (c *VirtualEnvironmentClient) DoRequest(method, path string, requestBody in
err = json.NewDecoder(res.Body).Decode(responseBody) err = json.NewDecoder(res.Body).Decode(responseBody)
if err != nil { if err != nil {
fErr := fmt.Errorf("Failed to decode HTTP %s response (path: %s) - Reason: %s", method, modifiedPath, err.Error()) fErr := fmt.Errorf("failed to decode HTTP %s response (path: %s) - Reason: %s", method, modifiedPath, err.Error())
log.Printf("[DEBUG] WARNING: %s", fErr.Error()) tflog.Warn(ctx, fErr.Error())
return fErr return fErr
} }
} else { } else {
data, _ := ioutil.ReadAll(res.Body) data, _ := ioutil.ReadAll(res.Body)
log.Printf("[DEBUG] WARNING: Unhandled HTTP response body: %s", string(data)) tflog.Warn(ctx, "unhandled HTTP response body", map[string]interface{}{
"data": string(data),
})
} }
return nil return nil
@ -185,7 +208,7 @@ func (c *VirtualEnvironmentClient) ValidateResponseCode(res *http.Response) erro
err := json.NewDecoder(res.Body).Decode(errRes) err := json.NewDecoder(res.Body).Decode(errRes)
if err == nil && errRes.Errors != nil { if err == nil && errRes.Errors != nil {
errList := []string{} var errList []string
for k, v := range *errRes.Errors { for k, v := range *errRes.Errors {
errList = append(errList, fmt.Sprintf("%s: %s", k, strings.TrimRight(v, "\n\r"))) errList = append(errList, fmt.Sprintf("%s: %s", k, strings.TrimRight(v, "\n\r")))
@ -194,7 +217,7 @@ func (c *VirtualEnvironmentClient) ValidateResponseCode(res *http.Response) erro
status = fmt.Sprintf("%s (%s)", status, strings.Join(errList, " - ")) status = fmt.Sprintf("%s (%s)", status, strings.Join(errList, " - "))
} }
return fmt.Errorf("Received an HTTP %d response - Reason: %s", res.StatusCode, status) return fmt.Errorf("received an HTTP %d response - Reason: %s", res.StatusCode, status)
} }
return nil return nil

View File

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

View File

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

View File

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

View File

@ -38,7 +38,7 @@ type VirtualEnvironmentClusterIPSetUpdateRequestBody struct {
Name string `json:"name" url:"name"` Name string `json:"name" url:"name"`
} }
// VirtualEnvironmentClusterIPSetGetResponseData contains list of IPSets from // VirtualEnvironmentClusterIPSetListResponseData contains list of IPSets from
type VirtualEnvironmentClusterIPSetListResponseData struct { type VirtualEnvironmentClusterIPSetListResponseData struct {
Comment *string `json:"comment,omitempty" url:"comment,omitempty"` Comment *string `json:"comment,omitempty" url:"comment,omitempty"`
Name string `json:"name" url:"name"` Name string `json:"name" url:"name"`

View File

@ -5,6 +5,7 @@
package proxmox package proxmox
import ( import (
"context"
"errors" "errors"
"fmt" "fmt"
"net/url" "net/url"
@ -13,79 +14,79 @@ import (
) )
// CloneContainer clones a container. // CloneContainer clones a container.
func (c *VirtualEnvironmentClient) CloneContainer(nodeName string, vmID int, d *VirtualEnvironmentContainerCloneRequestBody) error { func (c *VirtualEnvironmentClient) CloneContainer(ctx context.Context, nodeName string, vmID int, d *VirtualEnvironmentContainerCloneRequestBody) error {
return c.DoRequest(hmPOST, fmt.Sprintf("nodes/%s/lxc/%d/clone", url.PathEscape(nodeName), vmID), d, nil) return c.DoRequest(ctx, hmPOST, fmt.Sprintf("nodes/%s/lxc/%d/clone", url.PathEscape(nodeName), vmID), d, nil)
} }
// CreateContainer creates a container. // CreateContainer creates a container.
func (c *VirtualEnvironmentClient) CreateContainer(nodeName string, d *VirtualEnvironmentContainerCreateRequestBody) error { func (c *VirtualEnvironmentClient) CreateContainer(ctx context.Context, nodeName string, d *VirtualEnvironmentContainerCreateRequestBody) error {
return c.DoRequest(hmPOST, fmt.Sprintf("nodes/%s/lxc", url.PathEscape(nodeName)), d, nil) return c.DoRequest(ctx, hmPOST, fmt.Sprintf("nodes/%s/lxc", url.PathEscape(nodeName)), d, nil)
} }
// DeleteContainer deletes a container. // DeleteContainer deletes a container.
func (c *VirtualEnvironmentClient) DeleteContainer(nodeName string, vmID int) error { func (c *VirtualEnvironmentClient) DeleteContainer(ctx context.Context, nodeName string, vmID int) error {
return c.DoRequest(hmDELETE, fmt.Sprintf("nodes/%s/lxc/%d", url.PathEscape(nodeName), vmID), nil, nil) return c.DoRequest(ctx, hmDELETE, fmt.Sprintf("nodes/%s/lxc/%d", url.PathEscape(nodeName), vmID), nil, nil)
} }
// GetContainer retrieves a container. // GetContainer retrieves a container.
func (c *VirtualEnvironmentClient) GetContainer(nodeName string, vmID int) (*VirtualEnvironmentContainerGetResponseData, error) { func (c *VirtualEnvironmentClient) GetContainer(ctx context.Context, nodeName string, vmID int) (*VirtualEnvironmentContainerGetResponseData, error) {
resBody := &VirtualEnvironmentContainerGetResponseBody{} resBody := &VirtualEnvironmentContainerGetResponseBody{}
err := c.DoRequest(hmGET, fmt.Sprintf("nodes/%s/lxc/%d/config", url.PathEscape(nodeName), vmID), nil, resBody) err := c.DoRequest(ctx, hmGET, fmt.Sprintf("nodes/%s/lxc/%d/config", url.PathEscape(nodeName), vmID), nil, resBody)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if resBody.Data == nil { if resBody.Data == nil {
return nil, errors.New("The server did not include a data object in the response") return nil, errors.New("the server did not include a data object in the response")
} }
return resBody.Data, nil return resBody.Data, nil
} }
// GetContainerStatus retrieves the status for a container. // GetContainerStatus retrieves the status for a container.
func (c *VirtualEnvironmentClient) GetContainerStatus(nodeName string, vmID int) (*VirtualEnvironmentContainerGetStatusResponseData, error) { func (c *VirtualEnvironmentClient) GetContainerStatus(ctx context.Context, nodeName string, vmID int) (*VirtualEnvironmentContainerGetStatusResponseData, error) {
resBody := &VirtualEnvironmentContainerGetStatusResponseBody{} resBody := &VirtualEnvironmentContainerGetStatusResponseBody{}
err := c.DoRequest(hmGET, fmt.Sprintf("nodes/%s/lxc/%d/status/current", url.PathEscape(nodeName), vmID), nil, resBody) err := c.DoRequest(ctx, hmGET, fmt.Sprintf("nodes/%s/lxc/%d/status/current", url.PathEscape(nodeName), vmID), nil, resBody)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if resBody.Data == nil { if resBody.Data == nil {
return nil, errors.New("The server did not include a data object in the response") return nil, errors.New("the server did not include a data object in the response")
} }
return resBody.Data, nil return resBody.Data, nil
} }
// RebootContainer reboots a container. // RebootContainer reboots a container.
func (c *VirtualEnvironmentClient) RebootContainer(nodeName string, vmID int, d *VirtualEnvironmentContainerRebootRequestBody) error { func (c *VirtualEnvironmentClient) RebootContainer(ctx context.Context, nodeName string, vmID int, d *VirtualEnvironmentContainerRebootRequestBody) error {
return c.DoRequest(hmPOST, fmt.Sprintf("nodes/%s/lxc/%d/status/reboot", url.PathEscape(nodeName), vmID), d, nil) return c.DoRequest(ctx, hmPOST, fmt.Sprintf("nodes/%s/lxc/%d/status/reboot", url.PathEscape(nodeName), vmID), d, nil)
} }
// ShutdownContainer shuts down a container. // ShutdownContainer shuts down a container.
func (c *VirtualEnvironmentClient) ShutdownContainer(nodeName string, vmID int, d *VirtualEnvironmentContainerShutdownRequestBody) error { func (c *VirtualEnvironmentClient) ShutdownContainer(ctx context.Context, nodeName string, vmID int, d *VirtualEnvironmentContainerShutdownRequestBody) error {
return c.DoRequest(hmPOST, fmt.Sprintf("nodes/%s/lxc/%d/status/shutdown", url.PathEscape(nodeName), vmID), d, nil) return c.DoRequest(ctx, hmPOST, fmt.Sprintf("nodes/%s/lxc/%d/status/shutdown", url.PathEscape(nodeName), vmID), d, nil)
} }
// StartContainer starts a container. // StartContainer starts a container.
func (c *VirtualEnvironmentClient) StartContainer(nodeName string, vmID int) error { func (c *VirtualEnvironmentClient) StartContainer(ctx context.Context, nodeName string, vmID int) error {
return c.DoRequest(hmPOST, fmt.Sprintf("nodes/%s/lxc/%d/status/start", url.PathEscape(nodeName), vmID), nil, nil) return c.DoRequest(ctx, hmPOST, fmt.Sprintf("nodes/%s/lxc/%d/status/start", url.PathEscape(nodeName), vmID), nil, nil)
} }
// StopContainer stops a container immediately. // StopContainer stops a container immediately.
func (c *VirtualEnvironmentClient) StopContainer(nodeName string, vmID int) error { func (c *VirtualEnvironmentClient) StopContainer(ctx context.Context, nodeName string, vmID int) error {
return c.DoRequest(hmPOST, fmt.Sprintf("nodes/%s/lxc/%d/status/stop", url.PathEscape(nodeName), vmID), nil, nil) return c.DoRequest(ctx, hmPOST, fmt.Sprintf("nodes/%s/lxc/%d/status/stop", url.PathEscape(nodeName), vmID), nil, nil)
} }
// UpdateContainer updates a container. // UpdateContainer updates a container.
func (c *VirtualEnvironmentClient) UpdateContainer(nodeName string, vmID int, d *VirtualEnvironmentContainerUpdateRequestBody) error { func (c *VirtualEnvironmentClient) UpdateContainer(ctx context.Context, nodeName string, vmID int, d *VirtualEnvironmentContainerUpdateRequestBody) error {
return c.DoRequest(hmPUT, fmt.Sprintf("nodes/%s/lxc/%d/config", url.PathEscape(nodeName), vmID), d, nil) return c.DoRequest(ctx, hmPUT, fmt.Sprintf("nodes/%s/lxc/%d/config", url.PathEscape(nodeName), vmID), d, nil)
} }
// WaitForContainerState waits for a container to reach a specific state. // WaitForContainerState waits for a container to reach a specific state.
func (c *VirtualEnvironmentClient) WaitForContainerState(nodeName string, vmID int, state string, timeout int, delay int) error { func (c *VirtualEnvironmentClient) WaitForContainerState(ctx context.Context, nodeName string, vmID int, state string, timeout int, delay int) error {
state = strings.ToLower(state) state = strings.ToLower(state)
timeDelay := int64(delay) timeDelay := int64(delay)
@ -95,7 +96,7 @@ func (c *VirtualEnvironmentClient) WaitForContainerState(nodeName string, vmID i
for timeElapsed.Seconds() < timeMax { for timeElapsed.Seconds() < timeMax {
if int64(timeElapsed.Seconds())%timeDelay == 0 { if int64(timeElapsed.Seconds())%timeDelay == 0 {
data, err := c.GetContainerStatus(nodeName, vmID) data, err := c.GetContainerStatus(ctx, nodeName, vmID)
if err != nil { if err != nil {
return err return err
@ -111,13 +112,17 @@ func (c *VirtualEnvironmentClient) WaitForContainerState(nodeName string, vmID i
time.Sleep(200 * time.Millisecond) time.Sleep(200 * time.Millisecond)
timeElapsed = time.Now().Sub(timeStart) timeElapsed = time.Now().Sub(timeStart)
if ctx.Err() != nil {
return ctx.Err()
}
} }
return fmt.Errorf("Timeout while waiting for container \"%d\" to enter the state \"%s\"", vmID, state) return fmt.Errorf("timeout while waiting for container \"%d\" to enter the state \"%s\"", vmID, state)
} }
// WaitForContainerLock waits for a container lock to be released. // WaitForContainerLock waits for a container lock to be released.
func (c *VirtualEnvironmentClient) WaitForContainerLock(nodeName string, vmID int, timeout int, delay int, ignoreErrorResponse bool) error { func (c *VirtualEnvironmentClient) WaitForContainerLock(ctx context.Context, nodeName string, vmID int, timeout int, delay int, ignoreErrorResponse bool) error {
timeDelay := int64(delay) timeDelay := int64(delay)
timeMax := float64(timeout) timeMax := float64(timeout)
timeStart := time.Now() timeStart := time.Now()
@ -125,7 +130,7 @@ func (c *VirtualEnvironmentClient) WaitForContainerLock(nodeName string, vmID in
for timeElapsed.Seconds() < timeMax { for timeElapsed.Seconds() < timeMax {
if int64(timeElapsed.Seconds())%timeDelay == 0 { if int64(timeElapsed.Seconds())%timeDelay == 0 {
data, err := c.GetContainerStatus(nodeName, vmID) data, err := c.GetContainerStatus(ctx, nodeName, vmID)
if err != nil { if err != nil {
if !ignoreErrorResponse { if !ignoreErrorResponse {
@ -141,7 +146,11 @@ func (c *VirtualEnvironmentClient) WaitForContainerLock(nodeName string, vmID in
time.Sleep(200 * time.Millisecond) time.Sleep(200 * time.Millisecond)
timeElapsed = time.Now().Sub(timeStart) timeElapsed = time.Now().Sub(timeStart)
if ctx.Err() != nil {
return ctx.Err()
}
} }
return fmt.Errorf("Timeout while waiting for container \"%d\" to become unlocked", vmID) return fmt.Errorf("timeout while waiting for container \"%d\" to become unlocked", vmID)
} }

View File

@ -219,7 +219,7 @@ type VirtualEnvironmentContainerUpdateRequestBody VirtualEnvironmentContainerCre
// EncodeValues converts a VirtualEnvironmentContainerCustomFeatures struct to a URL vlaue. // EncodeValues converts a VirtualEnvironmentContainerCustomFeatures struct to a URL vlaue.
func (r VirtualEnvironmentContainerCustomFeatures) EncodeValues(key string, v *url.Values) error { func (r VirtualEnvironmentContainerCustomFeatures) EncodeValues(key string, v *url.Values) error {
values := []string{} var values []string
if r.FUSE != nil { if r.FUSE != nil {
if *r.FUSE { if *r.FUSE {
@ -260,7 +260,7 @@ func (r VirtualEnvironmentContainerCustomFeatures) EncodeValues(key string, v *u
// EncodeValues converts a VirtualEnvironmentContainerCustomMountPoint struct to a URL vlaue. // EncodeValues converts a VirtualEnvironmentContainerCustomMountPoint struct to a URL vlaue.
func (r VirtualEnvironmentContainerCustomMountPoint) EncodeValues(key string, v *url.Values) error { func (r VirtualEnvironmentContainerCustomMountPoint) EncodeValues(key string, v *url.Values) error {
values := []string{} var values []string
if r.ACL != nil { if r.ACL != nil {
if *r.ACL { if *r.ACL {
@ -334,7 +334,10 @@ func (r VirtualEnvironmentContainerCustomMountPoint) EncodeValues(key string, v
// EncodeValues converts a VirtualEnvironmentContainerCustomMountPointArray array to multiple URL values. // EncodeValues converts a VirtualEnvironmentContainerCustomMountPointArray array to multiple URL values.
func (r VirtualEnvironmentContainerCustomMountPointArray) EncodeValues(key string, v *url.Values) error { func (r VirtualEnvironmentContainerCustomMountPointArray) EncodeValues(key string, v *url.Values) error {
for i, d := range r { for i, d := range r {
d.EncodeValues(fmt.Sprintf("%s%d", key, i), v) err := d.EncodeValues(fmt.Sprintf("%s%d", key, i), v)
if err != nil {
return err
}
} }
return nil return nil
@ -342,7 +345,7 @@ func (r VirtualEnvironmentContainerCustomMountPointArray) EncodeValues(key strin
// EncodeValues converts a VirtualEnvironmentContainerCustomNetworkInterface struct to a URL vlaue. // EncodeValues converts a VirtualEnvironmentContainerCustomNetworkInterface struct to a URL vlaue.
func (r VirtualEnvironmentContainerCustomNetworkInterface) EncodeValues(key string, v *url.Values) error { func (r VirtualEnvironmentContainerCustomNetworkInterface) EncodeValues(key string, v *url.Values) error {
values := []string{} var values []string
if r.Bridge != nil { if r.Bridge != nil {
values = append(values, fmt.Sprintf("bridge=%s", *r.Bridge)) values = append(values, fmt.Sprintf("bridge=%s", *r.Bridge))
@ -414,7 +417,10 @@ func (r VirtualEnvironmentContainerCustomNetworkInterface) EncodeValues(key stri
// EncodeValues converts a VirtualEnvironmentContainerCustomNetworkInterfaceArray array to multiple URL values. // EncodeValues converts a VirtualEnvironmentContainerCustomNetworkInterfaceArray array to multiple URL values.
func (r VirtualEnvironmentContainerCustomNetworkInterfaceArray) EncodeValues(key string, v *url.Values) error { func (r VirtualEnvironmentContainerCustomNetworkInterfaceArray) EncodeValues(key string, v *url.Values) error {
for i, d := range r { for i, d := range r {
d.EncodeValues(fmt.Sprintf("%s%d", key, i), v) err := d.EncodeValues(fmt.Sprintf("%s%d", key, i), v)
if err != nil {
return err
}
} }
return nil return nil
@ -422,7 +428,7 @@ func (r VirtualEnvironmentContainerCustomNetworkInterfaceArray) EncodeValues(key
// EncodeValues converts a VirtualEnvironmentContainerCustomRootFS struct to a URL vlaue. // EncodeValues converts a VirtualEnvironmentContainerCustomRootFS struct to a URL vlaue.
func (r VirtualEnvironmentContainerCustomRootFS) EncodeValues(key string, v *url.Values) error { func (r VirtualEnvironmentContainerCustomRootFS) EncodeValues(key string, v *url.Values) error {
values := []string{} var values []string
if r.ACL != nil { if r.ACL != nil {
if *r.ACL { if *r.ACL {
@ -492,7 +498,7 @@ func (r VirtualEnvironmentContainerCustomSSHKeys) EncodeValues(key string, v *ur
// EncodeValues converts a VirtualEnvironmentContainerCustomStartupBehavior struct to a URL vlaue. // EncodeValues converts a VirtualEnvironmentContainerCustomStartupBehavior struct to a URL vlaue.
func (r VirtualEnvironmentContainerCustomStartupBehavior) EncodeValues(key string, v *url.Values) error { func (r VirtualEnvironmentContainerCustomStartupBehavior) EncodeValues(key string, v *url.Values) error {
values := []string{} var values []string
if r.Down != nil { if r.Down != nil {
values = append(values, fmt.Sprintf("down=%d", *r.Down)) values = append(values, fmt.Sprintf("down=%d", *r.Down))
@ -541,7 +547,7 @@ func (r *VirtualEnvironmentContainerCustomFeatures) UnmarshalJSON(b []byte) erro
a := strings.Split(v[1], ";") a := strings.Split(v[1], ";")
r.MountTypes = &a r.MountTypes = &a
} else { } else {
a := []string{} var a []string
r.MountTypes = &a r.MountTypes = &a
} }
case "nesting": case "nesting":
@ -584,7 +590,7 @@ func (r *VirtualEnvironmentContainerCustomMountPoint) UnmarshalJSON(b []byte) er
a := strings.Split(v[1], ";") a := strings.Split(v[1], ";")
r.MountOptions = &a r.MountOptions = &a
} else { } else {
a := []string{} var a []string
r.MountOptions = &a r.MountOptions = &a
} }
case "mp": case "mp":
@ -685,7 +691,7 @@ func (r *VirtualEnvironmentContainerCustomNetworkInterface) UnmarshalJSON(b []by
r.Trunks = &a r.Trunks = &a
} else { } else {
a := []int{} var a []int
r.Trunks = &a r.Trunks = &a
} }
case "type": case "type":
@ -724,7 +730,7 @@ func (r *VirtualEnvironmentContainerCustomRootFS) UnmarshalJSON(b []byte) error
a := strings.Split(v[1], ";") a := strings.Split(v[1], ";")
r.MountOptions = &a r.MountOptions = &a
} else { } else {
a := []string{} var a []string
r.MountOptions = &a r.MountOptions = &a
} }
case "quota": case "quota":

View File

@ -5,6 +5,7 @@
package proxmox package proxmox
import ( import (
"context"
"errors" "errors"
"fmt" "fmt"
"io" "io"
@ -19,8 +20,8 @@ import (
) )
// DeleteDatastoreFile deletes a file in a datastore. // DeleteDatastoreFile deletes a file in a datastore.
func (c *VirtualEnvironmentClient) DeleteDatastoreFile(nodeName, datastoreID, volumeID string) error { func (c *VirtualEnvironmentClient) DeleteDatastoreFile(ctx context.Context, nodeName, datastoreID, volumeID string) error {
err := c.DoRequest(hmDELETE, fmt.Sprintf("nodes/%s/storage/%s/content/%s", url.PathEscape(nodeName), url.PathEscape(datastoreID), url.PathEscape(volumeID)), nil, nil) err := c.DoRequest(ctx, hmDELETE, fmt.Sprintf("nodes/%s/storage/%s/content/%s", url.PathEscape(nodeName), url.PathEscape(datastoreID), url.PathEscape(volumeID)), nil, nil)
if err != nil { if err != nil {
return err return err
@ -30,16 +31,16 @@ func (c *VirtualEnvironmentClient) DeleteDatastoreFile(nodeName, datastoreID, vo
} }
// ListDatastoreFiles retrieves a list of the files in a datastore. // ListDatastoreFiles retrieves a list of the files in a datastore.
func (c *VirtualEnvironmentClient) ListDatastoreFiles(nodeName, datastoreID string) ([]*VirtualEnvironmentDatastoreFileListResponseData, error) { func (c *VirtualEnvironmentClient) ListDatastoreFiles(ctx context.Context, nodeName, datastoreID string) ([]*VirtualEnvironmentDatastoreFileListResponseData, error) {
resBody := &VirtualEnvironmentDatastoreFileListResponseBody{} resBody := &VirtualEnvironmentDatastoreFileListResponseBody{}
err := c.DoRequest(hmGET, fmt.Sprintf("nodes/%s/storage/%s/content", url.PathEscape(nodeName), url.PathEscape(datastoreID)), nil, resBody) err := c.DoRequest(ctx, hmGET, fmt.Sprintf("nodes/%s/storage/%s/content", url.PathEscape(nodeName), url.PathEscape(datastoreID)), nil, resBody)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if resBody.Data == nil { if resBody.Data == nil {
return nil, errors.New("The server did not include a data object in the response") return nil, errors.New("the server did not include a data object in the response")
} }
sort.Slice(resBody.Data, func(i, j int) bool { sort.Slice(resBody.Data, func(i, j int) bool {
@ -50,16 +51,16 @@ func (c *VirtualEnvironmentClient) ListDatastoreFiles(nodeName, datastoreID stri
} }
// ListDatastores retrieves a list of nodes. // ListDatastores retrieves a list of nodes.
func (c *VirtualEnvironmentClient) ListDatastores(nodeName string, d *VirtualEnvironmentDatastoreListRequestBody) ([]*VirtualEnvironmentDatastoreListResponseData, error) { func (c *VirtualEnvironmentClient) ListDatastores(ctx context.Context, nodeName string, d *VirtualEnvironmentDatastoreListRequestBody) ([]*VirtualEnvironmentDatastoreListResponseData, error) {
resBody := &VirtualEnvironmentDatastoreListResponseBody{} resBody := &VirtualEnvironmentDatastoreListResponseBody{}
err := c.DoRequest(hmGET, fmt.Sprintf("nodes/%s/storage", url.PathEscape(nodeName)), d, resBody) err := c.DoRequest(ctx, hmGET, fmt.Sprintf("nodes/%s/storage", url.PathEscape(nodeName)), d, resBody)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if resBody.Data == nil { if resBody.Data == nil {
return nil, errors.New("The server did not include a data object in the response") return nil, errors.New("the server did not include a data object in the response")
} }
sort.Slice(resBody.Data, func(i, j int) bool { sort.Slice(resBody.Data, func(i, j int) bool {
@ -70,7 +71,7 @@ func (c *VirtualEnvironmentClient) ListDatastores(nodeName string, d *VirtualEnv
} }
// UploadFileToDatastore uploads a file to a datastore. // UploadFileToDatastore uploads a file to a datastore.
func (c *VirtualEnvironmentClient) UploadFileToDatastore(d *VirtualEnvironmentDatastoreUploadRequestBody) (*VirtualEnvironmentDatastoreUploadResponseBody, error) { func (c *VirtualEnvironmentClient) UploadFileToDatastore(ctx context.Context, d *VirtualEnvironmentDatastoreUploadRequestBody) (*VirtualEnvironmentDatastoreUploadResponseBody, error) {
switch d.ContentType { switch d.ContentType {
case "iso", "vztmpl": case "iso", "vztmpl":
r, w := io.Pipe() r, w := io.Pipe()
@ -142,7 +143,7 @@ func (c *VirtualEnvironmentClient) UploadFileToDatastore(d *VirtualEnvironmentDa
} }
resBody := &VirtualEnvironmentDatastoreUploadResponseBody{} resBody := &VirtualEnvironmentDatastoreUploadResponseBody{}
err = c.DoRequest(hmPOST, fmt.Sprintf("nodes/%s/storage/%s/upload", url.PathEscape(d.NodeName), url.PathEscape(d.DatastoreID)), reqBody, resBody) err = c.DoRequest(ctx, hmPOST, fmt.Sprintf("nodes/%s/storage/%s/upload", url.PathEscape(d.NodeName), url.PathEscape(d.DatastoreID)), reqBody, resBody)
if err != nil { if err != nil {
return nil, err return nil, err
@ -152,7 +153,7 @@ func (c *VirtualEnvironmentClient) UploadFileToDatastore(d *VirtualEnvironmentDa
default: default:
// We need to upload all other files using SFTP due to API limitations. // We need to upload all other files using SFTP due to API limitations.
// Hopefully, this will not be required in future releases of Proxmox VE. // Hopefully, this will not be required in future releases of Proxmox VE.
sshClient, err := c.OpenNodeShell(d.NodeName) sshClient, err := c.OpenNodeShell(ctx, d.NodeName)
if err != nil { if err != nil {
return nil, err return nil, err
@ -181,7 +182,7 @@ func (c *VirtualEnvironmentClient) UploadFileToDatastore(d *VirtualEnvironmentDa
datastorePath := strings.Trim(string(buf), "\000") datastorePath := strings.Trim(string(buf), "\000")
if datastorePath == "" { if datastorePath == "" {
return nil, errors.New("Failed to determine the datastore path") return nil, errors.New("failed to determine the datastore path")
} }
remoteFileDir := datastorePath remoteFileDir := datastorePath

View File

@ -5,28 +5,29 @@
package proxmox package proxmox
import ( import (
"context"
"errors" "errors"
"fmt" "fmt"
"net/url" "net/url"
) )
// GetDNS retrieves the DNS configuration for a node. // GetDNS retrieves the DNS configuration for a node.
func (c *VirtualEnvironmentClient) GetDNS(nodeName string) (*VirtualEnvironmentDNSGetResponseData, error) { func (c *VirtualEnvironmentClient) GetDNS(ctx context.Context, nodeName string) (*VirtualEnvironmentDNSGetResponseData, error) {
resBody := &VirtualEnvironmentDNSGetResponseBody{} resBody := &VirtualEnvironmentDNSGetResponseBody{}
err := c.DoRequest(hmGET, fmt.Sprintf("nodes/%s/dns", url.PathEscape(nodeName)), nil, resBody) err := c.DoRequest(ctx, hmGET, fmt.Sprintf("nodes/%s/dns", url.PathEscape(nodeName)), nil, resBody)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if resBody.Data == nil { if resBody.Data == nil {
return nil, errors.New("The server did not include a data object in the response") return nil, errors.New("the server did not include a data object in the response")
} }
return resBody.Data, nil return resBody.Data, nil
} }
// UpdateDNS updates the DNS configuration for a node. // UpdateDNS updates the DNS configuration for a node.
func (c *VirtualEnvironmentClient) UpdateDNS(nodeName string, d *VirtualEnvironmentDNSUpdateRequestBody) error { func (c *VirtualEnvironmentClient) UpdateDNS(ctx context.Context, nodeName string, d *VirtualEnvironmentDNSUpdateRequestBody) error {
return c.DoRequest(hmPUT, fmt.Sprintf("nodes/%s/dns", url.PathEscape(nodeName)), d, nil) return c.DoRequest(ctx, hmPUT, fmt.Sprintf("nodes/%s/dns", url.PathEscape(nodeName)), d, nil)
} }

View File

@ -5,6 +5,7 @@
package proxmox package proxmox
import ( import (
"context"
"errors" "errors"
"fmt" "fmt"
"net/url" "net/url"
@ -12,26 +13,26 @@ import (
) )
// CreateGroup creates an access group. // CreateGroup creates an access group.
func (c *VirtualEnvironmentClient) CreateGroup(d *VirtualEnvironmentGroupCreateRequestBody) error { func (c *VirtualEnvironmentClient) CreateGroup(ctx context.Context, d *VirtualEnvironmentGroupCreateRequestBody) error {
return c.DoRequest(hmPOST, "access/groups", d, nil) return c.DoRequest(ctx, hmPOST, "access/groups", d, nil)
} }
// DeleteGroup deletes an access group. // DeleteGroup deletes an access group.
func (c *VirtualEnvironmentClient) DeleteGroup(id string) error { func (c *VirtualEnvironmentClient) DeleteGroup(ctx context.Context, id string) error {
return c.DoRequest(hmDELETE, fmt.Sprintf("access/groups/%s", url.PathEscape(id)), nil, nil) return c.DoRequest(ctx, hmDELETE, fmt.Sprintf("access/groups/%s", url.PathEscape(id)), nil, nil)
} }
// GetGroup retrieves an access group. // GetGroup retrieves an access group.
func (c *VirtualEnvironmentClient) GetGroup(id string) (*VirtualEnvironmentGroupGetResponseData, error) { func (c *VirtualEnvironmentClient) GetGroup(ctx context.Context, id string) (*VirtualEnvironmentGroupGetResponseData, error) {
resBody := &VirtualEnvironmentGroupGetResponseBody{} resBody := &VirtualEnvironmentGroupGetResponseBody{}
err := c.DoRequest(hmGET, fmt.Sprintf("access/groups/%s", url.PathEscape(id)), nil, resBody) err := c.DoRequest(ctx, hmGET, fmt.Sprintf("access/groups/%s", url.PathEscape(id)), nil, resBody)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if resBody.Data == nil { if resBody.Data == nil {
return nil, errors.New("The server did not include a data object in the response") return nil, errors.New("the server did not include a data object in the response")
} }
sort.Strings(resBody.Data.Members) sort.Strings(resBody.Data.Members)
@ -40,16 +41,16 @@ func (c *VirtualEnvironmentClient) GetGroup(id string) (*VirtualEnvironmentGroup
} }
// ListGroups retrieves a list of access groups. // ListGroups retrieves a list of access groups.
func (c *VirtualEnvironmentClient) ListGroups() ([]*VirtualEnvironmentGroupListResponseData, error) { func (c *VirtualEnvironmentClient) ListGroups(ctx context.Context) ([]*VirtualEnvironmentGroupListResponseData, error) {
resBody := &VirtualEnvironmentGroupListResponseBody{} resBody := &VirtualEnvironmentGroupListResponseBody{}
err := c.DoRequest(hmGET, "access/groups", nil, resBody) err := c.DoRequest(ctx, hmGET, "access/groups", nil, resBody)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if resBody.Data == nil { if resBody.Data == nil {
return nil, errors.New("The server did not include a data object in the response") return nil, errors.New("the server did not include a data object in the response")
} }
sort.Slice(resBody.Data, func(i, j int) bool { sort.Slice(resBody.Data, func(i, j int) bool {
@ -60,6 +61,6 @@ func (c *VirtualEnvironmentClient) ListGroups() ([]*VirtualEnvironmentGroupListR
} }
// UpdateGroup updates an access group. // UpdateGroup updates an access group.
func (c *VirtualEnvironmentClient) UpdateGroup(id string, d *VirtualEnvironmentGroupUpdateRequestBody) error { func (c *VirtualEnvironmentClient) UpdateGroup(ctx context.Context, id string, d *VirtualEnvironmentGroupUpdateRequestBody) error {
return c.DoRequest(hmPUT, fmt.Sprintf("access/groups/%s", url.PathEscape(id)), d, nil) return c.DoRequest(ctx, hmPUT, fmt.Sprintf("access/groups/%s", url.PathEscape(id)), d, nil)
} }

View File

@ -5,28 +5,29 @@
package proxmox package proxmox
import ( import (
"context"
"errors" "errors"
"fmt" "fmt"
"net/url" "net/url"
) )
// GetHosts retrieves the Hosts configuration for a node. // GetHosts retrieves the Hosts configuration for a node.
func (c *VirtualEnvironmentClient) GetHosts(nodeName string) (*VirtualEnvironmentHostsGetResponseData, error) { func (c *VirtualEnvironmentClient) GetHosts(ctx context.Context, nodeName string) (*VirtualEnvironmentHostsGetResponseData, error) {
resBody := &VirtualEnvironmentHostsGetResponseBody{} resBody := &VirtualEnvironmentHostsGetResponseBody{}
err := c.DoRequest(hmGET, fmt.Sprintf("nodes/%s/hosts", url.PathEscape(nodeName)), nil, resBody) err := c.DoRequest(ctx, hmGET, fmt.Sprintf("nodes/%s/hosts", url.PathEscape(nodeName)), nil, resBody)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if resBody.Data == nil { if resBody.Data == nil {
return nil, errors.New("The server did not include a data object in the response") return nil, errors.New("the server did not include a data object in the response")
} }
return resBody.Data, nil return resBody.Data, nil
} }
// UpdateHosts updates the Hosts configuration for a node. // UpdateHosts updates the Hosts configuration for a node.
func (c *VirtualEnvironmentClient) UpdateHosts(nodeName string, d *VirtualEnvironmentHostsUpdateRequestBody) error { func (c *VirtualEnvironmentClient) UpdateHosts(ctx context.Context, nodeName string, d *VirtualEnvironmentHostsUpdateRequestBody) error {
return c.DoRequest(hmPOST, fmt.Sprintf("nodes/%s/hosts", url.PathEscape(nodeName)), d, nil) return c.DoRequest(ctx, hmPOST, fmt.Sprintf("nodes/%s/hosts", url.PathEscape(nodeName)), d, nil)
} }

View File

@ -5,8 +5,10 @@
package proxmox package proxmox
import ( import (
"context"
"errors" "errors"
"fmt" "fmt"
"github.com/hashicorp/terraform-plugin-log/tflog"
"net/url" "net/url"
"sort" "sort"
"strings" "strings"
@ -16,14 +18,21 @@ import (
) )
// ExecuteNodeCommands executes commands on a given node. // ExecuteNodeCommands executes commands on a given node.
func (c *VirtualEnvironmentClient) ExecuteNodeCommands(nodeName string, commands []string) error { func (c *VirtualEnvironmentClient) ExecuteNodeCommands(ctx context.Context, nodeName string, commands []string) error {
sshClient, err := c.OpenNodeShell(nodeName) sshClient, err := c.OpenNodeShell(ctx, nodeName)
if err != nil { if err != nil {
return err return err
} }
defer sshClient.Close() defer func(sshClient *ssh.Client) {
err := sshClient.Close()
if err != nil {
tflog.Error(ctx, "Failed to close ssh client", map[string]interface{}{
"error": err,
})
}
}(sshClient)
sshSession, err := sshClient.NewSession() sshSession, err := sshClient.NewSession()
@ -31,7 +40,14 @@ func (c *VirtualEnvironmentClient) ExecuteNodeCommands(nodeName string, commands
return err return err
} }
defer sshSession.Close() defer func(sshSession *ssh.Session) {
err := sshSession.Close()
if err != nil {
tflog.Error(ctx, "Failed to close ssh session", map[string]interface{}{
"error": err,
})
}
}(sshSession)
output, err := sshSession.CombinedOutput( output, err := sshSession.CombinedOutput(
fmt.Sprintf( fmt.Sprintf(
@ -48,8 +64,8 @@ func (c *VirtualEnvironmentClient) ExecuteNodeCommands(nodeName string, commands
} }
// GetNodeIP retrieves the IP address of a node. // GetNodeIP retrieves the IP address of a node.
func (c *VirtualEnvironmentClient) GetNodeIP(nodeName string) (*string, error) { func (c *VirtualEnvironmentClient) GetNodeIP(ctx context.Context, nodeName string) (*string, error) {
networkDevices, err := c.ListNodeNetworkDevices(nodeName) networkDevices, err := c.ListNodeNetworkDevices(ctx, nodeName)
if err != nil { if err != nil {
return nil, err return nil, err
@ -65,7 +81,7 @@ func (c *VirtualEnvironmentClient) GetNodeIP(nodeName string) (*string, error) {
} }
if nodeAddress == "" { if nodeAddress == "" {
return nil, fmt.Errorf("Failed to determine the IP address of node \"%s\"", nodeName) return nil, fmt.Errorf("failed to determine the IP address of node \"%s\"", nodeName)
} }
nodeAddressParts := strings.Split(nodeAddress, "/") nodeAddressParts := strings.Split(nodeAddress, "/")
@ -74,48 +90,48 @@ func (c *VirtualEnvironmentClient) GetNodeIP(nodeName string) (*string, error) {
} }
// GetNodeTime retrieves the time information for a node. // GetNodeTime retrieves the time information for a node.
func (c *VirtualEnvironmentClient) GetNodeTime(nodeName string) (*VirtualEnvironmentNodeGetTimeResponseData, error) { func (c *VirtualEnvironmentClient) GetNodeTime(ctx context.Context, nodeName string) (*VirtualEnvironmentNodeGetTimeResponseData, error) {
resBody := &VirtualEnvironmentNodeGetTimeResponseBody{} resBody := &VirtualEnvironmentNodeGetTimeResponseBody{}
err := c.DoRequest(hmGET, fmt.Sprintf("nodes/%s/time", url.PathEscape(nodeName)), nil, resBody) err := c.DoRequest(ctx, hmGET, fmt.Sprintf("nodes/%s/time", url.PathEscape(nodeName)), nil, resBody)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if resBody.Data == nil { if resBody.Data == nil {
return nil, errors.New("The server did not include a data object in the response") return nil, errors.New("the server did not include a data object in the response")
} }
return resBody.Data, nil return resBody.Data, nil
} }
// GetNodeTaskStatus retrieves the status of a node task. // GetNodeTaskStatus retrieves the status of a node task.
func (c *VirtualEnvironmentClient) GetNodeTaskStatus(nodeName string, upid string) (*VirtualEnvironmentNodeGetTaskStatusResponseData, error) { func (c *VirtualEnvironmentClient) GetNodeTaskStatus(ctx context.Context, nodeName string, upid string) (*VirtualEnvironmentNodeGetTaskStatusResponseData, error) {
resBody := &VirtualEnvironmentNodeGetTaskStatusResponseBody{} resBody := &VirtualEnvironmentNodeGetTaskStatusResponseBody{}
err := c.DoRequest(hmGET, fmt.Sprintf("nodes/%s/tasks/%s/status", url.PathEscape(nodeName), url.PathEscape(upid)), nil, resBody) err := c.DoRequest(ctx, hmGET, fmt.Sprintf("nodes/%s/tasks/%s/status", url.PathEscape(nodeName), url.PathEscape(upid)), nil, resBody)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if resBody.Data == nil { if resBody.Data == nil {
return nil, errors.New("The server did not include a data object in the response") return nil, errors.New("the server did not include a data object in the response")
} }
return resBody.Data, nil return resBody.Data, nil
} }
// ListNodeNetworkDevices retrieves a list of network devices for a specific nodes. // ListNodeNetworkDevices retrieves a list of network devices for a specific nodes.
func (c *VirtualEnvironmentClient) ListNodeNetworkDevices(nodeName string) ([]*VirtualEnvironmentNodeNetworkDeviceListResponseData, error) { func (c *VirtualEnvironmentClient) ListNodeNetworkDevices(ctx context.Context, nodeName string) ([]*VirtualEnvironmentNodeNetworkDeviceListResponseData, error) {
resBody := &VirtualEnvironmentNodeNetworkDeviceListResponseBody{} resBody := &VirtualEnvironmentNodeNetworkDeviceListResponseBody{}
err := c.DoRequest(hmGET, fmt.Sprintf("nodes/%s/network", url.PathEscape(nodeName)), nil, resBody) err := c.DoRequest(ctx, hmGET, fmt.Sprintf("nodes/%s/network", url.PathEscape(nodeName)), nil, resBody)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if resBody.Data == nil { if resBody.Data == nil {
return nil, errors.New("The server did not include a data object in the response") return nil, errors.New("the server did not include a data object in the response")
} }
sort.Slice(resBody.Data, func(i, j int) bool { sort.Slice(resBody.Data, func(i, j int) bool {
@ -126,16 +142,16 @@ func (c *VirtualEnvironmentClient) ListNodeNetworkDevices(nodeName string) ([]*V
} }
// ListNodes retrieves a list of nodes. // ListNodes retrieves a list of nodes.
func (c *VirtualEnvironmentClient) ListNodes() ([]*VirtualEnvironmentNodeListResponseData, error) { func (c *VirtualEnvironmentClient) ListNodes(ctx context.Context) ([]*VirtualEnvironmentNodeListResponseData, error) {
resBody := &VirtualEnvironmentNodeListResponseBody{} resBody := &VirtualEnvironmentNodeListResponseBody{}
err := c.DoRequest(hmGET, "nodes", nil, resBody) err := c.DoRequest(ctx, hmGET, "nodes", nil, resBody)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if resBody.Data == nil { if resBody.Data == nil {
return nil, errors.New("The server did not include a data object in the response") return nil, errors.New("the server did not include a data object in the response")
} }
sort.Slice(resBody.Data, func(i, j int) bool { sort.Slice(resBody.Data, func(i, j int) bool {
@ -146,8 +162,8 @@ func (c *VirtualEnvironmentClient) ListNodes() ([]*VirtualEnvironmentNodeListRes
} }
// OpenNodeShell establishes a new SSH connection to a node. // OpenNodeShell establishes a new SSH connection to a node.
func (c *VirtualEnvironmentClient) OpenNodeShell(nodeName string) (*ssh.Client, error) { func (c *VirtualEnvironmentClient) OpenNodeShell(ctx context.Context, nodeName string) (*ssh.Client, error) {
nodeAddress, err := c.GetNodeIP(nodeName) nodeAddress, err := c.GetNodeIP(ctx, nodeName)
if err != nil { if err != nil {
return nil, err return nil, err
@ -171,12 +187,12 @@ func (c *VirtualEnvironmentClient) OpenNodeShell(nodeName string) (*ssh.Client,
} }
// UpdateNodeTime updates the time on a node. // UpdateNodeTime updates the time on a node.
func (c *VirtualEnvironmentClient) UpdateNodeTime(nodeName string, d *VirtualEnvironmentNodeUpdateTimeRequestBody) error { func (c *VirtualEnvironmentClient) UpdateNodeTime(ctx context.Context, nodeName string, d *VirtualEnvironmentNodeUpdateTimeRequestBody) error {
return c.DoRequest(hmPUT, fmt.Sprintf("nodes/%s/time", url.PathEscape(nodeName)), d, nil) return c.DoRequest(ctx, hmPUT, fmt.Sprintf("nodes/%s/time", url.PathEscape(nodeName)), d, nil)
} }
// WaitForNodeTask waits for a specific node task to complete. // WaitForNodeTask waits for a specific node task to complete.
func (c *VirtualEnvironmentClient) WaitForNodeTask(nodeName string, upid string, timeout int, delay int) error { func (c *VirtualEnvironmentClient) WaitForNodeTask(ctx context.Context, nodeName string, upid string, timeout int, delay int) error {
timeDelay := int64(delay) timeDelay := int64(delay)
timeMax := float64(timeout) timeMax := float64(timeout)
timeStart := time.Now() timeStart := time.Now()
@ -184,7 +200,7 @@ func (c *VirtualEnvironmentClient) WaitForNodeTask(nodeName string, upid string,
for timeElapsed.Seconds() < timeMax { for timeElapsed.Seconds() < timeMax {
if int64(timeElapsed.Seconds())%timeDelay == 0 { if int64(timeElapsed.Seconds())%timeDelay == 0 {
status, err := c.GetNodeTaskStatus(nodeName, upid) status, err := c.GetNodeTaskStatus(ctx, nodeName, upid)
if err != nil { if err != nil {
return err return err
@ -192,7 +208,7 @@ func (c *VirtualEnvironmentClient) WaitForNodeTask(nodeName string, upid string,
if status.Status != "running" { if status.Status != "running" {
if status.ExitCode != "OK" { if status.ExitCode != "OK" {
return fmt.Errorf("Task \"%s\" on node \"%s\" failed to complete with error: %s", upid, nodeName, status.ExitCode) return fmt.Errorf("task \"%s\" on node \"%s\" failed to complete with error: %s", upid, nodeName, status.ExitCode)
} }
return nil return nil
} }
@ -203,7 +219,11 @@ func (c *VirtualEnvironmentClient) WaitForNodeTask(nodeName string, upid string,
time.Sleep(200 * time.Millisecond) time.Sleep(200 * time.Millisecond)
timeElapsed = time.Now().Sub(timeStart) timeElapsed = time.Now().Sub(timeStart)
if ctx.Err() != nil {
return ctx.Err()
}
} }
return fmt.Errorf("Timeout while waiting for task \"%s\" on node \"%s\" to complete", upid, nodeName) return fmt.Errorf("timeout while waiting for task \"%s\" on node \"%s\" to complete", upid, nodeName)
} }

View File

@ -5,33 +5,34 @@
package proxmox package proxmox
import ( import (
"context"
"errors" "errors"
"fmt" "fmt"
"net/url" "net/url"
"sort" "sort"
) )
// CreatePool creates an pool. // CreatePool creates a pool.
func (c *VirtualEnvironmentClient) CreatePool(d *VirtualEnvironmentPoolCreateRequestBody) error { func (c *VirtualEnvironmentClient) CreatePool(ctx context.Context, d *VirtualEnvironmentPoolCreateRequestBody) error {
return c.DoRequest(hmPOST, "pools", d, nil) return c.DoRequest(ctx, hmPOST, "pools", d, nil)
} }
// DeletePool deletes an pool. // DeletePool deletes a pool.
func (c *VirtualEnvironmentClient) DeletePool(id string) error { func (c *VirtualEnvironmentClient) DeletePool(ctx context.Context, id string) error {
return c.DoRequest(hmDELETE, fmt.Sprintf("pools/%s", url.PathEscape(id)), nil, nil) return c.DoRequest(ctx, hmDELETE, fmt.Sprintf("pools/%s", url.PathEscape(id)), nil, nil)
} }
// GetPool retrieves an pool. // GetPool retrieves a pool.
func (c *VirtualEnvironmentClient) GetPool(id string) (*VirtualEnvironmentPoolGetResponseData, error) { func (c *VirtualEnvironmentClient) GetPool(ctx context.Context, id string) (*VirtualEnvironmentPoolGetResponseData, error) {
resBody := &VirtualEnvironmentPoolGetResponseBody{} resBody := &VirtualEnvironmentPoolGetResponseBody{}
err := c.DoRequest(hmGET, fmt.Sprintf("pools/%s", url.PathEscape(id)), nil, resBody) err := c.DoRequest(ctx, hmGET, fmt.Sprintf("pools/%s", url.PathEscape(id)), nil, resBody)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if resBody.Data == nil { if resBody.Data == nil {
return nil, errors.New("The server did not include a data object in the response") return nil, errors.New("the server did not include a data object in the response")
} }
sort.Slice(resBody.Data.Members, func(i, j int) bool { sort.Slice(resBody.Data.Members, func(i, j int) bool {
@ -42,16 +43,16 @@ func (c *VirtualEnvironmentClient) GetPool(id string) (*VirtualEnvironmentPoolGe
} }
// ListPools retrieves a list of pools. // ListPools retrieves a list of pools.
func (c *VirtualEnvironmentClient) ListPools() ([]*VirtualEnvironmentPoolListResponseData, error) { func (c *VirtualEnvironmentClient) ListPools(ctx context.Context) ([]*VirtualEnvironmentPoolListResponseData, error) {
resBody := &VirtualEnvironmentPoolListResponseBody{} resBody := &VirtualEnvironmentPoolListResponseBody{}
err := c.DoRequest(hmGET, "pools", nil, resBody) err := c.DoRequest(ctx, hmGET, "pools", nil, resBody)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if resBody.Data == nil { if resBody.Data == nil {
return nil, errors.New("The server did not include a data object in the response") return nil, errors.New("the server did not include a data object in the response")
} }
sort.Slice(resBody.Data, func(i, j int) bool { sort.Slice(resBody.Data, func(i, j int) bool {
@ -61,7 +62,7 @@ func (c *VirtualEnvironmentClient) ListPools() ([]*VirtualEnvironmentPoolListRes
return resBody.Data, nil return resBody.Data, nil
} }
// UpdatePool updates an pool. // UpdatePool updates a pool.
func (c *VirtualEnvironmentClient) UpdatePool(id string, d *VirtualEnvironmentPoolUpdateRequestBody) error { func (c *VirtualEnvironmentClient) UpdatePool(ctx context.Context, id string, d *VirtualEnvironmentPoolUpdateRequestBody) error {
return c.DoRequest(hmPUT, fmt.Sprintf("pools/%s", url.PathEscape(id)), d, nil) return c.DoRequest(ctx, hmPUT, fmt.Sprintf("pools/%s", url.PathEscape(id)), d, nil)
} }

View File

@ -5,6 +5,7 @@
package proxmox package proxmox
import ( import (
"context"
"errors" "errors"
"fmt" "fmt"
"net/url" "net/url"
@ -12,26 +13,26 @@ import (
) )
// CreateRole creates an access role. // CreateRole creates an access role.
func (c *VirtualEnvironmentClient) CreateRole(d *VirtualEnvironmentRoleCreateRequestBody) error { func (c *VirtualEnvironmentClient) CreateRole(ctx context.Context, d *VirtualEnvironmentRoleCreateRequestBody) error {
return c.DoRequest(hmPOST, "access/roles", d, nil) return c.DoRequest(ctx, hmPOST, "access/roles", d, nil)
} }
// DeleteRole deletes an access role. // DeleteRole deletes an access role.
func (c *VirtualEnvironmentClient) DeleteRole(id string) error { func (c *VirtualEnvironmentClient) DeleteRole(ctx context.Context, id string) error {
return c.DoRequest(hmDELETE, fmt.Sprintf("access/roles/%s", url.PathEscape(id)), nil, nil) return c.DoRequest(ctx, hmDELETE, fmt.Sprintf("access/roles/%s", url.PathEscape(id)), nil, nil)
} }
// GetRole retrieves an access role. // GetRole retrieves an access role.
func (c *VirtualEnvironmentClient) GetRole(id string) (*CustomPrivileges, error) { func (c *VirtualEnvironmentClient) GetRole(ctx context.Context, id string) (*CustomPrivileges, error) {
resBody := &VirtualEnvironmentRoleGetResponseBody{} resBody := &VirtualEnvironmentRoleGetResponseBody{}
err := c.DoRequest(hmGET, fmt.Sprintf("access/roles/%s", url.PathEscape(id)), nil, resBody) err := c.DoRequest(ctx, hmGET, fmt.Sprintf("access/roles/%s", url.PathEscape(id)), nil, resBody)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if resBody.Data == nil { if resBody.Data == nil {
return nil, errors.New("The server did not include a data object in the response") return nil, errors.New("the server did not include a data object in the response")
} }
sort.Strings(*resBody.Data) sort.Strings(*resBody.Data)
@ -40,16 +41,16 @@ func (c *VirtualEnvironmentClient) GetRole(id string) (*CustomPrivileges, error)
} }
// ListRoles retrieves a list of access roles. // ListRoles retrieves a list of access roles.
func (c *VirtualEnvironmentClient) ListRoles() ([]*VirtualEnvironmentRoleListResponseData, error) { func (c *VirtualEnvironmentClient) ListRoles(ctx context.Context) ([]*VirtualEnvironmentRoleListResponseData, error) {
resBody := &VirtualEnvironmentRoleListResponseBody{} resBody := &VirtualEnvironmentRoleListResponseBody{}
err := c.DoRequest(hmGET, "access/roles", nil, resBody) err := c.DoRequest(ctx, hmGET, "access/roles", nil, resBody)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if resBody.Data == nil { if resBody.Data == nil {
return nil, errors.New("The server did not include a data object in the response") return nil, errors.New("the server did not include a data object in the response")
} }
sort.Slice(resBody.Data, func(i, j int) bool { sort.Slice(resBody.Data, func(i, j int) bool {
@ -66,6 +67,6 @@ func (c *VirtualEnvironmentClient) ListRoles() ([]*VirtualEnvironmentRoleListRes
} }
// UpdateRole updates an access role. // UpdateRole updates an access role.
func (c *VirtualEnvironmentClient) UpdateRole(id string, d *VirtualEnvironmentRoleUpdateRequestBody) error { func (c *VirtualEnvironmentClient) UpdateRole(ctx context.Context, id string, d *VirtualEnvironmentRoleUpdateRequestBody) error {
return c.DoRequest(hmPUT, fmt.Sprintf("access/roles/%s", url.PathEscape(id)), d, nil) return c.DoRequest(ctx, hmPUT, fmt.Sprintf("access/roles/%s", url.PathEscape(id)), d, nil)
} }

View File

@ -5,6 +5,7 @@
package proxmox package proxmox
import ( import (
"context"
"errors" "errors"
"fmt" "fmt"
"net/url" "net/url"
@ -13,36 +14,36 @@ import (
) )
// ChangeUserPassword changes a user's password. // ChangeUserPassword changes a user's password.
func (c *VirtualEnvironmentClient) ChangeUserPassword(id, password string) error { func (c *VirtualEnvironmentClient) ChangeUserPassword(ctx context.Context, id, password string) error {
d := VirtualEnvironmentUserChangePasswordRequestBody{ d := VirtualEnvironmentUserChangePasswordRequestBody{
ID: id, ID: id,
Password: password, Password: password,
} }
return c.DoRequest(hmPUT, "access/password", d, nil) return c.DoRequest(ctx, hmPUT, "access/password", d, nil)
} }
// CreateUser creates an user. // CreateUser creates a user.
func (c *VirtualEnvironmentClient) CreateUser(d *VirtualEnvironmentUserCreateRequestBody) error { func (c *VirtualEnvironmentClient) CreateUser(ctx context.Context, d *VirtualEnvironmentUserCreateRequestBody) error {
return c.DoRequest(hmPOST, "access/users", d, nil) return c.DoRequest(ctx, hmPOST, "access/users", d, nil)
} }
// DeleteUser deletes an user. // DeleteUser deletes an user.
func (c *VirtualEnvironmentClient) DeleteUser(id string) error { func (c *VirtualEnvironmentClient) DeleteUser(ctx context.Context, id string) error {
return c.DoRequest(hmDELETE, fmt.Sprintf("access/users/%s", url.PathEscape(id)), nil, nil) return c.DoRequest(ctx, hmDELETE, fmt.Sprintf("access/users/%s", url.PathEscape(id)), nil, nil)
} }
// GetUser retrieves an user. // GetUser retrieves a user.
func (c *VirtualEnvironmentClient) GetUser(id string) (*VirtualEnvironmentUserGetResponseData, error) { func (c *VirtualEnvironmentClient) GetUser(ctx context.Context, id string) (*VirtualEnvironmentUserGetResponseData, error) {
resBody := &VirtualEnvironmentUserGetResponseBody{} resBody := &VirtualEnvironmentUserGetResponseBody{}
err := c.DoRequest(hmGET, fmt.Sprintf("access/users/%s", url.PathEscape(id)), nil, resBody) err := c.DoRequest(ctx, hmGET, fmt.Sprintf("access/users/%s", url.PathEscape(id)), nil, resBody)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if resBody.Data == nil { if resBody.Data == nil {
return nil, errors.New("The server did not include a data object in the response") return nil, errors.New("the server did not include a data object in the response")
} }
if resBody.Data.ExpirationDate != nil { if resBody.Data.ExpirationDate != nil {
@ -58,16 +59,16 @@ func (c *VirtualEnvironmentClient) GetUser(id string) (*VirtualEnvironmentUserGe
} }
// ListUsers retrieves a list of users. // ListUsers retrieves a list of users.
func (c *VirtualEnvironmentClient) ListUsers() ([]*VirtualEnvironmentUserListResponseData, error) { func (c *VirtualEnvironmentClient) ListUsers(ctx context.Context) ([]*VirtualEnvironmentUserListResponseData, error) {
resBody := &VirtualEnvironmentUserListResponseBody{} resBody := &VirtualEnvironmentUserListResponseBody{}
err := c.DoRequest(hmGET, "access/users", nil, resBody) err := c.DoRequest(ctx, hmGET, "access/users", nil, resBody)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if resBody.Data == nil { if resBody.Data == nil {
return nil, errors.New("The server did not include a data object in the response") return nil, errors.New("the server did not include a data object in the response")
} }
sort.Slice(resBody.Data, func(i, j int) bool { sort.Slice(resBody.Data, func(i, j int) bool {
@ -88,7 +89,7 @@ func (c *VirtualEnvironmentClient) ListUsers() ([]*VirtualEnvironmentUserListRes
return resBody.Data, nil return resBody.Data, nil
} }
// UpdateUser updates an user. // UpdateUser updates a user.
func (c *VirtualEnvironmentClient) UpdateUser(id string, d *VirtualEnvironmentUserUpdateRequestBody) error { func (c *VirtualEnvironmentClient) UpdateUser(ctx context.Context, id string, d *VirtualEnvironmentUserUpdateRequestBody) error {
return c.DoRequest(hmPUT, fmt.Sprintf("access/users/%s", url.PathEscape(id)), d, nil) return c.DoRequest(ctx, hmPUT, fmt.Sprintf("access/users/%s", url.PathEscape(id)), d, nil)
} }

View File

@ -5,20 +5,21 @@
package proxmox package proxmox
import ( import (
"context"
"errors" "errors"
) )
// Version retrieves the version information. // Version retrieves the version information.
func (c *VirtualEnvironmentClient) Version() (*VirtualEnvironmentVersionResponseData, error) { func (c *VirtualEnvironmentClient) Version(ctx context.Context) (*VirtualEnvironmentVersionResponseData, error) {
resBody := &VirtualEnvironmentVersionResponseBody{} resBody := &VirtualEnvironmentVersionResponseBody{}
err := c.DoRequest(hmGET, "version", nil, resBody) err := c.DoRequest(ctx, hmGET, "version", nil, resBody)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if resBody.Data == nil { if resBody.Data == nil {
return nil, errors.New("The server did not include a data object in the response") return nil, errors.New("the server did not include a data object in the response")
} }
return resBody.Data, nil return resBody.Data, nil

View File

@ -5,9 +5,10 @@
package proxmox package proxmox
import ( import (
"context"
"errors" "errors"
"fmt" "fmt"
"log" "github.com/hashicorp/terraform-plugin-log/tflog"
"net/url" "net/url"
"strings" "strings"
"sync" "sync"
@ -24,7 +25,7 @@ var (
) )
// CloneVM clones a virtual machine. // CloneVM clones a virtual machine.
func (c *VirtualEnvironmentClient) CloneVM(nodeName string, vmID int, retries int, d *VirtualEnvironmentVMCloneRequestBody, timeout int) error { func (c *VirtualEnvironmentClient) CloneVM(ctx context.Context, nodeName string, vmID int, retries int, d *VirtualEnvironmentVMCloneRequestBody, timeout int) error {
resBody := &VirtualEnvironmentVMMoveDiskResponseBody{} resBody := &VirtualEnvironmentVMMoveDiskResponseBody{}
var err error var err error
@ -34,17 +35,17 @@ func (c *VirtualEnvironmentClient) CloneVM(nodeName string, vmID int, retries in
} }
for i := 0; i < retries; i++ { for i := 0; i < retries; i++ {
err = c.DoRequest(hmPOST, fmt.Sprintf("nodes/%s/qemu/%d/clone", url.PathEscape(nodeName), vmID), d, resBody) err = c.DoRequest(ctx, hmPOST, fmt.Sprintf("nodes/%s/qemu/%d/clone", url.PathEscape(nodeName), vmID), d, resBody)
if err != nil { if err != nil {
return err return err
} }
if resBody.Data == nil { if resBody.Data == nil {
return errors.New("The server did not include a data object in the response") return errors.New("the server did not include a data object in the response")
} }
err = c.WaitForNodeTask(nodeName, *resBody.Data, timeout, 5) err = c.WaitForNodeTask(ctx, nodeName, *resBody.Data, timeout, 5)
if err == nil { if err == nil {
return nil return nil
@ -56,50 +57,52 @@ func (c *VirtualEnvironmentClient) CloneVM(nodeName string, vmID int, retries in
} }
// CreateVM creates a virtual machine. // CreateVM creates a virtual machine.
func (c *VirtualEnvironmentClient) CreateVM(nodeName string, d *VirtualEnvironmentVMCreateRequestBody) error { func (c *VirtualEnvironmentClient) CreateVM(ctx context.Context, nodeName string, d *VirtualEnvironmentVMCreateRequestBody) error {
return c.DoRequest(hmPOST, fmt.Sprintf("nodes/%s/qemu", url.PathEscape(nodeName)), d, nil) return c.DoRequest(ctx, hmPOST, fmt.Sprintf("nodes/%s/qemu", url.PathEscape(nodeName)), d, nil)
} }
// DeleteVM deletes a virtual machine. // DeleteVM deletes a virtual machine.
func (c *VirtualEnvironmentClient) DeleteVM(nodeName string, vmID int) error { func (c *VirtualEnvironmentClient) DeleteVM(ctx context.Context, nodeName string, vmID int) error {
return c.DoRequest(hmDELETE, fmt.Sprintf("nodes/%s/qemu/%d", url.PathEscape(nodeName), vmID), nil, nil) return c.DoRequest(ctx, hmDELETE, fmt.Sprintf("nodes/%s/qemu/%d", url.PathEscape(nodeName), vmID), nil, nil)
} }
// GetVM retrieves a virtual machine. // GetVM retrieves a virtual machine.
func (c *VirtualEnvironmentClient) GetVM(nodeName string, vmID int) (*VirtualEnvironmentVMGetResponseData, error) { func (c *VirtualEnvironmentClient) GetVM(ctx context.Context, nodeName string, vmID int) (*VirtualEnvironmentVMGetResponseData, error) {
resBody := &VirtualEnvironmentVMGetResponseBody{} resBody := &VirtualEnvironmentVMGetResponseBody{}
err := c.DoRequest(hmGET, fmt.Sprintf("nodes/%s/qemu/%d/config", url.PathEscape(nodeName), vmID), nil, resBody) err := c.DoRequest(ctx, hmGET, fmt.Sprintf("nodes/%s/qemu/%d/config", url.PathEscape(nodeName), vmID), nil, resBody)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if resBody.Data == nil { if resBody.Data == nil {
return nil, errors.New("The server did not include a data object in the response") return nil, errors.New("the server did not include a data object in the response")
} }
return resBody.Data, nil return resBody.Data, nil
} }
// GetVMID retrieves the next available VM identifier. // GetVMID retrieves the next available VM identifier.
func (c *VirtualEnvironmentClient) GetVMID() (*int, error) { func (c *VirtualEnvironmentClient) GetVMID(ctx context.Context) (*int, error) {
getVMIDCounterMutex.Lock() getVMIDCounterMutex.Lock()
defer getVMIDCounterMutex.Unlock() defer getVMIDCounterMutex.Unlock()
if getVMIDCounter < 0 { if getVMIDCounter < 0 {
nextVMID, err := c.GetClusterNextID(nil) nextVMID, err := c.GetClusterNextID(ctx, nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if nextVMID == nil { if nextVMID == nil {
return nil, errors.New("Unable to retrieve the next available VM identifier") return nil, errors.New("unable to retrieve the next available VM identifier")
} }
getVMIDCounter = *nextVMID + getVMIDStep getVMIDCounter = *nextVMID + getVMIDStep
log.Printf("[DEBUG] Determined next available VM identifier to be %d", *nextVMID) tflog.Debug(ctx, "next VM identifier", map[string]interface{}{
"id": *nextVMID,
})
return nextVMID, nil return nextVMID, nil
} }
@ -107,7 +110,7 @@ func (c *VirtualEnvironmentClient) GetVMID() (*int, error) {
vmID := getVMIDCounter vmID := getVMIDCounter
for vmID <= 2147483637 { for vmID <= 2147483637 {
_, err := c.GetClusterNextID(&vmID) _, err := c.GetClusterNextID(ctx, &vmID)
if err != nil { if err != nil {
vmID += getVMIDStep vmID += getVMIDStep
@ -117,49 +120,51 @@ func (c *VirtualEnvironmentClient) GetVMID() (*int, error) {
getVMIDCounter = vmID + getVMIDStep getVMIDCounter = vmID + getVMIDStep
log.Printf("[DEBUG] Determined next available VM identifier to be %d", vmID) tflog.Debug(ctx, "next VM identifier", map[string]interface{}{
"id": vmID,
})
return &vmID, nil return &vmID, nil
} }
return nil, errors.New("Unable to determine the next available VM identifier") return nil, errors.New("unable to determine the next available VM identifier")
} }
// GetVMNetworkInterfacesFromAgent retrieves the network interfaces reported by the QEMU agent. // GetVMNetworkInterfacesFromAgent retrieves the network interfaces reported by the QEMU agent.
func (c *VirtualEnvironmentClient) GetVMNetworkInterfacesFromAgent(nodeName string, vmID int) (*VirtualEnvironmentVMGetQEMUNetworkInterfacesResponseData, error) { func (c *VirtualEnvironmentClient) GetVMNetworkInterfacesFromAgent(ctx context.Context, nodeName string, vmID int) (*VirtualEnvironmentVMGetQEMUNetworkInterfacesResponseData, error) {
resBody := &VirtualEnvironmentVMGetQEMUNetworkInterfacesResponseBody{} resBody := &VirtualEnvironmentVMGetQEMUNetworkInterfacesResponseBody{}
err := c.DoRequest(hmGET, fmt.Sprintf("nodes/%s/qemu/%d/agent/network-get-interfaces", url.PathEscape(nodeName), vmID), nil, resBody) err := c.DoRequest(ctx, hmGET, fmt.Sprintf("nodes/%s/qemu/%d/agent/network-get-interfaces", url.PathEscape(nodeName), vmID), nil, resBody)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if resBody.Data == nil { if resBody.Data == nil {
return nil, errors.New("The server did not include a data object in the response") return nil, errors.New("the server did not include a data object in the response")
} }
return resBody.Data, nil return resBody.Data, nil
} }
// GetVMStatus retrieves the status for a virtual machine. // GetVMStatus retrieves the status for a virtual machine.
func (c *VirtualEnvironmentClient) GetVMStatus(nodeName string, vmID int) (*VirtualEnvironmentVMGetStatusResponseData, error) { func (c *VirtualEnvironmentClient) GetVMStatus(ctx context.Context, nodeName string, vmID int) (*VirtualEnvironmentVMGetStatusResponseData, error) {
resBody := &VirtualEnvironmentVMGetStatusResponseBody{} resBody := &VirtualEnvironmentVMGetStatusResponseBody{}
err := c.DoRequest(hmGET, fmt.Sprintf("nodes/%s/qemu/%d/status/current", url.PathEscape(nodeName), vmID), nil, resBody) err := c.DoRequest(ctx, hmGET, fmt.Sprintf("nodes/%s/qemu/%d/status/current", url.PathEscape(nodeName), vmID), nil, resBody)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if resBody.Data == nil { if resBody.Data == nil {
return nil, errors.New("The server did not include a data object in the response") return nil, errors.New("the server did not include a data object in the response")
} }
return resBody.Data, nil return resBody.Data, nil
} }
// MoveVMDisk moves a virtual machine disk. // MoveVMDisk moves a virtual machine disk.
func (c *VirtualEnvironmentClient) MoveVMDisk(nodeName string, vmID int, d *VirtualEnvironmentVMMoveDiskRequestBody, timeout int) error { func (c *VirtualEnvironmentClient) MoveVMDisk(ctx context.Context, nodeName string, vmID int, d *VirtualEnvironmentVMMoveDiskRequestBody, timeout int) error {
taskID, err := c.MoveVMDiskAsync(nodeName, vmID, d) taskID, err := c.MoveVMDiskAsync(ctx, nodeName, vmID, d)
if err != nil { if err != nil {
if strings.Contains(err.Error(), "you can't move to the same storage with same format") { if strings.Contains(err.Error(), "you can't move to the same storage with same format") {
@ -170,7 +175,7 @@ func (c *VirtualEnvironmentClient) MoveVMDisk(nodeName string, vmID int, d *Virt
return err return err
} }
err = c.WaitForNodeTask(nodeName, *taskID, timeout, 5) err = c.WaitForNodeTask(ctx, nodeName, *taskID, timeout, 5)
if err != nil { if err != nil {
return err return err
@ -180,16 +185,16 @@ func (c *VirtualEnvironmentClient) MoveVMDisk(nodeName string, vmID int, d *Virt
} }
// MoveVMDiskAsync moves a virtual machine disk asynchronously. // MoveVMDiskAsync moves a virtual machine disk asynchronously.
func (c *VirtualEnvironmentClient) MoveVMDiskAsync(nodeName string, vmID int, d *VirtualEnvironmentVMMoveDiskRequestBody) (*string, error) { func (c *VirtualEnvironmentClient) MoveVMDiskAsync(ctx context.Context, nodeName string, vmID int, d *VirtualEnvironmentVMMoveDiskRequestBody) (*string, error) {
resBody := &VirtualEnvironmentVMMoveDiskResponseBody{} resBody := &VirtualEnvironmentVMMoveDiskResponseBody{}
err := c.DoRequest(hmPOST, fmt.Sprintf("nodes/%s/qemu/%d/move_disk", url.PathEscape(nodeName), vmID), d, resBody) err := c.DoRequest(ctx, hmPOST, fmt.Sprintf("nodes/%s/qemu/%d/move_disk", url.PathEscape(nodeName), vmID), d, resBody)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if resBody.Data == nil { if resBody.Data == nil {
return nil, errors.New("The server did not include a data object in the response") return nil, errors.New("the server did not include a data object in the response")
} }
return resBody.Data, nil return resBody.Data, nil
@ -197,18 +202,18 @@ func (c *VirtualEnvironmentClient) MoveVMDiskAsync(nodeName string, vmID int, d
// ListVMs retrieves a list of virtual machines. // ListVMs retrieves a list of virtual machines.
func (c *VirtualEnvironmentClient) ListVMs() ([]*VirtualEnvironmentVMListResponseData, error) { func (c *VirtualEnvironmentClient) ListVMs() ([]*VirtualEnvironmentVMListResponseData, error) {
return nil, errors.New("Not implemented") return nil, errors.New("not implemented")
} }
// RebootVM reboots a virtual machine. // RebootVM reboots a virtual machine.
func (c *VirtualEnvironmentClient) RebootVM(nodeName string, vmID int, d *VirtualEnvironmentVMRebootRequestBody, timeout int) error { func (c *VirtualEnvironmentClient) RebootVM(ctx context.Context, nodeName string, vmID int, d *VirtualEnvironmentVMRebootRequestBody, timeout int) error {
taskID, err := c.RebootVMAsync(nodeName, vmID, d) taskID, err := c.RebootVMAsync(ctx, nodeName, vmID, d)
if err != nil { if err != nil {
return err return err
} }
err = c.WaitForNodeTask(nodeName, *taskID, timeout, 5) err = c.WaitForNodeTask(ctx, nodeName, *taskID, timeout, 5)
if err != nil { if err != nil {
return err return err
@ -218,45 +223,54 @@ func (c *VirtualEnvironmentClient) RebootVM(nodeName string, vmID int, d *Virtua
} }
// RebootVMAsync reboots a virtual machine asynchronously. // RebootVMAsync reboots a virtual machine asynchronously.
func (c *VirtualEnvironmentClient) RebootVMAsync(nodeName string, vmID int, d *VirtualEnvironmentVMRebootRequestBody) (*string, error) { func (c *VirtualEnvironmentClient) RebootVMAsync(ctx context.Context, nodeName string, vmID int, d *VirtualEnvironmentVMRebootRequestBody) (*string, error) {
resBody := &VirtualEnvironmentVMRebootResponseBody{} resBody := &VirtualEnvironmentVMRebootResponseBody{}
err := c.DoRequest(hmPOST, fmt.Sprintf("nodes/%s/qemu/%d/status/reboot", url.PathEscape(nodeName), vmID), d, resBody) err := c.DoRequest(ctx, hmPOST, fmt.Sprintf("nodes/%s/qemu/%d/status/reboot", url.PathEscape(nodeName), vmID), d, resBody)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if resBody.Data == nil { if resBody.Data == nil {
return nil, errors.New("The server did not include a data object in the response") return nil, errors.New("the server did not include a data object in the response")
} }
return resBody.Data, nil return resBody.Data, nil
} }
// ResizeVMDisk resizes a virtual machine disk. // ResizeVMDisk resizes a virtual machine disk.
func (c *VirtualEnvironmentClient) ResizeVMDisk(nodeName string, vmID int, d *VirtualEnvironmentVMResizeDiskRequestBody) error { func (c *VirtualEnvironmentClient) ResizeVMDisk(ctx context.Context, nodeName string, vmID int, d *VirtualEnvironmentVMResizeDiskRequestBody) error {
var err error var err error
log.Printf("[DEBUG] RESIZE size: %s, disk: %s", d.Size, d.Disk) tflog.Debug(ctx, "resize disk", map[string]interface{}{
"disk": d.Disk,
"size": d.Size,
})
for i := 0; i < 5; i++ { for i := 0; i < 5; i++ {
err = c.DoRequest(hmPUT, fmt.Sprintf("nodes/%s/qemu/%d/resize", url.PathEscape(nodeName), vmID), d, nil) err = c.DoRequest(ctx, hmPUT, fmt.Sprintf("nodes/%s/qemu/%d/resize", url.PathEscape(nodeName), vmID), d, nil)
if err == nil { if err == nil {
return nil return nil
} }
log.Printf("[DEBUG] resize disk failed, retry nr: %d", i) tflog.Debug(ctx, "resize disk failed", map[string]interface{}{
"retry": i,
})
time.Sleep(5 * time.Second) time.Sleep(5 * time.Second)
if ctx.Err() != nil {
return ctx.Err()
}
} }
return err return err
} }
// ShutdownVM shuts down a virtual machine. // ShutdownVM shuts down a virtual machine.
func (c *VirtualEnvironmentClient) ShutdownVM(nodeName string, vmID int, d *VirtualEnvironmentVMShutdownRequestBody, timeout int) error { func (c *VirtualEnvironmentClient) ShutdownVM(ctx context.Context, nodeName string, vmID int, d *VirtualEnvironmentVMShutdownRequestBody, timeout int) error {
taskID, err := c.ShutdownVMAsync(nodeName, vmID, d) taskID, err := c.ShutdownVMAsync(ctx, nodeName, vmID, d)
if err != nil { if err != nil {
return err return err
} }
err = c.WaitForNodeTask(nodeName, *taskID, timeout, 5) err = c.WaitForNodeTask(ctx, nodeName, *taskID, timeout, 5)
if err != nil { if err != nil {
return err return err
@ -266,30 +280,30 @@ func (c *VirtualEnvironmentClient) ShutdownVM(nodeName string, vmID int, d *Virt
} }
// ShutdownVMAsync shuts down a virtual machine asynchronously. // ShutdownVMAsync shuts down a virtual machine asynchronously.
func (c *VirtualEnvironmentClient) ShutdownVMAsync(nodeName string, vmID int, d *VirtualEnvironmentVMShutdownRequestBody) (*string, error) { func (c *VirtualEnvironmentClient) ShutdownVMAsync(ctx context.Context, nodeName string, vmID int, d *VirtualEnvironmentVMShutdownRequestBody) (*string, error) {
resBody := &VirtualEnvironmentVMShutdownResponseBody{} resBody := &VirtualEnvironmentVMShutdownResponseBody{}
err := c.DoRequest(hmPOST, fmt.Sprintf("nodes/%s/qemu/%d/status/shutdown", url.PathEscape(nodeName), vmID), d, resBody) err := c.DoRequest(ctx, hmPOST, fmt.Sprintf("nodes/%s/qemu/%d/status/shutdown", url.PathEscape(nodeName), vmID), d, resBody)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if resBody.Data == nil { if resBody.Data == nil {
return nil, errors.New("The server did not include a data object in the response") return nil, errors.New("the server did not include a data object in the response")
} }
return resBody.Data, nil return resBody.Data, nil
} }
// StartVM starts a virtual machine. // StartVM starts a virtual machine.
func (c *VirtualEnvironmentClient) StartVM(nodeName string, vmID int, timeout int) error { func (c *VirtualEnvironmentClient) StartVM(ctx context.Context, nodeName string, vmID int, timeout int) error {
taskID, err := c.StartVMAsync(nodeName, vmID) taskID, err := c.StartVMAsync(ctx, nodeName, vmID)
if err != nil { if err != nil {
return err return err
} }
err = c.WaitForNodeTask(nodeName, *taskID, timeout, 5) err = c.WaitForNodeTask(ctx, nodeName, *taskID, timeout, 5)
if err != nil { if err != nil {
return err return err
@ -299,30 +313,30 @@ func (c *VirtualEnvironmentClient) StartVM(nodeName string, vmID int, timeout in
} }
// StartVMAsync starts a virtual machine asynchronously. // StartVMAsync starts a virtual machine asynchronously.
func (c *VirtualEnvironmentClient) StartVMAsync(nodeName string, vmID int) (*string, error) { func (c *VirtualEnvironmentClient) StartVMAsync(ctx context.Context, nodeName string, vmID int) (*string, error) {
resBody := &VirtualEnvironmentVMStartResponseBody{} resBody := &VirtualEnvironmentVMStartResponseBody{}
err := c.DoRequest(hmPOST, fmt.Sprintf("nodes/%s/qemu/%d/status/start", url.PathEscape(nodeName), vmID), nil, resBody) err := c.DoRequest(ctx, hmPOST, fmt.Sprintf("nodes/%s/qemu/%d/status/start", url.PathEscape(nodeName), vmID), nil, resBody)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if resBody.Data == nil { if resBody.Data == nil {
return nil, errors.New("The server did not include a data object in the response") return nil, errors.New("the server did not include a data object in the response")
} }
return resBody.Data, nil return resBody.Data, nil
} }
// StopVM stops a virtual machine. // StopVM stops a virtual machine.
func (c *VirtualEnvironmentClient) StopVM(nodeName string, vmID int, timeout int) error { func (c *VirtualEnvironmentClient) StopVM(ctx context.Context, nodeName string, vmID int, timeout int) error {
taskID, err := c.StopVMAsync(nodeName, vmID) taskID, err := c.StopVMAsync(ctx, nodeName, vmID)
if err != nil { if err != nil {
return err return err
} }
err = c.WaitForNodeTask(nodeName, *taskID, timeout, 5) err = c.WaitForNodeTask(ctx, nodeName, *taskID, timeout, 5)
if err != nil { if err != nil {
return err return err
@ -332,44 +346,44 @@ func (c *VirtualEnvironmentClient) StopVM(nodeName string, vmID int, timeout int
} }
// StopVMAsync stops a virtual machine asynchronously. // StopVMAsync stops a virtual machine asynchronously.
func (c *VirtualEnvironmentClient) StopVMAsync(nodeName string, vmID int) (*string, error) { func (c *VirtualEnvironmentClient) StopVMAsync(ctx context.Context, nodeName string, vmID int) (*string, error) {
resBody := &VirtualEnvironmentVMStopResponseBody{} resBody := &VirtualEnvironmentVMStopResponseBody{}
err := c.DoRequest(hmPOST, fmt.Sprintf("nodes/%s/qemu/%d/status/stop", url.PathEscape(nodeName), vmID), nil, resBody) err := c.DoRequest(ctx, hmPOST, fmt.Sprintf("nodes/%s/qemu/%d/status/stop", url.PathEscape(nodeName), vmID), nil, resBody)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if resBody.Data == nil { if resBody.Data == nil {
return nil, errors.New("The server did not include a data object in the response") return nil, errors.New("the server did not include a data object in the response")
} }
return resBody.Data, nil return resBody.Data, nil
} }
// UpdateVM updates a virtual machine. // UpdateVM updates a virtual machine.
func (c *VirtualEnvironmentClient) UpdateVM(nodeName string, vmID int, d *VirtualEnvironmentVMUpdateRequestBody) error { func (c *VirtualEnvironmentClient) UpdateVM(ctx context.Context, nodeName string, vmID int, d *VirtualEnvironmentVMUpdateRequestBody) error {
return c.DoRequest(hmPUT, fmt.Sprintf("nodes/%s/qemu/%d/config", url.PathEscape(nodeName), vmID), d, nil) return c.DoRequest(ctx, hmPUT, fmt.Sprintf("nodes/%s/qemu/%d/config", url.PathEscape(nodeName), vmID), d, nil)
} }
// UpdateVMAsync updates a virtual machine asynchronously. // UpdateVMAsync updates a virtual machine asynchronously.
func (c *VirtualEnvironmentClient) UpdateVMAsync(nodeName string, vmID int, d *VirtualEnvironmentVMUpdateRequestBody) (*string, error) { func (c *VirtualEnvironmentClient) UpdateVMAsync(ctx context.Context, nodeName string, vmID int, d *VirtualEnvironmentVMUpdateRequestBody) (*string, error) {
resBody := &VirtualEnvironmentVMUpdateAsyncResponseBody{} resBody := &VirtualEnvironmentVMUpdateAsyncResponseBody{}
err := c.DoRequest(hmPOST, fmt.Sprintf("nodes/%s/qemu/%d/config", url.PathEscape(nodeName), vmID), d, resBody) err := c.DoRequest(ctx, hmPOST, fmt.Sprintf("nodes/%s/qemu/%d/config", url.PathEscape(nodeName), vmID), d, resBody)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if resBody.Data == nil { if resBody.Data == nil {
return nil, errors.New("The server did not include a data object in the response") return nil, errors.New("the server did not include a data object in the response")
} }
return resBody.Data, nil return resBody.Data, nil
} }
// WaitForNetworkInterfacesFromVMAgent waits for a virtual machine's QEMU agent to publish the network interfaces. // WaitForNetworkInterfacesFromVMAgent waits for a virtual machine's QEMU agent to publish the network interfaces.
func (c *VirtualEnvironmentClient) WaitForNetworkInterfacesFromVMAgent(nodeName string, vmID int, timeout int, delay int, waitForIP bool) (*VirtualEnvironmentVMGetQEMUNetworkInterfacesResponseData, error) { func (c *VirtualEnvironmentClient) WaitForNetworkInterfacesFromVMAgent(ctx context.Context, nodeName string, vmID int, timeout int, delay int, waitForIP bool) (*VirtualEnvironmentVMGetQEMUNetworkInterfacesResponseData, error) {
timeDelay := int64(delay) timeDelay := int64(delay)
timeMax := float64(timeout) timeMax := float64(timeout)
timeStart := time.Now() timeStart := time.Now()
@ -377,7 +391,7 @@ func (c *VirtualEnvironmentClient) WaitForNetworkInterfacesFromVMAgent(nodeName
for timeElapsed.Seconds() < timeMax { for timeElapsed.Seconds() < timeMax {
if int64(timeElapsed.Seconds())%timeDelay == 0 { if int64(timeElapsed.Seconds())%timeDelay == 0 {
data, err := c.GetVMNetworkInterfacesFromAgent(nodeName, vmID) data, err := c.GetVMNetworkInterfacesFromAgent(ctx, nodeName, vmID)
if err == nil && data != nil && data.Result != nil { if err == nil && data != nil && data.Result != nil {
missingIP := false missingIP := false
@ -406,13 +420,17 @@ func (c *VirtualEnvironmentClient) WaitForNetworkInterfacesFromVMAgent(nodeName
time.Sleep(200 * time.Millisecond) time.Sleep(200 * time.Millisecond)
timeElapsed = time.Now().Sub(timeStart) timeElapsed = time.Now().Sub(timeStart)
if ctx.Err() != nil {
return nil, ctx.Err()
}
} }
return nil, fmt.Errorf("Timeout while waiting for the QEMU agent on VM \"%d\" to publish the network interfaces", vmID) return nil, fmt.Errorf("timeout while waiting for the QEMU agent on VM \"%d\" to publish the network interfaces", vmID)
} }
// WaitForNoNetworkInterfacesFromVMAgent waits for a virtual machine's QEMU agent to unpublish the network interfaces. // WaitForNoNetworkInterfacesFromVMAgent waits for a virtual machine's QEMU agent to unpublish the network interfaces.
func (c *VirtualEnvironmentClient) WaitForNoNetworkInterfacesFromVMAgent(nodeName string, vmID int, timeout int, delay int) error { func (c *VirtualEnvironmentClient) WaitForNoNetworkInterfacesFromVMAgent(ctx context.Context, nodeName string, vmID int, timeout int, delay int) error {
timeDelay := int64(delay) timeDelay := int64(delay)
timeMax := float64(timeout) timeMax := float64(timeout)
timeStart := time.Now() timeStart := time.Now()
@ -420,7 +438,7 @@ func (c *VirtualEnvironmentClient) WaitForNoNetworkInterfacesFromVMAgent(nodeNam
for timeElapsed.Seconds() < timeMax { for timeElapsed.Seconds() < timeMax {
if int64(timeElapsed.Seconds())%timeDelay == 0 { if int64(timeElapsed.Seconds())%timeDelay == 0 {
_, err := c.GetVMNetworkInterfacesFromAgent(nodeName, vmID) _, err := c.GetVMNetworkInterfacesFromAgent(ctx, nodeName, vmID)
if err != nil { if err != nil {
return nil return nil
@ -432,13 +450,17 @@ func (c *VirtualEnvironmentClient) WaitForNoNetworkInterfacesFromVMAgent(nodeNam
time.Sleep(200 * time.Millisecond) time.Sleep(200 * time.Millisecond)
timeElapsed = time.Now().Sub(timeStart) timeElapsed = time.Now().Sub(timeStart)
if ctx.Err() != nil {
return ctx.Err()
}
} }
return fmt.Errorf("Timeout while waiting for the QEMU agent on VM \"%d\" to unpublish the network interfaces", vmID) return fmt.Errorf("timeout while waiting for the QEMU agent on VM \"%d\" to unpublish the network interfaces", vmID)
} }
// WaitForVMConfigUnlock waits for a virtual machine configuration to become unlocked. // WaitForVMConfigUnlock waits for a virtual machine configuration to become unlocked.
func (c *VirtualEnvironmentClient) WaitForVMConfigUnlock(nodeName string, vmID int, timeout int, delay int, ignoreErrorResponse bool) error { func (c *VirtualEnvironmentClient) WaitForVMConfigUnlock(ctx context.Context, nodeName string, vmID int, timeout int, delay int, ignoreErrorResponse bool) error {
timeDelay := int64(delay) timeDelay := int64(delay)
timeMax := float64(timeout) timeMax := float64(timeout)
timeStart := time.Now() timeStart := time.Now()
@ -446,7 +468,7 @@ func (c *VirtualEnvironmentClient) WaitForVMConfigUnlock(nodeName string, vmID i
for timeElapsed.Seconds() < timeMax { for timeElapsed.Seconds() < timeMax {
if int64(timeElapsed.Seconds())%timeDelay == 0 { if int64(timeElapsed.Seconds())%timeDelay == 0 {
data, err := c.GetVMStatus(nodeName, vmID) data, err := c.GetVMStatus(ctx, nodeName, vmID)
if err != nil { if err != nil {
if !ignoreErrorResponse { if !ignoreErrorResponse {
@ -462,13 +484,17 @@ func (c *VirtualEnvironmentClient) WaitForVMConfigUnlock(nodeName string, vmID i
time.Sleep(200 * time.Millisecond) time.Sleep(200 * time.Millisecond)
timeElapsed = time.Now().Sub(timeStart) timeElapsed = time.Now().Sub(timeStart)
if ctx.Err() != nil {
return ctx.Err()
}
} }
return fmt.Errorf("Timeout while waiting for VM \"%d\" configuration to become unlocked", vmID) return fmt.Errorf("timeout while waiting for VM \"%d\" configuration to become unlocked", vmID)
} }
// WaitForVMState waits for a virtual machine to reach a specific state. // WaitForVMState waits for a virtual machine to reach a specific state.
func (c *VirtualEnvironmentClient) WaitForVMState(nodeName string, vmID int, state string, timeout int, delay int) error { func (c *VirtualEnvironmentClient) WaitForVMState(ctx context.Context, nodeName string, vmID int, state string, timeout int, delay int) error {
state = strings.ToLower(state) state = strings.ToLower(state)
timeDelay := int64(delay) timeDelay := int64(delay)
@ -478,8 +504,7 @@ func (c *VirtualEnvironmentClient) WaitForVMState(nodeName string, vmID int, sta
for timeElapsed.Seconds() < timeMax { for timeElapsed.Seconds() < timeMax {
if int64(timeElapsed.Seconds())%timeDelay == 0 { if int64(timeElapsed.Seconds())%timeDelay == 0 {
data, err := c.GetVMStatus(nodeName, vmID) data, err := c.GetVMStatus(ctx, nodeName, vmID)
if err != nil { if err != nil {
return err return err
} }
@ -494,7 +519,11 @@ func (c *VirtualEnvironmentClient) WaitForVMState(nodeName string, vmID int, sta
time.Sleep(200 * time.Millisecond) time.Sleep(200 * time.Millisecond)
timeElapsed = time.Now().Sub(timeStart) timeElapsed = time.Now().Sub(timeStart)
if ctx.Err() != nil {
return ctx.Err()
}
} }
return fmt.Errorf("Timeout while waiting for VM \"%d\" to enter the state \"%s\"", vmID, state) return fmt.Errorf("timeout while waiting for VM \"%d\" to enter the state \"%s\"", vmID, state)
} }

View File

@ -564,7 +564,7 @@ type VirtualEnvironmentVMUpdateRequestBody VirtualEnvironmentVMCreateRequestBody
// EncodeValues converts a CustomAgent struct to a URL vlaue. // EncodeValues converts a CustomAgent struct to a URL vlaue.
func (r CustomAgent) EncodeValues(key string, v *url.Values) error { func (r CustomAgent) EncodeValues(key string, v *url.Values) error {
values := []string{} var values []string
if r.Enabled != nil { if r.Enabled != nil {
if *r.Enabled { if *r.Enabled {
@ -610,7 +610,10 @@ func (r CustomAudioDevice) EncodeValues(key string, v *url.Values) error {
func (r CustomAudioDevices) EncodeValues(key string, v *url.Values) error { func (r CustomAudioDevices) EncodeValues(key string, v *url.Values) error {
for i, d := range r { for i, d := range r {
if d.Enabled { if d.Enabled {
d.EncodeValues(fmt.Sprintf("%s%d", key, i), v) err := d.EncodeValues(fmt.Sprintf("%s%d", key, i), v)
if err != nil {
return err
}
} }
} }
@ -618,9 +621,9 @@ func (r CustomAudioDevices) EncodeValues(key string, v *url.Values) error {
} }
// EncodeValues converts a CustomCloudInitConfig struct to multiple URL vlaues. // EncodeValues converts a CustomCloudInitConfig struct to multiple URL vlaues.
func (r CustomCloudInitConfig) EncodeValues(key string, v *url.Values) error { func (r CustomCloudInitConfig) EncodeValues(_ string, v *url.Values) error {
if r.Files != nil { if r.Files != nil {
volumes := []string{} var volumes []string
if r.Files.MetaVolume != nil { if r.Files.MetaVolume != nil {
volumes = append(volumes, fmt.Sprintf("meta=%s", *r.Files.MetaVolume)) volumes = append(volumes, fmt.Sprintf("meta=%s", *r.Files.MetaVolume))
@ -640,7 +643,7 @@ func (r CustomCloudInitConfig) EncodeValues(key string, v *url.Values) error {
} }
for i, c := range r.IPConfig { for i, c := range r.IPConfig {
config := []string{} var config []string
if c.GatewayIPv4 != nil { if c.GatewayIPv4 != nil {
config = append(config, fmt.Sprintf("gw=%s", *c.GatewayIPv4)) config = append(config, fmt.Sprintf("gw=%s", *c.GatewayIPv4))
@ -797,7 +800,10 @@ func (r CustomNetworkDevice) EncodeValues(key string, v *url.Values) error {
func (r CustomNetworkDevices) EncodeValues(key string, v *url.Values) error { func (r CustomNetworkDevices) EncodeValues(key string, v *url.Values) error {
for i, d := range r { for i, d := range r {
if d.Enabled { if d.Enabled {
d.EncodeValues(fmt.Sprintf("%s%d", key, i), v) err := d.EncodeValues(fmt.Sprintf("%s%d", key, i), v)
if err != nil {
return err
}
} }
} }
@ -830,7 +836,10 @@ func (r CustomNUMADevice) EncodeValues(key string, v *url.Values) error {
// EncodeValues converts a CustomNUMADevices array to multiple URL values. // EncodeValues converts a CustomNUMADevices array to multiple URL values.
func (r CustomNUMADevices) EncodeValues(key string, v *url.Values) error { func (r CustomNUMADevices) EncodeValues(key string, v *url.Values) error {
for i, d := range r { for i, d := range r {
d.EncodeValues(fmt.Sprintf("%s%d", key, i), v) err := d.EncodeValues(fmt.Sprintf("%s%d", key, i), v)
if err != nil {
return err
}
} }
return nil return nil
@ -882,7 +891,10 @@ func (r CustomPCIDevice) EncodeValues(key string, v *url.Values) error {
// EncodeValues converts a CustomPCIDevices array to multiple URL values. // EncodeValues converts a CustomPCIDevices array to multiple URL values.
func (r CustomPCIDevices) EncodeValues(key string, v *url.Values) error { func (r CustomPCIDevices) EncodeValues(key string, v *url.Values) error {
for i, d := range r { for i, d := range r {
d.EncodeValues(fmt.Sprintf("%s%d", key, i), v) err := d.EncodeValues(fmt.Sprintf("%s%d", key, i), v)
if err != nil {
return err
}
} }
return nil return nil
@ -914,7 +926,7 @@ func (r CustomSharedMemory) EncodeValues(key string, v *url.Values) error {
// EncodeValues converts a CustomSMBIOS struct to a URL vlaue. // EncodeValues converts a CustomSMBIOS struct to a URL vlaue.
func (r CustomSMBIOS) EncodeValues(key string, v *url.Values) error { func (r CustomSMBIOS) EncodeValues(key string, v *url.Values) error {
values := []string{} var values []string
if r.Base64 != nil { if r.Base64 != nil {
if *r.Base64 { if *r.Base64 {
@ -961,7 +973,7 @@ func (r CustomSMBIOS) EncodeValues(key string, v *url.Values) error {
// EncodeValues converts a CustomSpiceEnhancements struct to a URL vlaue. // EncodeValues converts a CustomSpiceEnhancements struct to a URL vlaue.
func (r CustomSpiceEnhancements) EncodeValues(key string, v *url.Values) error { func (r CustomSpiceEnhancements) EncodeValues(key string, v *url.Values) error {
values := []string{} var values []string
if r.FolderSharing != nil { if r.FolderSharing != nil {
if *r.FolderSharing { if *r.FolderSharing {
@ -984,7 +996,7 @@ func (r CustomSpiceEnhancements) EncodeValues(key string, v *url.Values) error {
// EncodeValues converts a CustomStartupOrder struct to a URL vlaue. // EncodeValues converts a CustomStartupOrder struct to a URL vlaue.
func (r CustomStartupOrder) EncodeValues(key string, v *url.Values) error { func (r CustomStartupOrder) EncodeValues(key string, v *url.Values) error {
values := []string{} var values []string
if r.Order != nil { if r.Order != nil {
values = append(values, fmt.Sprintf("order=%d", *r.Order)) values = append(values, fmt.Sprintf("order=%d", *r.Order))
@ -1053,10 +1065,13 @@ func (r CustomStorageDevice) EncodeValues(key string, v *url.Values) error {
} }
// EncodeValues converts a CustomStorageDevices array to multiple URL values. // EncodeValues converts a CustomStorageDevices array to multiple URL values.
func (r CustomStorageDevices) EncodeValues(key string, v *url.Values) error { func (r CustomStorageDevices) EncodeValues(_ string, v *url.Values) error {
for i, d := range r { for i, d := range r {
if d.Enabled { if d.Enabled {
d.EncodeValues(i, v) err := d.EncodeValues(i, v)
if err != nil {
return err
}
} }
} }
@ -1085,7 +1100,10 @@ func (r CustomUSBDevice) EncodeValues(key string, v *url.Values) error {
// EncodeValues converts a CustomUSBDevices array to multiple URL values. // EncodeValues converts a CustomUSBDevices array to multiple URL values.
func (r CustomUSBDevices) EncodeValues(key string, v *url.Values) error { func (r CustomUSBDevices) EncodeValues(key string, v *url.Values) error {
for i, d := range r { for i, d := range r {
d.EncodeValues(fmt.Sprintf("%s%d", key, i), v) err := d.EncodeValues(fmt.Sprintf("%s%d", key, i), v)
if err != nil {
return err
}
} }
return nil return nil
@ -1093,7 +1111,7 @@ func (r CustomUSBDevices) EncodeValues(key string, v *url.Values) error {
// EncodeValues converts a CustomVGADevice struct to a URL vlaue. // EncodeValues converts a CustomVGADevice struct to a URL vlaue.
func (r CustomVGADevice) EncodeValues(key string, v *url.Values) error { func (r CustomVGADevice) EncodeValues(key string, v *url.Values) error {
values := []string{} var values []string
if r.Memory != nil { if r.Memory != nil {
values = append(values, fmt.Sprintf("memory=%d", *r.Memory)) values = append(values, fmt.Sprintf("memory=%d", *r.Memory))
@ -1135,7 +1153,10 @@ func (r CustomVirtualIODevice) EncodeValues(key string, v *url.Values) error {
func (r CustomVirtualIODevices) EncodeValues(key string, v *url.Values) error { func (r CustomVirtualIODevices) EncodeValues(key string, v *url.Values) error {
for i, d := range r { for i, d := range r {
if d.Enabled { if d.Enabled {
d.EncodeValues(fmt.Sprintf("%s%d", key, i), v) err := d.EncodeValues(fmt.Sprintf("%s%d", key, i), v)
if err != nil {
return err
}
} }
} }
@ -1318,7 +1339,7 @@ func (r *CustomCPUEmulation) UnmarshalJSON(b []byte) error {
} }
if s == "" { if s == "" {
return errors.New("Unexpected empty string") return errors.New("unexpected empty string")
} }
pairs := strings.Split(s, ",") pairs := strings.Split(s, ",")
@ -1337,7 +1358,7 @@ func (r *CustomCPUEmulation) UnmarshalJSON(b []byte) error {
f := strings.Split(v[1], ";") f := strings.Split(v[1], ";")
r.Flags = &f r.Flags = &f
} else { } else {
f := []string{} var f []string
r.Flags = &f r.Flags = &f
} }
case "hidden": case "hidden":

View File

@ -5,7 +5,9 @@
package proxmoxtf package proxmoxtf
import ( import (
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "context"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
const ( const (
@ -35,34 +37,36 @@ func dataSourceVirtualEnvironmentClusterAlias() *schema.Resource {
Computed: true, Computed: true,
}, },
}, },
Read: dataSourceVirtualEnvironmentAliasRead, ReadContext: dataSourceVirtualEnvironmentAliasRead,
} }
} }
func dataSourceVirtualEnvironmentAliasRead(d *schema.ResourceData, m interface{}) error { func dataSourceVirtualEnvironmentAliasRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
var diags diag.Diagnostics
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
AliasID := d.Get(mkDataSourceVirtualEnvironmentClusterAliasName).(string) AliasID := d.Get(mkDataSourceVirtualEnvironmentClusterAliasName).(string)
Alias, err := veClient.GetAlias(AliasID) Alias, err := veClient.GetAlias(ctx, AliasID)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
d.SetId(AliasID) d.SetId(AliasID)
d.Set(mkDataSourceVirtualEnvironmentClusterAliasCIDR, Alias.CIDR) err = d.Set(mkDataSourceVirtualEnvironmentClusterAliasCIDR, Alias.CIDR)
diags = append(diags, diag.FromErr(err)...)
if Alias.Comment != nil { if Alias.Comment != nil {
d.Set(mkDataSourceVirtualEnvironmentClusterAliasComment, Alias.Comment) err = d.Set(mkDataSourceVirtualEnvironmentClusterAliasComment, Alias.Comment)
} else { } else {
d.Set(mkDataSourceVirtualEnvironmentClusterAliasComment, dvDataVirtualEnvironmentClusterAliasComment) err = d.Set(mkDataSourceVirtualEnvironmentClusterAliasComment, dvDataVirtualEnvironmentClusterAliasComment)
} }
diags = append(diags, diag.FromErr(err)...)
return nil return diags
} }

View File

@ -7,7 +7,7 @@ package proxmoxtf
import ( import (
"testing" "testing"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
// TestDataSourceVirtualEnvironmentAliasInstantiation tests whether the DataSourceVirtualEnvironmentAlias instance can be instantiated. // TestDataSourceVirtualEnvironmentAliasInstantiation tests whether the DataSourceVirtualEnvironmentAlias instance can be instantiated.

View File

@ -5,7 +5,9 @@
package proxmoxtf package proxmoxtf
import ( import (
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "context"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
const ( const (
@ -22,22 +24,20 @@ func dataSourceVirtualEnvironmentClusterAliases() *schema.Resource {
Elem: &schema.Schema{Type: schema.TypeString}, Elem: &schema.Schema{Type: schema.TypeString},
}, },
}, },
Read: dataSourceVirtualEnvironmentClusterAliasesRead, ReadContext: dataSourceVirtualEnvironmentClusterAliasesRead,
} }
} }
func dataSourceVirtualEnvironmentClusterAliasesRead(d *schema.ResourceData, m interface{}) error { func dataSourceVirtualEnvironmentClusterAliasesRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
list, err := veClient.ListPools() list, err := veClient.ListPools(ctx)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
aliasIDs := make([]interface{}, len(list)) aliasIDs := make([]interface{}, len(list))
@ -48,7 +48,7 @@ func dataSourceVirtualEnvironmentClusterAliasesRead(d *schema.ResourceData, m in
d.SetId("aliases") d.SetId("aliases")
d.Set(mkDataSourceVirtualEnvironmentClusterAliasesAliasIDs, aliasIDs) err = d.Set(mkDataSourceVirtualEnvironmentClusterAliasesAliasIDs, aliasIDs)
return nil return diag.FromErr(err)
} }

View File

@ -7,7 +7,7 @@ package proxmoxtf
import ( import (
"testing" "testing"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
// TestDataSourceVirtualEnvironmentAliasesInstantiation tests whether the DataSourceVirtualEnvironmentAliases instance can be instantiated. // TestDataSourceVirtualEnvironmentAliasesInstantiation tests whether the DataSourceVirtualEnvironmentAliases instance can be instantiated.

View File

@ -5,10 +5,12 @@
package proxmoxtf package proxmoxtf
import ( import (
"context"
"fmt" "fmt"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"sort" "sort"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
const ( const (
@ -87,26 +89,26 @@ func dataSourceVirtualEnvironmentDatastores() *schema.Resource {
Type: schema.TypeList, Type: schema.TypeList,
Description: "The storage type", Description: "The storage type",
Computed: true, Computed: true,
Elem: &schema.Schema{Type: schema.TypeInt}, Elem: &schema.Schema{Type: schema.TypeString},
}, },
}, },
Read: dataSourceVirtualEnvironmentDatastoresRead, ReadContext: dataSourceVirtualEnvironmentDatastoresRead,
} }
} }
func dataSourceVirtualEnvironmentDatastoresRead(d *schema.ResourceData, m interface{}) error { func dataSourceVirtualEnvironmentDatastoresRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
var diags diag.Diagnostics
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
nodeName := d.Get(mkDataSourceVirtualEnvironmentDatastoresNodeName).(string) nodeName := d.Get(mkDataSourceVirtualEnvironmentDatastoresNodeName).(string)
list, err := veClient.ListDatastores(nodeName, nil) list, err := veClient.ListDatastores(ctx, nodeName, nil)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
active := make([]interface{}, len(list)) active := make([]interface{}, len(list))
@ -149,19 +151,19 @@ func dataSourceVirtualEnvironmentDatastoresRead(d *schema.ResourceData, m interf
} }
if v.SpaceAvailable != nil { if v.SpaceAvailable != nil {
spaceAvailable[i] = int(*v.SpaceAvailable) spaceAvailable[i] = *v.SpaceAvailable
} else { } else {
spaceAvailable[i] = 0 spaceAvailable[i] = 0
} }
if v.SpaceTotal != nil { if v.SpaceTotal != nil {
spaceTotal[i] = int(*v.SpaceTotal) spaceTotal[i] = *v.SpaceTotal
} else { } else {
spaceTotal[i] = 0 spaceTotal[i] = 0
} }
if v.SpaceUsed != nil { if v.SpaceUsed != nil {
spaceUsed[i] = int(*v.SpaceUsed) spaceUsed[i] = *v.SpaceUsed
} else { } else {
spaceUsed[i] = 0 spaceUsed[i] = 0
} }
@ -171,15 +173,24 @@ func dataSourceVirtualEnvironmentDatastoresRead(d *schema.ResourceData, m interf
d.SetId(fmt.Sprintf("%s_datastores", nodeName)) d.SetId(fmt.Sprintf("%s_datastores", nodeName))
d.Set(mkDataSourceVirtualEnvironmentDatastoresActive, active) err = d.Set(mkDataSourceVirtualEnvironmentDatastoresActive, active)
d.Set(mkDataSourceVirtualEnvironmentDatastoresContentTypes, contentTypes) diags = append(diags, diag.FromErr(err)...)
d.Set(mkDataSourceVirtualEnvironmentDatastoresDatastoreIDs, datastoreIDs) err = d.Set(mkDataSourceVirtualEnvironmentDatastoresContentTypes, contentTypes)
d.Set(mkDataSourceVirtualEnvironmentDatastoresEnabled, enabled) diags = append(diags, diag.FromErr(err)...)
d.Set(mkDataSourceVirtualEnvironmentDatastoresShared, shared) err = d.Set(mkDataSourceVirtualEnvironmentDatastoresDatastoreIDs, datastoreIDs)
d.Set(mkDataSourceVirtualEnvironmentDatastoresSpaceAvailable, spaceAvailable) diags = append(diags, diag.FromErr(err)...)
d.Set(mkDataSourceVirtualEnvironmentDatastoresSpaceTotal, spaceTotal) err = d.Set(mkDataSourceVirtualEnvironmentDatastoresEnabled, enabled)
d.Set(mkDataSourceVirtualEnvironmentDatastoresSpaceUsed, spaceUsed) diags = append(diags, diag.FromErr(err)...)
d.Set(mkDataSourceVirtualEnvironmentDatastoresTypes, types) err = d.Set(mkDataSourceVirtualEnvironmentDatastoresShared, shared)
diags = append(diags, diag.FromErr(err)...)
err = d.Set(mkDataSourceVirtualEnvironmentDatastoresSpaceAvailable, spaceAvailable)
diags = append(diags, diag.FromErr(err)...)
err = d.Set(mkDataSourceVirtualEnvironmentDatastoresSpaceTotal, spaceTotal)
diags = append(diags, diag.FromErr(err)...)
err = d.Set(mkDataSourceVirtualEnvironmentDatastoresSpaceUsed, spaceUsed)
diags = append(diags, diag.FromErr(err)...)
err = d.Set(mkDataSourceVirtualEnvironmentDatastoresTypes, types)
diags = append(diags, diag.FromErr(err)...)
return nil return diags
} }

View File

@ -5,7 +5,7 @@
package proxmoxtf package proxmoxtf
import ( import (
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"testing" "testing"
) )

View File

@ -5,9 +5,11 @@
package proxmoxtf package proxmoxtf
import ( import (
"context"
"fmt" "fmt"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
const ( const (
@ -36,34 +38,35 @@ func dataSourceVirtualEnvironmentDNS() *schema.Resource {
Elem: &schema.Schema{Type: schema.TypeString}, Elem: &schema.Schema{Type: schema.TypeString},
}, },
}, },
Read: dataSourceVirtualEnvironmentDNSRead, ReadContext: dataSourceVirtualEnvironmentDNSRead,
} }
} }
func dataSourceVirtualEnvironmentDNSRead(d *schema.ResourceData, m interface{}) error { func dataSourceVirtualEnvironmentDNSRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
var diags diag.Diagnostics
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
nodeName := d.Get(mkDataSourceVirtualEnvironmentDNSNodeName).(string) nodeName := d.Get(mkDataSourceVirtualEnvironmentDNSNodeName).(string)
dns, err := veClient.GetDNS(nodeName) dns, err := veClient.GetDNS(ctx, nodeName)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
d.SetId(fmt.Sprintf("%s_dns", nodeName)) d.SetId(fmt.Sprintf("%s_dns", nodeName))
if dns.SearchDomain != nil { if dns.SearchDomain != nil {
d.Set(mkDataSourceVirtualEnvironmentDNSDomain, *dns.SearchDomain) err = d.Set(mkDataSourceVirtualEnvironmentDNSDomain, *dns.SearchDomain)
} else { } else {
d.Set(mkDataSourceVirtualEnvironmentDNSDomain, "") err = d.Set(mkDataSourceVirtualEnvironmentDNSDomain, "")
} }
diags = append(diags, diag.FromErr(err)...)
servers := []interface{}{} var servers []interface{}
if dns.Server1 != nil { if dns.Server1 != nil {
servers = append(servers, *dns.Server1) servers = append(servers, *dns.Server1)
@ -77,7 +80,8 @@ func dataSourceVirtualEnvironmentDNSRead(d *schema.ResourceData, m interface{})
servers = append(servers, *dns.Server3) servers = append(servers, *dns.Server3)
} }
d.Set(mkDataSourceVirtualEnvironmentDNSServers, servers) err = d.Set(mkDataSourceVirtualEnvironmentDNSServers, servers)
diags = append(diags, diag.FromErr(err)...)
return nil return diags
} }

View File

@ -5,7 +5,7 @@
package proxmoxtf package proxmoxtf
import ( import (
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"testing" "testing"
) )

View File

@ -5,7 +5,9 @@
package proxmoxtf package proxmoxtf
import ( import (
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "context"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
const ( const (
@ -62,34 +64,33 @@ func dataSourceVirtualEnvironmentGroup() *schema.Resource {
Elem: &schema.Schema{Type: schema.TypeString}, Elem: &schema.Schema{Type: schema.TypeString},
}, },
}, },
Read: dataSourceVirtualEnvironmentGroupRead, ReadContext: dataSourceVirtualEnvironmentGroupRead,
} }
} }
func dataSourceVirtualEnvironmentGroupRead(d *schema.ResourceData, m interface{}) error { func dataSourceVirtualEnvironmentGroupRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
var diags diag.Diagnostics
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
groupID := d.Get(mkDataSourceVirtualEnvironmentGroupID).(string) groupID := d.Get(mkDataSourceVirtualEnvironmentGroupID).(string)
group, err := veClient.GetGroup(groupID) group, err := veClient.GetGroup(ctx, groupID)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
acl, err := veClient.GetACL() acl, err := veClient.GetACL(ctx)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
d.SetId(groupID) d.SetId(groupID)
aclParsed := []interface{}{} var aclParsed []interface{}
for _, v := range acl { for _, v := range acl {
if v.Type == "group" && v.UserOrGroupID == groupID { if v.Type == "group" && v.UserOrGroupID == groupID {
@ -109,15 +110,18 @@ func dataSourceVirtualEnvironmentGroupRead(d *schema.ResourceData, m interface{}
} }
} }
d.Set(mkDataSourceVirtualEnvironmentGroupACL, aclParsed) err = d.Set(mkDataSourceVirtualEnvironmentGroupACL, aclParsed)
diags = append(diags, diag.FromErr(err)...)
if group.Comment != nil { if group.Comment != nil {
d.Set(mkDataSourceVirtualEnvironmentGroupComment, group.Comment) err = d.Set(mkDataSourceVirtualEnvironmentGroupComment, group.Comment)
} else { } else {
d.Set(mkDataSourceVirtualEnvironmentGroupComment, "") err = d.Set(mkDataSourceVirtualEnvironmentGroupComment, "")
} }
diags = append(diags, diag.FromErr(err)...)
d.Set(mkDataSourceVirtualEnvironmentGroupMembers, group.Members) err = d.Set(mkDataSourceVirtualEnvironmentGroupMembers, group.Members)
diags = append(diags, diag.FromErr(err)...)
return nil return diags
} }

View File

@ -7,7 +7,7 @@ package proxmoxtf
import ( import (
"testing" "testing"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
// TestDataSourceVirtualEnvironmentGroupInstantiation tests whether the DataSourceVirtualEnvironmentGroup instance can be instantiated. // TestDataSourceVirtualEnvironmentGroupInstantiation tests whether the DataSourceVirtualEnvironmentGroup instance can be instantiated.

View File

@ -5,7 +5,9 @@
package proxmoxtf package proxmoxtf
import ( import (
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "context"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
const ( const (
@ -29,22 +31,22 @@ func dataSourceVirtualEnvironmentGroups() *schema.Resource {
Elem: &schema.Schema{Type: schema.TypeString}, Elem: &schema.Schema{Type: schema.TypeString},
}, },
}, },
Read: dataSourceVirtualEnvironmentGroupsRead, ReadContext: dataSourceVirtualEnvironmentGroupsRead,
} }
} }
func dataSourceVirtualEnvironmentGroupsRead(d *schema.ResourceData, m interface{}) error { func dataSourceVirtualEnvironmentGroupsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
var diags diag.Diagnostics
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
list, err := veClient.ListGroups() list, err := veClient.ListGroups(ctx)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
comments := make([]interface{}, len(list)) comments := make([]interface{}, len(list))
@ -62,8 +64,10 @@ func dataSourceVirtualEnvironmentGroupsRead(d *schema.ResourceData, m interface{
d.SetId("groups") d.SetId("groups")
d.Set(mkDataSourceVirtualEnvironmentGroupsComments, comments) err = d.Set(mkDataSourceVirtualEnvironmentGroupsComments, comments)
d.Set(mkDataSourceVirtualEnvironmentGroupsGroupIDs, groupIDs) diags = append(diags, diag.FromErr(err)...)
err = d.Set(mkDataSourceVirtualEnvironmentGroupsGroupIDs, groupIDs)
diags = append(diags, diag.FromErr(err)...)
return nil return diags
} }

View File

@ -5,7 +5,7 @@
package proxmoxtf package proxmoxtf
import ( import (
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"testing" "testing"
) )

View File

@ -5,10 +5,12 @@
package proxmoxtf package proxmoxtf
import ( import (
"context"
"fmt" "fmt"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"strings" "strings"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
const ( const (
@ -70,31 +72,31 @@ func dataSourceVirtualEnvironmentHosts() *schema.Resource {
Required: true, Required: true,
}, },
}, },
Read: dataSourceVirtualEnvironmentHostsRead, ReadContext: dataSourceVirtualEnvironmentHostsRead,
} }
} }
func dataSourceVirtualEnvironmentHostsRead(d *schema.ResourceData, m interface{}) error { func dataSourceVirtualEnvironmentHostsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
var diags diag.Diagnostics
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
nodeName := d.Get(mkDataSourceVirtualEnvironmentHostsNodeName).(string) nodeName := d.Get(mkDataSourceVirtualEnvironmentHostsNodeName).(string)
hosts, err := veClient.GetHosts(nodeName) hosts, err := veClient.GetHosts(ctx, nodeName)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
d.SetId(fmt.Sprintf("%s_hosts", nodeName)) d.SetId(fmt.Sprintf("%s_hosts", nodeName))
// Parse the entries in the hosts file. // Parse the entries in the hosts file.
addresses := []interface{}{} var addresses []interface{}
entries := []interface{}{} var entries []interface{}
hostnames := []interface{}{} var hostnames []interface{}
lines := strings.Split(hosts.Data, "\n") lines := strings.Split(hosts.Data, "\n")
for _, line := range lines { for _, line := range lines {
@ -111,7 +113,7 @@ func dataSourceVirtualEnvironmentHostsRead(d *schema.ResourceData, m interface{}
addresses = append(addresses, values[0]) addresses = append(addresses, values[0])
entry := map[string]interface{}{} entry := map[string]interface{}{}
hostnamesForAddress := []interface{}{} var hostnamesForAddress []interface{}
for _, hostname := range values[1:] { for _, hostname := range values[1:] {
if hostname != "" { if hostname != "" {
@ -126,16 +128,20 @@ func dataSourceVirtualEnvironmentHostsRead(d *schema.ResourceData, m interface{}
hostnames = append(hostnames, hostnamesForAddress) hostnames = append(hostnames, hostnamesForAddress)
} }
d.Set(mkDataSourceVirtualEnvironmentHostsAddresses, addresses) err = d.Set(mkDataSourceVirtualEnvironmentHostsAddresses, addresses)
diags = append(diags, diag.FromErr(err)...)
if hosts.Digest != nil { if hosts.Digest != nil {
d.Set(mkDataSourceVirtualEnvironmentHostsDigest, *hosts.Digest) err = d.Set(mkDataSourceVirtualEnvironmentHostsDigest, *hosts.Digest)
} else { } else {
d.Set(mkDataSourceVirtualEnvironmentHostsDigest, "") err = d.Set(mkDataSourceVirtualEnvironmentHostsDigest, "")
} }
diags = append(diags, diag.FromErr(err)...)
d.Set(mkDataSourceVirtualEnvironmentHostsEntries, entries) err = d.Set(mkDataSourceVirtualEnvironmentHostsEntries, entries)
d.Set(mkDataSourceVirtualEnvironmentHostsHostnames, hostnames) diags = append(diags, diag.FromErr(err)...)
err = d.Set(mkDataSourceVirtualEnvironmentHostsHostnames, hostnames)
diags = append(diags, diag.FromErr(err)...)
return nil return diags
} }

View File

@ -5,7 +5,7 @@
package proxmoxtf package proxmoxtf
import ( import (
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"testing" "testing"
) )

View File

@ -5,9 +5,11 @@
package proxmoxtf package proxmoxtf
import ( import (
"context"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"math" "math"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
const ( const (
@ -80,22 +82,22 @@ func dataSourceVirtualEnvironmentNodes() *schema.Resource {
Elem: &schema.Schema{Type: schema.TypeString}, Elem: &schema.Schema{Type: schema.TypeString},
}, },
}, },
Read: dataSourceVirtualEnvironmentNodesRead, ReadContext: dataSourceVirtualEnvironmentNodesRead,
} }
} }
func dataSourceVirtualEnvironmentNodesRead(d *schema.ResourceData, m interface{}) error { func dataSourceVirtualEnvironmentNodesRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
var diags diag.Diagnostics
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
list, err := veClient.ListNodes() list, err := veClient.ListNodes(ctx)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
cpuCount := make([]interface{}, len(list)) cpuCount := make([]interface{}, len(list))
@ -162,15 +164,24 @@ func dataSourceVirtualEnvironmentNodesRead(d *schema.ResourceData, m interface{}
d.SetId("nodes") d.SetId("nodes")
d.Set(mkDataSourceVirtualEnvironmentNodesCPUCount, cpuCount) err = d.Set(mkDataSourceVirtualEnvironmentNodesCPUCount, cpuCount)
d.Set(mkDataSourceVirtualEnvironmentNodesCPUUtilization, cpuUtilization) diags = append(diags, diag.FromErr(err)...)
d.Set(mkDataSourceVirtualEnvironmentNodesMemoryAvailable, memoryAvailable) err = d.Set(mkDataSourceVirtualEnvironmentNodesCPUUtilization, cpuUtilization)
d.Set(mkDataSourceVirtualEnvironmentNodesMemoryUsed, memoryUsed) diags = append(diags, diag.FromErr(err)...)
d.Set(mkDataSourceVirtualEnvironmentNodesNames, name) err = d.Set(mkDataSourceVirtualEnvironmentNodesMemoryAvailable, memoryAvailable)
d.Set(mkDataSourceVirtualEnvironmentNodesOnline, online) diags = append(diags, diag.FromErr(err)...)
d.Set(mkDataSourceVirtualEnvironmentNodesSSLFingerprints, sslFingerprints) err = d.Set(mkDataSourceVirtualEnvironmentNodesMemoryUsed, memoryUsed)
d.Set(mkDataSourceVirtualEnvironmentNodesSupportLevels, supportLevels) diags = append(diags, diag.FromErr(err)...)
d.Set(mkDataSourceVirtualEnvironmentNodesUptime, uptime) err = d.Set(mkDataSourceVirtualEnvironmentNodesNames, name)
diags = append(diags, diag.FromErr(err)...)
err = d.Set(mkDataSourceVirtualEnvironmentNodesOnline, online)
diags = append(diags, diag.FromErr(err)...)
err = d.Set(mkDataSourceVirtualEnvironmentNodesSSLFingerprints, sslFingerprints)
diags = append(diags, diag.FromErr(err)...)
err = d.Set(mkDataSourceVirtualEnvironmentNodesSupportLevels, supportLevels)
diags = append(diags, diag.FromErr(err)...)
err = d.Set(mkDataSourceVirtualEnvironmentNodesUptime, uptime)
diags = append(diags, diag.FromErr(err)...)
return nil return nil
} }

View File

@ -7,7 +7,7 @@ package proxmoxtf
import ( import (
"testing" "testing"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
// TestDataSourceVirtualEnvironmentNodesInstantiation tests whether the DataSourceVirtualEnvironmentNodes instance can be instantiated. // TestDataSourceVirtualEnvironmentNodesInstantiation tests whether the DataSourceVirtualEnvironmentNodes instance can be instantiated.

View File

@ -5,7 +5,9 @@
package proxmoxtf package proxmoxtf
import ( import (
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "context"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
const ( const (
@ -67,32 +69,33 @@ func dataSourceVirtualEnvironmentPool() *schema.Resource {
Required: true, Required: true,
}, },
}, },
Read: dataSourceVirtualEnvironmentPoolRead, ReadContext: dataSourceVirtualEnvironmentPoolRead,
} }
} }
func dataSourceVirtualEnvironmentPoolRead(d *schema.ResourceData, m interface{}) error { func dataSourceVirtualEnvironmentPoolRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
var diags diag.Diagnostics
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
poolID := d.Get(mkDataSourceVirtualEnvironmentPoolPoolID).(string) poolID := d.Get(mkDataSourceVirtualEnvironmentPoolPoolID).(string)
pool, err := veClient.GetPool(poolID) pool, err := veClient.GetPool(ctx, poolID)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
d.SetId(poolID) d.SetId(poolID)
if pool.Comment != nil { if pool.Comment != nil {
d.Set(mkDataSourceVirtualEnvironmentPoolComment, pool.Comment) err = d.Set(mkDataSourceVirtualEnvironmentPoolComment, pool.Comment)
} else { } else {
d.Set(mkDataSourceVirtualEnvironmentPoolComment, "") err = d.Set(mkDataSourceVirtualEnvironmentPoolComment, "")
} }
diags = append(diags, diag.FromErr(err)...)
members := make([]interface{}, len(pool.Members)) members := make([]interface{}, len(pool.Members))
@ -119,7 +122,8 @@ func dataSourceVirtualEnvironmentPoolRead(d *schema.ResourceData, m interface{})
members[i] = values members[i] = values
} }
d.Set(mkDataSourceVirtualEnvironmentPoolMembers, members) err = d.Set(mkDataSourceVirtualEnvironmentPoolMembers, members)
diags = append(diags, diag.FromErr(err)...)
return nil return diags
} }

View File

@ -7,7 +7,7 @@ package proxmoxtf
import ( import (
"testing" "testing"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
// TestDataSourceVirtualEnvironmentPoolInstantiation tests whether the DataSourceVirtualEnvironmentPool instance can be instantiated. // TestDataSourceVirtualEnvironmentPoolInstantiation tests whether the DataSourceVirtualEnvironmentPool instance can be instantiated.

View File

@ -5,7 +5,9 @@
package proxmoxtf package proxmoxtf
import ( import (
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "context"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
const ( const (
@ -22,22 +24,20 @@ func dataSourceVirtualEnvironmentPools() *schema.Resource {
Elem: &schema.Schema{Type: schema.TypeString}, Elem: &schema.Schema{Type: schema.TypeString},
}, },
}, },
Read: dataSourceVirtualEnvironmentPoolsRead, ReadContext: dataSourceVirtualEnvironmentPoolsRead,
} }
} }
func dataSourceVirtualEnvironmentPoolsRead(d *schema.ResourceData, m interface{}) error { func dataSourceVirtualEnvironmentPoolsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
list, err := veClient.ListPools() list, err := veClient.ListPools(ctx)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
poolIDs := make([]interface{}, len(list)) poolIDs := make([]interface{}, len(list))
@ -48,7 +48,7 @@ func dataSourceVirtualEnvironmentPoolsRead(d *schema.ResourceData, m interface{}
d.SetId("pools") d.SetId("pools")
d.Set(mkDataSourceVirtualEnvironmentPoolsPoolIDs, poolIDs) err = d.Set(mkDataSourceVirtualEnvironmentPoolsPoolIDs, poolIDs)
return nil return diag.FromErr(err)
} }

View File

@ -7,7 +7,7 @@ package proxmoxtf
import ( import (
"testing" "testing"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
// TestDataSourceVirtualEnvironmentPoolsInstantiation tests whether the DataSourceVirtualEnvironmentPools instance can be instantiated. // TestDataSourceVirtualEnvironmentPoolsInstantiation tests whether the DataSourceVirtualEnvironmentPools instance can be instantiated.

View File

@ -5,7 +5,9 @@
package proxmoxtf package proxmoxtf
import ( import (
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "context"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
const ( const (
@ -28,23 +30,21 @@ func dataSourceVirtualEnvironmentRole() *schema.Resource {
Elem: &schema.Schema{Type: schema.TypeString}, Elem: &schema.Schema{Type: schema.TypeString},
}, },
}, },
Read: dataSourceVirtualEnvironmentRoleRead, ReadContext: dataSourceVirtualEnvironmentRoleRead,
} }
} }
func dataSourceVirtualEnvironmentRoleRead(d *schema.ResourceData, m interface{}) error { func dataSourceVirtualEnvironmentRoleRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
roleID := d.Get(mkDataSourceVirtualEnvironmentRoleID).(string) roleID := d.Get(mkDataSourceVirtualEnvironmentRoleID).(string)
accessRole, err := veClient.GetRole(roleID) accessRole, err := veClient.GetRole(ctx, roleID)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
privileges := schema.NewSet(schema.HashString, []interface{}{}) privileges := schema.NewSet(schema.HashString, []interface{}{})
@ -57,7 +57,7 @@ func dataSourceVirtualEnvironmentRoleRead(d *schema.ResourceData, m interface{})
d.SetId(roleID) d.SetId(roleID)
d.Set(mkDataSourceVirtualEnvironmentRolePrivileges, privileges) err = d.Set(mkDataSourceVirtualEnvironmentRolePrivileges, privileges)
return nil return diag.FromErr(err)
} }

View File

@ -7,7 +7,7 @@ package proxmoxtf
import ( import (
"testing" "testing"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
// TestDataSourceVirtualEnvironmentRoleInstantiation tests whether the DataSourceVirtualEnvironmentRole instance can be instantiated. // TestDataSourceVirtualEnvironmentRoleInstantiation tests whether the DataSourceVirtualEnvironmentRole instance can be instantiated.

View File

@ -5,7 +5,9 @@
package proxmoxtf package proxmoxtf
import ( import (
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "context"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
const ( const (
@ -39,22 +41,22 @@ func dataSourceVirtualEnvironmentRoles() *schema.Resource {
Elem: &schema.Schema{Type: schema.TypeBool}, Elem: &schema.Schema{Type: schema.TypeBool},
}, },
}, },
Read: dataSourceVirtualEnvironmentRolesRead, ReadContext: dataSourceVirtualEnvironmentRolesRead,
} }
} }
func dataSourceVirtualEnvironmentRolesRead(d *schema.ResourceData, m interface{}) error { func dataSourceVirtualEnvironmentRolesRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
var diags diag.Diagnostics
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
list, err := veClient.ListRoles() list, err := veClient.ListRoles(ctx)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
privileges := make([]interface{}, len(list)) privileges := make([]interface{}, len(list))
@ -85,9 +87,12 @@ func dataSourceVirtualEnvironmentRolesRead(d *schema.ResourceData, m interface{}
d.SetId("roles") d.SetId("roles")
d.Set(mkDataSourceVirtualEnvironmentRolesPrivileges, privileges) err = d.Set(mkDataSourceVirtualEnvironmentRolesPrivileges, privileges)
d.Set(mkDataSourceVirtualEnvironmentRolesRoleIDs, roleIDs) diags = append(diags, diag.FromErr(err)...)
d.Set(mkDataSourceVirtualEnvironmentRolesSpecial, special) err = d.Set(mkDataSourceVirtualEnvironmentRolesRoleIDs, roleIDs)
diags = append(diags, diag.FromErr(err)...)
err = d.Set(mkDataSourceVirtualEnvironmentRolesSpecial, special)
diags = append(diags, diag.FromErr(err)...)
return nil return diags
} }

View File

@ -5,7 +5,7 @@
package proxmoxtf package proxmoxtf
import ( import (
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"testing" "testing"
) )

View File

@ -5,10 +5,12 @@
package proxmoxtf package proxmoxtf
import ( import (
"context"
"fmt" "fmt"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"time" "time"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
const ( const (
@ -42,29 +44,28 @@ func dataSourceVirtualEnvironmentTime() *schema.Resource {
Computed: true, Computed: true,
}, },
}, },
Read: dataSourceVirtualEnvironmentTimeRead, ReadContext: dataSourceVirtualEnvironmentTimeRead,
} }
} }
func dataSourceVirtualEnvironmentTimeRead(d *schema.ResourceData, m interface{}) error { func dataSourceVirtualEnvironmentTimeRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
var diags diag.Diagnostics
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
nodeName := d.Get(mkDataSourceVirtualEnvironmentTimeNodeName).(string) nodeName := d.Get(mkDataSourceVirtualEnvironmentTimeNodeName).(string)
nodeTime, err := veClient.GetNodeTime(nodeName) nodeTime, err := veClient.GetNodeTime(ctx, nodeName)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
localLocation, err := time.LoadLocation(nodeTime.TimeZone) localLocation, err := time.LoadLocation(nodeTime.TimeZone)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
d.SetId(fmt.Sprintf("%s_time", nodeName)) d.SetId(fmt.Sprintf("%s_time", nodeName))
@ -72,9 +73,12 @@ func dataSourceVirtualEnvironmentTimeRead(d *schema.ResourceData, m interface{})
localTimeOffset := time.Time(nodeTime.LocalTime).Sub(time.Now().UTC()) localTimeOffset := time.Time(nodeTime.LocalTime).Sub(time.Now().UTC())
localTime := time.Time(nodeTime.LocalTime).Add(-localTimeOffset).In(localLocation) localTime := time.Time(nodeTime.LocalTime).Add(-localTimeOffset).In(localLocation)
d.Set(mkDataSourceVirtualEnvironmentTimeLocalTime, localTime.Format(time.RFC3339)) err = d.Set(mkDataSourceVirtualEnvironmentTimeLocalTime, localTime.Format(time.RFC3339))
d.Set(mkDataSourceVirtualEnvironmentTimeTimeZone, nodeTime.TimeZone) diags = append(diags, diag.FromErr(err)...)
d.Set(mkDataSourceVirtualEnvironmentTimeUTCTime, time.Time(nodeTime.UTCTime).Format(time.RFC3339)) err = d.Set(mkDataSourceVirtualEnvironmentTimeTimeZone, nodeTime.TimeZone)
diags = append(diags, diag.FromErr(err)...)
err = d.Set(mkDataSourceVirtualEnvironmentTimeUTCTime, time.Time(nodeTime.UTCTime).Format(time.RFC3339))
diags = append(diags, diag.FromErr(err)...)
return nil return diags
} }

View File

@ -7,7 +7,7 @@ package proxmoxtf
import ( import (
"testing" "testing"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
// TestDataSourceVirtualEnvironmentTimeInstantiation tests whether the DataSourceVirtualEnvironmentRoles instance can be instantiated. // TestDataSourceVirtualEnvironmentTimeInstantiation tests whether the DataSourceVirtualEnvironmentRoles instance can be instantiated.

View File

@ -5,9 +5,11 @@
package proxmoxtf package proxmoxtf
import ( import (
"context"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"time" "time"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
const ( const (
@ -100,34 +102,33 @@ func dataSourceVirtualEnvironmentUser() *schema.Resource {
Required: true, Required: true,
}, },
}, },
Read: dataSourceVirtualEnvironmentUserRead, ReadContext: dataSourceVirtualEnvironmentUserRead,
} }
} }
func dataSourceVirtualEnvironmentUserRead(d *schema.ResourceData, m interface{}) error { func dataSourceVirtualEnvironmentUserRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
var diags diag.Diagnostics
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
userID := d.Get(mkDataSourceVirtualEnvironmentUserUserID).(string) userID := d.Get(mkDataSourceVirtualEnvironmentUserUserID).(string)
v, err := veClient.GetUser(userID) v, err := veClient.GetUser(ctx, userID)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
acl, err := veClient.GetACL() acl, err := veClient.GetACL(ctx)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
d.SetId(userID) d.SetId(userID)
aclParsed := []interface{}{} var aclParsed []interface{}
for _, v := range acl { for _, v := range acl {
if v.Type == "user" && v.UserOrGroupID == userID { if v.Type == "user" && v.UserOrGroupID == userID {
@ -147,61 +148,69 @@ func dataSourceVirtualEnvironmentUserRead(d *schema.ResourceData, m interface{})
} }
} }
d.Set(mkDataSourceVirtualEnvironmentUserACL, aclParsed) err = d.Set(mkDataSourceVirtualEnvironmentUserACL, aclParsed)
diags = append(diags, diag.FromErr(err)...)
if v.Comment != nil { if v.Comment != nil {
d.Set(mkDataSourceVirtualEnvironmentUserComment, v.Comment) err = d.Set(mkDataSourceVirtualEnvironmentUserComment, v.Comment)
} else { } else {
d.Set(mkDataSourceVirtualEnvironmentUserComment, "") err = d.Set(mkDataSourceVirtualEnvironmentUserComment, "")
} }
diags = append(diags, diag.FromErr(err)...)
if v.Email != nil { if v.Email != nil {
d.Set(mkDataSourceVirtualEnvironmentUserEmail, v.Email) err = d.Set(mkDataSourceVirtualEnvironmentUserEmail, v.Email)
} else { } else {
d.Set(mkDataSourceVirtualEnvironmentUserEmail, "") err = d.Set(mkDataSourceVirtualEnvironmentUserEmail, "")
} }
diags = append(diags, diag.FromErr(err)...)
if v.Enabled != nil { if v.Enabled != nil {
d.Set(mkDataSourceVirtualEnvironmentUserEnabled, v.Enabled) err = d.Set(mkDataSourceVirtualEnvironmentUserEnabled, v.Enabled)
} else { } else {
d.Set(mkDataSourceVirtualEnvironmentUserEnabled, true) err = d.Set(mkDataSourceVirtualEnvironmentUserEnabled, true)
} }
diags = append(diags, diag.FromErr(err)...)
if v.ExpirationDate != nil { if v.ExpirationDate != nil {
t := time.Time(*v.ExpirationDate) t := time.Time(*v.ExpirationDate)
if t.Unix() > 0 { if t.Unix() > 0 {
d.Set(mkDataSourceVirtualEnvironmentUserExpirationDate, t.UTC().Format(time.RFC3339)) err = d.Set(mkDataSourceVirtualEnvironmentUserExpirationDate, t.UTC().Format(time.RFC3339))
} else { } else {
d.Set(mkDataSourceVirtualEnvironmentUserExpirationDate, time.Unix(0, 0).UTC().Format(time.RFC3339)) err = d.Set(mkDataSourceVirtualEnvironmentUserExpirationDate, time.Unix(0, 0).UTC().Format(time.RFC3339))
} }
} else { } else {
d.Set(mkDataSourceVirtualEnvironmentUserExpirationDate, time.Unix(0, 0).UTC().Format(time.RFC3339)) err = d.Set(mkDataSourceVirtualEnvironmentUserExpirationDate, time.Unix(0, 0).UTC().Format(time.RFC3339))
} }
diags = append(diags, diag.FromErr(err)...)
if v.FirstName != nil { if v.FirstName != nil {
d.Set(mkDataSourceVirtualEnvironmentUserFirstName, v.FirstName) err = d.Set(mkDataSourceVirtualEnvironmentUserFirstName, v.FirstName)
} else { } else {
d.Set(mkDataSourceVirtualEnvironmentUserFirstName, "") err = d.Set(mkDataSourceVirtualEnvironmentUserFirstName, "")
} }
diags = append(diags, diag.FromErr(err)...)
if v.Groups != nil { if v.Groups != nil {
d.Set(mkDataSourceVirtualEnvironmentUserGroups, v.Groups) err = d.Set(mkDataSourceVirtualEnvironmentUserGroups, v.Groups)
} else { } else {
d.Set(mkDataSourceVirtualEnvironmentUserGroups, "") err = d.Set(mkDataSourceVirtualEnvironmentUserGroups, []string{})
} }
diags = append(diags, diag.FromErr(err)...)
if v.Keys != nil { if v.Keys != nil {
d.Set(mkDataSourceVirtualEnvironmentUserGroups, v.Keys) err = d.Set(mkDataSourceVirtualEnvironmentUsersKeys, v.Keys)
} else { } else {
d.Set(mkDataSourceVirtualEnvironmentUserGroups, "") err = d.Set(mkDataSourceVirtualEnvironmentUsersKeys, "")
} }
diags = append(diags, diag.FromErr(err)...)
if v.LastName != nil { if v.LastName != nil {
d.Set(mkDataSourceVirtualEnvironmentUserLastName, v.LastName) err = d.Set(mkDataSourceVirtualEnvironmentUserLastName, v.LastName)
} else { } else {
d.Set(mkDataSourceVirtualEnvironmentUserLastName, "") err = d.Set(mkDataSourceVirtualEnvironmentUserLastName, "")
} }
diags = append(diags, diag.FromErr(err)...)
return nil return diags
} }

View File

@ -7,7 +7,7 @@ package proxmoxtf
import ( import (
"testing" "testing"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
// TestDataSourceVirtualEnvironmentUserInstantiation tests whether the DataSourceVirtualEnvironmentUser instance can be instantiated. // TestDataSourceVirtualEnvironmentUserInstantiation tests whether the DataSourceVirtualEnvironmentUser instance can be instantiated.

View File

@ -5,9 +5,11 @@
package proxmoxtf package proxmoxtf
import ( import (
"context"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"time" "time"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
const ( const (
@ -83,22 +85,22 @@ func dataSourceVirtualEnvironmentUsers() *schema.Resource {
Elem: &schema.Schema{Type: schema.TypeString}, Elem: &schema.Schema{Type: schema.TypeString},
}, },
}, },
Read: dataSourceVirtualEnvironmentUsersRead, ReadContext: dataSourceVirtualEnvironmentUsersRead,
} }
} }
func dataSourceVirtualEnvironmentUsersRead(d *schema.ResourceData, m interface{}) error { func dataSourceVirtualEnvironmentUsersRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
var diags diag.Diagnostics
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
list, err := veClient.ListUsers() list, err := veClient.ListUsers(ctx)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
comments := make([]interface{}, len(list)) comments := make([]interface{}, len(list))
@ -171,15 +173,24 @@ func dataSourceVirtualEnvironmentUsersRead(d *schema.ResourceData, m interface{}
d.SetId("users") d.SetId("users")
d.Set(mkDataSourceVirtualEnvironmentUsersComments, comments) err = d.Set(mkDataSourceVirtualEnvironmentUsersComments, comments)
d.Set(mkDataSourceVirtualEnvironmentUsersEmails, emails) diags = append(diags, diag.FromErr(err)...)
d.Set(mkDataSourceVirtualEnvironmentUsersEnabled, enabled) err = d.Set(mkDataSourceVirtualEnvironmentUsersEmails, emails)
d.Set(mkDataSourceVirtualEnvironmentUsersExpirationDates, expirationDates) diags = append(diags, diag.FromErr(err)...)
d.Set(mkDataSourceVirtualEnvironmentUsersFirstNames, firstNames) err = d.Set(mkDataSourceVirtualEnvironmentUsersEnabled, enabled)
d.Set(mkDataSourceVirtualEnvironmentUsersGroups, groups) diags = append(diags, diag.FromErr(err)...)
d.Set(mkDataSourceVirtualEnvironmentUsersKeys, keys) err = d.Set(mkDataSourceVirtualEnvironmentUsersExpirationDates, expirationDates)
d.Set(mkDataSourceVirtualEnvironmentUsersLastNames, lastNames) diags = append(diags, diag.FromErr(err)...)
d.Set(mkDataSourceVirtualEnvironmentUsersUserIDs, userIDs) err = d.Set(mkDataSourceVirtualEnvironmentUsersFirstNames, firstNames)
diags = append(diags, diag.FromErr(err)...)
err = d.Set(mkDataSourceVirtualEnvironmentUsersGroups, groups)
diags = append(diags, diag.FromErr(err)...)
err = d.Set(mkDataSourceVirtualEnvironmentUsersKeys, keys)
diags = append(diags, diag.FromErr(err)...)
err = d.Set(mkDataSourceVirtualEnvironmentUsersLastNames, lastNames)
diags = append(diags, diag.FromErr(err)...)
err = d.Set(mkDataSourceVirtualEnvironmentUsersUserIDs, userIDs)
diags = append(diags, diag.FromErr(err)...)
return nil return diags
} }

View File

@ -7,7 +7,7 @@ package proxmoxtf
import ( import (
"testing" "testing"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
// TestDataSourceVirtualEnvironmentUsersInstantiation tests whether the DataSourceVirtualEnvironmentUsers instance can be instantiated. // TestDataSourceVirtualEnvironmentUsersInstantiation tests whether the DataSourceVirtualEnvironmentUsers instance can be instantiated.

View File

@ -5,7 +5,9 @@
package proxmoxtf package proxmoxtf
import ( import (
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "context"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
const ( const (
@ -43,30 +45,34 @@ func dataSourceVirtualEnvironmentVersion() *schema.Resource {
ForceNew: true, ForceNew: true,
}, },
}, },
Read: dataSourceVirtualEnvironmentVersionRead, ReadContext: dataSourceVirtualEnvironmentVersionRead,
} }
} }
func dataSourceVirtualEnvironmentVersionRead(d *schema.ResourceData, m interface{}) error { func dataSourceVirtualEnvironmentVersionRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
var diags diag.Diagnostics
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
version, err := veClient.Version() version, err := veClient.Version(ctx)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
d.SetId("version") d.SetId("version")
d.Set(mkDataSourceVirtualEnvironmentVersionKeyboardLayout, version.Keyboard) err = d.Set(mkDataSourceVirtualEnvironmentVersionKeyboardLayout, version.Keyboard)
d.Set(mkDataSourceVirtualEnvironmentVersionRelease, version.Release) diags = append(diags, diag.FromErr(err)...)
d.Set(mkDataSourceVirtualEnvironmentVersionRepositoryID, version.RepositoryID) err = d.Set(mkDataSourceVirtualEnvironmentVersionRelease, version.Release)
d.Set(mkDataSourceVirtualEnvironmentVersionVersion, version.Version) diags = append(diags, diag.FromErr(err)...)
err = d.Set(mkDataSourceVirtualEnvironmentVersionRepositoryID, version.RepositoryID)
diags = append(diags, diag.FromErr(err)...)
err = d.Set(mkDataSourceVirtualEnvironmentVersionVersion, version.Version)
diags = append(diags, diag.FromErr(err)...)
return nil return diags
} }

View File

@ -7,7 +7,7 @@ package proxmoxtf
import ( import (
"testing" "testing"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
// TestDataSourceVirtualEnvironmentVersionInstantiation tests whether the DataSourceVirtualEnvironmentVersion instance can be instantiated. // TestDataSourceVirtualEnvironmentVersionInstantiation tests whether the DataSourceVirtualEnvironmentVersion instance can be instantiated.

View File

@ -5,12 +5,14 @@
package proxmoxtf package proxmoxtf
import ( import (
"context"
"errors" "errors"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"net/url" "net/url"
"os" "os"
"github.com/bpg/terraform-provider-proxmox/proxmox" "github.com/bpg/terraform-provider-proxmox/proxmox"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
const ( const (
@ -34,7 +36,7 @@ type providerConfiguration struct {
// Provider returns the object for this provider. // Provider returns the object for this provider.
func Provider() *schema.Provider { func Provider() *schema.Provider {
return &schema.Provider{ return &schema.Provider{
ConfigureFunc: providerConfigure, ConfigureContextFunc: providerConfigure,
DataSourcesMap: map[string]*schema.Resource{ DataSourcesMap: map[string]*schema.Resource{
"proxmox_virtual_environment_cluster_alias": dataSourceVirtualEnvironmentClusterAlias(), "proxmox_virtual_environment_cluster_alias": dataSourceVirtualEnvironmentClusterAlias(),
"proxmox_virtual_environment_cluster_aliases": dataSourceVirtualEnvironmentClusterAliases(), "proxmox_virtual_environment_cluster_aliases": dataSourceVirtualEnvironmentClusterAliases(),
@ -87,7 +89,7 @@ func Provider() *schema.Provider {
if value == "" { if value == "" {
return []string{}, []error{ return []string{}, []error{
errors.New("You must specify an endpoint for the Proxmox Virtual Environment API (valid: https://host:port)"), errors.New("you must specify an endpoint for the Proxmox Virtual Environment API (valid: https://host:port)"),
} }
} }
@ -95,7 +97,7 @@ func Provider() *schema.Provider {
if err != nil { if err != nil {
return []string{}, []error{ return []string{}, []error{
errors.New("You must specify a valid endpoint for the Proxmox Virtual Environment API (valid: https://host:port)"), errors.New("you must specify a valid endpoint for the Proxmox Virtual Environment API (valid: https://host:port)"),
} }
} }
@ -140,7 +142,7 @@ func Provider() *schema.Provider {
if value == "" { if value == "" {
return []string{}, []error{ return []string{}, []error{
errors.New("You must specify a password for the Proxmox Virtual Environment API"), errors.New("you must specify a password for the Proxmox Virtual Environment API"),
} }
} }
@ -160,7 +162,7 @@ func Provider() *schema.Provider {
if value == "" { if value == "" {
return []string{}, []error{ return []string{}, []error{
errors.New("You must specify a username for the Proxmox Virtual Environment API (valid: username@realm)"), errors.New("you must specify a username for the Proxmox Virtual Environment API (valid: username@realm)"),
} }
} }
@ -175,7 +177,7 @@ func Provider() *schema.Provider {
} }
} }
func providerConfigure(d *schema.ResourceData) (interface{}, error) { func providerConfigure(_ context.Context, d *schema.ResourceData) (interface{}, diag.Diagnostics) {
var err error var err error
var veClient *proxmox.VirtualEnvironmentClient var veClient *proxmox.VirtualEnvironmentClient
@ -192,9 +194,8 @@ func providerConfigure(d *schema.ResourceData) (interface{}, error) {
veConfig[mkProviderVirtualEnvironmentOTP].(string), veConfig[mkProviderVirtualEnvironmentOTP].(string),
veConfig[mkProviderVirtualEnvironmentInsecure].(bool), veConfig[mkProviderVirtualEnvironmentInsecure].(bool),
) )
if err != nil { if err != nil {
return nil, err return nil, diag.FromErr(err)
} }
} }
@ -207,7 +208,7 @@ func providerConfigure(d *schema.ResourceData) (interface{}, error) {
func (c *providerConfiguration) GetVEClient() (*proxmox.VirtualEnvironmentClient, error) { func (c *providerConfiguration) GetVEClient() (*proxmox.VirtualEnvironmentClient, error) {
if c.veClient == nil { if c.veClient == nil {
return nil, errors.New("You must specify the virtual environment details in the provider configuration") return nil, errors.New("you must specify the virtual environment details in the provider configuration")
} }
return c.veClient, nil return c.veClient, nil

View File

@ -7,7 +7,7 @@ package proxmoxtf
import ( import (
"testing" "testing"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
// TestProviderInstantiation() tests whether the Provider instance can be instantiated. // TestProviderInstantiation() tests whether the Provider instance can be instantiated.

View File

@ -5,12 +5,14 @@
package proxmoxtf package proxmoxtf
import ( import (
"context"
"fmt" "fmt"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"strings" "strings"
"time" "time"
"github.com/bpg/terraform-provider-proxmox/proxmox" "github.com/bpg/terraform-provider-proxmox/proxmox"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
const ( const (
@ -112,18 +114,17 @@ func resourceVirtualEnvironmentCertificate() *schema.Resource {
Elem: &schema.Schema{Type: schema.TypeString}, Elem: &schema.Schema{Type: schema.TypeString},
}, },
}, },
Create: resourceVirtualEnvironmentCertificateCreate, CreateContext: resourceVirtualEnvironmentCertificateCreate,
Read: resourceVirtualEnvironmentCertificateRead, ReadContext: resourceVirtualEnvironmentCertificateRead,
Update: resourceVirtualEnvironmentCertificateUpdate, UpdateContext: resourceVirtualEnvironmentCertificateUpdate,
Delete: resourceVirtualEnvironmentCertificateDelete, DeleteContext: resourceVirtualEnvironmentCertificateDelete,
} }
} }
func resourceVirtualEnvironmentCertificateCreate(d *schema.ResourceData, m interface{}) error { func resourceVirtualEnvironmentCertificateCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
err := resourceVirtualEnvironmentCertificateUpdate(d, m) diags := resourceVirtualEnvironmentCertificateUpdate(ctx, d, m)
if diags.HasError() {
if err != nil { return diags
return err
} }
nodeName := d.Get(mkResourceVirtualEnvironmentCertificateNodeName).(string) nodeName := d.Get(mkResourceVirtualEnvironmentCertificateNodeName).(string)
@ -133,7 +134,7 @@ func resourceVirtualEnvironmentCertificateCreate(d *schema.ResourceData, m inter
return nil return nil
} }
func resourceVirtualEnvironmentCertificateGetUpdateBody(d *schema.ResourceData, m interface{}) (*proxmox.VirtualEnvironmentCertificateUpdateRequestBody, error) { func resourceVirtualEnvironmentCertificateGetUpdateBody(d *schema.ResourceData) (*proxmox.VirtualEnvironmentCertificateUpdateRequestBody, error) {
certificate := d.Get(mkResourceVirtualEnvironmentCertificateCertificate).(string) certificate := d.Get(mkResourceVirtualEnvironmentCertificateCertificate).(string)
certificateChain := d.Get(mkResourceVirtualEnvironmentCertificateCertificateChain).(string) certificateChain := d.Get(mkResourceVirtualEnvironmentCertificateCertificateChain).(string)
overwrite := proxmox.CustomBool(d.Get(mkResourceVirtualEnvironmentCertificateOverwrite).(bool)) overwrite := proxmox.CustomBool(d.Get(mkResourceVirtualEnvironmentCertificateOverwrite).(bool))
@ -148,7 +149,7 @@ func resourceVirtualEnvironmentCertificateGetUpdateBody(d *schema.ResourceData,
force := overwrite force := overwrite
if d.Id() != "" { if d.Id() != "" {
force = proxmox.CustomBool(true) force = true
} }
restart := proxmox.CustomBool(true) restart := proxmox.CustomBool(true)
@ -163,23 +164,25 @@ func resourceVirtualEnvironmentCertificateGetUpdateBody(d *schema.ResourceData,
return body, nil return body, nil
} }
func resourceVirtualEnvironmentCertificateRead(d *schema.ResourceData, m interface{}) error { func resourceVirtualEnvironmentCertificateRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
var diags diag.Diagnostics
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
nodeName := d.Get(mkResourceVirtualEnvironmentCertificateNodeName).(string) nodeName := d.Get(mkResourceVirtualEnvironmentCertificateNodeName).(string)
list, err := veClient.ListCertificates(nodeName) list, err := veClient.ListCertificates(ctx, nodeName)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
d.Set(mkResourceVirtualEnvironmentCertificateCertificate, "") err = d.Set(mkResourceVirtualEnvironmentCertificateCertificate, "")
d.Set(mkResourceVirtualEnvironmentCertificateCertificateChain, "") diags = append(diags, diag.FromErr(err)...)
err = d.Set(mkResourceVirtualEnvironmentCertificateCertificateChain, "")
diags = append(diags, diag.FromErr(err)...)
certificateChain := d.Get(mkResourceVirtualEnvironmentCertificateCertificateChain).(string) certificateChain := d.Get(mkResourceVirtualEnvironmentCertificateCertificateChain).(string)
@ -200,125 +203,125 @@ func resourceVirtualEnvironmentCertificateRead(d *schema.ResourceData, m interfa
newCertificate = *c.Certificates newCertificate = *c.Certificates
} }
d.Set(mkResourceVirtualEnvironmentCertificateCertificate, newCertificate) err = d.Set(mkResourceVirtualEnvironmentCertificateCertificate, newCertificate)
d.Set(mkResourceVirtualEnvironmentCertificateCertificateChain, newCertificateChain) diags = append(diags, diag.FromErr(err)...)
err = d.Set(mkResourceVirtualEnvironmentCertificateCertificateChain, newCertificateChain)
diags = append(diags, diag.FromErr(err)...)
} }
d.Set(mkResourceVirtualEnvironmentCertificateFileName, *c.FileName) err = d.Set(mkResourceVirtualEnvironmentCertificateFileName, *c.FileName)
diags = append(diags, diag.FromErr(err)...)
if c.NotAfter != nil { if c.NotAfter != nil {
t := time.Time(*c.NotAfter) t := time.Time(*c.NotAfter)
err = d.Set(mkResourceVirtualEnvironmentCertificateExpirationDate, t.UTC().Format(time.RFC3339))
d.Set(mkResourceVirtualEnvironmentCertificateExpirationDate, t.UTC().Format(time.RFC3339))
} else { } else {
d.Set(mkResourceVirtualEnvironmentCertificateExpirationDate, "") err = d.Set(mkResourceVirtualEnvironmentCertificateExpirationDate, "")
} }
diags = append(diags, diag.FromErr(err)...)
if c.Issuer != nil { if c.Issuer != nil {
d.Set(mkResourceVirtualEnvironmentCertificateIssuer, *c.Issuer) err = d.Set(mkResourceVirtualEnvironmentCertificateIssuer, *c.Issuer)
} else { } else {
d.Set(mkResourceVirtualEnvironmentCertificateIssuer, "") err = d.Set(mkResourceVirtualEnvironmentCertificateIssuer, "")
} }
diags = append(diags, diag.FromErr(err)...)
if c.PublicKeyBits != nil { if c.PublicKeyBits != nil {
d.Set(mkResourceVirtualEnvironmentCertificatePublicKeySize, *c.PublicKeyBits) err = d.Set(mkResourceVirtualEnvironmentCertificatePublicKeySize, *c.PublicKeyBits)
} else { } else {
d.Set(mkResourceVirtualEnvironmentCertificatePublicKeySize, 0) err = d.Set(mkResourceVirtualEnvironmentCertificatePublicKeySize, 0)
} }
diags = append(diags, diag.FromErr(err)...)
if c.PublicKeyType != nil { if c.PublicKeyType != nil {
pkType := *c.PublicKeyType pkType := *c.PublicKeyType
for _, pkt := range []string{"ecdsa", "dsa", "rsa"} { for _, pkt := range []string{"ecdsa", "dsa", "rsa"} {
if strings.Contains(pkType, pkt) { if strings.Contains(pkType, pkt) {
pkType = pkt pkType = pkt
} }
} }
err = d.Set(mkResourceVirtualEnvironmentCertificatePublicKeyType, pkType)
d.Set(mkResourceVirtualEnvironmentCertificatePublicKeyType, pkType)
} else { } else {
d.Set(mkResourceVirtualEnvironmentCertificatePublicKeyType, "") err = d.Set(mkResourceVirtualEnvironmentCertificatePublicKeyType, "")
} }
diags = append(diags, diag.FromErr(err)...)
if c.Fingerprint != nil { if c.Fingerprint != nil {
d.Set(mkResourceVirtualEnvironmentCertificateSSLFingerprint, *c.Fingerprint) err = d.Set(mkResourceVirtualEnvironmentCertificateSSLFingerprint, *c.Fingerprint)
} else { } else {
d.Set(mkResourceVirtualEnvironmentCertificateSSLFingerprint, "") err = d.Set(mkResourceVirtualEnvironmentCertificateSSLFingerprint, "")
} }
diags = append(diags, diag.FromErr(err)...)
if c.NotBefore != nil { if c.NotBefore != nil {
t := time.Time(*c.NotBefore) t := time.Time(*c.NotBefore)
err = d.Set(mkResourceVirtualEnvironmentCertificateStartDate, t.UTC().Format(time.RFC3339))
d.Set(mkResourceVirtualEnvironmentCertificateStartDate, t.UTC().Format(time.RFC3339))
} else { } else {
d.Set(mkResourceVirtualEnvironmentCertificateStartDate, "") err = d.Set(mkResourceVirtualEnvironmentCertificateStartDate, "")
} }
diags = append(diags, diag.FromErr(err)...)
if c.Subject != nil { if c.Subject != nil {
d.Set(mkResourceVirtualEnvironmentCertificateSubject, *c.Subject) err = d.Set(mkResourceVirtualEnvironmentCertificateSubject, *c.Subject)
} else { } else {
d.Set(mkResourceVirtualEnvironmentCertificateSubject, "") err = d.Set(mkResourceVirtualEnvironmentCertificateSubject, "")
} }
diags = append(diags, diag.FromErr(err)...)
if c.SubjectAlternativeNames != nil { if c.SubjectAlternativeNames != nil {
sanList := make([]interface{}, len(*c.SubjectAlternativeNames)) sanList := make([]interface{}, len(*c.SubjectAlternativeNames))
for i, san := range *c.SubjectAlternativeNames { for i, san := range *c.SubjectAlternativeNames {
sanList[i] = san sanList[i] = san
} }
err = d.Set(mkResourceVirtualEnvironmentCertificateSubjectAlternativeNames, sanList)
d.Set(mkResourceVirtualEnvironmentCertificateSubjectAlternativeNames, sanList)
} else { } else {
d.Set(mkResourceVirtualEnvironmentCertificateSubjectAlternativeNames, []interface{}{}) err = d.Set(mkResourceVirtualEnvironmentCertificateSubjectAlternativeNames, []interface{}{})
} }
diags = append(diags, diag.FromErr(err)...)
} }
} }
return nil return diags
} }
func resourceVirtualEnvironmentCertificateUpdate(d *schema.ResourceData, m interface{}) error { func resourceVirtualEnvironmentCertificateUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
nodeName := d.Get(mkResourceVirtualEnvironmentCertificateNodeName).(string) nodeName := d.Get(mkResourceVirtualEnvironmentCertificateNodeName).(string)
body, err := resourceVirtualEnvironmentCertificateGetUpdateBody(d, m) body, err := resourceVirtualEnvironmentCertificateGetUpdateBody(d)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
err = veClient.UpdateCertificate(nodeName, body) err = veClient.UpdateCertificate(ctx, nodeName, body)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
return resourceVirtualEnvironmentCertificateRead(d, m) return resourceVirtualEnvironmentCertificateRead(ctx, d, m)
} }
func resourceVirtualEnvironmentCertificateDelete(d *schema.ResourceData, m interface{}) error { func resourceVirtualEnvironmentCertificateDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
nodeName := d.Get(mkResourceVirtualEnvironmentCertificateNodeName).(string) nodeName := d.Get(mkResourceVirtualEnvironmentCertificateNodeName).(string)
restart := proxmox.CustomBool(true) restart := proxmox.CustomBool(true)
err = veClient.DeleteCertificate(nodeName, &proxmox.VirtualEnvironmentCertificateDeleteRequestBody{ err = veClient.DeleteCertificate(ctx, nodeName, &proxmox.VirtualEnvironmentCertificateDeleteRequestBody{
Restart: &restart, Restart: &restart,
}) })
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
d.SetId("") d.SetId("")

View File

@ -7,7 +7,7 @@ package proxmoxtf
import ( import (
"testing" "testing"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
// TestResourceVirtualEnvironmentCertificateInstantiation tests whether the ResourceVirtualEnvironmentCertificate instance can be instantiated. // TestResourceVirtualEnvironmentCertificateInstantiation tests whether the ResourceVirtualEnvironmentCertificate instance can be instantiated.

View File

@ -5,10 +5,12 @@
package proxmoxtf package proxmoxtf
import ( import (
"context"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"strings" "strings"
"github.com/bpg/terraform-provider-proxmox/proxmox" "github.com/bpg/terraform-provider-proxmox/proxmox"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
const ( const (
@ -41,19 +43,18 @@ func resourceVirtualEnvironmentClusterAlias() *schema.Resource {
Default: dvResourceVirtualEnvironmentClusterAliasComment, Default: dvResourceVirtualEnvironmentClusterAliasComment,
}, },
}, },
Create: resourceVirtualEnvironmentClusterAliasCreate, CreateContext: resourceVirtualEnvironmentClusterAliasCreate,
Read: resourceVirtualEnvironmentClusterAliasRead, ReadContext: resourceVirtualEnvironmentClusterAliasRead,
Update: resourceVirtualEnvironmentClusterAliasUpdate, UpdateContext: resourceVirtualEnvironmentClusterAliasUpdate,
Delete: resourceVirtualEnvironmentClusterAliasDelete, DeleteContext: resourceVirtualEnvironmentClusterAliasDelete,
} }
} }
func resourceVirtualEnvironmentClusterAliasCreate(d *schema.ResourceData, m interface{}) error { func resourceVirtualEnvironmentClusterAliasCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
comment := d.Get(mkResourceVirtualEnvironmentClusterAliasComment).(string) comment := d.Get(mkResourceVirtualEnvironmentClusterAliasComment).(string)
@ -66,35 +67,32 @@ func resourceVirtualEnvironmentClusterAliasCreate(d *schema.ResourceData, m inte
CIDR: cidr, CIDR: cidr,
} }
err = veClient.CreateAlias(body) err = veClient.CreateAlias(ctx, body)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
d.SetId(name) d.SetId(name)
return resourceVirtualEnvironmentClusterAliasRead(d, m) return resourceVirtualEnvironmentClusterAliasRead(ctx, d, m)
} }
func resourceVirtualEnvironmentClusterAliasRead(d *schema.ResourceData, m interface{}) error { func resourceVirtualEnvironmentClusterAliasRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
name := d.Id() name := d.Id()
alias, err := veClient.GetAlias(name) alias, err := veClient.GetAlias(ctx, name)
if err != nil { if err != nil {
if strings.Contains(err.Error(), "HTTP 404") { if strings.Contains(err.Error(), "HTTP 404") {
d.SetId("") d.SetId("")
return nil return nil
} }
return diag.FromErr(err)
return err
} }
aliasMap := map[string]interface{}{ aliasMap := map[string]interface{}{
@ -105,21 +103,19 @@ func resourceVirtualEnvironmentClusterAliasRead(d *schema.ResourceData, m interf
for key, val := range aliasMap { for key, val := range aliasMap {
err = d.Set(key, val) err = d.Set(key, val)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
} }
return nil return nil
} }
func resourceVirtualEnvironmentClusterAliasUpdate(d *schema.ResourceData, m interface{}) error { func resourceVirtualEnvironmentClusterAliasUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
comment := d.Get(mkResourceVirtualEnvironmentClusterAliasComment).(string) comment := d.Get(mkResourceVirtualEnvironmentClusterAliasComment).(string)
@ -133,35 +129,32 @@ func resourceVirtualEnvironmentClusterAliasUpdate(d *schema.ResourceData, m inte
Comment: &comment, Comment: &comment,
} }
err = veClient.UpdateAlias(previousName, body) err = veClient.UpdateAlias(ctx, previousName, body)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
d.SetId(newName) d.SetId(newName)
return resourceVirtualEnvironmentClusterAliasRead(d, m) return resourceVirtualEnvironmentClusterAliasRead(ctx, d, m)
} }
func resourceVirtualEnvironmentClusterAliasDelete(d *schema.ResourceData, m interface{}) error { func resourceVirtualEnvironmentClusterAliasDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return nil return diag.FromErr(err)
} }
name := d.Id() name := d.Id()
err = veClient.DeleteAlias(name) err = veClient.DeleteAlias(ctx, name)
if err != nil { if err != nil {
if strings.Contains(err.Error(), "HTTP 404") { if strings.Contains(err.Error(), "HTTP 404") {
d.SetId("") d.SetId("")
return nil return nil
} }
return diag.FromErr(err)
return err
} }
d.SetId("") d.SetId("")

View File

@ -7,7 +7,7 @@ package proxmoxtf
import ( import (
"testing" "testing"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
// TestResourceVirtualEnvironmentAliasInstantiation tests whether the ResourceVirtualEnvironmentAlias instance can be instantiated. // TestResourceVirtualEnvironmentAliasInstantiation tests whether the ResourceVirtualEnvironmentAlias instance can be instantiated.

View File

@ -5,10 +5,12 @@
package proxmoxtf package proxmoxtf
import ( import (
"context"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"strings" "strings"
"github.com/bpg/terraform-provider-proxmox/proxmox" "github.com/bpg/terraform-provider-proxmox/proxmox"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
const ( const (
@ -63,6 +65,8 @@ func resourceVirtualEnvironmentClusterIPSet() *schema.Resource {
}, },
}, },
}, },
MaxItems: 14,
MinItems: 0,
}, },
mkResourceVirtualEnvironmentClusterIPSetCIDRComment: { mkResourceVirtualEnvironmentClusterIPSetCIDRComment: {
Type: schema.TypeString, Type: schema.TypeString,
@ -71,19 +75,18 @@ func resourceVirtualEnvironmentClusterIPSet() *schema.Resource {
Default: dvResourceVirtualEnvironmentClusterIPSetCIDRComment, Default: dvResourceVirtualEnvironmentClusterIPSetCIDRComment,
}, },
}, },
Create: resourceVirtualEnvironmentClusterIPSetCreate, CreateContext: resourceVirtualEnvironmentClusterIPSetCreate,
Read: resourceVirtualEnvironmentClusterIPSetRead, ReadContext: resourceVirtualEnvironmentClusterIPSetRead,
Update: resourceVirtualEnvironmentClusterIPSetUpdate, UpdateContext: resourceVirtualEnvironmentClusterIPSetUpdate,
Delete: resourceVirtualEnvironmentClusterIPSetDelete, DeleteContext: resourceVirtualEnvironmentClusterIPSetDelete,
} }
} }
func resourceVirtualEnvironmentClusterIPSetCreate(d *schema.ResourceData, m interface{}) error { func resourceVirtualEnvironmentClusterIPSetCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
comment := d.Get(mkResourceVirtualEnvironmentClusterIPSetCIDRComment).(string) comment := d.Get(mkResourceVirtualEnvironmentClusterIPSetCIDRComment).(string)
@ -116,80 +119,80 @@ func resourceVirtualEnvironmentClusterIPSetCreate(d *schema.ResourceData, m inte
Name: name, Name: name,
} }
err = veClient.CreateIPSet(body) err = veClient.CreateIPSet(ctx, body)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
for _, v := range IPSetsArray { for _, v := range IPSetsArray {
err = veClient.AddCIDRToIPSet(name, &v) err = veClient.AddCIDRToIPSet(ctx, name, &v)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
} }
d.SetId(name) d.SetId(name)
return resourceVirtualEnvironmentClusterIPSetRead(d, m) return resourceVirtualEnvironmentClusterIPSetRead(ctx, d, m)
} }
func resourceVirtualEnvironmentClusterIPSetRead(d *schema.ResourceData, m interface{}) error { func resourceVirtualEnvironmentClusterIPSetRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
var diags diag.Diagnostics
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
name := d.Id() name := d.Id()
allIPSets, err := veClient.GetListIPSets() allIPSets, err := veClient.GetListIPSets(ctx)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
for _, v := range allIPSets.Data { for _, v := range allIPSets.Data {
if v.Name == name { if v.Name == name {
err = d.Set(mkResourceVirtualEnvironmentClusterIPSetName, v.Name) err = d.Set(mkResourceVirtualEnvironmentClusterIPSetName, v.Name)
diags = append(diags, diag.FromErr(err)...)
if err != nil {
return err
}
err = d.Set(mkResourceVirtualEnvironmentClusterIPSetCIDRComment, v.Comment) err = d.Set(mkResourceVirtualEnvironmentClusterIPSetCIDRComment, v.Comment)
diags = append(diags, diag.FromErr(err)...)
if err != nil {
return err
}
} }
} }
IPSet, err := veClient.GetListIPSetContent(name) IPSet, err := veClient.GetListIPSetContent(ctx, name)
if err != nil { if err != nil {
if strings.Contains(err.Error(), "HTTP 404") { if strings.Contains(err.Error(), "HTTP 404") {
d.SetId("") d.SetId("")
return nil return nil
} }
diags = append(diags, diag.FromErr(err)...)
return err return diags
} }
var entries []interface{}
for key := range IPSet { for key := range IPSet {
d.Set(mkResourceVirtualEnvironmentClusterIPSetCIDR, IPSet[key]) entry := map[string]interface{}{}
entry[mkResourceVirtualEnvironmentClusterIPSetCIDRName] = IPSet[key].CIDR
entry[mkResourceVirtualEnvironmentClusterIPSetCIDRNoMatch] = IPSet[key].NoMatch
entry[mkResourceVirtualEnvironmentClusterIPSetCIDRComment] = IPSet[key].Comment
entries = append(entries, entry)
} }
return nil err = d.Set(mkResourceVirtualEnvironmentClusterIPSetCIDR, entries)
diags = append(diags, diag.FromErr(err)...)
return diags
} }
func resourceVirtualEnvironmentClusterIPSetUpdate(d *schema.ResourceData, m interface{}) error { func resourceVirtualEnvironmentClusterIPSetUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
comment := d.Get(mkResourceVirtualEnvironmentClusterIPSetCIDRComment).(string) comment := d.Get(mkResourceVirtualEnvironmentClusterIPSetCIDRComment).(string)
@ -202,44 +205,44 @@ func resourceVirtualEnvironmentClusterIPSetUpdate(d *schema.ResourceData, m inte
Comment: &comment, Comment: &comment,
} }
err = veClient.UpdateIPSet(body) err = veClient.UpdateIPSet(ctx, body)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
d.SetId(newName) d.SetId(newName)
return resourceVirtualEnvironmentClusterIPSetRead(d, m) return resourceVirtualEnvironmentClusterIPSetRead(ctx, d, m)
} }
func resourceVirtualEnvironmentClusterIPSetDelete(d *schema.ResourceData, m interface{}) error { func resourceVirtualEnvironmentClusterIPSetDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
var diags diag.Diagnostics
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return nil return diag.FromErr(err)
} }
name := d.Id() name := d.Id()
IPSetContent, err := veClient.GetListIPSetContent(name) IPSetContent, err := veClient.GetListIPSetContent(ctx, name)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
// PVE requires content of IPSet be cleared before removal // PVE requires content of IPSet be cleared before removal
if len(IPSetContent) > 0 { if len(IPSetContent) > 0 {
for _, IPSet := range IPSetContent { for _, IPSet := range IPSetContent {
err = veClient.DeleteIPSetContent(name, IPSet.CIDR) err = veClient.DeleteIPSetContent(ctx, name, IPSet.CIDR)
if err != nil { diags = append(diags, diag.FromErr(err)...)
return err
}
} }
} }
err = veClient.DeleteIPSet(name) if diags.HasError() {
return diags
}
err = veClient.DeleteIPSet(ctx, name)
if err != nil { if err != nil {
if strings.Contains(err.Error(), "HTTP 404") { if strings.Contains(err.Error(), "HTTP 404") {
@ -247,7 +250,7 @@ func resourceVirtualEnvironmentClusterIPSetDelete(d *schema.ResourceData, m inte
return nil return nil
} }
return err return diag.FromErr(err)
} }
d.SetId("") d.SetId("")

View File

@ -7,7 +7,7 @@ package proxmoxtf
import ( import (
"testing" "testing"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
// TestResourceVirtualEnvironmentIPSetInstantiation tests whether the resourceVirtualEnvironmentClusterIPSet // TestResourceVirtualEnvironmentIPSetInstantiation tests whether the resourceVirtualEnvironmentClusterIPSet

View File

@ -5,13 +5,15 @@
package proxmoxtf package proxmoxtf
import ( import (
"context"
"fmt" "fmt"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"strconv" "strconv"
"strings" "strings"
"github.com/bpg/terraform-provider-proxmox/proxmox" "github.com/bpg/terraform-provider-proxmox/proxmox"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/helper/validation" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
) )
const ( const (
@ -130,7 +132,7 @@ func resourceVirtualEnvironmentContainer() *schema.Resource {
Description: "The ID of the source container", Description: "The ID of the source container",
Required: true, Required: true,
ForceNew: true, ForceNew: true,
ValidateFunc: getVMIDValidator(), ValidateDiagFunc: getVMIDValidator(),
}, },
}, },
}, },
@ -163,14 +165,14 @@ func resourceVirtualEnvironmentContainer() *schema.Resource {
Description: "The console mode", Description: "The console mode",
Optional: true, Optional: true,
Default: dvResourceVirtualEnvironmentContainerConsoleMode, Default: dvResourceVirtualEnvironmentContainerConsoleMode,
ValidateFunc: resourceVirtualEnvironmentContainerGetConsoleModeValidator(), ValidateDiagFunc: resourceVirtualEnvironmentContainerGetConsoleModeValidator(),
}, },
mkResourceVirtualEnvironmentContainerConsoleTTYCount: { mkResourceVirtualEnvironmentContainerConsoleTTYCount: {
Type: schema.TypeInt, Type: schema.TypeInt,
Description: "The number of available TTY", Description: "The number of available TTY",
Optional: true, Optional: true,
Default: dvResourceVirtualEnvironmentContainerConsoleTTYCount, Default: dvResourceVirtualEnvironmentContainerConsoleTTYCount,
ValidateFunc: validation.IntBetween(0, 6), ValidateDiagFunc: validation.ToDiagFunc(validation.IntBetween(0, 6)),
}, },
}, },
}, },
@ -197,21 +199,21 @@ func resourceVirtualEnvironmentContainer() *schema.Resource {
Description: "The CPU architecture", Description: "The CPU architecture",
Optional: true, Optional: true,
Default: dvResourceVirtualEnvironmentContainerCPUArchitecture, Default: dvResourceVirtualEnvironmentContainerCPUArchitecture,
ValidateFunc: resourceVirtualEnvironmentContainerGetCPUArchitectureValidator(), ValidateDiagFunc: resourceVirtualEnvironmentContainerGetCPUArchitectureValidator(),
}, },
mkResourceVirtualEnvironmentContainerCPUCores: { mkResourceVirtualEnvironmentContainerCPUCores: {
Type: schema.TypeInt, Type: schema.TypeInt,
Description: "The number of CPU cores", Description: "The number of CPU cores",
Optional: true, Optional: true,
Default: dvResourceVirtualEnvironmentContainerCPUCores, Default: dvResourceVirtualEnvironmentContainerCPUCores,
ValidateFunc: validation.IntBetween(1, 128), ValidateDiagFunc: validation.ToDiagFunc(validation.IntBetween(1, 128)),
}, },
mkResourceVirtualEnvironmentContainerCPUUnits: { mkResourceVirtualEnvironmentContainerCPUUnits: {
Type: schema.TypeInt, Type: schema.TypeInt,
Description: "The CPU units", Description: "The CPU units",
Optional: true, Optional: true,
Default: dvResourceVirtualEnvironmentContainerCPUUnits, Default: dvResourceVirtualEnvironmentContainerCPUUnits,
ValidateFunc: validation.IntBetween(0, 500000), ValidateDiagFunc: validation.ToDiagFunc(validation.IntBetween(0, 500000)),
}, },
}, },
}, },
@ -417,14 +419,14 @@ func resourceVirtualEnvironmentContainer() *schema.Resource {
Description: "The dedicated memory in megabytes", Description: "The dedicated memory in megabytes",
Optional: true, Optional: true,
Default: dvResourceVirtualEnvironmentContainerMemoryDedicated, Default: dvResourceVirtualEnvironmentContainerMemoryDedicated,
ValidateFunc: validation.IntBetween(16, 268435456), ValidateDiagFunc: validation.ToDiagFunc(validation.IntBetween(16, 268435456)),
}, },
mkResourceVirtualEnvironmentContainerMemorySwap: { mkResourceVirtualEnvironmentContainerMemorySwap: {
Type: schema.TypeInt, Type: schema.TypeInt,
Description: "The swap size in megabytes", Description: "The swap size in megabytes",
Optional: true, Optional: true,
Default: dvResourceVirtualEnvironmentContainerMemorySwap, Default: dvResourceVirtualEnvironmentContainerMemorySwap,
ValidateFunc: validation.IntBetween(0, 268435456), ValidateDiagFunc: validation.ToDiagFunc(validation.IntBetween(0, 268435456)),
}, },
}, },
}, },
@ -460,7 +462,7 @@ func resourceVirtualEnvironmentContainer() *schema.Resource {
DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool {
return new == "" return new == ""
}, },
ValidateFunc: getMACAddressValidator(), ValidateDiagFunc: getMACAddressValidator(),
}, },
mkResourceVirtualEnvironmentContainerNetworkInterfaceName: { mkResourceVirtualEnvironmentContainerNetworkInterfaceName: {
Type: schema.TypeString, Type: schema.TypeString,
@ -502,14 +504,14 @@ func resourceVirtualEnvironmentContainer() *schema.Resource {
Description: "The ID of an OS template file", Description: "The ID of an OS template file",
Required: true, Required: true,
ForceNew: true, ForceNew: true,
ValidateFunc: getFileIDValidator(), ValidateDiagFunc: getFileIDValidator(),
}, },
mkResourceVirtualEnvironmentContainerOperatingSystemType: { mkResourceVirtualEnvironmentContainerOperatingSystemType: {
Type: schema.TypeString, Type: schema.TypeString,
Description: "The type", Description: "The type",
Optional: true, Optional: true,
Default: dvResourceVirtualEnvironmentContainerOperatingSystemType, Default: dvResourceVirtualEnvironmentContainerOperatingSystemType,
ValidateFunc: resourceVirtualEnvironmentContainerGetOperatingSystemTypeValidator(), ValidateDiagFunc: resourceVirtualEnvironmentContainerGetOperatingSystemTypeValidator(),
}, },
}, },
}, },
@ -545,32 +547,31 @@ func resourceVirtualEnvironmentContainer() *schema.Resource {
Optional: true, Optional: true,
ForceNew: true, ForceNew: true,
Default: dvResourceVirtualEnvironmentContainerVMID, Default: dvResourceVirtualEnvironmentContainerVMID,
ValidateFunc: getVMIDValidator(), ValidateDiagFunc: getVMIDValidator(),
}, },
}, },
Create: resourceVirtualEnvironmentContainerCreate, CreateContext: resourceVirtualEnvironmentContainerCreate,
Read: resourceVirtualEnvironmentContainerRead, ReadContext: resourceVirtualEnvironmentContainerRead,
Update: resourceVirtualEnvironmentContainerUpdate, UpdateContext: resourceVirtualEnvironmentContainerUpdate,
Delete: resourceVirtualEnvironmentContainerDelete, DeleteContext: resourceVirtualEnvironmentContainerDelete,
} }
} }
func resourceVirtualEnvironmentContainerCreate(d *schema.ResourceData, m interface{}) error { func resourceVirtualEnvironmentContainerCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
clone := d.Get(mkResourceVirtualEnvironmentContainerClone).([]interface{}) clone := d.Get(mkResourceVirtualEnvironmentContainerClone).([]interface{})
if len(clone) > 0 { if len(clone) > 0 {
return resourceVirtualEnvironmentContainerCreateClone(d, m) return resourceVirtualEnvironmentContainerCreateClone(ctx, d, m)
} }
return resourceVirtualEnvironmentContainerCreateCustom(d, m) return resourceVirtualEnvironmentContainerCreateCustom(ctx, d, m)
} }
func resourceVirtualEnvironmentContainerCreateClone(d *schema.ResourceData, m interface{}) error { func resourceVirtualEnvironmentContainerCreateClone(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
clone := d.Get(mkResourceVirtualEnvironmentContainerClone).([]interface{}) clone := d.Get(mkResourceVirtualEnvironmentContainerClone).([]interface{})
@ -594,10 +595,9 @@ func resourceVirtualEnvironmentContainerCreateClone(d *schema.ResourceData, m in
vmID := d.Get(mkResourceVirtualEnvironmentContainerVMID).(int) vmID := d.Get(mkResourceVirtualEnvironmentContainerVMID).(int)
if vmID == -1 { if vmID == -1 {
vmIDNew, err := veClient.GetVMID() vmIDNew, err := veClient.GetVMID(ctx)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
vmID = *vmIDNew vmID = *vmIDNew
@ -629,22 +629,21 @@ func resourceVirtualEnvironmentContainerCreateClone(d *schema.ResourceData, m in
if cloneNodeName != "" && cloneNodeName != nodeName { if cloneNodeName != "" && cloneNodeName != nodeName {
cloneBody.TargetNodeName = &nodeName cloneBody.TargetNodeName = &nodeName
err = veClient.CloneContainer(cloneNodeName, cloneVMID, cloneBody) err = veClient.CloneContainer(ctx, cloneNodeName, cloneVMID, cloneBody)
} else { } else {
err = veClient.CloneContainer(nodeName, cloneVMID, cloneBody) err = veClient.CloneContainer(ctx, nodeName, cloneVMID, cloneBody)
} }
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
d.SetId(strconv.Itoa(vmID)) d.SetId(strconv.Itoa(vmID))
// Wait for the container to be created and its configuration lock to be released. // Wait for the container to be created and its configuration lock to be released.
err = veClient.WaitForContainerLock(nodeName, vmID, 600, 5, true) err = veClient.WaitForContainerLock(ctx, nodeName, vmID, 600, 5, true)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
// 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.
@ -678,10 +677,10 @@ func resourceVirtualEnvironmentContainerCreateClone(d *schema.ResourceData, m in
updateBody.CPUUnits = &cpuUnits updateBody.CPUUnits = &cpuUnits
} }
initializationIPConfigIPv4Address := []string{} var initializationIPConfigIPv4Address []string
initializationIPConfigIPv4Gateway := []string{} var initializationIPConfigIPv4Gateway []string
initializationIPConfigIPv6Address := []string{} var initializationIPConfigIPv6Address []string
initializationIPConfigIPv6Gateway := []string{} var initializationIPConfigIPv6Gateway []string
if len(initialization) > 0 { if len(initialization) > 0 {
initializationBlock := initialization[0].(map[string]interface{}) initializationBlock := initialization[0].(map[string]interface{})
@ -774,10 +773,9 @@ func resourceVirtualEnvironmentContainerCreateClone(d *schema.ResourceData, m in
networkInterface := d.Get(mkResourceVirtualEnvironmentContainerNetworkInterface).([]interface{}) networkInterface := d.Get(mkResourceVirtualEnvironmentContainerNetworkInterface).([]interface{})
if len(networkInterface) == 0 { if len(networkInterface) == 0 {
networkInterface, err = resourceVirtualEnvironmentContainerGetExistingNetworkInterface(veClient, nodeName, vmID) networkInterface, err = resourceVirtualEnvironmentContainerGetExistingNetworkInterface(ctx, veClient, nodeName, vmID)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
} }
@ -865,47 +863,42 @@ func resourceVirtualEnvironmentContainerCreateClone(d *schema.ResourceData, m in
updateBody.Template = &template updateBody.Template = &template
} }
err = veClient.UpdateContainer(nodeName, vmID, updateBody) err = veClient.UpdateContainer(ctx, nodeName, vmID, updateBody)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
// Wait for the container's lock to be released. // Wait for the container's lock to be released.
err = veClient.WaitForContainerLock(nodeName, vmID, 600, 5, true) err = veClient.WaitForContainerLock(ctx, nodeName, vmID, 600, 5, true)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
return resourceVirtualEnvironmentContainerCreateStart(d, m) return resourceVirtualEnvironmentContainerCreateStart(ctx, d, m)
} }
func resourceVirtualEnvironmentContainerCreateCustom(d *schema.ResourceData, m interface{}) error { func resourceVirtualEnvironmentContainerCreateCustom(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
nodeName := d.Get(mkResourceVirtualEnvironmentContainerNodeName).(string) nodeName := d.Get(mkResourceVirtualEnvironmentContainerNodeName).(string)
resource := resourceVirtualEnvironmentContainer() resource := resourceVirtualEnvironmentContainer()
consoleBlock, err := getSchemaBlock(resource, d, m, []string{mkResourceVirtualEnvironmentContainerConsole}, 0, true) consoleBlock, err := getSchemaBlock(resource, d, []string{mkResourceVirtualEnvironmentContainerConsole}, 0, true)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
consoleEnabled := proxmox.CustomBool(consoleBlock[mkResourceVirtualEnvironmentContainerConsoleEnabled].(bool)) consoleEnabled := proxmox.CustomBool(consoleBlock[mkResourceVirtualEnvironmentContainerConsoleEnabled].(bool))
consoleMode := consoleBlock[mkResourceVirtualEnvironmentContainerConsoleMode].(string) consoleMode := consoleBlock[mkResourceVirtualEnvironmentContainerConsoleMode].(string)
consoleTTYCount := consoleBlock[mkResourceVirtualEnvironmentContainerConsoleTTYCount].(int) consoleTTYCount := consoleBlock[mkResourceVirtualEnvironmentContainerConsoleTTYCount].(int)
cpuBlock, err := getSchemaBlock(resource, d, m, []string{mkResourceVirtualEnvironmentContainerCPU}, 0, true) cpuBlock, err := getSchemaBlock(resource, d, []string{mkResourceVirtualEnvironmentContainerCPU}, 0, true)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
cpuArchitecture := cpuBlock[mkResourceVirtualEnvironmentContainerCPUArchitecture].(string) cpuArchitecture := cpuBlock[mkResourceVirtualEnvironmentContainerCPUArchitecture].(string)
@ -914,10 +907,9 @@ func resourceVirtualEnvironmentContainerCreateCustom(d *schema.ResourceData, m i
description := d.Get(mkResourceVirtualEnvironmentContainerDescription).(string) description := d.Get(mkResourceVirtualEnvironmentContainerDescription).(string)
diskBlock, err := getSchemaBlock(resource, d, m, []string{mkResourceVirtualEnvironmentContainerDisk}, 0, true) diskBlock, err := getSchemaBlock(resource, d, []string{mkResourceVirtualEnvironmentContainerDisk}, 0, true)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
diskDatastoreID := diskBlock[mkResourceVirtualEnvironmentContainerDiskDatastoreID].(string) diskDatastoreID := diskBlock[mkResourceVirtualEnvironmentContainerDiskDatastoreID].(string)
@ -926,10 +918,10 @@ func resourceVirtualEnvironmentContainerCreateCustom(d *schema.ResourceData, m i
initializationDNSDomain := dvResourceVirtualEnvironmentContainerInitializationDNSDomain initializationDNSDomain := dvResourceVirtualEnvironmentContainerInitializationDNSDomain
initializationDNSServer := dvResourceVirtualEnvironmentContainerInitializationDNSServer initializationDNSServer := dvResourceVirtualEnvironmentContainerInitializationDNSServer
initializationHostname := dvResourceVirtualEnvironmentContainerInitializationHostname initializationHostname := dvResourceVirtualEnvironmentContainerInitializationHostname
initializationIPConfigIPv4Address := []string{} var initializationIPConfigIPv4Address []string
initializationIPConfigIPv4Gateway := []string{} var initializationIPConfigIPv4Gateway []string
initializationIPConfigIPv6Address := []string{} var initializationIPConfigIPv6Address []string
initializationIPConfigIPv6Gateway := []string{} var initializationIPConfigIPv6Gateway []string
initializationUserAccountKeys := proxmox.VirtualEnvironmentContainerCustomSSHKeys{} initializationUserAccountKeys := proxmox.VirtualEnvironmentContainerCustomSSHKeys{}
initializationUserAccountPassword := dvResourceVirtualEnvironmentContainerInitializationUserAccountPassword initializationUserAccountPassword := dvResourceVirtualEnvironmentContainerInitializationUserAccountPassword
@ -989,10 +981,9 @@ func resourceVirtualEnvironmentContainerCreateCustom(d *schema.ResourceData, m i
} }
} }
memoryBlock, err := getSchemaBlock(resource, d, m, []string{mkResourceVirtualEnvironmentContainerMemory}, 0, true) memoryBlock, err := getSchemaBlock(resource, d, []string{mkResourceVirtualEnvironmentContainerMemory}, 0, true)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
memoryDedicated := memoryBlock[mkResourceVirtualEnvironmentContainerMemoryDedicated].(int) memoryDedicated := memoryBlock[mkResourceVirtualEnvironmentContainerMemoryDedicated].(int)
@ -1056,7 +1047,7 @@ func resourceVirtualEnvironmentContainerCreateCustom(d *schema.ResourceData, m i
operatingSystem := d.Get(mkResourceVirtualEnvironmentContainerOperatingSystem).([]interface{}) operatingSystem := d.Get(mkResourceVirtualEnvironmentContainerOperatingSystem).([]interface{})
if len(operatingSystem) == 0 { if len(operatingSystem) == 0 {
return fmt.Errorf("\"%s\": required field is not set", mkResourceVirtualEnvironmentContainerOperatingSystem) return diag.Errorf("\"%s\": required field is not set", mkResourceVirtualEnvironmentContainerOperatingSystem)
} }
operatingSystemBlock := operatingSystem[0].(map[string]interface{}) operatingSystemBlock := operatingSystem[0].(map[string]interface{})
@ -1069,10 +1060,9 @@ func resourceVirtualEnvironmentContainerCreateCustom(d *schema.ResourceData, m i
vmID := d.Get(mkResourceVirtualEnvironmentContainerVMID).(int) vmID := d.Get(mkResourceVirtualEnvironmentContainerVMID).(int)
if vmID == -1 { if vmID == -1 {
vmIDNew, err := veClient.GetVMID() vmIDNew, err := veClient.GetVMID(ctx)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
vmID = *vmIDNew vmID = *vmIDNew
@ -1125,87 +1115,81 @@ func resourceVirtualEnvironmentContainerCreateCustom(d *schema.ResourceData, m i
createBody.PoolID = &poolID createBody.PoolID = &poolID
} }
err = veClient.CreateContainer(nodeName, &createBody) err = veClient.CreateContainer(ctx, nodeName, &createBody)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
d.SetId(strconv.Itoa(vmID)) d.SetId(strconv.Itoa(vmID))
// Wait for the container's lock to be released. // Wait for the container's lock to be released.
err = veClient.WaitForContainerLock(nodeName, vmID, 600, 5, true) err = veClient.WaitForContainerLock(ctx, nodeName, vmID, 600, 5, true)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
return resourceVirtualEnvironmentContainerCreateStart(d, m) return resourceVirtualEnvironmentContainerCreateStart(ctx, d, m)
} }
func resourceVirtualEnvironmentContainerCreateStart(d *schema.ResourceData, m interface{}) error { func resourceVirtualEnvironmentContainerCreateStart(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
started := d.Get(mkResourceVirtualEnvironmentContainerStarted).(bool) started := d.Get(mkResourceVirtualEnvironmentContainerStarted).(bool)
template := d.Get(mkResourceVirtualEnvironmentContainerTemplate).(bool) template := d.Get(mkResourceVirtualEnvironmentContainerTemplate).(bool)
if !started || template { if !started || template {
return resourceVirtualEnvironmentContainerRead(d, m) return resourceVirtualEnvironmentContainerRead(ctx, d, m)
} }
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
nodeName := d.Get(mkResourceVirtualEnvironmentContainerNodeName).(string) nodeName := d.Get(mkResourceVirtualEnvironmentContainerNodeName).(string)
vmID, err := strconv.Atoi(d.Id()) vmID, err := strconv.Atoi(d.Id())
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
// Start the container and wait for it to reach a running state before continuing. // Start the container and wait for it to reach a running state before continuing.
err = veClient.StartContainer(nodeName, vmID) err = veClient.StartContainer(ctx, nodeName, vmID)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
err = veClient.WaitForContainerState(nodeName, vmID, "running", 120, 5) err = veClient.WaitForContainerState(ctx, nodeName, vmID, "running", 120, 5)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
return resourceVirtualEnvironmentContainerRead(d, m) return resourceVirtualEnvironmentContainerRead(ctx, d, m)
} }
func resourceVirtualEnvironmentContainerGetConsoleModeValidator() schema.SchemaValidateFunc { func resourceVirtualEnvironmentContainerGetConsoleModeValidator() schema.SchemaValidateDiagFunc {
return validation.StringInSlice([]string{ return validation.ToDiagFunc(validation.StringInSlice([]string{
"console", "console",
"shell", "shell",
"tty", "tty",
}, false) }, false))
} }
func resourceVirtualEnvironmentContainerGetCPUArchitectureValidator() schema.SchemaValidateFunc { func resourceVirtualEnvironmentContainerGetCPUArchitectureValidator() schema.SchemaValidateDiagFunc {
return validation.StringInSlice([]string{ return validation.ToDiagFunc(validation.StringInSlice([]string{
"amd64", "amd64",
"arm64", "arm64",
"armhf", "armhf",
"i386", "i386",
}, false) }, false))
} }
func resourceVirtualEnvironmentContainerGetExistingNetworkInterface(client *proxmox.VirtualEnvironmentClient, nodeName string, vmID int) ([]interface{}, error) { func resourceVirtualEnvironmentContainerGetExistingNetworkInterface(ctx context.Context, client *proxmox.VirtualEnvironmentClient, nodeName string, vmID int) ([]interface{}, error) {
containerInfo, err := client.GetContainer(nodeName, vmID) containerInfo, err := client.GetContainer(ctx, nodeName, vmID)
if err != nil { if err != nil {
return []interface{}{}, err return []interface{}{}, err
} }
networkInterfaces := []interface{}{} var networkInterfaces []interface{}
networkInterfaceArray := []*proxmox.VirtualEnvironmentContainerCustomNetworkInterface{ networkInterfaceArray := []*proxmox.VirtualEnvironmentContainerCustomNetworkInterface{
containerInfo.NetworkInterface0, containerInfo.NetworkInterface0,
containerInfo.NetworkInterface1, containerInfo.NetworkInterface1,
@ -1258,8 +1242,8 @@ func resourceVirtualEnvironmentContainerGetExistingNetworkInterface(client *prox
return networkInterfaces, nil return networkInterfaces, nil
} }
func resourceVirtualEnvironmentContainerGetOperatingSystemTypeValidator() schema.SchemaValidateFunc { func resourceVirtualEnvironmentContainerGetOperatingSystemTypeValidator() schema.SchemaValidateDiagFunc {
return validation.StringInSlice([]string{ return validation.ToDiagFunc(validation.StringInSlice([]string{
"alpine", "alpine",
"archlinux", "archlinux",
"centos", "centos",
@ -1269,26 +1253,26 @@ func resourceVirtualEnvironmentContainerGetOperatingSystemTypeValidator() schema
"opensuse", "opensuse",
"ubuntu", "ubuntu",
"unmanaged", "unmanaged",
}, false) }, false))
} }
func resourceVirtualEnvironmentContainerRead(d *schema.ResourceData, m interface{}) error { func resourceVirtualEnvironmentContainerRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
var diags diag.Diagnostics
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
nodeName := d.Get(mkResourceVirtualEnvironmentContainerNodeName).(string) nodeName := d.Get(mkResourceVirtualEnvironmentContainerNodeName).(string)
vmID, err := strconv.Atoi(d.Id()) vmID, err := strconv.Atoi(d.Id())
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
// Retrieve the entire configuration in order to compare it to the state. // Retrieve the entire configuration in order to compare it to the state.
containerConfig, err := veClient.GetContainer(nodeName, vmID) containerConfig, err := veClient.GetContainer(ctx, nodeName, vmID)
if err != nil { if err != nil {
if strings.Contains(err.Error(), "HTTP 404") || if strings.Contains(err.Error(), "HTTP 404") ||
@ -1297,8 +1281,7 @@ func resourceVirtualEnvironmentContainerRead(d *schema.ResourceData, m interface
return nil return nil
} }
return diag.FromErr(err)
return err
} }
clone := d.Get(mkResourceVirtualEnvironmentVMClone).([]interface{}) clone := d.Get(mkResourceVirtualEnvironmentVMClone).([]interface{})
@ -1308,10 +1291,11 @@ func resourceVirtualEnvironmentContainerRead(d *schema.ResourceData, m interface
if len(clone) == 0 || currentDescription != dvResourceVirtualEnvironmentContainerDescription { if len(clone) == 0 || currentDescription != dvResourceVirtualEnvironmentContainerDescription {
if containerConfig.Description != nil { if containerConfig.Description != nil {
d.Set(mkResourceVirtualEnvironmentContainerDescription, strings.TrimSpace(*containerConfig.Description)) err = d.Set(mkResourceVirtualEnvironmentContainerDescription, strings.TrimSpace(*containerConfig.Description))
} else { } else {
d.Set(mkResourceVirtualEnvironmentContainerDescription, "") err = d.Set(mkResourceVirtualEnvironmentContainerDescription, "")
} }
diags = append(diags, diag.FromErr(err)...)
} }
// Compare the console configuration to the one stored in the state. // Compare the console configuration to the one stored in the state.
@ -1342,13 +1326,15 @@ func resourceVirtualEnvironmentContainerRead(d *schema.ResourceData, m interface
if len(clone) > 0 { if len(clone) > 0 {
if len(currentConsole) > 0 { if len(currentConsole) > 0 {
d.Set(mkResourceVirtualEnvironmentContainerConsole, []interface{}{console}) err := d.Set(mkResourceVirtualEnvironmentContainerConsole, []interface{}{console})
diags = append(diags, diag.FromErr(err)...)
} }
} else if len(currentConsole) > 0 || } else if len(currentConsole) > 0 ||
console[mkResourceVirtualEnvironmentContainerConsoleEnabled] != proxmox.CustomBool(dvResourceVirtualEnvironmentContainerConsoleEnabled) || console[mkResourceVirtualEnvironmentContainerConsoleEnabled] != proxmox.CustomBool(dvResourceVirtualEnvironmentContainerConsoleEnabled) ||
console[mkResourceVirtualEnvironmentContainerConsoleMode] != dvResourceVirtualEnvironmentContainerConsoleMode || console[mkResourceVirtualEnvironmentContainerConsoleMode] != dvResourceVirtualEnvironmentContainerConsoleMode ||
console[mkResourceVirtualEnvironmentContainerConsoleTTYCount] != dvResourceVirtualEnvironmentContainerConsoleTTYCount { console[mkResourceVirtualEnvironmentContainerConsoleTTYCount] != dvResourceVirtualEnvironmentContainerConsoleTTYCount {
d.Set(mkResourceVirtualEnvironmentContainerConsole, []interface{}{console}) err := d.Set(mkResourceVirtualEnvironmentContainerConsole, []interface{}{console})
diags = append(diags, diag.FromErr(err)...)
} }
// Compare the CPU configuration to the one stored in the state. // Compare the CPU configuration to the one stored in the state.
@ -1379,13 +1365,15 @@ func resourceVirtualEnvironmentContainerRead(d *schema.ResourceData, m interface
if len(clone) > 0 { if len(clone) > 0 {
if len(currentCPU) > 0 { if len(currentCPU) > 0 {
d.Set(mkResourceVirtualEnvironmentContainerCPU, []interface{}{cpu}) err := d.Set(mkResourceVirtualEnvironmentContainerCPU, []interface{}{cpu})
diags = append(diags, diag.FromErr(err)...)
} }
} else if len(currentCPU) > 0 || } else if len(currentCPU) > 0 ||
cpu[mkResourceVirtualEnvironmentContainerCPUArchitecture] != dvResourceVirtualEnvironmentContainerCPUArchitecture || cpu[mkResourceVirtualEnvironmentContainerCPUArchitecture] != dvResourceVirtualEnvironmentContainerCPUArchitecture ||
cpu[mkResourceVirtualEnvironmentContainerCPUCores] != dvResourceVirtualEnvironmentContainerCPUCores || cpu[mkResourceVirtualEnvironmentContainerCPUCores] != dvResourceVirtualEnvironmentContainerCPUCores ||
cpu[mkResourceVirtualEnvironmentContainerCPUUnits] != dvResourceVirtualEnvironmentContainerCPUUnits { cpu[mkResourceVirtualEnvironmentContainerCPUUnits] != dvResourceVirtualEnvironmentContainerCPUUnits {
d.Set(mkResourceVirtualEnvironmentContainerCPU, []interface{}{cpu}) err := d.Set(mkResourceVirtualEnvironmentContainerCPU, []interface{}{cpu})
diags = append(diags, diag.FromErr(err)...)
} }
// Compare the disk configuration to the one stored in the state. // Compare the disk configuration to the one stored in the state.
@ -1404,11 +1392,13 @@ func resourceVirtualEnvironmentContainerRead(d *schema.ResourceData, m interface
if len(clone) > 0 { if len(clone) > 0 {
if len(currentDisk) > 0 { if len(currentDisk) > 0 {
d.Set(mkResourceVirtualEnvironmentContainerDiskDatastoreID, []interface{}{disk}) err := d.Set(mkResourceVirtualEnvironmentContainerDiskDatastoreID, []interface{}{disk})
diags = append(diags, diag.FromErr(err)...)
} }
} else if len(currentDisk) > 0 || } else if len(currentDisk) > 0 ||
disk[mkResourceVirtualEnvironmentContainerDiskDatastoreID] != dvResourceVirtualEnvironmentContainerDiskDatastoreID { disk[mkResourceVirtualEnvironmentContainerDiskDatastoreID] != dvResourceVirtualEnvironmentContainerDiskDatastoreID {
d.Set(mkResourceVirtualEnvironmentContainerDiskDatastoreID, []interface{}{disk}) err := d.Set(mkResourceVirtualEnvironmentContainerDiskDatastoreID, []interface{}{disk})
diags = append(diags, diag.FromErr(err)...)
} }
// Compare the memory configuration to the one stored in the state. // Compare the memory configuration to the one stored in the state.
@ -1430,12 +1420,14 @@ func resourceVirtualEnvironmentContainerRead(d *schema.ResourceData, m interface
if len(clone) > 0 { if len(clone) > 0 {
if len(currentMemory) > 0 { if len(currentMemory) > 0 {
d.Set(mkResourceVirtualEnvironmentContainerMemory, []interface{}{memory}) err := d.Set(mkResourceVirtualEnvironmentContainerMemory, []interface{}{memory})
diags = append(diags, diag.FromErr(err)...)
} }
} else if len(currentMemory) > 0 || } else if len(currentMemory) > 0 ||
memory[mkResourceVirtualEnvironmentContainerMemoryDedicated] != dvResourceVirtualEnvironmentContainerMemoryDedicated || memory[mkResourceVirtualEnvironmentContainerMemoryDedicated] != dvResourceVirtualEnvironmentContainerMemoryDedicated ||
memory[mkResourceVirtualEnvironmentContainerMemorySwap] != dvResourceVirtualEnvironmentContainerMemorySwap { memory[mkResourceVirtualEnvironmentContainerMemorySwap] != dvResourceVirtualEnvironmentContainerMemorySwap {
d.Set(mkResourceVirtualEnvironmentContainerMemory, []interface{}{memory}) err := d.Set(mkResourceVirtualEnvironmentContainerMemory, []interface{}{memory})
diags = append(diags, diag.FromErr(err)...)
} }
// Compare the initialization and network interface configuration to the one stored in the state. // Compare the initialization and network interface configuration to the one stored in the state.
@ -1465,7 +1457,7 @@ func resourceVirtualEnvironmentContainerRead(d *schema.ResourceData, m interface
initialization[mkResourceVirtualEnvironmentContainerInitializationHostname] = "" initialization[mkResourceVirtualEnvironmentContainerInitializationHostname] = ""
} }
ipConfigList := []interface{}{} var ipConfigList []interface{}
networkInterfaceArray := []*proxmox.VirtualEnvironmentContainerCustomNetworkInterface{ networkInterfaceArray := []*proxmox.VirtualEnvironmentContainerCustomNetworkInterface{
containerConfig.NetworkInterface0, containerConfig.NetworkInterface0,
containerConfig.NetworkInterface1, containerConfig.NetworkInterface1,
@ -1476,7 +1468,7 @@ func resourceVirtualEnvironmentContainerRead(d *schema.ResourceData, m interface
containerConfig.NetworkInterface6, containerConfig.NetworkInterface6,
containerConfig.NetworkInterface7, containerConfig.NetworkInterface7,
} }
networkInterfaceList := []interface{}{} var networkInterfaceList []interface{}
for _, nv := range networkInterfaceArray { for _, nv := range networkInterfaceArray {
if nv == nil { if nv == nil {
@ -1594,25 +1586,29 @@ func resourceVirtualEnvironmentContainerRead(d *schema.ResourceData, m interface
} }
if len(initialization) > 0 { if len(initialization) > 0 {
d.Set(mkResourceVirtualEnvironmentContainerInitialization, []interface{}{initialization}) err = d.Set(mkResourceVirtualEnvironmentContainerInitialization, []interface{}{initialization})
} else { } else {
d.Set(mkResourceVirtualEnvironmentContainerInitialization, []interface{}{}) err = d.Set(mkResourceVirtualEnvironmentContainerInitialization, []interface{}{})
} }
diags = append(diags, diag.FromErr(err)...)
} }
currentNetworkInterface := d.Get(mkResourceVirtualEnvironmentContainerNetworkInterface).([]interface{}) currentNetworkInterface := d.Get(mkResourceVirtualEnvironmentContainerNetworkInterface).([]interface{})
if len(currentNetworkInterface) > 0 { if len(currentNetworkInterface) > 0 {
d.Set(mkResourceVirtualEnvironmentContainerNetworkInterface, networkInterfaceList) err := d.Set(mkResourceVirtualEnvironmentContainerNetworkInterface, networkInterfaceList)
diags = append(diags, diag.FromErr(err)...)
} }
} else { } else {
if len(initialization) > 0 { if len(initialization) > 0 {
d.Set(mkResourceVirtualEnvironmentContainerInitialization, []interface{}{initialization}) err = d.Set(mkResourceVirtualEnvironmentContainerInitialization, []interface{}{initialization})
} else { } else {
d.Set(mkResourceVirtualEnvironmentContainerInitialization, []interface{}{}) err = d.Set(mkResourceVirtualEnvironmentContainerInitialization, []interface{}{})
} }
diags = append(diags, diag.FromErr(err)...)
d.Set(mkResourceVirtualEnvironmentContainerNetworkInterface, networkInterfaceList) err := d.Set(mkResourceVirtualEnvironmentContainerNetworkInterface, networkInterfaceList)
diags = append(diags, diag.FromErr(err)...)
} }
// Compare the operating system configuration to the one stored in the state. // Compare the operating system configuration to the one stored in the state.
@ -1635,48 +1631,49 @@ func resourceVirtualEnvironmentContainerRead(d *schema.ResourceData, m interface
if len(clone) > 0 { if len(clone) > 0 {
if len(currentMemory) > 0 { if len(currentMemory) > 0 {
d.Set(mkResourceVirtualEnvironmentContainerOperatingSystem, []interface{}{operatingSystem}) err := d.Set(mkResourceVirtualEnvironmentContainerOperatingSystem, []interface{}{operatingSystem})
diags = append(diags, diag.FromErr(err)...)
} }
} else if len(currentOperatingSystem) > 0 || } else if len(currentOperatingSystem) > 0 ||
operatingSystem[mkResourceVirtualEnvironmentContainerOperatingSystemType] != dvResourceVirtualEnvironmentContainerOperatingSystemType { operatingSystem[mkResourceVirtualEnvironmentContainerOperatingSystemType] != dvResourceVirtualEnvironmentContainerOperatingSystemType {
d.Set(mkResourceVirtualEnvironmentContainerOperatingSystem, []interface{}{operatingSystem}) err := d.Set(mkResourceVirtualEnvironmentContainerOperatingSystem, []interface{}{operatingSystem})
diags = append(diags, diag.FromErr(err)...)
} }
currentTemplate := d.Get(mkResourceVirtualEnvironmentContainerTemplate).(bool) currentTemplate := d.Get(mkResourceVirtualEnvironmentContainerTemplate).(bool)
if len(clone) == 0 || currentTemplate != dvResourceVirtualEnvironmentContainerTemplate { if len(clone) == 0 || currentTemplate != dvResourceVirtualEnvironmentContainerTemplate {
if containerConfig.Template != nil { if containerConfig.Template != nil {
d.Set(mkResourceVirtualEnvironmentContainerTemplate, bool(*containerConfig.Template)) err = d.Set(mkResourceVirtualEnvironmentContainerTemplate, bool(*containerConfig.Template))
} else { } else {
d.Set(mkResourceVirtualEnvironmentContainerTemplate, false) err = d.Set(mkResourceVirtualEnvironmentContainerTemplate, false)
} }
diags = append(diags, diag.FromErr(err)...)
} }
// Determine the state of the container in order to update the "started" argument. // Determine the state of the container in order to update the "started" argument.
status, err := veClient.GetContainerStatus(nodeName, vmID) status, err := veClient.GetContainerStatus(ctx, nodeName, vmID)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
d.Set(mkResourceVirtualEnvironmentContainerStarted, status.Status == "running") err = d.Set(mkResourceVirtualEnvironmentContainerStarted, status.Status == "running")
diags = append(diags, diag.FromErr(err)...)
return nil return diags
} }
func resourceVirtualEnvironmentContainerUpdate(d *schema.ResourceData, m interface{}) error { func resourceVirtualEnvironmentContainerUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
nodeName := d.Get(mkResourceVirtualEnvironmentContainerNodeName).(string) nodeName := d.Get(mkResourceVirtualEnvironmentContainerNodeName).(string)
vmID, err := strconv.Atoi(d.Id()) vmID, err := strconv.Atoi(d.Id())
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
// Prepare the new request object. // Prepare the new request object.
@ -1702,10 +1699,9 @@ func resourceVirtualEnvironmentContainerUpdate(d *schema.ResourceData, m interfa
// Prepare the new console configuration. // Prepare the new console configuration.
if d.HasChange(mkResourceVirtualEnvironmentContainerConsole) { if d.HasChange(mkResourceVirtualEnvironmentContainerConsole) {
consoleBlock, err := getSchemaBlock(resource, d, m, []string{mkResourceVirtualEnvironmentContainerConsole}, 0, true) consoleBlock, err := getSchemaBlock(resource, d, []string{mkResourceVirtualEnvironmentContainerConsole}, 0, true)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
consoleEnabled := proxmox.CustomBool(consoleBlock[mkResourceVirtualEnvironmentContainerConsoleEnabled].(bool)) consoleEnabled := proxmox.CustomBool(consoleBlock[mkResourceVirtualEnvironmentContainerConsoleEnabled].(bool))
@ -1721,10 +1717,9 @@ func resourceVirtualEnvironmentContainerUpdate(d *schema.ResourceData, m interfa
// Prepare the new CPU configuration. // Prepare the new CPU configuration.
if d.HasChange(mkResourceVirtualEnvironmentContainerCPU) { if d.HasChange(mkResourceVirtualEnvironmentContainerCPU) {
cpuBlock, err := getSchemaBlock(resource, d, m, []string{mkResourceVirtualEnvironmentContainerCPU}, 0, true) cpuBlock, err := getSchemaBlock(resource, d, []string{mkResourceVirtualEnvironmentContainerCPU}, 0, true)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
cpuArchitecture := cpuBlock[mkResourceVirtualEnvironmentContainerCPUArchitecture].(string) cpuArchitecture := cpuBlock[mkResourceVirtualEnvironmentContainerCPUArchitecture].(string)
@ -1743,10 +1738,10 @@ func resourceVirtualEnvironmentContainerUpdate(d *schema.ResourceData, m interfa
initializationDNSDomain := dvResourceVirtualEnvironmentContainerInitializationDNSDomain initializationDNSDomain := dvResourceVirtualEnvironmentContainerInitializationDNSDomain
initializationDNSServer := dvResourceVirtualEnvironmentContainerInitializationDNSServer initializationDNSServer := dvResourceVirtualEnvironmentContainerInitializationDNSServer
initializationHostname := dvResourceVirtualEnvironmentContainerInitializationHostname initializationHostname := dvResourceVirtualEnvironmentContainerInitializationHostname
initializationIPConfigIPv4Address := []string{} var initializationIPConfigIPv4Address []string
initializationIPConfigIPv4Gateway := []string{} var initializationIPConfigIPv4Gateway []string
initializationIPConfigIPv6Address := []string{} var initializationIPConfigIPv6Address []string
initializationIPConfigIPv6Gateway := []string{} var initializationIPConfigIPv6Gateway []string
if len(initialization) > 0 { if len(initialization) > 0 {
initializationBlock := initialization[0].(map[string]interface{}) initializationBlock := initialization[0].(map[string]interface{})
@ -1799,10 +1794,9 @@ func resourceVirtualEnvironmentContainerUpdate(d *schema.ResourceData, m interfa
// Prepare the new memory configuration. // Prepare the new memory configuration.
if d.HasChange(mkResourceVirtualEnvironmentContainerMemory) { if d.HasChange(mkResourceVirtualEnvironmentContainerMemory) {
memoryBlock, err := getSchemaBlock(resource, d, m, []string{mkResourceVirtualEnvironmentContainerMemory}, 0, true) memoryBlock, err := getSchemaBlock(resource, d, []string{mkResourceVirtualEnvironmentContainerMemory}, 0, true)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
memoryDedicated := memoryBlock[mkResourceVirtualEnvironmentContainerMemoryDedicated].(int) memoryDedicated := memoryBlock[mkResourceVirtualEnvironmentContainerMemoryDedicated].(int)
@ -1818,10 +1812,9 @@ func resourceVirtualEnvironmentContainerUpdate(d *schema.ResourceData, m interfa
networkInterface := d.Get(mkResourceVirtualEnvironmentContainerNetworkInterface).([]interface{}) networkInterface := d.Get(mkResourceVirtualEnvironmentContainerNetworkInterface).([]interface{})
if len(networkInterface) == 0 && len(clone) > 0 { if len(networkInterface) == 0 && len(clone) > 0 {
networkInterface, err = resourceVirtualEnvironmentContainerGetExistingNetworkInterface(veClient, nodeName, vmID) networkInterface, err = resourceVirtualEnvironmentContainerGetExistingNetworkInterface(ctx, veClient, nodeName, vmID)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
} }
@ -1897,10 +1890,9 @@ func resourceVirtualEnvironmentContainerUpdate(d *schema.ResourceData, m interfa
// Prepare the new operating system configuration. // Prepare the new operating system configuration.
if d.HasChange(mkResourceVirtualEnvironmentContainerOperatingSystem) { if d.HasChange(mkResourceVirtualEnvironmentContainerOperatingSystem) {
operatingSystem, err := getSchemaBlock(resource, d, m, []string{mkResourceVirtualEnvironmentContainerOperatingSystem}, 0, true) operatingSystem, err := getSchemaBlock(resource, d, []string{mkResourceVirtualEnvironmentContainerOperatingSystem}, 0, true)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
operatingSystemType := operatingSystem[mkResourceVirtualEnvironmentContainerOperatingSystemType].(string) operatingSystemType := operatingSystem[mkResourceVirtualEnvironmentContainerOperatingSystemType].(string)
@ -1911,10 +1903,9 @@ func resourceVirtualEnvironmentContainerUpdate(d *schema.ResourceData, m interfa
} }
// Update the configuration now that everything has been prepared. // Update the configuration now that everything has been prepared.
err = veClient.UpdateContainer(nodeName, vmID, &updateBody) err = veClient.UpdateContainer(ctx, nodeName, vmID, &updateBody)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
// Determine if the state of the container needs to be changed. // Determine if the state of the container needs to be changed.
@ -1922,34 +1913,30 @@ func resourceVirtualEnvironmentContainerUpdate(d *schema.ResourceData, m interfa
if d.HasChange(mkResourceVirtualEnvironmentContainerStarted) && !bool(template) { if d.HasChange(mkResourceVirtualEnvironmentContainerStarted) && !bool(template) {
if started { if started {
err = veClient.StartContainer(nodeName, vmID) err = veClient.StartContainer(ctx, nodeName, vmID)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
err = veClient.WaitForContainerState(nodeName, vmID, "running", 300, 5) err = veClient.WaitForContainerState(ctx, nodeName, vmID, "running", 300, 5)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
} else { } else {
forceStop := proxmox.CustomBool(true) forceStop := proxmox.CustomBool(true)
shutdownTimeout := 300 shutdownTimeout := 300
err = veClient.ShutdownContainer(nodeName, vmID, &proxmox.VirtualEnvironmentContainerShutdownRequestBody{ err = veClient.ShutdownContainer(ctx, nodeName, vmID, &proxmox.VirtualEnvironmentContainerShutdownRequestBody{
ForceStop: &forceStop, ForceStop: &forceStop,
Timeout: &shutdownTimeout, Timeout: &shutdownTimeout,
}) })
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
err = veClient.WaitForContainerState(nodeName, vmID, "stopped", 300, 5) err = veClient.WaitForContainerState(ctx, nodeName, vmID, "stopped", 300, 5)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
rebootRequired = false rebootRequired = false
@ -1960,61 +1947,55 @@ func resourceVirtualEnvironmentContainerUpdate(d *schema.ResourceData, m interfa
if !bool(template) && rebootRequired { if !bool(template) && rebootRequired {
rebootTimeout := 300 rebootTimeout := 300
err = veClient.RebootContainer(nodeName, vmID, &proxmox.VirtualEnvironmentContainerRebootRequestBody{ err = veClient.RebootContainer(ctx, nodeName, vmID, &proxmox.VirtualEnvironmentContainerRebootRequestBody{
Timeout: &rebootTimeout, Timeout: &rebootTimeout,
}) })
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
} }
return resourceVirtualEnvironmentContainerRead(d, m) return resourceVirtualEnvironmentContainerRead(ctx, d, m)
} }
func resourceVirtualEnvironmentContainerDelete(d *schema.ResourceData, m interface{}) error { func resourceVirtualEnvironmentContainerDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
nodeName := d.Get(mkResourceVirtualEnvironmentContainerNodeName).(string) nodeName := d.Get(mkResourceVirtualEnvironmentContainerNodeName).(string)
vmID, err := strconv.Atoi(d.Id()) vmID, err := strconv.Atoi(d.Id())
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
// Shut down the container before deleting it. // Shut down the container before deleting it.
status, err := veClient.GetContainerStatus(nodeName, vmID) status, err := veClient.GetContainerStatus(ctx, nodeName, vmID)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
if status.Status != "stopped" { if status.Status != "stopped" {
forceStop := proxmox.CustomBool(true) forceStop := proxmox.CustomBool(true)
shutdownTimeout := 300 shutdownTimeout := 300
err = veClient.ShutdownContainer(nodeName, vmID, &proxmox.VirtualEnvironmentContainerShutdownRequestBody{ err = veClient.ShutdownContainer(ctx, nodeName, vmID, &proxmox.VirtualEnvironmentContainerShutdownRequestBody{
ForceStop: &forceStop, ForceStop: &forceStop,
Timeout: &shutdownTimeout, Timeout: &shutdownTimeout,
}) })
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
err = veClient.WaitForContainerState(nodeName, vmID, "stopped", 30, 5) err = veClient.WaitForContainerState(ctx, nodeName, vmID, "stopped", 30, 5)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
} }
err = veClient.DeleteContainer(nodeName, vmID) err = veClient.DeleteContainer(ctx, nodeName, vmID)
if err != nil { if err != nil {
if strings.Contains(err.Error(), "HTTP 404") { if strings.Contains(err.Error(), "HTTP 404") {
@ -2022,15 +2003,13 @@ func resourceVirtualEnvironmentContainerDelete(d *schema.ResourceData, m interfa
return nil return nil
} }
return diag.FromErr(err)
return err
} }
// Wait for the state to become unavailable as that clearly indicates the destruction of the container. // Wait for the state to become unavailable as that clearly indicates the destruction of the container.
err = veClient.WaitForContainerState(nodeName, vmID, "", 60, 2) err = veClient.WaitForContainerState(ctx, nodeName, vmID, "", 60, 2)
if err == nil { if err == nil {
return fmt.Errorf("Failed to delete container \"%d\"", vmID) return diag.Errorf("failed to delete container \"%d\"", vmID)
} }
d.SetId("") d.SetId("")

View File

@ -7,7 +7,7 @@ package proxmoxtf
import ( import (
"testing" "testing"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
// TestResourceVirtualEnvironmentContainerInstantiation tests whether the ResourceVirtualEnvironmentContainer instance can be instantiated. // TestResourceVirtualEnvironmentContainerInstantiation tests whether the ResourceVirtualEnvironmentContainer instance can be instantiated.

View File

@ -5,10 +5,12 @@
package proxmoxtf package proxmoxtf
import ( import (
"context"
"fmt" "fmt"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/bpg/terraform-provider-proxmox/proxmox" "github.com/bpg/terraform-provider-proxmox/proxmox"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
const ( const (
@ -43,18 +45,17 @@ func resourceVirtualEnvironmentDNS() *schema.Resource {
MaxItems: 3, MaxItems: 3,
}, },
}, },
Create: resourceVirtualEnvironmentDNSCreate, CreateContext: resourceVirtualEnvironmentDNSCreate,
Read: resourceVirtualEnvironmentDNSRead, ReadContext: resourceVirtualEnvironmentDNSRead,
Update: resourceVirtualEnvironmentDNSUpdate, UpdateContext: resourceVirtualEnvironmentDNSUpdate,
Delete: resourceVirtualEnvironmentDNSDelete, DeleteContext: resourceVirtualEnvironmentDNSDelete,
} }
} }
func resourceVirtualEnvironmentDNSCreate(d *schema.ResourceData, m interface{}) error { func resourceVirtualEnvironmentDNSCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
err := resourceVirtualEnvironmentDNSUpdate(d, m) diags := resourceVirtualEnvironmentDNSUpdate(ctx, d, m)
if diags.HasError() {
if err != nil { return diags
return err
} }
nodeName := d.Get(mkResourceVirtualEnvironmentDNSNodeName).(string) nodeName := d.Get(mkResourceVirtualEnvironmentDNSNodeName).(string)
@ -64,7 +65,7 @@ func resourceVirtualEnvironmentDNSCreate(d *schema.ResourceData, m interface{})
return nil return nil
} }
func resourceVirtualEnvironmentDNSGetUpdateBody(d *schema.ResourceData, m interface{}) (*proxmox.VirtualEnvironmentDNSUpdateRequestBody, error) { func resourceVirtualEnvironmentDNSGetUpdateBody(d *schema.ResourceData) (*proxmox.VirtualEnvironmentDNSUpdateRequestBody, error) {
domain := d.Get(mkResourceVirtualEnvironmentDNSDomain).(string) domain := d.Get(mkResourceVirtualEnvironmentDNSDomain).(string)
servers := d.Get(mkResourceVirtualEnvironmentDNSServers).([]interface{}) servers := d.Get(mkResourceVirtualEnvironmentDNSServers).([]interface{})
@ -88,28 +89,29 @@ func resourceVirtualEnvironmentDNSGetUpdateBody(d *schema.ResourceData, m interf
return body, nil return body, nil
} }
func resourceVirtualEnvironmentDNSRead(d *schema.ResourceData, m interface{}) error { func resourceVirtualEnvironmentDNSRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
var diags diag.Diagnostics
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
nodeName := d.Get(mkResourceVirtualEnvironmentDNSNodeName).(string) nodeName := d.Get(mkResourceVirtualEnvironmentDNSNodeName).(string)
dns, err := veClient.GetDNS(nodeName) dns, err := veClient.GetDNS(ctx, nodeName)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
if dns.SearchDomain != nil { if dns.SearchDomain != nil {
d.Set(mkResourceVirtualEnvironmentDNSDomain, *dns.SearchDomain) err = d.Set(mkResourceVirtualEnvironmentDNSDomain, *dns.SearchDomain)
} else { } else {
d.Set(mkResourceVirtualEnvironmentDNSDomain, "") err = d.Set(mkResourceVirtualEnvironmentDNSDomain, "")
} }
diags = append(diags, diag.FromErr(err)...)
servers := []interface{}{} var servers []interface{}
if dns.Server1 != nil { if dns.Server1 != nil {
servers = append(servers, *dns.Server1) servers = append(servers, *dns.Server1)
@ -123,37 +125,35 @@ func resourceVirtualEnvironmentDNSRead(d *schema.ResourceData, m interface{}) er
servers = append(servers, *dns.Server3) servers = append(servers, *dns.Server3)
} }
d.Set(mkResourceVirtualEnvironmentDNSServers, servers) err = d.Set(mkResourceVirtualEnvironmentDNSServers, servers)
diags = append(diags, diag.FromErr(err)...)
return nil return diags
} }
func resourceVirtualEnvironmentDNSUpdate(d *schema.ResourceData, m interface{}) error { func resourceVirtualEnvironmentDNSUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
nodeName := d.Get(mkResourceVirtualEnvironmentDNSNodeName).(string) nodeName := d.Get(mkResourceVirtualEnvironmentDNSNodeName).(string)
body, err := resourceVirtualEnvironmentDNSGetUpdateBody(d, m) body, err := resourceVirtualEnvironmentDNSGetUpdateBody(d)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
err = veClient.UpdateDNS(nodeName, body) err = veClient.UpdateDNS(ctx, nodeName, body)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
return resourceVirtualEnvironmentDNSRead(d, m) return resourceVirtualEnvironmentDNSRead(ctx, d, m)
} }
func resourceVirtualEnvironmentDNSDelete(d *schema.ResourceData, m interface{}) error { func resourceVirtualEnvironmentDNSDelete(_ context.Context, d *schema.ResourceData, _ interface{}) diag.Diagnostics {
d.SetId("") d.SetId("")
return nil return nil

View File

@ -7,7 +7,7 @@ package proxmoxtf
import ( import (
"testing" "testing"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
// TestResourceVirtualEnvironmentDNSInstantiation tests whether the ResourceVirtualEnvironmentDNS instance can be instantiated. // TestResourceVirtualEnvironmentDNSInstantiation tests whether the ResourceVirtualEnvironmentDNS instance can be instantiated.

View File

@ -6,12 +6,15 @@ package proxmoxtf
import ( import (
"bytes" "bytes"
"context"
"crypto/sha256" "crypto/sha256"
"crypto/tls" "crypto/tls"
"fmt" "fmt"
"github.com/hashicorp/go-cty/cty"
"github.com/hashicorp/terraform-plugin-log/tflog"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"io" "io"
"io/ioutil" "io/ioutil"
"log"
"net/http" "net/http"
"net/url" "net/url"
"os" "os"
@ -20,7 +23,7 @@ import (
"time" "time"
"github.com/bpg/terraform-provider-proxmox/proxmox" "github.com/bpg/terraform-provider-proxmox/proxmox"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
const ( const (
@ -60,7 +63,7 @@ func resourceVirtualEnvironmentFile() *schema.Resource {
Optional: true, Optional: true,
ForceNew: true, ForceNew: true,
Default: dvResourceVirtualEnvironmentFileContentType, Default: dvResourceVirtualEnvironmentFileContentType,
ValidateFunc: getContentTypeValidator(), ValidateDiagFunc: getContentTypeValidator(),
}, },
mkResourceVirtualEnvironmentFileDatastoreID: { mkResourceVirtualEnvironmentFileDatastoreID: {
Type: schema.TypeString, Type: schema.TypeString,
@ -181,32 +184,27 @@ func resourceVirtualEnvironmentFile() *schema.Resource {
MinItems: 0, MinItems: 0,
}, },
}, },
Create: resourceVirtualEnvironmentFileCreate, CreateContext: resourceVirtualEnvironmentFileCreate,
Read: resourceVirtualEnvironmentFileRead, ReadContext: resourceVirtualEnvironmentFileRead,
Delete: resourceVirtualEnvironmentFileDelete, DeleteContext: resourceVirtualEnvironmentFileDelete,
} }
} }
func resourceVirtualEnvironmentFileCreate(d *schema.ResourceData, m interface{}) error { func resourceVirtualEnvironmentFileCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
var diags diag.Diagnostics
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
contentType, err := resourceVirtualEnvironmentFileGetContentType(d, m) contentType, dg := resourceVirtualEnvironmentFileGetContentType(d)
diags = append(diags, dg...)
if err != nil {
return err
}
datastoreID := d.Get(mkResourceVirtualEnvironmentFileDatastoreID).(string) datastoreID := d.Get(mkResourceVirtualEnvironmentFileDatastoreID).(string)
fileName, err := resourceVirtualEnvironmentFileGetFileName(d, m) fileName, err := resourceVirtualEnvironmentFileGetFileName(d)
diags = append(diags, diag.FromErr(err)...)
if err != nil {
return err
}
nodeName := d.Get(mkResourceVirtualEnvironmentFileNodeName).(string) nodeName := d.Get(mkResourceVirtualEnvironmentFileNodeName).(string)
sourceFile := d.Get(mkResourceVirtualEnvironmentFileSourceFile).([]interface{}) sourceFile := d.Get(mkResourceVirtualEnvironmentFileSourceFile).([]interface{})
@ -216,12 +214,16 @@ func resourceVirtualEnvironmentFileCreate(d *schema.ResourceData, m interface{})
// Determine if both source_data and source_file is specified as this is not supported. // Determine if both source_data and source_file is specified as this is not supported.
if len(sourceFile) > 0 && len(sourceRaw) > 0 { if len(sourceFile) > 0 && len(sourceRaw) > 0 {
return fmt.Errorf( diags = append(diags, diag.Errorf(
"Please specify \"%s.%s\" or \"%s\" - not both", "please specify \"%s.%s\" or \"%s\" - not both",
mkResourceVirtualEnvironmentFileSourceFile, mkResourceVirtualEnvironmentFileSourceFile,
mkResourceVirtualEnvironmentFileSourceFilePath, mkResourceVirtualEnvironmentFileSourceFilePath,
mkResourceVirtualEnvironmentFileSourceRaw, mkResourceVirtualEnvironmentFileSourceRaw,
) )...)
}
if diags.HasError() {
return diags
} }
// Determine if we're dealing with raw file data or a reference to a file or URL. // Determine if we're dealing with raw file data or a reference to a file or URL.
@ -233,8 +235,10 @@ func resourceVirtualEnvironmentFileCreate(d *schema.ResourceData, m interface{})
sourceFileChecksum := sourceFileBlock[mkResourceVirtualEnvironmentFileSourceFileChecksum].(string) sourceFileChecksum := sourceFileBlock[mkResourceVirtualEnvironmentFileSourceFileChecksum].(string)
sourceFileInsecure := sourceFileBlock[mkResourceVirtualEnvironmentFileSourceFileInsecure].(bool) sourceFileInsecure := sourceFileBlock[mkResourceVirtualEnvironmentFileSourceFileInsecure].(bool)
if resourceVirtualEnvironmentFileIsURL(d, m) { if resourceVirtualEnvironmentFileIsURL(d) {
log.Printf("[DEBUG] Downloading file from '%s'", sourceFilePath) tflog.Debug(ctx, "Downloading file from URL", map[string]interface{}{
"url": sourceFilePath,
})
httpClient := http.Client{ httpClient := http.Client{
Transport: &http.Transport{ Transport: &http.Transport{
@ -245,31 +249,42 @@ func resourceVirtualEnvironmentFileCreate(d *schema.ResourceData, m interface{})
} }
res, err := httpClient.Get(sourceFilePath) res, err := httpClient.Get(sourceFilePath)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
defer func(Body io.ReadCloser) {
defer res.Body.Close() err := Body.Close()
if err != nil {
tflog.Error(ctx, "Failed to close body", map[string]interface{}{
"error": err,
})
}
}(res.Body)
tempDownloadedFile, err := ioutil.TempFile("", "download") tempDownloadedFile, err := ioutil.TempFile("", "download")
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
tempDownloadedFileName := tempDownloadedFile.Name() tempDownloadedFileName := tempDownloadedFile.Name()
_, err = io.Copy(tempDownloadedFile, res.Body) defer func(name string) {
err := os.Remove(name)
if err != nil { if err != nil {
tempDownloadedFile.Close() tflog.Error(ctx, "Failed to remove temporary file", map[string]interface{}{
"error": err,
return err "file": name,
})
} }
}(tempDownloadedFileName)
tempDownloadedFile.Close() _, err = io.Copy(tempDownloadedFile, res.Body)
diags = append(diags, diag.FromErr(err)...)
err = tempDownloadedFile.Close()
diags = append(diags, diag.FromErr(err)...)
defer os.Remove(tempDownloadedFileName) if diags.HasError() {
return diags
}
sourceFilePathLocal = tempDownloadedFileName sourceFilePathLocal = tempDownloadedFileName
} else { } else {
@ -279,28 +294,27 @@ func resourceVirtualEnvironmentFileCreate(d *schema.ResourceData, m interface{})
// Calculate the checksum of the source file now that it's available locally. // Calculate the checksum of the source file now that it's available locally.
if sourceFileChecksum != "" { if sourceFileChecksum != "" {
file, err := os.Open(sourceFilePathLocal) file, err := os.Open(sourceFilePathLocal)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
h := sha256.New() h := sha256.New()
_, err = io.Copy(h, file) _, err = io.Copy(h, file)
diags = append(diags, diag.FromErr(err)...)
if err != nil { err = file.Close()
file.Close() diags = append(diags, diag.FromErr(err)...)
if diags.HasError() {
return err return diags
} }
file.Close()
calculatedChecksum := fmt.Sprintf("%x", h.Sum(nil)) calculatedChecksum := fmt.Sprintf("%x", h.Sum(nil))
tflog.Debug(ctx, "Calculated checksum", map[string]interface{}{
log.Printf("[DEBUG] The calculated SHA256 checksum for source \"%s\" is \"%s\"", sourceFilePath, calculatedChecksum) "source": sourceFilePath,
"sha256": calculatedChecksum,
})
if sourceFileChecksum != calculatedChecksum { if sourceFileChecksum != calculatedChecksum {
return fmt.Errorf("The calculated SHA256 checksum \"%s\" does not match source checksum \"%s\"", calculatedChecksum, sourceFileChecksum) return diag.Errorf("the calculated SHA256 checksum \"%s\" does not match source checksum \"%s\"", calculatedChecksum, sourceFileChecksum)
} }
} }
} else if len(sourceRaw) > 0 { } else if len(sourceRaw) > 0 {
@ -312,33 +326,38 @@ func resourceVirtualEnvironmentFileCreate(d *schema.ResourceData, m interface{})
if len(sourceRawData) <= sourceRawResize { if len(sourceRawData) <= sourceRawResize {
sourceRawData = fmt.Sprintf(fmt.Sprintf("%%-%dv", sourceRawResize), sourceRawData) sourceRawData = fmt.Sprintf(fmt.Sprintf("%%-%dv", sourceRawResize), sourceRawData)
} else { } else {
return fmt.Errorf("Cannot resize %d bytes to %d bytes", len(sourceRawData), sourceRawResize) return diag.Errorf("cannot resize %d bytes to %d bytes", len(sourceRawData), sourceRawResize)
} }
} }
tempRawFile, err := ioutil.TempFile("", "raw") tempRawFile, err := ioutil.TempFile("", "raw")
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
tempRawFileName := tempRawFile.Name() tempRawFileName := tempRawFile.Name()
_, err = io.Copy(tempRawFile, bytes.NewBufferString(sourceRawData)) _, err = io.Copy(tempRawFile, bytes.NewBufferString(sourceRawData))
diags = append(diags, diag.FromErr(err)...)
if err != nil { err = tempRawFile.Close()
tempRawFile.Close() diags = append(diags, diag.FromErr(err)...)
if diags.HasError() {
return err return diags
} }
tempRawFile.Close() defer func(name string) {
err := os.Remove(name)
defer os.Remove(tempRawFileName) if err != nil {
tflog.Error(ctx, "Failed to remove temporary file", map[string]interface{}{
"error": err,
"file": name,
})
}
}(tempRawFileName)
sourceFilePathLocal = tempRawFileName sourceFilePathLocal = tempRawFileName
} else { } else {
return fmt.Errorf( return diag.Errorf(
"Please specify either \"%s.%s\" or \"%s\"", "please specify either \"%s.%s\" or \"%s\"",
mkResourceVirtualEnvironmentFileSourceFile, mkResourceVirtualEnvironmentFileSourceFile,
mkResourceVirtualEnvironmentFileSourceFilePath, mkResourceVirtualEnvironmentFileSourceFilePath,
mkResourceVirtualEnvironmentFileSourceRaw, mkResourceVirtualEnvironmentFileSourceRaw,
@ -347,12 +366,18 @@ func resourceVirtualEnvironmentFileCreate(d *schema.ResourceData, m interface{})
// Open the source file for reading in order to upload it. // Open the source file for reading in order to upload it.
file, err := os.Open(sourceFilePathLocal) file, err := os.Open(sourceFilePathLocal)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
defer file.Close() defer func(file *os.File) {
err := file.Close()
if err != nil {
tflog.Error(ctx, "Failed to close file", map[string]interface{}{
"error": err,
})
}
}(file)
body := &proxmox.VirtualEnvironmentDatastoreUploadRequestBody{ body := &proxmox.VirtualEnvironmentDatastoreUploadRequestBody{
ContentType: *contentType, ContentType: *contentType,
@ -362,24 +387,22 @@ func resourceVirtualEnvironmentFileCreate(d *schema.ResourceData, m interface{})
NodeName: nodeName, NodeName: nodeName,
} }
_, err = veClient.UploadFileToDatastore(body) _, err = veClient.UploadFileToDatastore(ctx, body)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
volumeID, err := resourceVirtualEnvironmentFileGetVolumeID(d, m) volumeID, diags := resourceVirtualEnvironmentFileGetVolumeID(d)
if diags.HasError() {
if err != nil { return diags
return err
} }
d.SetId(*volumeID) d.SetId(*volumeID)
return resourceVirtualEnvironmentFileRead(d, m) return resourceVirtualEnvironmentFileRead(ctx, d, m)
} }
func resourceVirtualEnvironmentFileGetContentType(d *schema.ResourceData, m interface{}) (*string, error) { func resourceVirtualEnvironmentFileGetContentType(d *schema.ResourceData) (*string, diag.Diagnostics) {
contentType := d.Get(mkResourceVirtualEnvironmentFileContentType).(string) contentType := d.Get(mkResourceVirtualEnvironmentFileContentType).(string)
sourceFile := d.Get(mkResourceVirtualEnvironmentFileSourceFile).([]interface{}) sourceFile := d.Get(mkResourceVirtualEnvironmentFileSourceFile).([]interface{})
sourceRaw := d.Get(mkResourceVirtualEnvironmentFileSourceRaw).([]interface{}) sourceRaw := d.Get(mkResourceVirtualEnvironmentFileSourceRaw).([]interface{})
@ -393,8 +416,8 @@ func resourceVirtualEnvironmentFileGetContentType(d *schema.ResourceData, m inte
sourceRawBlock := sourceRaw[0].(map[string]interface{}) sourceRawBlock := sourceRaw[0].(map[string]interface{})
sourceFilePath = sourceRawBlock[mkResourceVirtualEnvironmentFileSourceRawFileName].(string) sourceFilePath = sourceRawBlock[mkResourceVirtualEnvironmentFileSourceRawFileName].(string)
} else { } else {
return nil, fmt.Errorf( return nil, diag.Errorf(
"Missing argument \"%s.%s\" or \"%s\"", "missing argument \"%s.%s\" or \"%s\"",
mkResourceVirtualEnvironmentFileSourceFile, mkResourceVirtualEnvironmentFileSourceFile,
mkResourceVirtualEnvironmentFileSourceFilePath, mkResourceVirtualEnvironmentFileSourceFilePath,
mkResourceVirtualEnvironmentFileSourceRaw, mkResourceVirtualEnvironmentFileSourceRaw,
@ -417,8 +440,8 @@ func resourceVirtualEnvironmentFileGetContentType(d *schema.ResourceData, m inte
} }
if contentType == "" { if contentType == "" {
return nil, fmt.Errorf( return nil, diag.Errorf(
"Cannot determine the content type of source \"%s\" - Please manually define the \"%s\" argument", "cannot determine the content type of source \"%s\" - Please manually define the \"%s\" argument",
sourceFilePath, sourceFilePath,
mkResourceVirtualEnvironmentFileContentType, mkResourceVirtualEnvironmentFileContentType,
) )
@ -426,16 +449,12 @@ func resourceVirtualEnvironmentFileGetContentType(d *schema.ResourceData, m inte
} }
ctValidator := getContentTypeValidator() ctValidator := getContentTypeValidator()
_, errs := ctValidator(contentType, mkResourceVirtualEnvironmentFileContentType) diags := ctValidator(contentType, cty.GetAttrPath(mkResourceVirtualEnvironmentFileContentType))
if len(errs) > 0 { return &contentType, diags
return nil, errs[0]
} }
return &contentType, nil func resourceVirtualEnvironmentFileGetFileName(d *schema.ResourceData) (*string, error) {
}
func resourceVirtualEnvironmentFileGetFileName(d *schema.ResourceData, m interface{}) (*string, error) {
sourceFile := d.Get(mkResourceVirtualEnvironmentFileSourceFile).([]interface{}) sourceFile := d.Get(mkResourceVirtualEnvironmentFileSourceFile).([]interface{})
sourceRaw := d.Get(mkResourceVirtualEnvironmentFileSourceRaw).([]interface{}) sourceRaw := d.Get(mkResourceVirtualEnvironmentFileSourceRaw).([]interface{})
@ -451,14 +470,14 @@ func resourceVirtualEnvironmentFileGetFileName(d *schema.ResourceData, m interfa
sourceFileFileName = sourceRawBlock[mkResourceVirtualEnvironmentFileSourceRawFileName].(string) sourceFileFileName = sourceRawBlock[mkResourceVirtualEnvironmentFileSourceRawFileName].(string)
} else { } else {
return nil, fmt.Errorf( return nil, fmt.Errorf(
"Missing argument \"%s.%s\"", "missing argument \"%s.%s\"",
mkResourceVirtualEnvironmentFileSourceFile, mkResourceVirtualEnvironmentFileSourceFile,
mkResourceVirtualEnvironmentFileSourceFilePath, mkResourceVirtualEnvironmentFileSourceFilePath,
) )
} }
if sourceFileFileName == "" { if sourceFileFileName == "" {
if resourceVirtualEnvironmentFileIsURL(d, m) { if resourceVirtualEnvironmentFileIsURL(d) {
downloadURL, err := url.ParseRequestURI(sourceFilePath) downloadURL, err := url.ParseRequestURI(sourceFilePath)
if err != nil { if err != nil {
@ -469,7 +488,7 @@ func resourceVirtualEnvironmentFileGetFileName(d *schema.ResourceData, m interfa
sourceFileFileName = path[len(path)-1] sourceFileFileName = path[len(path)-1]
if sourceFileFileName == "" { if sourceFileFileName == "" {
return nil, fmt.Errorf("Failed to determine file name from the URL \"%s\"", sourceFilePath) return nil, fmt.Errorf("failed to determine file name from the URL \"%s\"", sourceFilePath)
} }
} else { } else {
sourceFileFileName = filepath.Base(sourceFilePath) sourceFileFileName = filepath.Base(sourceFilePath)
@ -479,26 +498,21 @@ func resourceVirtualEnvironmentFileGetFileName(d *schema.ResourceData, m interfa
return &sourceFileFileName, nil return &sourceFileFileName, nil
} }
func resourceVirtualEnvironmentFileGetVolumeID(d *schema.ResourceData, m interface{}) (*string, error) { func resourceVirtualEnvironmentFileGetVolumeID(d *schema.ResourceData) (*string, diag.Diagnostics) {
fileName, err := resourceVirtualEnvironmentFileGetFileName(d, m) fileName, err := resourceVirtualEnvironmentFileGetFileName(d)
if err != nil { if err != nil {
return nil, err return nil, diag.FromErr(err)
} }
datastoreID := d.Get(mkResourceVirtualEnvironmentFileDatastoreID).(string) datastoreID := d.Get(mkResourceVirtualEnvironmentFileDatastoreID).(string)
contentType, err := resourceVirtualEnvironmentFileGetContentType(d, m) contentType, diags := resourceVirtualEnvironmentFileGetContentType(d)
if err != nil {
return nil, err
}
volumeID := fmt.Sprintf("%s:%s/%s", datastoreID, *contentType, *fileName) volumeID := fmt.Sprintf("%s:%s/%s", datastoreID, *contentType, *fileName)
return &volumeID, nil return &volumeID, diags
} }
func resourceVirtualEnvironmentFileIsURL(d *schema.ResourceData, m interface{}) bool { func resourceVirtualEnvironmentFileIsURL(d *schema.ResourceData) bool {
sourceFile := d.Get(mkResourceVirtualEnvironmentFileSourceFile).([]interface{}) sourceFile := d.Get(mkResourceVirtualEnvironmentFileSourceFile).([]interface{})
sourceFilePath := "" sourceFilePath := ""
@ -512,12 +526,11 @@ func resourceVirtualEnvironmentFileIsURL(d *schema.ResourceData, m interface{})
return strings.HasPrefix(sourceFilePath, "http://") || strings.HasPrefix(sourceFilePath, "https://") return strings.HasPrefix(sourceFilePath, "http://") || strings.HasPrefix(sourceFilePath, "https://")
} }
func resourceVirtualEnvironmentFileRead(d *schema.ResourceData, m interface{}) error { func resourceVirtualEnvironmentFileRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
datastoreID := d.Get(mkResourceVirtualEnvironmentFileDatastoreID).(string) datastoreID := d.Get(mkResourceVirtualEnvironmentFileDatastoreID).(string)
@ -532,19 +545,19 @@ func resourceVirtualEnvironmentFileRead(d *schema.ResourceData, m interface{}) e
sourceFileBlock := sourceFile[0].(map[string]interface{}) sourceFileBlock := sourceFile[0].(map[string]interface{})
sourceFilePath = sourceFileBlock[mkResourceVirtualEnvironmentFileSourceFilePath].(string) sourceFilePath = sourceFileBlock[mkResourceVirtualEnvironmentFileSourceFilePath].(string)
list, err := veClient.ListDatastoreFiles(nodeName, datastoreID) list, err := veClient.ListDatastoreFiles(ctx, nodeName, datastoreID)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
fileIsURL := resourceVirtualEnvironmentFileIsURL(d, m) fileIsURL := resourceVirtualEnvironmentFileIsURL(d)
fileName, err := resourceVirtualEnvironmentFileGetFileName(d, m) fileName, err := resourceVirtualEnvironmentFileGetFileName(d)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
var diags diag.Diagnostics
for _, v := range list { for _, v := range list {
if v.VolumeID == d.Id() { if v.VolumeID == d.Id() {
var fileModificationDate string var fileModificationDate string
@ -552,31 +565,103 @@ func resourceVirtualEnvironmentFileRead(d *schema.ResourceData, m interface{}) e
var fileTag string var fileTag string
if fileIsURL { if fileIsURL {
res, err := http.Head(sourceFilePath) fileSize, fileModificationDate, fileTag, err = readURL(ctx, d, sourceFilePath)
} else {
fileModificationDate, fileSize, fileTag, err = readFile(ctx, sourceFilePath)
}
diags = append(diags, diag.FromErr(err)...)
if err != nil { lastFileModificationDate := d.Get(mkResourceVirtualEnvironmentFileFileModificationDate).(string)
return err lastFileSize := int64(d.Get(mkResourceVirtualEnvironmentFileFileSize).(int))
lastFileTag := d.Get(mkResourceVirtualEnvironmentFileFileTag).(string)
err = d.Set(mkResourceVirtualEnvironmentFileFileModificationDate, fileModificationDate)
diags = append(diags, diag.FromErr(err)...)
err = d.Set(mkResourceVirtualEnvironmentFileFileName, *fileName)
diags = append(diags, diag.FromErr(err)...)
err = d.Set(mkResourceVirtualEnvironmentFileFileSize, fileSize)
diags = append(diags, diag.FromErr(err)...)
err = d.Set(mkResourceVirtualEnvironmentFileFileTag, fileTag)
diags = append(diags, diag.FromErr(err)...)
sourceFileBlock[mkResourceVirtualEnvironmentFileSourceFileChanged] = lastFileModificationDate != fileModificationDate || lastFileSize != fileSize || lastFileTag != fileTag
err = d.Set(mkResourceVirtualEnvironmentFileSourceFile, sourceFile)
diags = append(diags, diag.FromErr(err)...)
if diags.HasError() {
return diags
}
return nil
}
} }
defer res.Body.Close() d.SetId("")
return nil
}
func readFile(ctx context.Context, sourceFilePath string) (fileModificationDate string, fileSize int64, fileTag string, err error) {
f, err := os.Open(sourceFilePath)
if err != nil {
return
}
defer func(f *os.File) {
var err = f.Close()
if err != nil {
tflog.Error(ctx, "failed to close the file", map[string]interface{}{
"error": err.Error(),
})
}
}(f)
fileInfo, err := f.Stat()
if err != nil {
return
}
fileModificationDate = fileInfo.ModTime().UTC().Format(time.RFC3339)
fileSize = fileInfo.Size()
fileTag = fmt.Sprintf("%x-%x", fileInfo.ModTime().UTC().Unix(), fileInfo.Size())
return fileModificationDate, fileSize, fileTag, nil
}
func readURL(ctx context.Context, d *schema.ResourceData, sourceFilePath string) (fileSize int64, fileModificationDate string, fileTag string, err error) {
res, err := http.Head(sourceFilePath)
if err != nil {
return
}
defer func(Body io.ReadCloser) {
var err = Body.Close()
if err != nil {
tflog.Error(ctx, "failed to close the response body", map[string]interface{}{
"error": err.Error(),
})
}
}(res.Body)
fileSize = res.ContentLength fileSize = res.ContentLength
httpLastModified := res.Header.Get("Last-Modified") httpLastModified := res.Header.Get("Last-Modified")
if httpLastModified != "" { if httpLastModified != "" {
timeParsed, err := time.Parse(time.RFC1123, httpLastModified) var timeParsed time.Time
timeParsed, err = time.Parse(time.RFC1123, httpLastModified)
if err != nil { if err != nil {
timeParsed, err = time.Parse(time.RFC1123Z, httpLastModified) timeParsed, err = time.Parse(time.RFC1123Z, httpLastModified)
if err != nil { if err != nil {
return err return
} }
} }
fileModificationDate = timeParsed.UTC().Format(time.RFC3339) fileModificationDate = timeParsed.UTC().Format(time.RFC3339)
} else { } else {
d.Set(mkResourceVirtualEnvironmentFileFileModificationDate, "") err = d.Set(mkResourceVirtualEnvironmentFileFileModificationDate, "")
if err != nil {
return
}
} }
httpTag := res.Header.Get("ETag") httpTag := res.Header.Get("ETag")
@ -592,66 +677,29 @@ func resourceVirtualEnvironmentFileRead(d *schema.ResourceData, m interface{}) e
} else { } else {
fileTag = "" fileTag = ""
} }
} else {
f, err := os.Open(sourceFilePath)
if err != nil { return
return err
} }
defer f.Close() func resourceVirtualEnvironmentFileDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
fileInfo, err := f.Stat()
if err != nil {
return err
}
fileModificationDate = fileInfo.ModTime().UTC().Format(time.RFC3339)
fileSize = fileInfo.Size()
fileTag = fmt.Sprintf("%x-%x", fileInfo.ModTime().UTC().Unix(), fileInfo.Size())
}
lastFileModificationDate := d.Get(mkResourceVirtualEnvironmentFileFileModificationDate).(string)
lastFileSize := int64(d.Get(mkResourceVirtualEnvironmentFileFileSize).(int))
lastFileTag := d.Get(mkResourceVirtualEnvironmentFileFileTag).(string)
d.Set(mkResourceVirtualEnvironmentFileFileModificationDate, fileModificationDate)
d.Set(mkResourceVirtualEnvironmentFileFileName, *fileName)
d.Set(mkResourceVirtualEnvironmentFileFileSize, fileSize)
d.Set(mkResourceVirtualEnvironmentFileFileTag, fileTag)
d.Set(mkResourceVirtualEnvironmentFileSourceFileChanged, lastFileModificationDate != fileModificationDate || lastFileSize != fileSize || lastFileTag != fileTag)
return nil
}
}
d.SetId("")
return nil
}
func resourceVirtualEnvironmentFileDelete(d *schema.ResourceData, m interface{}) error {
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
datastoreID := d.Get(mkResourceVirtualEnvironmentFileDatastoreID).(string) datastoreID := d.Get(mkResourceVirtualEnvironmentFileDatastoreID).(string)
nodeName := d.Get(mkResourceVirtualEnvironmentFileNodeName).(string) nodeName := d.Get(mkResourceVirtualEnvironmentFileNodeName).(string)
err = veClient.DeleteDatastoreFile(nodeName, datastoreID, d.Id()) err = veClient.DeleteDatastoreFile(ctx, nodeName, datastoreID, d.Id())
if err != nil { if err != nil {
if strings.Contains(err.Error(), "HTTP 404") { if strings.Contains(err.Error(), "HTTP 404") {
d.SetId("") d.SetId("")
return nil return nil
} }
return err return diag.FromErr(err)
} }
d.SetId("") d.SetId("")

View File

@ -7,7 +7,7 @@ package proxmoxtf
import ( import (
"testing" "testing"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
// TestResourceVirtualEnvironmentFileInstantiation tests whether the ResourceVirtualEnvironmentFile instance can be instantiated. // TestResourceVirtualEnvironmentFileInstantiation tests whether the ResourceVirtualEnvironmentFile instance can be instantiated.

View File

@ -5,10 +5,12 @@
package proxmoxtf package proxmoxtf
import ( import (
"context"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"strings" "strings"
"github.com/bpg/terraform-provider-proxmox/proxmox" "github.com/bpg/terraform-provider-proxmox/proxmox"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
const ( const (
@ -73,19 +75,18 @@ func resourceVirtualEnvironmentGroup() *schema.Resource {
Elem: &schema.Schema{Type: schema.TypeString}, Elem: &schema.Schema{Type: schema.TypeString},
}, },
}, },
Create: resourceVirtualEnvironmentGroupCreate, CreateContext: resourceVirtualEnvironmentGroupCreate,
Read: resourceVirtualEnvironmentGroupRead, ReadContext: resourceVirtualEnvironmentGroupRead,
Update: resourceVirtualEnvironmentGroupUpdate, UpdateContext: resourceVirtualEnvironmentGroupUpdate,
Delete: resourceVirtualEnvironmentGroupDelete, DeleteContext: resourceVirtualEnvironmentGroupDelete,
} }
} }
func resourceVirtualEnvironmentGroupCreate(d *schema.ResourceData, m interface{}) error { func resourceVirtualEnvironmentGroupCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
comment := d.Get(mkResourceVirtualEnvironmentGroupComment).(string) comment := d.Get(mkResourceVirtualEnvironmentGroupComment).(string)
@ -96,10 +97,9 @@ func resourceVirtualEnvironmentGroupCreate(d *schema.ResourceData, m interface{}
ID: groupID, ID: groupID,
} }
err = veClient.CreateGroup(body) err = veClient.CreateGroup(ctx, body)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
d.SetId(groupID) d.SetId(groupID)
@ -119,26 +119,26 @@ func resourceVirtualEnvironmentGroupCreate(d *schema.ResourceData, m interface{}
Roles: []string{aclEntry[mkResourceVirtualEnvironmentGroupACLRoleID].(string)}, Roles: []string{aclEntry[mkResourceVirtualEnvironmentGroupACLRoleID].(string)},
} }
err := veClient.UpdateACL(aclBody) err := veClient.UpdateACL(ctx, aclBody)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
} }
return resourceVirtualEnvironmentGroupRead(d, m) return resourceVirtualEnvironmentGroupRead(ctx, d, m)
} }
func resourceVirtualEnvironmentGroupRead(d *schema.ResourceData, m interface{}) error { func resourceVirtualEnvironmentGroupRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
var diags diag.Diagnostics
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
groupID := d.Id() groupID := d.Id()
group, err := veClient.GetGroup(groupID) group, err := veClient.GetGroup(ctx, groupID)
if err != nil { if err != nil {
if strings.Contains(err.Error(), "HTTP 404") { if strings.Contains(err.Error(), "HTTP 404") {
@ -146,17 +146,15 @@ func resourceVirtualEnvironmentGroupRead(d *schema.ResourceData, m interface{})
return nil return nil
} }
return diag.FromErr(err)
return err
} }
acl, err := veClient.GetACL() acl, err := veClient.GetACL(ctx)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
aclParsed := []interface{}{} var aclParsed []interface{}
for _, v := range acl { for _, v := range acl {
if v.Type == "group" && v.UserOrGroupID == groupID { if v.Type == "group" && v.UserOrGroupID == groupID {
@ -176,25 +174,27 @@ func resourceVirtualEnvironmentGroupRead(d *schema.ResourceData, m interface{})
} }
} }
d.Set(mkResourceVirtualEnvironmentGroupACL, aclParsed) err = d.Set(mkResourceVirtualEnvironmentGroupACL, aclParsed)
diags = append(diags, diag.FromErr(err)...)
if group.Comment != nil { if group.Comment != nil {
d.Set(mkResourceVirtualEnvironmentGroupComment, group.Comment) err = d.Set(mkResourceVirtualEnvironmentGroupComment, group.Comment)
} else { } else {
d.Set(mkResourceVirtualEnvironmentGroupComment, "") err = d.Set(mkResourceVirtualEnvironmentGroupComment, "")
}
diags = append(diags, diag.FromErr(err)...)
err = d.Set(mkResourceVirtualEnvironmentGroupMembers, group.Members)
diags = append(diags, diag.FromErr(err)...)
return diags
} }
d.Set(mkResourceVirtualEnvironmentGroupMembers, group.Members) func resourceVirtualEnvironmentGroupUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
return nil
}
func resourceVirtualEnvironmentGroupUpdate(d *schema.ResourceData, m interface{}) error {
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
comment := d.Get(mkResourceVirtualEnvironmentGroupComment).(string) comment := d.Get(mkResourceVirtualEnvironmentGroupComment).(string)
@ -204,10 +204,9 @@ func resourceVirtualEnvironmentGroupUpdate(d *schema.ResourceData, m interface{}
Comment: &comment, Comment: &comment,
} }
err = veClient.UpdateGroup(groupID, body) err = veClient.UpdateGroup(ctx, groupID, body)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
aclArgOld, aclArg := d.GetChange(mkResourceVirtualEnvironmentGroupACL) aclArgOld, aclArg := d.GetChange(mkResourceVirtualEnvironmentGroupACL)
@ -226,10 +225,9 @@ func resourceVirtualEnvironmentGroupUpdate(d *schema.ResourceData, m interface{}
Roles: []string{aclEntry[mkResourceVirtualEnvironmentGroupACLRoleID].(string)}, Roles: []string{aclEntry[mkResourceVirtualEnvironmentGroupACLRoleID].(string)},
} }
err := veClient.UpdateACL(aclBody) err := veClient.UpdateACL(ctx, aclBody)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
} }
@ -248,22 +246,20 @@ func resourceVirtualEnvironmentGroupUpdate(d *schema.ResourceData, m interface{}
Roles: []string{aclEntry[mkResourceVirtualEnvironmentGroupACLRoleID].(string)}, Roles: []string{aclEntry[mkResourceVirtualEnvironmentGroupACLRoleID].(string)},
} }
err := veClient.UpdateACL(aclBody) err := veClient.UpdateACL(ctx, aclBody)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
} }
return resourceVirtualEnvironmentGroupRead(d, m) return resourceVirtualEnvironmentGroupRead(ctx, d, m)
} }
func resourceVirtualEnvironmentGroupDelete(d *schema.ResourceData, m interface{}) error { func resourceVirtualEnvironmentGroupDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
aclParsed := d.Get(mkResourceVirtualEnvironmentGroupACL).(*schema.Set).List() aclParsed := d.Get(mkResourceVirtualEnvironmentGroupACL).(*schema.Set).List()
@ -282,14 +278,13 @@ func resourceVirtualEnvironmentGroupDelete(d *schema.ResourceData, m interface{}
Roles: []string{aclEntry[mkResourceVirtualEnvironmentGroupACLRoleID].(string)}, Roles: []string{aclEntry[mkResourceVirtualEnvironmentGroupACLRoleID].(string)},
} }
err := veClient.UpdateACL(aclBody) err := veClient.UpdateACL(ctx, aclBody)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
} }
err = veClient.DeleteGroup(groupID) err = veClient.DeleteGroup(ctx, groupID)
if err != nil { if err != nil {
if strings.Contains(err.Error(), "HTTP 404") { if strings.Contains(err.Error(), "HTTP 404") {
@ -297,8 +292,7 @@ func resourceVirtualEnvironmentGroupDelete(d *schema.ResourceData, m interface{}
return nil return nil
} }
return diag.FromErr(err)
return err
} }
d.SetId("") d.SetId("")

View File

@ -7,7 +7,7 @@ package proxmoxtf
import ( import (
"testing" "testing"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
// TestResourceVirtualEnvironmentGroupInstantiation tests whether the ResourceVirtualEnvironmentGroup instance can be instantiated. // TestResourceVirtualEnvironmentGroupInstantiation tests whether the ResourceVirtualEnvironmentGroup instance can be instantiated.

View File

@ -5,11 +5,13 @@
package proxmoxtf package proxmoxtf
import ( import (
"context"
"fmt" "fmt"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"strings" "strings"
"github.com/bpg/terraform-provider-proxmox/proxmox" "github.com/bpg/terraform-provider-proxmox/proxmox"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
const ( const (
@ -96,46 +98,45 @@ func resourceVirtualEnvironmentHosts() *schema.Resource {
Required: true, Required: true,
}, },
}, },
Create: resourceVirtualEnvironmentHostsCreate, CreateContext: resourceVirtualEnvironmentHostsCreate,
Read: resourceVirtualEnvironmentHostsRead, ReadContext: resourceVirtualEnvironmentHostsRead,
Update: resourceVirtualEnvironmentHostsUpdate, UpdateContext: resourceVirtualEnvironmentHostsUpdate,
Delete: resourceVirtualEnvironmentHostsDelete, DeleteContext: resourceVirtualEnvironmentHostsDelete,
} }
} }
func resourceVirtualEnvironmentHostsCreate(d *schema.ResourceData, m interface{}) error { func resourceVirtualEnvironmentHostsCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
err := resourceVirtualEnvironmentHostsUpdate(d, m) diags := resourceVirtualEnvironmentHostsUpdate(ctx, d, m)
if diags.HasError() {
if err != nil { return diags
return err
} }
nodeName := d.Get(mkResourceVirtualEnvironmentHostsNodeName).(string) nodeName := d.Get(mkResourceVirtualEnvironmentHostsNodeName).(string)
d.SetId(fmt.Sprintf("%s_hosts", nodeName)) d.SetId(fmt.Sprintf("%s_hosts", nodeName))
return nil return diags
} }
func resourceVirtualEnvironmentHostsRead(d *schema.ResourceData, m interface{}) error { func resourceVirtualEnvironmentHostsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
var diags diag.Diagnostics
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
nodeName := d.Get(mkResourceVirtualEnvironmentHostsNodeName).(string) nodeName := d.Get(mkResourceVirtualEnvironmentHostsNodeName).(string)
hosts, err := veClient.GetHosts(nodeName) hosts, err := veClient.GetHosts(ctx, nodeName)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
// Parse the entries in the hosts file. // Parse the entries in the hosts file.
addresses := []interface{}{} var addresses []interface{}
entries := []interface{}{} var entries []interface{}
hostnames := []interface{}{} var hostnames []interface{}
lines := strings.Split(hosts.Data, "\n") lines := strings.Split(hosts.Data, "\n")
for _, line := range lines { for _, line := range lines {
@ -152,7 +153,7 @@ func resourceVirtualEnvironmentHostsRead(d *schema.ResourceData, m interface{})
addresses = append(addresses, values[0]) addresses = append(addresses, values[0])
entry := map[string]interface{}{} entry := map[string]interface{}{}
hostnamesForAddress := []interface{}{} var hostnamesForAddress []interface{}
for _, hostname := range values[1:] { for _, hostname := range values[1:] {
if hostname != "" { if hostname != "" {
@ -167,27 +168,31 @@ func resourceVirtualEnvironmentHostsRead(d *schema.ResourceData, m interface{})
hostnames = append(hostnames, hostnamesForAddress) hostnames = append(hostnames, hostnamesForAddress)
} }
d.Set(mkResourceVirtualEnvironmentHostsAddresses, addresses) err = d.Set(mkResourceVirtualEnvironmentHostsAddresses, addresses)
diags = append(diags, diag.FromErr(err)...)
if hosts.Digest != nil { if hosts.Digest != nil {
d.Set(mkResourceVirtualEnvironmentHostsDigest, *hosts.Digest) err = d.Set(mkResourceVirtualEnvironmentHostsDigest, *hosts.Digest)
} else { } else {
d.Set(mkResourceVirtualEnvironmentHostsDigest, "") err = d.Set(mkResourceVirtualEnvironmentHostsDigest, "")
}
diags = append(diags, diag.FromErr(err)...)
err = d.Set(mkResourceVirtualEnvironmentHostsEntries, entries)
diags = append(diags, diag.FromErr(err)...)
err = d.Set(mkResourceVirtualEnvironmentHostsEntry, entries)
diags = append(diags, diag.FromErr(err)...)
err = d.Set(mkResourceVirtualEnvironmentHostsHostnames, hostnames)
diags = append(diags, diag.FromErr(err)...)
return diags
} }
d.Set(mkResourceVirtualEnvironmentHostsEntries, entries) func resourceVirtualEnvironmentHostsUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
d.Set(mkResourceVirtualEnvironmentHostsEntry, entries)
d.Set(mkResourceVirtualEnvironmentHostsHostnames, hostnames)
return nil
}
func resourceVirtualEnvironmentHostsUpdate(d *schema.ResourceData, m interface{}) error {
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
entry := d.Get(mkResourceVirtualEnvironmentHostsEntry).([]interface{}) entry := d.Get(mkResourceVirtualEnvironmentHostsEntry).([]interface{})
@ -214,16 +219,15 @@ func resourceVirtualEnvironmentHostsUpdate(d *schema.ResourceData, m interface{}
body.Data += "\n" body.Data += "\n"
} }
err = veClient.UpdateHosts(nodeName, &body) err = veClient.UpdateHosts(ctx, nodeName, &body)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
return resourceVirtualEnvironmentHostsRead(d, m) return resourceVirtualEnvironmentHostsRead(ctx, d, m)
} }
func resourceVirtualEnvironmentHostsDelete(d *schema.ResourceData, m interface{}) error { func resourceVirtualEnvironmentHostsDelete(_ context.Context, d *schema.ResourceData, _ interface{}) diag.Diagnostics {
d.SetId("") d.SetId("")
return nil return nil

View File

@ -7,7 +7,7 @@ package proxmoxtf
import ( import (
"testing" "testing"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
// TestResourceVirtualEnvironmentHostsInstantiation tests whether the ResourceVirtualEnvironmentHosts instance can be instantiated. // TestResourceVirtualEnvironmentHostsInstantiation tests whether the ResourceVirtualEnvironmentHosts instance can be instantiated.

View File

@ -5,10 +5,12 @@
package proxmoxtf package proxmoxtf
import ( import (
"context"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"strings" "strings"
"github.com/bpg/terraform-provider-proxmox/proxmox" "github.com/bpg/terraform-provider-proxmox/proxmox"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
const ( const (
@ -74,19 +76,18 @@ func resourceVirtualEnvironmentPool() *schema.Resource {
ForceNew: true, ForceNew: true,
}, },
}, },
Create: resourceVirtualEnvironmentPoolCreate, CreateContext: resourceVirtualEnvironmentPoolCreate,
Read: resourceVirtualEnvironmentPoolRead, ReadContext: resourceVirtualEnvironmentPoolRead,
Update: resourceVirtualEnvironmentPoolUpdate, UpdateContext: resourceVirtualEnvironmentPoolUpdate,
Delete: resourceVirtualEnvironmentPoolDelete, DeleteContext: resourceVirtualEnvironmentPoolDelete,
} }
} }
func resourceVirtualEnvironmentPoolCreate(d *schema.ResourceData, m interface{}) error { func resourceVirtualEnvironmentPoolCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
comment := d.Get(mkResourceVirtualEnvironmentPoolComment).(string) comment := d.Get(mkResourceVirtualEnvironmentPoolComment).(string)
@ -97,43 +98,42 @@ func resourceVirtualEnvironmentPoolCreate(d *schema.ResourceData, m interface{})
ID: poolID, ID: poolID,
} }
err = veClient.CreatePool(body) err = veClient.CreatePool(ctx, body)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
d.SetId(poolID) d.SetId(poolID)
return resourceVirtualEnvironmentPoolRead(d, m) return resourceVirtualEnvironmentPoolRead(ctx, d, m)
} }
func resourceVirtualEnvironmentPoolRead(d *schema.ResourceData, m interface{}) error { func resourceVirtualEnvironmentPoolRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
var diags diag.Diagnostics
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
poolID := d.Id() poolID := d.Id()
pool, err := veClient.GetPool(poolID) pool, err := veClient.GetPool(ctx, poolID)
if err != nil { if err != nil {
if strings.Contains(err.Error(), "HTTP 404") { if strings.Contains(err.Error(), "HTTP 404") {
d.SetId("") d.SetId("")
return nil return nil
} }
return diag.FromErr(err)
return err
} }
if pool.Comment != nil { if pool.Comment != nil {
d.Set(mkResourceVirtualEnvironmentPoolComment, pool.Comment) err = d.Set(mkResourceVirtualEnvironmentPoolComment, pool.Comment)
} else { } else {
d.Set(mkResourceVirtualEnvironmentPoolComment, "") err = d.Set(mkResourceVirtualEnvironmentPoolComment, "")
} }
diags = append(diags, diag.FromErr(err)...)
members := make([]interface{}, len(pool.Members)) members := make([]interface{}, len(pool.Members))
@ -160,17 +160,17 @@ func resourceVirtualEnvironmentPoolRead(d *schema.ResourceData, m interface{}) e
members[i] = values members[i] = values
} }
d.Set(mkResourceVirtualEnvironmentPoolMembers, members) err = d.Set(mkResourceVirtualEnvironmentPoolMembers, members)
diags = append(diags, diag.FromErr(err)...)
return nil return diag.FromErr(err)
} }
func resourceVirtualEnvironmentPoolUpdate(d *schema.ResourceData, m interface{}) error { func resourceVirtualEnvironmentPoolUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
comment := d.Get(mkResourceVirtualEnvironmentPoolComment).(string) comment := d.Get(mkResourceVirtualEnvironmentPoolComment).(string)
@ -180,25 +180,23 @@ func resourceVirtualEnvironmentPoolUpdate(d *schema.ResourceData, m interface{})
Comment: &comment, Comment: &comment,
} }
err = veClient.UpdatePool(poolID, body) err = veClient.UpdatePool(ctx, poolID, body)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
return resourceVirtualEnvironmentPoolRead(d, m) return resourceVirtualEnvironmentPoolRead(ctx, d, m)
} }
func resourceVirtualEnvironmentPoolDelete(d *schema.ResourceData, m interface{}) error { func resourceVirtualEnvironmentPoolDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
poolID := d.Id() poolID := d.Id()
err = veClient.DeletePool(poolID) err = veClient.DeletePool(ctx, poolID)
if err != nil { if err != nil {
if strings.Contains(err.Error(), "HTTP 404") { if strings.Contains(err.Error(), "HTTP 404") {
@ -207,7 +205,7 @@ func resourceVirtualEnvironmentPoolDelete(d *schema.ResourceData, m interface{})
return nil return nil
} }
return err return diag.FromErr(err)
} }
d.SetId("") d.SetId("")

View File

@ -7,7 +7,7 @@ package proxmoxtf
import ( import (
"testing" "testing"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
// TestResourceVirtualEnvironmentPoolInstantiation tests whether the ResourceVirtualEnvironmentPool instance can be instantiated. // TestResourceVirtualEnvironmentPoolInstantiation tests whether the ResourceVirtualEnvironmentPool instance can be instantiated.

View File

@ -5,10 +5,12 @@
package proxmoxtf package proxmoxtf
import ( import (
"context"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"strings" "strings"
"github.com/bpg/terraform-provider-proxmox/proxmox" "github.com/bpg/terraform-provider-proxmox/proxmox"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
const ( const (
@ -32,19 +34,18 @@ func resourceVirtualEnvironmentRole() *schema.Resource {
ForceNew: true, ForceNew: true,
}, },
}, },
Create: resourceVirtualEnvironmentRoleCreate, CreateContext: resourceVirtualEnvironmentRoleCreate,
Read: resourceVirtualEnvironmentRoleRead, ReadContext: resourceVirtualEnvironmentRoleRead,
Update: resourceVirtualEnvironmentRoleUpdate, UpdateContext: resourceVirtualEnvironmentRoleUpdate,
Delete: resourceVirtualEnvironmentRoleDelete, DeleteContext: resourceVirtualEnvironmentRoleDelete,
} }
} }
func resourceVirtualEnvironmentRoleCreate(d *schema.ResourceData, m interface{}) error { func resourceVirtualEnvironmentRoleCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
privileges := d.Get(mkResourceVirtualEnvironmentRolePrivileges).(*schema.Set).List() privileges := d.Get(mkResourceVirtualEnvironmentRolePrivileges).(*schema.Set).List()
@ -60,27 +61,25 @@ func resourceVirtualEnvironmentRoleCreate(d *schema.ResourceData, m interface{})
Privileges: customPrivileges, Privileges: customPrivileges,
} }
err = veClient.CreateRole(body) err = veClient.CreateRole(ctx, body)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
d.SetId(roleID) d.SetId(roleID)
return resourceVirtualEnvironmentRoleRead(d, m) return resourceVirtualEnvironmentRoleRead(ctx, d, m)
} }
func resourceVirtualEnvironmentRoleRead(d *schema.ResourceData, m interface{}) error { func resourceVirtualEnvironmentRoleRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
roleID := d.Id() roleID := d.Id()
role, err := veClient.GetRole(roleID) role, err := veClient.GetRole(ctx, roleID)
if err != nil { if err != nil {
if strings.Contains(err.Error(), "HTTP 404") { if strings.Contains(err.Error(), "HTTP 404") {
@ -88,8 +87,7 @@ func resourceVirtualEnvironmentRoleRead(d *schema.ResourceData, m interface{}) e
return nil return nil
} }
return diag.FromErr(err)
return err
} }
privileges := schema.NewSet(schema.HashString, []interface{}{}) privileges := schema.NewSet(schema.HashString, []interface{}{})
@ -100,17 +98,15 @@ func resourceVirtualEnvironmentRoleRead(d *schema.ResourceData, m interface{}) e
} }
} }
d.Set(mkResourceVirtualEnvironmentRolePrivileges, privileges) err = d.Set(mkResourceVirtualEnvironmentRolePrivileges, privileges)
return diag.FromErr(err)
return nil
} }
func resourceVirtualEnvironmentRoleUpdate(d *schema.ResourceData, m interface{}) error { func resourceVirtualEnvironmentRoleUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
privileges := d.Get(mkResourceVirtualEnvironmentRolePrivileges).(*schema.Set).List() privileges := d.Get(mkResourceVirtualEnvironmentRolePrivileges).(*schema.Set).List()
@ -125,25 +121,23 @@ func resourceVirtualEnvironmentRoleUpdate(d *schema.ResourceData, m interface{})
Privileges: customPrivileges, Privileges: customPrivileges,
} }
err = veClient.UpdateRole(roleID, body) err = veClient.UpdateRole(ctx, roleID, body)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
return resourceVirtualEnvironmentRoleRead(d, m) return resourceVirtualEnvironmentRoleRead(ctx, d, m)
} }
func resourceVirtualEnvironmentRoleDelete(d *schema.ResourceData, m interface{}) error { func resourceVirtualEnvironmentRoleDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
roleID := d.Id() roleID := d.Id()
err = veClient.DeleteRole(roleID) err = veClient.DeleteRole(ctx, roleID)
if err != nil { if err != nil {
if strings.Contains(err.Error(), "HTTP 404") { if strings.Contains(err.Error(), "HTTP 404") {
@ -151,8 +145,7 @@ func resourceVirtualEnvironmentRoleDelete(d *schema.ResourceData, m interface{})
return nil return nil
} }
return diag.FromErr(err)
return err
} }
d.SetId("") d.SetId("")

View File

@ -7,7 +7,7 @@ package proxmoxtf
import ( import (
"testing" "testing"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
// TestResourceVirtualEnvironmentRoleInstantiation tests whether the ResourceVirtualEnvironmentRole instance can be instantiated. // TestResourceVirtualEnvironmentRoleInstantiation tests whether the ResourceVirtualEnvironmentRole instance can be instantiated.

View File

@ -5,11 +5,13 @@
package proxmoxtf package proxmoxtf
import ( import (
"context"
"fmt" "fmt"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"time" "time"
"github.com/bpg/terraform-provider-proxmox/proxmox" "github.com/bpg/terraform-provider-proxmox/proxmox"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
const ( const (
@ -43,18 +45,17 @@ func resourceVirtualEnvironmentTime() *schema.Resource {
Computed: true, Computed: true,
}, },
}, },
Create: resourceVirtualEnvironmentTimeCreate, CreateContext: resourceVirtualEnvironmentTimeCreate,
Read: resourceVirtualEnvironmentTimeRead, ReadContext: resourceVirtualEnvironmentTimeRead,
Update: resourceVirtualEnvironmentTimeUpdate, UpdateContext: resourceVirtualEnvironmentTimeUpdate,
Delete: resourceVirtualEnvironmentTimeDelete, DeleteContext: resourceVirtualEnvironmentTimeDelete,
} }
} }
func resourceVirtualEnvironmentTimeCreate(d *schema.ResourceData, m interface{}) error { func resourceVirtualEnvironmentTimeCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
err := resourceVirtualEnvironmentTimeUpdate(d, m) diags := resourceVirtualEnvironmentTimeUpdate(ctx, d, m)
if diags.HasError() {
if err != nil { return diags
return err
} }
nodeName := d.Get(mkResourceVirtualEnvironmentTimeNodeName).(string) nodeName := d.Get(mkResourceVirtualEnvironmentTimeNodeName).(string)
@ -64,25 +65,24 @@ func resourceVirtualEnvironmentTimeCreate(d *schema.ResourceData, m interface{})
return nil return nil
} }
func resourceVirtualEnvironmentTimeRead(d *schema.ResourceData, m interface{}) error { func resourceVirtualEnvironmentTimeRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
var diags diag.Diagnostics
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
nodeName := d.Get(mkResourceVirtualEnvironmentTimeNodeName).(string) nodeName := d.Get(mkResourceVirtualEnvironmentTimeNodeName).(string)
nodeTime, err := veClient.GetNodeTime(nodeName) nodeTime, err := veClient.GetNodeTime(ctx, nodeName)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
localLocation, err := time.LoadLocation(nodeTime.TimeZone) localLocation, err := time.LoadLocation(nodeTime.TimeZone)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
d.SetId(fmt.Sprintf("%s_time", nodeName)) d.SetId(fmt.Sprintf("%s_time", nodeName))
@ -90,36 +90,37 @@ func resourceVirtualEnvironmentTimeRead(d *schema.ResourceData, m interface{}) e
localTimeOffset := time.Time(nodeTime.LocalTime).Sub(time.Now().UTC()) localTimeOffset := time.Time(nodeTime.LocalTime).Sub(time.Now().UTC())
localTime := time.Time(nodeTime.LocalTime).Add(-localTimeOffset).In(localLocation) localTime := time.Time(nodeTime.LocalTime).Add(-localTimeOffset).In(localLocation)
d.Set(mkDataSourceVirtualEnvironmentTimeLocalTime, localTime.Format(time.RFC3339)) err = d.Set(mkDataSourceVirtualEnvironmentTimeLocalTime, localTime.Format(time.RFC3339))
d.Set(mkDataSourceVirtualEnvironmentTimeTimeZone, nodeTime.TimeZone) diags = append(diags, diag.FromErr(err)...)
d.Set(mkDataSourceVirtualEnvironmentTimeUTCTime, time.Time(nodeTime.UTCTime).Format(time.RFC3339)) err = d.Set(mkDataSourceVirtualEnvironmentTimeTimeZone, nodeTime.TimeZone)
diags = append(diags, diag.FromErr(err)...)
err = d.Set(mkDataSourceVirtualEnvironmentTimeUTCTime, time.Time(nodeTime.UTCTime).Format(time.RFC3339))
diags = append(diags, diag.FromErr(err)...)
return nil return nil
} }
func resourceVirtualEnvironmentTimeUpdate(d *schema.ResourceData, m interface{}) error { func resourceVirtualEnvironmentTimeUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
nodeName := d.Get(mkResourceVirtualEnvironmentTimeNodeName).(string) nodeName := d.Get(mkResourceVirtualEnvironmentTimeNodeName).(string)
timeZone := d.Get(mkResourceVirtualEnvironmentTimeTimeZone).(string) timeZone := d.Get(mkResourceVirtualEnvironmentTimeTimeZone).(string)
err = veClient.UpdateNodeTime(nodeName, &proxmox.VirtualEnvironmentNodeUpdateTimeRequestBody{ err = veClient.UpdateNodeTime(ctx, nodeName, &proxmox.VirtualEnvironmentNodeUpdateTimeRequestBody{
TimeZone: timeZone, TimeZone: timeZone,
}) })
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
return resourceVirtualEnvironmentTimeRead(d, m) return resourceVirtualEnvironmentTimeRead(ctx, d, m)
} }
func resourceVirtualEnvironmentTimeDelete(d *schema.ResourceData, m interface{}) error { func resourceVirtualEnvironmentTimeDelete(_ context.Context, d *schema.ResourceData, _ interface{}) diag.Diagnostics {
d.SetId("") d.SetId("")
return nil return nil

View File

@ -7,7 +7,7 @@ package proxmoxtf
import ( import (
"testing" "testing"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
// TestResourceVirtualEnvironmentTimeInstantiation tests whether the ResourceVirtualEnvironmentTime instance can be instantiated. // TestResourceVirtualEnvironmentTimeInstantiation tests whether the ResourceVirtualEnvironmentTime instance can be instantiated.

View File

@ -5,12 +5,14 @@
package proxmoxtf package proxmoxtf
import ( import (
"context"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"strings" "strings"
"time" "time"
"github.com/bpg/terraform-provider-proxmox/proxmox" "github.com/bpg/terraform-provider-proxmox/proxmox"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/helper/validation" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
) )
const ( const (
@ -91,7 +93,7 @@ func resourceVirtualEnvironmentUser() *schema.Resource {
Description: "The user account's expiration date", Description: "The user account's expiration date",
Optional: true, Optional: true,
Default: time.Unix(0, 0).UTC().Format(time.RFC3339), Default: time.Unix(0, 0).UTC().Format(time.RFC3339),
ValidateFunc: validation.ValidateRFC3339TimeString, ValidateFunc: validation.IsRFC3339Time,
}, },
mkResourceVirtualEnvironmentUserFirstName: { mkResourceVirtualEnvironmentUserFirstName: {
Type: schema.TypeString, Type: schema.TypeString,
@ -132,28 +134,26 @@ func resourceVirtualEnvironmentUser() *schema.Resource {
ForceNew: true, ForceNew: true,
}, },
}, },
Create: resourceVirtualEnvironmentUserCreate, CreateContext: resourceVirtualEnvironmentUserCreate,
Read: resourceVirtualEnvironmentUserRead, ReadContext: resourceVirtualEnvironmentUserRead,
Update: resourceVirtualEnvironmentUserUpdate, UpdateContext: resourceVirtualEnvironmentUserUpdate,
Delete: resourceVirtualEnvironmentUserDelete, DeleteContext: resourceVirtualEnvironmentUserDelete,
} }
} }
func resourceVirtualEnvironmentUserCreate(d *schema.ResourceData, m interface{}) error { func resourceVirtualEnvironmentUserCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
comment := d.Get(mkResourceVirtualEnvironmentUserComment).(string) comment := d.Get(mkResourceVirtualEnvironmentUserComment).(string)
email := d.Get(mkResourceVirtualEnvironmentUserEmail).(string) email := d.Get(mkResourceVirtualEnvironmentUserEmail).(string)
enabled := proxmox.CustomBool(d.Get(mkResourceVirtualEnvironmentUserEnabled).(bool)) enabled := proxmox.CustomBool(d.Get(mkResourceVirtualEnvironmentUserEnabled).(bool))
expirationDate, err := time.Parse(time.RFC3339, d.Get(mkResourceVirtualEnvironmentUserExpirationDate).(string)) expirationDate, err := time.Parse(time.RFC3339, d.Get(mkResourceVirtualEnvironmentUserExpirationDate).(string))
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
expirationDateCustom := proxmox.CustomTimestamp(expirationDate) expirationDateCustom := proxmox.CustomTimestamp(expirationDate)
@ -183,10 +183,9 @@ func resourceVirtualEnvironmentUserCreate(d *schema.ResourceData, m interface{})
Password: password, Password: password,
} }
err = veClient.CreateUser(body) err = veClient.CreateUser(ctx, body)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
d.SetId(userID) d.SetId(userID)
@ -206,26 +205,24 @@ func resourceVirtualEnvironmentUserCreate(d *schema.ResourceData, m interface{})
Users: []string{userID}, Users: []string{userID},
} }
err := veClient.UpdateACL(aclBody) err := veClient.UpdateACL(ctx, aclBody)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
} }
return resourceVirtualEnvironmentUserRead(d, m) return resourceVirtualEnvironmentUserRead(ctx, d, m)
} }
func resourceVirtualEnvironmentUserRead(d *schema.ResourceData, m interface{}) error { func resourceVirtualEnvironmentUserRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
userID := d.Id() userID := d.Id()
user, err := veClient.GetUser(userID) user, err := veClient.GetUser(ctx, userID)
if err != nil { if err != nil {
if strings.Contains(err.Error(), "HTTP 404") { if strings.Contains(err.Error(), "HTTP 404") {
@ -233,17 +230,15 @@ func resourceVirtualEnvironmentUserRead(d *schema.ResourceData, m interface{}) e
return nil return nil
} }
return diag.FromErr(err)
return err
} }
acl, err := veClient.GetACL() acl, err := veClient.GetACL(ctx)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
aclParsed := []interface{}{} var aclParsed []interface{}
for _, v := range acl { for _, v := range acl {
if v.Type == "user" && v.UserOrGroupID == userID { if v.Type == "user" && v.UserOrGroupID == userID {
@ -263,37 +258,45 @@ func resourceVirtualEnvironmentUserRead(d *schema.ResourceData, m interface{}) e
} }
} }
d.Set(mkResourceVirtualEnvironmentUserACL, aclParsed) var diags diag.Diagnostics
err = d.Set(mkResourceVirtualEnvironmentUserACL, aclParsed)
diags = append(diags, diag.FromErr(err)...)
if user.Comment != nil { if user.Comment != nil {
d.Set(mkResourceVirtualEnvironmentUserComment, user.Comment) err = d.Set(mkResourceVirtualEnvironmentUserComment, user.Comment)
} else { } else {
d.Set(mkResourceVirtualEnvironmentUserComment, "") err = d.Set(mkResourceVirtualEnvironmentUserComment, "")
} }
diags = append(diags, diag.FromErr(err)...)
if user.Email != nil { if user.Email != nil {
d.Set(mkResourceVirtualEnvironmentUserEmail, user.Email) err = d.Set(mkResourceVirtualEnvironmentUserEmail, user.Email)
} else { } else {
d.Set(mkResourceVirtualEnvironmentUserEmail, "") err = d.Set(mkResourceVirtualEnvironmentUserEmail, "")
} }
diags = append(diags, diag.FromErr(err)...)
if user.Enabled != nil { if user.Enabled != nil {
d.Set(mkResourceVirtualEnvironmentUserEnabled, user.Enabled) err = d.Set(mkResourceVirtualEnvironmentUserEnabled, user.Enabled)
} else { } else {
d.Set(mkResourceVirtualEnvironmentUserEnabled, true) err = d.Set(mkResourceVirtualEnvironmentUserEnabled, true)
} }
diags = append(diags, diag.FromErr(err)...)
if user.ExpirationDate != nil { if user.ExpirationDate != nil {
d.Set(mkResourceVirtualEnvironmentUserExpirationDate, time.Time(*user.ExpirationDate).Format(time.RFC3339)) err = d.Set(mkResourceVirtualEnvironmentUserExpirationDate, time.Time(*user.ExpirationDate).Format(time.RFC3339))
} else { } else {
d.Set(mkResourceVirtualEnvironmentUserExpirationDate, time.Unix(0, 0).UTC().Format(time.RFC3339)) err = d.Set(mkResourceVirtualEnvironmentUserExpirationDate, time.Unix(0, 0).UTC().Format(time.RFC3339))
} }
diags = append(diags, diag.FromErr(err)...)
if user.FirstName != nil { if user.FirstName != nil {
d.Set(mkResourceVirtualEnvironmentUserFirstName, user.FirstName) err = d.Set(mkResourceVirtualEnvironmentUserFirstName, user.FirstName)
} else { } else {
d.Set(mkResourceVirtualEnvironmentUserFirstName, "") err = d.Set(mkResourceVirtualEnvironmentUserFirstName, "")
} }
diags = append(diags, diag.FromErr(err)...)
groups := schema.NewSet(schema.HashString, []interface{}{}) groups := schema.NewSet(schema.HashString, []interface{}{})
@ -303,38 +306,39 @@ func resourceVirtualEnvironmentUserRead(d *schema.ResourceData, m interface{}) e
} }
} }
d.Set(mkResourceVirtualEnvironmentUserGroups, groups) err = d.Set(mkResourceVirtualEnvironmentUserGroups, groups)
diags = append(diags, diag.FromErr(err)...)
if user.Keys != nil { if user.Keys != nil {
d.Set(mkResourceVirtualEnvironmentUserKeys, user.Keys) err = d.Set(mkResourceVirtualEnvironmentUserKeys, user.Keys)
} else { } else {
d.Set(mkResourceVirtualEnvironmentUserKeys, "") err = d.Set(mkResourceVirtualEnvironmentUserKeys, "")
} }
diags = append(diags, diag.FromErr(err)...)
if user.LastName != nil { if user.LastName != nil {
d.Set(mkResourceVirtualEnvironmentUserLastName, user.LastName) err = d.Set(mkResourceVirtualEnvironmentUserLastName, user.LastName)
} else { } else {
d.Set(mkResourceVirtualEnvironmentUserLastName, "") err = d.Set(mkResourceVirtualEnvironmentUserLastName, "")
}
diags = append(diags, diag.FromErr(err)...)
return diags
} }
return nil func resourceVirtualEnvironmentUserUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
}
func resourceVirtualEnvironmentUserUpdate(d *schema.ResourceData, m interface{}) error {
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
comment := d.Get(mkResourceVirtualEnvironmentUserComment).(string) comment := d.Get(mkResourceVirtualEnvironmentUserComment).(string)
email := d.Get(mkResourceVirtualEnvironmentUserEmail).(string) email := d.Get(mkResourceVirtualEnvironmentUserEmail).(string)
enabled := proxmox.CustomBool(d.Get(mkResourceVirtualEnvironmentUserEnabled).(bool)) enabled := proxmox.CustomBool(d.Get(mkResourceVirtualEnvironmentUserEnabled).(bool))
expirationDate, err := time.Parse(time.RFC3339, d.Get(mkResourceVirtualEnvironmentUserExpirationDate).(string)) expirationDate, err := time.Parse(time.RFC3339, d.Get(mkResourceVirtualEnvironmentUserExpirationDate).(string))
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
expirationDateCustom := proxmox.CustomTimestamp(expirationDate) expirationDateCustom := proxmox.CustomTimestamp(expirationDate)
@ -361,18 +365,16 @@ func resourceVirtualEnvironmentUserUpdate(d *schema.ResourceData, m interface{})
} }
userID := d.Id() userID := d.Id()
err = veClient.UpdateUser(userID, body) err = veClient.UpdateUser(ctx, userID, body)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
if d.HasChange(mkResourceVirtualEnvironmentUserPassword) { if d.HasChange(mkResourceVirtualEnvironmentUserPassword) {
password := d.Get(mkResourceVirtualEnvironmentUserPassword).(string) password := d.Get(mkResourceVirtualEnvironmentUserPassword).(string)
err = veClient.ChangeUserPassword(userID, password) err = veClient.ChangeUserPassword(ctx, userID, password)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
} }
@ -392,10 +394,9 @@ func resourceVirtualEnvironmentUserUpdate(d *schema.ResourceData, m interface{})
Users: []string{userID}, Users: []string{userID},
} }
err := veClient.UpdateACL(aclBody) err := veClient.UpdateACL(ctx, aclBody)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
} }
@ -414,22 +415,21 @@ func resourceVirtualEnvironmentUserUpdate(d *schema.ResourceData, m interface{})
Users: []string{userID}, Users: []string{userID},
} }
err := veClient.UpdateACL(aclBody) err := veClient.UpdateACL(ctx, aclBody)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
} }
return resourceVirtualEnvironmentUserRead(d, m) return resourceVirtualEnvironmentUserRead(ctx, d, m)
} }
func resourceVirtualEnvironmentUserDelete(d *schema.ResourceData, m interface{}) error { func resourceVirtualEnvironmentUserDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
config := m.(providerConfiguration) config := m.(providerConfiguration)
veClient, err := config.GetVEClient() veClient, err := config.GetVEClient()
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
aclParsed := d.Get(mkResourceVirtualEnvironmentUserACL).(*schema.Set).List() aclParsed := d.Get(mkResourceVirtualEnvironmentUserACL).(*schema.Set).List()
@ -448,14 +448,13 @@ func resourceVirtualEnvironmentUserDelete(d *schema.ResourceData, m interface{})
Users: []string{userID}, Users: []string{userID},
} }
err := veClient.UpdateACL(aclBody) err := veClient.UpdateACL(ctx, aclBody)
if err != nil { if err != nil {
return err return diag.FromErr(err)
} }
} }
err = veClient.DeleteUser(userID) err = veClient.DeleteUser(ctx, userID)
if err != nil { if err != nil {
if strings.Contains(err.Error(), "HTTP 404") { if strings.Contains(err.Error(), "HTTP 404") {
@ -463,8 +462,7 @@ func resourceVirtualEnvironmentUserDelete(d *schema.ResourceData, m interface{})
return nil return nil
} }
return diag.FromErr(err)
return err
} }
d.SetId("") d.SetId("")

View File

@ -7,7 +7,7 @@ package proxmoxtf
import ( import (
"testing" "testing"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
// TestResourceVirtualEnvironmentUserInstantiation tests whether the ResourceVirtualEnvironmentUser instance can be instantiated. // TestResourceVirtualEnvironmentUserInstantiation tests whether the ResourceVirtualEnvironmentUser instance can be instantiated.

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,7 @@ package proxmoxtf
import ( import (
"testing" "testing"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
) )
// TestResourceVirtualEnvironmentVMInstantiation tests whether the ResourceVirtualEnvironmentVM instance can be instantiated. // TestResourceVirtualEnvironmentVMInstantiation tests whether the ResourceVirtualEnvironmentVM instance can be instantiated.

View File

@ -5,7 +5,10 @@
package proxmoxtf package proxmoxtf
import ( import (
"errors"
"fmt" "fmt"
"github.com/hashicorp/go-multierror"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"math" "math"
"regexp" "regexp"
"strconv" "strconv"
@ -15,28 +18,28 @@ import (
"unicode" "unicode"
"github.com/bpg/terraform-provider-proxmox/proxmox" "github.com/bpg/terraform-provider-proxmox/proxmox"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/helper/validation" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
) )
func getBIOSValidator() schema.SchemaValidateFunc { func getBIOSValidator() schema.SchemaValidateDiagFunc {
return validation.StringInSlice([]string{ return validation.ToDiagFunc(validation.StringInSlice([]string{
"ovmf", "ovmf",
"seabios", "seabios",
}, false) }, false))
} }
func getContentTypeValidator() schema.SchemaValidateFunc { func getContentTypeValidator() schema.SchemaValidateDiagFunc {
return validation.StringInSlice([]string{ return validation.ToDiagFunc(validation.StringInSlice([]string{
"backup", "backup",
"iso", "iso",
"snippets", "snippets",
"vztmpl", "vztmpl",
}, false) }, false))
} }
func getCPUFlagsValidator() schema.SchemaValidateFunc { func getCPUFlagsValidator() schema.SchemaValidateDiagFunc {
return func(i interface{}, k string) (ws []string, es []error) { return validation.ToDiagFunc(func(i interface{}, k string) (ws []string, es []error) {
list, ok := i.([]interface{}) list, ok := i.([]interface{})
if !ok { if !ok {
@ -90,11 +93,11 @@ func getCPUFlagsValidator() schema.SchemaValidateFunc {
} }
return return
} })
} }
func getCPUTypeValidator() schema.SchemaValidateFunc { func getCPUTypeValidator() schema.SchemaValidateDiagFunc {
return validation.StringInSlice([]string{ return validation.ToDiagFunc(validation.StringInSlice([]string{
"486", "486",
"Broadwell", "Broadwell",
"Broadwell-IBRS", "Broadwell-IBRS",
@ -140,19 +143,19 @@ func getCPUTypeValidator() schema.SchemaValidateFunc {
"phenom", "phenom",
"qemu32", "qemu32",
"qemu64", "qemu64",
}, false) }, false))
} }
func getFileFormatValidator() schema.SchemaValidateFunc { func getFileFormatValidator() schema.SchemaValidateDiagFunc {
return validation.StringInSlice([]string{ return validation.ToDiagFunc(validation.StringInSlice([]string{
"qcow2", "qcow2",
"raw", "raw",
"vmdk", "vmdk",
}, false) }, false))
} }
func getFileIDValidator() schema.SchemaValidateFunc { func getFileIDValidator() schema.SchemaValidateDiagFunc {
return func(i interface{}, k string) (ws []string, es []error) { return validation.ToDiagFunc(func(i interface{}, k string) (ws []string, es []error) {
v, ok := i.(string) v, ok := i.(string)
if !ok { if !ok {
@ -161,7 +164,7 @@ func getFileIDValidator() schema.SchemaValidateFunc {
} }
if v != "" { if v != "" {
r := regexp.MustCompile(`^(?i)[a-z0-9\-_]+:([a-z0-9\-_]+/)?.+$`) r := regexp.MustCompile(`^(?i)[a-z\d\-_]+:([a-z\d\-_]+/)?.+$`)
ok := r.MatchString(v) ok := r.MatchString(v)
if !ok { if !ok {
@ -171,11 +174,11 @@ func getFileIDValidator() schema.SchemaValidateFunc {
} }
return return
} })
} }
func getKeyboardLayoutValidator() schema.SchemaValidateFunc { func getKeyboardLayoutValidator() schema.SchemaValidateDiagFunc {
return validation.StringInSlice([]string{ return validation.ToDiagFunc(validation.StringInSlice([]string{
"da", "da",
"de", "de",
"de-ch", "de-ch",
@ -201,7 +204,7 @@ func getKeyboardLayoutValidator() schema.SchemaValidateFunc {
"sl", "sl",
"sv", "sv",
"tr", "tr",
}, false) }, false))
} }
func diskDigitPrefix(s string) string { func diskDigitPrefix(s string) string {
@ -213,8 +216,8 @@ func diskDigitPrefix(s string) string {
return s return s
} }
func getMACAddressValidator() schema.SchemaValidateFunc { func getMACAddressValidator() schema.SchemaValidateDiagFunc {
return func(i interface{}, k string) (ws []string, es []error) { return validation.ToDiagFunc(func(i interface{}, k string) (ws []string, es []error) {
v, ok := i.(string) v, ok := i.(string)
if !ok { if !ok {
@ -223,7 +226,7 @@ func getMACAddressValidator() schema.SchemaValidateFunc {
} }
if v != "" { if v != "" {
r := regexp.MustCompile(`^[A-Z0-9]{2}(:[A-Z0-9]{2}){5}$`) r := regexp.MustCompile(`^[A-Z\d]{2}(:[A-Z\d]{2}){5}$`)
ok := r.MatchString(v) ok := r.MatchString(v)
if !ok { if !ok {
@ -233,18 +236,18 @@ func getMACAddressValidator() schema.SchemaValidateFunc {
} }
return return
} })
} }
func getNetworkDeviceModelValidator() schema.SchemaValidateFunc { func getNetworkDeviceModelValidator() schema.SchemaValidateDiagFunc {
return validation.StringInSlice([]string{"e1000", "rtl8139", "virtio", "vmxnet3"}, false) return validation.ToDiagFunc(validation.StringInSlice([]string{"e1000", "rtl8139", "virtio", "vmxnet3"}, false))
} }
func getQEMUAgentTypeValidator() schema.SchemaValidateFunc { func getQEMUAgentTypeValidator() schema.SchemaValidateDiagFunc {
return validation.StringInSlice([]string{"isa", "virtio"}, false) return validation.ToDiagFunc(validation.StringInSlice([]string{"isa", "virtio"}, false))
} }
func getSchemaBlock(r *schema.Resource, d *schema.ResourceData, m interface{}, k []string, i int, allowDefault bool) (map[string]interface{}, error) { func getSchemaBlock(r *schema.Resource, d *schema.ResourceData, k []string, i int, allowDefault bool) (map[string]interface{}, error) {
var resourceBlock map[string]interface{} var resourceBlock map[string]interface{}
var resourceData interface{} var resourceData interface{}
var resourceSchema *schema.Schema var resourceSchema *schema.Schema
@ -257,7 +260,7 @@ func getSchemaBlock(r *schema.Resource, d *schema.ResourceData, m interface{}, k
mapValues := resourceData.([]interface{}) mapValues := resourceData.([]interface{})
if len(mapValues) <= i { if len(mapValues) <= i {
return resourceBlock, fmt.Errorf("Index out of bounds %d", i) return resourceBlock, fmt.Errorf("index out of bounds %d", i)
} }
mapValue := mapValues[i].(map[string]interface{}) mapValue := mapValues[i].(map[string]interface{})
@ -288,8 +291,8 @@ func getSchemaBlock(r *schema.Resource, d *schema.ResourceData, m interface{}, k
return resourceBlock, nil return resourceBlock, nil
} }
func getTimeoutValidator() schema.SchemaValidateFunc { func getTimeoutValidator() schema.SchemaValidateDiagFunc {
return func(i interface{}, k string) (ws []string, es []error) { return validation.ToDiagFunc(func(i interface{}, k string) (ws []string, es []error) {
v, ok := i.(string) v, ok := i.(string)
if !ok { if !ok {
@ -305,15 +308,15 @@ func getTimeoutValidator() schema.SchemaValidateFunc {
} }
return return
} })
} }
func getVGAMemoryValidator() schema.SchemaValidateFunc { func getVGAMemoryValidator() schema.SchemaValidateDiagFunc {
return validation.IntBetween(4, 512) return validation.ToDiagFunc(validation.IntBetween(4, 512))
} }
func getVGATypeValidator() schema.SchemaValidateFunc { func getVGATypeValidator() schema.SchemaValidateDiagFunc {
return validation.StringInSlice([]string{ return validation.ToDiagFunc(validation.StringInSlice([]string{
"cirrus", "cirrus",
"qxl", "qxl",
"qxl2", "qxl2",
@ -326,11 +329,11 @@ func getVGATypeValidator() schema.SchemaValidateFunc {
"std", "std",
"virtio", "virtio",
"vmware", "vmware",
}, false) }, false))
} }
func getVLANIDsValidator() schema.SchemaValidateFunc { func getVLANIDsValidator() schema.SchemaValidateDiagFunc {
return func(i interface{}, k string) (ws []string, es []error) { return validation.ToDiagFunc(func(i interface{}, k string) (ws []string, es []error) {
min := 1 min := 1
max := 4094 max := 4094
@ -358,11 +361,11 @@ func getVLANIDsValidator() schema.SchemaValidateFunc {
} }
return return
} })
} }
func getVMIDValidator() schema.SchemaValidateFunc { func getVMIDValidator() schema.SchemaValidateDiagFunc {
return 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
max := 2147483647 max := 2147483647
@ -381,7 +384,7 @@ func getVMIDValidator() schema.SchemaValidateFunc {
} }
return return
} })
} }
func getDiskInfo(vm *proxmox.VirtualEnvironmentVMGetResponseData, d *schema.ResourceData) map[string]*proxmox.CustomStorageDevice { func getDiskInfo(vm *proxmox.VirtualEnvironmentVMGetResponseData, d *schema.ResourceData) map[string]*proxmox.CustomStorageDevice {
@ -392,7 +395,7 @@ func getDiskInfo(vm *proxmox.VirtualEnvironmentVMGetResponseData, d *schema.Reso
for _, v := range currentDiskList { for _, v := range currentDiskList {
diskMap := v.(map[string]interface{}) diskMap := v.(map[string]interface{})
diskInterface := diskMap[mkResourcevirtualEnvironmentVMDiskInterface].(string) diskInterface := diskMap[mkResourceVirtualEnvironmentVMDiskInterface].(string)
currentDiskMap[diskInterface] = diskMap currentDiskMap[diskInterface] = diskMap
} }
@ -485,17 +488,17 @@ func parseDiskSize(size *string) (int, error) {
diskSize = int(math.Ceil(float64(diskSize) / 1024)) diskSize = int(math.Ceil(float64(diskSize) / 1024))
} else { } else {
return -1, fmt.Errorf("Cannot parse storage size \"%s\"", *size) return -1, fmt.Errorf("cannot parse storage size \"%s\"", *size)
} }
} }
return diskSize, err return diskSize, err
} }
func getCloudInitTypeValidator() schema.SchemaValidateFunc { func getCloudInitTypeValidator() schema.SchemaValidateDiagFunc {
return validation.StringInSlice([]string{ return validation.ToDiagFunc(validation.StringInSlice([]string{
"configdrive2", "configdrive2",
"nocloud", "nocloud",
}, false) }, false))
} }
func testComputedAttributes(t *testing.T, s *schema.Resource, keys []string) { func testComputedAttributes(t *testing.T, s *schema.Resource, keys []string) {
@ -511,7 +514,7 @@ func testComputedAttributes(t *testing.T, s *schema.Resource, keys []string) {
} }
func testNestedSchemaExistence(t *testing.T, s *schema.Resource, key string) *schema.Resource { func testNestedSchemaExistence(t *testing.T, s *schema.Resource, key string) *schema.Resource {
schema, ok := s.Schema[key].Elem.(*schema.Resource) sh, ok := s.Schema[key].Elem.(*schema.Resource)
if !ok { if !ok {
t.Fatalf("Error in Schema: Missing nested schema for \"%s\"", key) t.Fatalf("Error in Schema: Missing nested schema for \"%s\"", key)
@ -519,7 +522,7 @@ func testNestedSchemaExistence(t *testing.T, s *schema.Resource, key string) *sc
return nil return nil
} }
return schema return sh
} }
func testOptionalArguments(t *testing.T, s *schema.Resource, keys []string) { func testOptionalArguments(t *testing.T, s *schema.Resource, keys []string) {
@ -557,3 +560,23 @@ func testValueTypes(t *testing.T, s *schema.Resource, f map[string]schema.ValueT
} }
} }
} }
type ErrorDiags diag.Diagnostics
func (diags ErrorDiags) Errors() []error {
var es []error
for i := range diags {
if diags[i].Severity == diag.Error {
s := fmt.Sprintf("Error: %s", diags[i].Summary)
if diags[i].Detail != "" {
s = fmt.Sprintf("%s: %s", s, diags[i].Detail)
}
es = append(es, errors.New(s))
}
}
return es
}
func (diags ErrorDiags) Error() string {
return multierror.ListFormatFunc(diags.Errors())
}

View File

@ -4,10 +4,11 @@
package proxmoxtf package proxmoxtf
//goland:noinspection ALL
const ( const (
// TerraformProviderName specifies the full name of this provider. // TerraformProviderName specifies the full name of this provider.
TerraformProviderName = "terraform-provider-proxmox" TerraformProviderName = "terraform-provider-proxmox"
// TerraformProviderVersion specifies the version number. // TerraformProviderVersion specifies the version number.
TerraformProviderVersion = "0.5.1" TerraformProviderVersion = "0.6.0"
) )

View File

@ -1,3 +1,4 @@
//go:build tools
// +build tools // +build tools
package tools package tools