0
0
mirror of https://github.com/bpg/terraform-provider-proxmox.git synced 2025-06-30 02:31:10 +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 --->
Relates OR Closes #0000
Release note for [CHANGELOG](https://github.com/bpg/terraform-provider-proxmox/blob/main/CHANGELOG.md):
<!-- If change is not user facing, just write "NONE" in the release-note block below. -->
```release-note
```
<!--- 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. --->

View File

@ -1,14 +1,11 @@
# 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).
#
# 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`
# secret. If you would rather own your own GPG handling, please fork this action
# 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
on:
push:
@ -27,7 +24,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: 1.16
go-version: 1.18
- name: Import GPG key
id: import_gpg

View File

@ -20,7 +20,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: '1.16'
go-version: '1.18'
id: go
- name: Check out code into the Go module directory
@ -43,15 +43,15 @@ jobs:
matrix:
# list whatever Terraform versions here you would like to support
terraform:
- '0.14.11'
- '0.15.5'
- '1.1.7'
- '1.0.1'
- '1.1.9'
- '1.2.5'
steps:
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: '1.16'
go-version: '1.18'
id: go
- 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_EXTENSION=.exe
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
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 |
## Requirements
- [Terraform](https://www.terraform.io/downloads.html) 0.14+
- [Go](https://golang.org/doc/install) 1.16+ (to build the provider plugin)
- [GoReleaser](https://goreleaser.com/install/) 0.155+ (to build the provider plugin)
- [Terraform](https://www.terraform.io/downloads.html) 1.0+
- [Go](https://golang.org/doc/install) 1.18+ (to build the provider plugin)
- [GoReleaser](https://goreleaser.com/install/) v1.10+ (to build the provider plugin)
## Table of Contents
- [Building the provider](#building-the-provider)
@ -56,6 +56,25 @@ $ make test
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
### 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" {
...
//...
disk {
datastore_id = "datastore-id"
@ -87,7 +106,7 @@ resource "proxmox_virtual_environment_vm" "example" {
file_id = "${proxmox_virtual_environment_file.vmdk_disk_image.id}"
}
...
//...
}
```

View File

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

66
go.mod
View File

@ -1,47 +1,55 @@
module github.com/bpg/terraform-provider-proxmox
go 1.16
go 1.18
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/martian/v3 v3.3.2 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320
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/go-getter v1.6.1 // indirect
github.com/hashicorp/go-hclog v1.2.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/go-hclog v1.2.1 // indirect
github.com/hashicorp/go-plugin v1.4.4 // indirect
github.com/hashicorp/go-uuid v1.0.3 // indirect
github.com/hashicorp/go-version v1.5.0 // indirect
github.com/hashicorp/hcl/v2 v2.12.0 // indirect
github.com/hashicorp/terraform-plugin-sdk v1.17.2
github.com/hashicorp/go-version v1.6.0 // indirect
github.com/hashicorp/hcl/v2 v2.13.0 // indirect
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/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/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/go-testing-interface v1.14.1 // indirect
github.com/mitchellh/go-wordwrap v1.0.1 // 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/pkg/sftp v1.13.5
github.com/posener/complete v1.2.3 // 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/msgpack v4.0.4+incompatible // indirect
github.com/vmihailenco/msgpack/v4 v4.3.12 // indirect
github.com/vmihailenco/tagparser v0.1.2 // 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-20220531201128-c960675eff93 // indirect
google.golang.org/api v0.82.0 // indirect
google.golang.org/genproto v0.0.0-20220601144221-27df5f98adab // indirect
google.golang.org/grpc v1.47.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
golang.org/x/net v0.0.0-20220708220712-1185a9018129 // indirect
golang.org/x/sys v0.0.0-20220712014510-0a85c31ab51e // indirect
golang.org/x/text v0.3.7 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20220713161829-9c7dac0a6568 // 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.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/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/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/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/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/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/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/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
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/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-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-20211001041855-01bcc9b48dfe/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.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
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.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.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.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/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/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/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/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
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.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.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.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.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.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
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.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
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/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.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.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.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.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.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/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/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.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/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/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.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
github.com/hashicorp/go-getter v1.5.3/go.mod h1:BrrV/1clo8cCYu6mxvboYg+KutTiFnXjMEgDD8+i7ZI=
github.com/hashicorp/go-getter v1.6.1 h1:NASsgP4q6tL94WH6nJxKWj8As2H/2kop/bB1d8JMyRY=
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-cty v1.4.1-0.20200414143053-d3edf31b6320 h1:1/D3zfFHttUKaCaGKZ/dR2roBXv0vKbSCnssIldfQdI=
github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320/go.mod h1:EiZBMaudVLy8fmjf9Npq1dq9RalhveqZG5w/yz3mHWs=
github.com/hashicorp/go-hclog v1.2.1 h1:YQsLlGDJgwhXFpucSPyVbCBviQtjlHv3jLTlp8YmtEw=
github.com/hashicorp/go-hclog v1.2.1/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
github.com/hashicorp/go-multierror v1.1.1/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/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/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.3.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go-version v1.5.0 h1:O293SZ2Eg+AAYijkVK3jR786Am1bhDEh2GHT0tIVE5E=
github.com/hashicorp/go-version v1.5.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/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/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek=
github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/hcl/v2 v2.13.0 h1:0Apadu1w6M11dyGFxWnmhhcMjkbAiKCv7G1r/2QgCNc=
github.com/hashicorp/hcl/v2 v2.13.0/go.mod h1:e4z5nxYlWNPdDSNYX+ph14EvWYMFm3eP0zIUqPc2jr0=
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/terraform-config-inspect v0.0.0-20191212124732-c6ae6269b9d7 h1:Pc5TCv9mbxFN6UVX0LH6CpQrdTM5YjbVI2w15237Pjk=
github.com/hashicorp/terraform-config-inspect v0.0.0-20191212124732-c6ae6269b9d7/go.mod h1:p+ivJws3dpqbp1iP84+npOyAmTTOLMgCzrXd3GSdn/A=
github.com/hashicorp/terraform-exec v0.13.3/go.mod h1:SSg6lbUsVB3DmFyCPjBPklqf6EYGX0TlQ6QTxOlikDU=
github.com/hashicorp/terraform-json v0.10.0/go.mod h1:3defM4kkMfttwiE7VakJDwCd4R+umhSQnvJwORXbprE=
github.com/hashicorp/terraform-plugin-sdk v1.17.2 h1:V7DUR3yBWFrVB9z3ddpY7kiYVSsq4NYR67NiTs93NQo=
github.com/hashicorp/terraform-plugin-sdk v1.17.2/go.mod h1:wkvldbraEMkz23NxkkAsFS88A1R9eUiooiaUZyS6TLw=
github.com/hashicorp/terraform-plugin-test/v2 v2.2.1/go.mod h1:eZ9JL3O69Cb71Skn6OhHyj17sLmHRb+H6VrDcJjKrYU=
github.com/hashicorp/terraform-plugin-go v0.11.0 h1:YXsvSCx7GbQO5jIUQd77FesqmIBxgSvYAtAX1NqErTk=
github.com/hashicorp/terraform-plugin-go v0.11.0/go.mod h1:aphXBG8qtQH0yF1waMRlaw/3G+ZFlR/6Artnvt1QEDE=
github.com/hashicorp/terraform-plugin-log v0.5.0 h1:2/5mE8+e0152+cxZ4QqZ2Ai8o0LPvXS9ZPTIPCvsg1g=
github.com/hashicorp/terraform-plugin-log v0.5.0/go.mod h1:p4R1jWBXRTvL4odmEkFfDdhUjHf9zcs/BCoNHAc7IK4=
github.com/hashicorp/terraform-plugin-sdk/v2 v2.18.0 h1:/cdI5di5XA+N80gXzXF4YcHq36DprBskubk6Z8i26ZQ=
github.com/hashicorp/terraform-plugin-sdk/v2 v2.18.0/go.mod h1:L3SHkD/Q8zPVgXviQmpVwy9nKwpXXZscVIpVEnQ/T50=
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/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/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/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/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
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/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/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.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
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.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
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/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/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/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/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/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
github.com/nsf/jsondiff v0.0.0-20200515183724-f29ed568f4ce h1:RPclfga2SEJmgMmz2k+Mg7cowZ8yv4Trqw9UsJby758=
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/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/go.mod h1:wHDZ0IZX6JcBYRK1TH9bcVq8G7TLpVHYIGJRFnmPfxg=
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/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/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.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.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/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
github.com/ulikunitz/xz v0.5.10 h1:t92gobL9l3HE202wg3rlk19F6X+JOxl9BBrCCMYEYd8=
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/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s=
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
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/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.2 h1:gnjoVuB/kljJ5wICEEOpx98oXMWPLj22G67Vbd1qPqc=
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.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/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=
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-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-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-20220507011949-2cf3adece122 h1:NvGWuYG8dkDHFSKksI1P9faiVJ9rayE6l0+ouWVIDs8=
golang.org/x/crypto v0.0.0-20220507011949-2cf3adece122/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d h1:sK3txAijHtOK88l68nt020reeT1ZdKLIYetKl95FzVY=
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-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-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-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-20180811021610-c39426892332/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-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-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-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-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-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-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-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-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-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
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/net v0.0.0-20220708220712-1185a9018129 h1:vucSRfWwTsoXro7P+3Cjlr6flUMtzCwzlvkxEQtHHB0=
golang.org/x/net v0.0.0-20220708220712-1185a9018129/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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-20220517195934-5e4e11fc645e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220712014510-0a85c31ab51e h1:NHvCuwuS43lGnYhten69ZWqi2QOj/CiDNcKbVqwVoew=
golang.org/x/sys v0.0.0-20220712014510-0a85c31ab51e/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-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.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.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.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
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/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-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-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-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-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.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.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
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/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-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-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-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-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
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/genproto v0.0.0-20220713161829-9c7dac0a6568 h1:iKx0VcikTdB4xj9Ho1Opn9AKzWFknYDE7oW/KBWZf9g=
google.golang.org/genproto v0.0.0-20220713161829-9c7dac0a6568/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
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.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.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.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.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/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-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
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.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.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
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/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=
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-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/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.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.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
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-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.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
import (
"flag"
"github.com/bpg/terraform-provider-proxmox/proxmoxtf"
"github.com/hashicorp/terraform-plugin-sdk/plugin"
"github.com/hashicorp/terraform-plugin-sdk/terraform"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/plugin"
)
func main() {
plugin.Serve(&plugin.ServeOpts{
ProviderFunc: func() terraform.ResourceProvider {
var debug bool
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()
},
})
}
plugin.Serve(opts)
}

View File

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

View File

@ -5,21 +5,22 @@
package proxmox
import (
"context"
"errors"
"sort"
)
// GetACL retrieves the access control list.
func (c *VirtualEnvironmentClient) GetACL() ([]*VirtualEnvironmentACLGetResponseData, error) {
func (c *VirtualEnvironmentClient) GetACL(ctx context.Context) ([]*VirtualEnvironmentACLGetResponseData, error) {
resBody := &VirtualEnvironmentACLGetResponseBody{}
err := c.DoRequest(hmGET, "access/acl", nil, resBody)
err := c.DoRequest(ctx, hmGET, "access/acl", nil, resBody)
if err != nil {
return nil, err
}
if resBody.Data == nil {
return nil, errors.New("The server did not include a data object in the response")
return nil, errors.New("the server did not include a data object in the response")
}
sort.Slice(resBody.Data, func(i, j int) bool {
@ -30,6 +31,6 @@ func (c *VirtualEnvironmentClient) GetACL() ([]*VirtualEnvironmentACLGetResponse
}
// UpdateACL updates the access control list.
func (c *VirtualEnvironmentClient) UpdateACL(d *VirtualEnvironmentACLUpdateRequestBody) error {
return c.DoRequest(hmPUT, "access/acl", d, nil)
func (c *VirtualEnvironmentClient) UpdateACL(ctx context.Context, d *VirtualEnvironmentACLUpdateRequestBody) error {
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)
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")
@ -52,7 +52,7 @@ func (c *VirtualEnvironmentClient) Authenticate(reset bool) error {
res, err := c.httpClient.Do(req)
if err != nil {
return errors.New("Failed to retrieve authentication response")
return errors.New("failed to retrieve authentication response")
}
err = c.ValidateResponseCode(res)
@ -65,23 +65,23 @@ func (c *VirtualEnvironmentClient) Authenticate(reset bool) error {
err = json.NewDecoder(res.Body).Decode(&resBody)
if err != nil {
return errors.New("Failed to decode authentication response")
return errors.New("failed to decode authentication response")
}
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 {
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 {
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 == "" {
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

View File

@ -5,33 +5,34 @@
package proxmox
import (
"context"
"errors"
"fmt"
"net/url"
)
// DeleteCertificate deletes the custom certificate for a node.
func (c *VirtualEnvironmentClient) DeleteCertificate(nodeName string, d *VirtualEnvironmentCertificateDeleteRequestBody) error {
return c.DoRequest(hmDELETE, fmt.Sprintf("nodes/%s/certificates/custom", url.PathEscape(nodeName)), d, nil)
func (c *VirtualEnvironmentClient) DeleteCertificate(ctx context.Context, nodeName string, d *VirtualEnvironmentCertificateDeleteRequestBody) error {
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.
func (c *VirtualEnvironmentClient) ListCertificates(nodeName string) (*[]VirtualEnvironmentCertificateListResponseData, error) {
func (c *VirtualEnvironmentClient) ListCertificates(ctx context.Context, nodeName string) (*[]VirtualEnvironmentCertificateListResponseData, error) {
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 {
return nil, err
}
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
}
// UpdateCertificate updates the custom certificate for a node.
func (c *VirtualEnvironmentClient) UpdateCertificate(nodeName string, d *VirtualEnvironmentCertificateUpdateRequestBody) error {
return c.DoRequest(hmPOST, fmt.Sprintf("nodes/%s/certificates/custom", url.PathEscape(nodeName)), d, nil)
func (c *VirtualEnvironmentClient) UpdateCertificate(ctx context.Context, nodeName string, d *VirtualEnvironmentCertificateUpdateRequestBody) error {
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 (
"bytes"
"context"
"crypto/tls"
"encoding/json"
"errors"
"fmt"
"github.com/hashicorp/terraform-plugin-log/tflog"
"io"
"io/ioutil"
"log"
"net/http"
"net/url"
"strings"
@ -22,22 +23,22 @@ import (
// NewVirtualEnvironmentClient creates and initializes a VirtualEnvironmentClient instance.
func NewVirtualEnvironmentClient(endpoint, username, password, otp string, insecure bool) (*VirtualEnvironmentClient, error) {
url, err := url.ParseRequestURI(endpoint)
u, err := url.ParseRequestURI(endpoint)
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" {
return nil, errors.New("You must specify a secure endpoint for the Proxmox Virtual Environment API (valid: https://host:port/)")
if u.Scheme != "https" {
return nil, errors.New("you must specify a secure endpoint for the Proxmox Virtual Environment API (valid: https://host:port/)")
}
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 == "" {
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
@ -55,7 +56,7 @@ func NewVirtualEnvironmentClient(endpoint, username, password, otp string, insec
}
return &VirtualEnvironmentClient{
Endpoint: strings.TrimRight(url.String(), "/"),
Endpoint: strings.TrimRight(u.String(), "/"),
Insecure: insecure,
OTP: pOTP,
Password: password,
@ -65,11 +66,14 @@ func NewVirtualEnvironmentClient(endpoint, username, password, otp string, insec
}
// 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 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
reqBodyType := ""
@ -83,17 +87,24 @@ func (c *VirtualEnvironmentClient) DoRequest(method, path string, requestBody in
reqBodyType = fmt.Sprintf("multipart/form-data; boundary=%s", multipartData.Boundary)
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 {
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 {
v, err := query.Values(requestBody)
if err != nil {
fErr := fmt.Errorf("Failed to encode HTTP %s request (path: %s) - Reason: %s", method, modifiedPath, err.Error())
log.Printf("[DEBUG] WARNING: %s", fErr.Error())
fErr := fmt.Errorf("failed to encode HTTP %s request (path: %s) - Reason: %s", method, modifiedPath, err.Error())
tflog.Warn(ctx, fErr.Error())
return fErr
}
@ -111,7 +122,11 @@ func (c *VirtualEnvironmentClient) DoRequest(method, path string, requestBody in
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 {
@ -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)
if err != nil {
fErr := fmt.Errorf("Failed to create HTTP %s request (path: %s) - Reason: %s", method, modifiedPath, err.Error())
log.Printf("[DEBUG] WARNING: %s", fErr.Error())
fErr := fmt.Errorf("failed to create HTTP %s request (path: %s) - Reason: %s", method, modifiedPath, err.Error())
tflog.Warn(ctx, fErr.Error())
return fErr
}
@ -139,24 +154,30 @@ func (c *VirtualEnvironmentClient) DoRequest(method, path string, requestBody in
err = c.AuthenticateRequest(req)
if err != nil {
log.Printf("[DEBUG] WARNING: %s", err.Error())
tflog.Warn(ctx, err.Error())
return err
}
res, err := c.httpClient.Do(req)
if err != nil {
fErr := fmt.Errorf("Failed to perform HTTP %s request (path: %s) - Reason: %s", method, modifiedPath, err.Error())
log.Printf("[DEBUG] WARNING: %s", fErr.Error())
fErr := fmt.Errorf("failed to perform HTTP %s request (path: %s) - Reason: %s", method, modifiedPath, err.Error())
tflog.Warn(ctx, fErr.Error())
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)
if err != nil {
log.Printf("[DEBUG] WARNING: %s", err.Error())
tflog.Warn(ctx, err.Error())
return err
}
@ -164,13 +185,15 @@ func (c *VirtualEnvironmentClient) DoRequest(method, path string, requestBody in
err = json.NewDecoder(res.Body).Decode(responseBody)
if err != nil {
fErr := fmt.Errorf("Failed to decode HTTP %s response (path: %s) - Reason: %s", method, modifiedPath, err.Error())
log.Printf("[DEBUG] WARNING: %s", fErr.Error())
fErr := fmt.Errorf("failed to decode HTTP %s response (path: %s) - Reason: %s", method, modifiedPath, err.Error())
tflog.Warn(ctx, fErr.Error())
return fErr
}
} else {
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
@ -185,7 +208,7 @@ func (c *VirtualEnvironmentClient) ValidateResponseCode(res *http.Response) erro
err := json.NewDecoder(res.Body).Decode(errRes)
if err == nil && errRes.Errors != nil {
errList := []string{}
var errList []string
for k, v := range *errRes.Errors {
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, " - "))
}
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

View File

@ -5,24 +5,25 @@
package proxmox
import (
"context"
"errors"
)
// 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{
VMID: vmID,
}
resBody := &VirtualEnvironmentClusterNextIDResponseBody{}
err := c.DoRequest(hmGET, "cluster/nextid", reqBody, resBody)
err := c.DoRequest(ctx, hmGET, "cluster/nextid", reqBody, resBody)
if err != nil {
return nil, err
}
if resBody.Data == nil {
return nil, errors.New("The server did not include a data object in the response")
return nil, errors.New("the server did not include a data object in the response")
}
return (*int)(resBody.Data), nil

View File

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

View File

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

View File

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

View File

@ -5,6 +5,7 @@
package proxmox
import (
"context"
"errors"
"fmt"
"net/url"
@ -13,79 +14,79 @@ import (
)
// CloneContainer clones a container.
func (c *VirtualEnvironmentClient) CloneContainer(nodeName string, vmID int, d *VirtualEnvironmentContainerCloneRequestBody) error {
return c.DoRequest(hmPOST, fmt.Sprintf("nodes/%s/lxc/%d/clone", url.PathEscape(nodeName), vmID), d, nil)
func (c *VirtualEnvironmentClient) CloneContainer(ctx context.Context, nodeName string, vmID int, d *VirtualEnvironmentContainerCloneRequestBody) error {
return c.DoRequest(ctx, hmPOST, fmt.Sprintf("nodes/%s/lxc/%d/clone", url.PathEscape(nodeName), vmID), d, nil)
}
// CreateContainer creates a container.
func (c *VirtualEnvironmentClient) CreateContainer(nodeName string, d *VirtualEnvironmentContainerCreateRequestBody) error {
return c.DoRequest(hmPOST, fmt.Sprintf("nodes/%s/lxc", url.PathEscape(nodeName)), d, nil)
func (c *VirtualEnvironmentClient) CreateContainer(ctx context.Context, nodeName string, d *VirtualEnvironmentContainerCreateRequestBody) error {
return c.DoRequest(ctx, hmPOST, fmt.Sprintf("nodes/%s/lxc", url.PathEscape(nodeName)), d, nil)
}
// DeleteContainer deletes a container.
func (c *VirtualEnvironmentClient) DeleteContainer(nodeName string, vmID int) error {
return c.DoRequest(hmDELETE, fmt.Sprintf("nodes/%s/lxc/%d", url.PathEscape(nodeName), vmID), nil, nil)
func (c *VirtualEnvironmentClient) DeleteContainer(ctx context.Context, nodeName string, vmID int) error {
return c.DoRequest(ctx, hmDELETE, fmt.Sprintf("nodes/%s/lxc/%d", url.PathEscape(nodeName), vmID), nil, nil)
}
// 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{}
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 {
return nil, err
}
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
}
// 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{}
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 {
return nil, err
}
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
}
// RebootContainer reboots a container.
func (c *VirtualEnvironmentClient) RebootContainer(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)
func (c *VirtualEnvironmentClient) RebootContainer(ctx context.Context, nodeName string, vmID int, d *VirtualEnvironmentContainerRebootRequestBody) error {
return c.DoRequest(ctx, hmPOST, fmt.Sprintf("nodes/%s/lxc/%d/status/reboot", url.PathEscape(nodeName), vmID), d, nil)
}
// ShutdownContainer shuts down a container.
func (c *VirtualEnvironmentClient) ShutdownContainer(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)
func (c *VirtualEnvironmentClient) ShutdownContainer(ctx context.Context, nodeName string, vmID int, d *VirtualEnvironmentContainerShutdownRequestBody) error {
return c.DoRequest(ctx, hmPOST, fmt.Sprintf("nodes/%s/lxc/%d/status/shutdown", url.PathEscape(nodeName), vmID), d, nil)
}
// StartContainer starts a container.
func (c *VirtualEnvironmentClient) StartContainer(nodeName string, vmID int) error {
return c.DoRequest(hmPOST, fmt.Sprintf("nodes/%s/lxc/%d/status/start", url.PathEscape(nodeName), vmID), nil, nil)
func (c *VirtualEnvironmentClient) StartContainer(ctx context.Context, nodeName string, vmID int) error {
return c.DoRequest(ctx, hmPOST, fmt.Sprintf("nodes/%s/lxc/%d/status/start", url.PathEscape(nodeName), vmID), nil, nil)
}
// StopContainer stops a container immediately.
func (c *VirtualEnvironmentClient) StopContainer(nodeName string, vmID int) error {
return c.DoRequest(hmPOST, fmt.Sprintf("nodes/%s/lxc/%d/status/stop", url.PathEscape(nodeName), vmID), nil, nil)
func (c *VirtualEnvironmentClient) StopContainer(ctx context.Context, nodeName string, vmID int) error {
return c.DoRequest(ctx, hmPOST, fmt.Sprintf("nodes/%s/lxc/%d/status/stop", url.PathEscape(nodeName), vmID), nil, nil)
}
// UpdateContainer updates a container.
func (c *VirtualEnvironmentClient) UpdateContainer(nodeName string, vmID int, d *VirtualEnvironmentContainerUpdateRequestBody) error {
return c.DoRequest(hmPUT, fmt.Sprintf("nodes/%s/lxc/%d/config", url.PathEscape(nodeName), vmID), d, nil)
func (c *VirtualEnvironmentClient) UpdateContainer(ctx context.Context, nodeName string, vmID int, d *VirtualEnvironmentContainerUpdateRequestBody) error {
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.
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)
timeDelay := int64(delay)
@ -95,7 +96,7 @@ func (c *VirtualEnvironmentClient) WaitForContainerState(nodeName string, vmID i
for timeElapsed.Seconds() < timeMax {
if int64(timeElapsed.Seconds())%timeDelay == 0 {
data, err := c.GetContainerStatus(nodeName, vmID)
data, err := c.GetContainerStatus(ctx, nodeName, vmID)
if err != nil {
return err
@ -111,13 +112,17 @@ func (c *VirtualEnvironmentClient) WaitForContainerState(nodeName string, vmID i
time.Sleep(200 * time.Millisecond)
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.
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)
timeMax := float64(timeout)
timeStart := time.Now()
@ -125,7 +130,7 @@ func (c *VirtualEnvironmentClient) WaitForContainerLock(nodeName string, vmID in
for timeElapsed.Seconds() < timeMax {
if int64(timeElapsed.Seconds())%timeDelay == 0 {
data, err := c.GetContainerStatus(nodeName, vmID)
data, err := c.GetContainerStatus(ctx, nodeName, vmID)
if err != nil {
if !ignoreErrorResponse {
@ -141,7 +146,11 @@ func (c *VirtualEnvironmentClient) WaitForContainerLock(nodeName string, vmID in
time.Sleep(200 * time.Millisecond)
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.
func (r VirtualEnvironmentContainerCustomFeatures) EncodeValues(key string, v *url.Values) error {
values := []string{}
var values []string
if r.FUSE != nil {
if *r.FUSE {
@ -260,7 +260,7 @@ func (r VirtualEnvironmentContainerCustomFeatures) EncodeValues(key string, v *u
// EncodeValues converts a VirtualEnvironmentContainerCustomMountPoint struct to a URL vlaue.
func (r VirtualEnvironmentContainerCustomMountPoint) EncodeValues(key string, v *url.Values) error {
values := []string{}
var values []string
if r.ACL != nil {
if *r.ACL {
@ -334,7 +334,10 @@ func (r VirtualEnvironmentContainerCustomMountPoint) EncodeValues(key string, v
// EncodeValues converts a VirtualEnvironmentContainerCustomMountPointArray array to multiple URL values.
func (r VirtualEnvironmentContainerCustomMountPointArray) EncodeValues(key string, v *url.Values) error {
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
@ -342,7 +345,7 @@ func (r VirtualEnvironmentContainerCustomMountPointArray) EncodeValues(key strin
// EncodeValues converts a VirtualEnvironmentContainerCustomNetworkInterface struct to a URL vlaue.
func (r VirtualEnvironmentContainerCustomNetworkInterface) EncodeValues(key string, v *url.Values) error {
values := []string{}
var values []string
if r.Bridge != nil {
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.
func (r VirtualEnvironmentContainerCustomNetworkInterfaceArray) EncodeValues(key string, v *url.Values) error {
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
@ -422,7 +428,7 @@ func (r VirtualEnvironmentContainerCustomNetworkInterfaceArray) EncodeValues(key
// EncodeValues converts a VirtualEnvironmentContainerCustomRootFS struct to a URL vlaue.
func (r VirtualEnvironmentContainerCustomRootFS) EncodeValues(key string, v *url.Values) error {
values := []string{}
var values []string
if r.ACL != nil {
if *r.ACL {
@ -492,7 +498,7 @@ func (r VirtualEnvironmentContainerCustomSSHKeys) EncodeValues(key string, v *ur
// EncodeValues converts a VirtualEnvironmentContainerCustomStartupBehavior struct to a URL vlaue.
func (r VirtualEnvironmentContainerCustomStartupBehavior) EncodeValues(key string, v *url.Values) error {
values := []string{}
var values []string
if r.Down != nil {
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], ";")
r.MountTypes = &a
} else {
a := []string{}
var a []string
r.MountTypes = &a
}
case "nesting":
@ -584,7 +590,7 @@ func (r *VirtualEnvironmentContainerCustomMountPoint) UnmarshalJSON(b []byte) er
a := strings.Split(v[1], ";")
r.MountOptions = &a
} else {
a := []string{}
var a []string
r.MountOptions = &a
}
case "mp":
@ -685,7 +691,7 @@ func (r *VirtualEnvironmentContainerCustomNetworkInterface) UnmarshalJSON(b []by
r.Trunks = &a
} else {
a := []int{}
var a []int
r.Trunks = &a
}
case "type":
@ -724,7 +730,7 @@ func (r *VirtualEnvironmentContainerCustomRootFS) UnmarshalJSON(b []byte) error
a := strings.Split(v[1], ";")
r.MountOptions = &a
} else {
a := []string{}
var a []string
r.MountOptions = &a
}
case "quota":

View File

@ -5,6 +5,7 @@
package proxmox
import (
"context"
"errors"
"fmt"
"io"
@ -19,8 +20,8 @@ import (
)
// DeleteDatastoreFile deletes a file in a datastore.
func (c *VirtualEnvironmentClient) DeleteDatastoreFile(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)
func (c *VirtualEnvironmentClient) DeleteDatastoreFile(ctx context.Context, nodeName, datastoreID, volumeID string) error {
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 {
return err
@ -30,16 +31,16 @@ func (c *VirtualEnvironmentClient) DeleteDatastoreFile(nodeName, datastoreID, vo
}
// 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{}
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 {
return nil, err
}
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 {
@ -50,16 +51,16 @@ func (c *VirtualEnvironmentClient) ListDatastoreFiles(nodeName, datastoreID stri
}
// 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{}
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 {
return nil, err
}
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 {
@ -70,7 +71,7 @@ func (c *VirtualEnvironmentClient) ListDatastores(nodeName string, d *VirtualEnv
}
// 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 {
case "iso", "vztmpl":
r, w := io.Pipe()
@ -142,7 +143,7 @@ func (c *VirtualEnvironmentClient) UploadFileToDatastore(d *VirtualEnvironmentDa
}
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 {
return nil, err
@ -152,7 +153,7 @@ func (c *VirtualEnvironmentClient) UploadFileToDatastore(d *VirtualEnvironmentDa
default:
// 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.
sshClient, err := c.OpenNodeShell(d.NodeName)
sshClient, err := c.OpenNodeShell(ctx, d.NodeName)
if err != nil {
return nil, err
@ -181,7 +182,7 @@ func (c *VirtualEnvironmentClient) UploadFileToDatastore(d *VirtualEnvironmentDa
datastorePath := strings.Trim(string(buf), "\000")
if datastorePath == "" {
return nil, errors.New("Failed to determine the datastore path")
return nil, errors.New("failed to determine the datastore path")
}
remoteFileDir := datastorePath

View File

@ -5,28 +5,29 @@
package proxmox
import (
"context"
"errors"
"fmt"
"net/url"
)
// 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{}
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 {
return nil, err
}
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
}
// UpdateDNS updates the DNS configuration for a node.
func (c *VirtualEnvironmentClient) UpdateDNS(nodeName string, d *VirtualEnvironmentDNSUpdateRequestBody) error {
return c.DoRequest(hmPUT, fmt.Sprintf("nodes/%s/dns", url.PathEscape(nodeName)), d, nil)
func (c *VirtualEnvironmentClient) UpdateDNS(ctx context.Context, nodeName string, d *VirtualEnvironmentDNSUpdateRequestBody) error {
return c.DoRequest(ctx, hmPUT, fmt.Sprintf("nodes/%s/dns", url.PathEscape(nodeName)), d, nil)
}

View File

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

View File

@ -5,28 +5,29 @@
package proxmox
import (
"context"
"errors"
"fmt"
"net/url"
)
// 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{}
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 {
return nil, err
}
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
}
// UpdateHosts updates the Hosts configuration for a node.
func (c *VirtualEnvironmentClient) UpdateHosts(nodeName string, d *VirtualEnvironmentHostsUpdateRequestBody) error {
return c.DoRequest(hmPOST, fmt.Sprintf("nodes/%s/hosts", url.PathEscape(nodeName)), d, nil)
func (c *VirtualEnvironmentClient) UpdateHosts(ctx context.Context, nodeName string, d *VirtualEnvironmentHostsUpdateRequestBody) error {
return c.DoRequest(ctx, hmPOST, fmt.Sprintf("nodes/%s/hosts", url.PathEscape(nodeName)), d, nil)
}

View File

@ -5,8 +5,10 @@
package proxmox
import (
"context"
"errors"
"fmt"
"github.com/hashicorp/terraform-plugin-log/tflog"
"net/url"
"sort"
"strings"
@ -16,14 +18,21 @@ import (
)
// ExecuteNodeCommands executes commands on a given node.
func (c *VirtualEnvironmentClient) ExecuteNodeCommands(nodeName string, commands []string) error {
sshClient, err := c.OpenNodeShell(nodeName)
func (c *VirtualEnvironmentClient) ExecuteNodeCommands(ctx context.Context, nodeName string, commands []string) error {
sshClient, err := c.OpenNodeShell(ctx, nodeName)
if err != nil {
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()
@ -31,7 +40,14 @@ func (c *VirtualEnvironmentClient) ExecuteNodeCommands(nodeName string, commands
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(
fmt.Sprintf(
@ -48,8 +64,8 @@ func (c *VirtualEnvironmentClient) ExecuteNodeCommands(nodeName string, commands
}
// GetNodeIP retrieves the IP address of a node.
func (c *VirtualEnvironmentClient) GetNodeIP(nodeName string) (*string, error) {
networkDevices, err := c.ListNodeNetworkDevices(nodeName)
func (c *VirtualEnvironmentClient) GetNodeIP(ctx context.Context, nodeName string) (*string, error) {
networkDevices, err := c.ListNodeNetworkDevices(ctx, nodeName)
if err != nil {
return nil, err
@ -65,7 +81,7 @@ func (c *VirtualEnvironmentClient) GetNodeIP(nodeName string) (*string, error) {
}
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, "/")
@ -74,48 +90,48 @@ func (c *VirtualEnvironmentClient) GetNodeIP(nodeName string) (*string, error) {
}
// 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{}
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 {
return nil, err
}
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
}
// 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{}
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 {
return nil, err
}
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
}
// 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{}
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 {
return nil, err
}
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 {
@ -126,16 +142,16 @@ func (c *VirtualEnvironmentClient) ListNodeNetworkDevices(nodeName string) ([]*V
}
// ListNodes retrieves a list of nodes.
func (c *VirtualEnvironmentClient) ListNodes() ([]*VirtualEnvironmentNodeListResponseData, error) {
func (c *VirtualEnvironmentClient) ListNodes(ctx context.Context) ([]*VirtualEnvironmentNodeListResponseData, error) {
resBody := &VirtualEnvironmentNodeListResponseBody{}
err := c.DoRequest(hmGET, "nodes", nil, resBody)
err := c.DoRequest(ctx, hmGET, "nodes", nil, resBody)
if err != nil {
return nil, err
}
if resBody.Data == nil {
return nil, errors.New("The server did not include a data object in the response")
return nil, errors.New("the server did not include a data object in the response")
}
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.
func (c *VirtualEnvironmentClient) OpenNodeShell(nodeName string) (*ssh.Client, error) {
nodeAddress, err := c.GetNodeIP(nodeName)
func (c *VirtualEnvironmentClient) OpenNodeShell(ctx context.Context, nodeName string) (*ssh.Client, error) {
nodeAddress, err := c.GetNodeIP(ctx, nodeName)
if err != nil {
return nil, err
@ -171,12 +187,12 @@ func (c *VirtualEnvironmentClient) OpenNodeShell(nodeName string) (*ssh.Client,
}
// UpdateNodeTime updates the time on a node.
func (c *VirtualEnvironmentClient) UpdateNodeTime(nodeName string, d *VirtualEnvironmentNodeUpdateTimeRequestBody) error {
return c.DoRequest(hmPUT, fmt.Sprintf("nodes/%s/time", url.PathEscape(nodeName)), d, nil)
func (c *VirtualEnvironmentClient) UpdateNodeTime(ctx context.Context, nodeName string, d *VirtualEnvironmentNodeUpdateTimeRequestBody) error {
return c.DoRequest(ctx, hmPUT, fmt.Sprintf("nodes/%s/time", url.PathEscape(nodeName)), d, nil)
}
// 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)
timeMax := float64(timeout)
timeStart := time.Now()
@ -184,7 +200,7 @@ func (c *VirtualEnvironmentClient) WaitForNodeTask(nodeName string, upid string,
for timeElapsed.Seconds() < timeMax {
if int64(timeElapsed.Seconds())%timeDelay == 0 {
status, err := c.GetNodeTaskStatus(nodeName, upid)
status, err := c.GetNodeTaskStatus(ctx, nodeName, upid)
if err != nil {
return err
@ -192,7 +208,7 @@ func (c *VirtualEnvironmentClient) WaitForNodeTask(nodeName string, upid string,
if status.Status != "running" {
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
}
@ -203,7 +219,11 @@ func (c *VirtualEnvironmentClient) WaitForNodeTask(nodeName string, upid string,
time.Sleep(200 * time.Millisecond)
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
import (
"context"
"errors"
"fmt"
"net/url"
"sort"
)
// CreatePool creates an pool.
func (c *VirtualEnvironmentClient) CreatePool(d *VirtualEnvironmentPoolCreateRequestBody) error {
return c.DoRequest(hmPOST, "pools", d, nil)
// CreatePool creates a pool.
func (c *VirtualEnvironmentClient) CreatePool(ctx context.Context, d *VirtualEnvironmentPoolCreateRequestBody) error {
return c.DoRequest(ctx, hmPOST, "pools", d, nil)
}
// DeletePool deletes an pool.
func (c *VirtualEnvironmentClient) DeletePool(id string) error {
return c.DoRequest(hmDELETE, fmt.Sprintf("pools/%s", url.PathEscape(id)), nil, nil)
// DeletePool deletes a pool.
func (c *VirtualEnvironmentClient) DeletePool(ctx context.Context, id string) error {
return c.DoRequest(ctx, hmDELETE, fmt.Sprintf("pools/%s", url.PathEscape(id)), nil, nil)
}
// GetPool retrieves an pool.
func (c *VirtualEnvironmentClient) GetPool(id string) (*VirtualEnvironmentPoolGetResponseData, error) {
// GetPool retrieves a pool.
func (c *VirtualEnvironmentClient) GetPool(ctx context.Context, id string) (*VirtualEnvironmentPoolGetResponseData, error) {
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 {
return nil, err
}
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 {
@ -42,16 +43,16 @@ func (c *VirtualEnvironmentClient) GetPool(id string) (*VirtualEnvironmentPoolGe
}
// ListPools retrieves a list of pools.
func (c *VirtualEnvironmentClient) ListPools() ([]*VirtualEnvironmentPoolListResponseData, error) {
func (c *VirtualEnvironmentClient) ListPools(ctx context.Context) ([]*VirtualEnvironmentPoolListResponseData, error) {
resBody := &VirtualEnvironmentPoolListResponseBody{}
err := c.DoRequest(hmGET, "pools", nil, resBody)
err := c.DoRequest(ctx, hmGET, "pools", nil, resBody)
if err != nil {
return nil, err
}
if resBody.Data == nil {
return nil, errors.New("The server did not include a data object in the response")
return nil, errors.New("the server did not include a data object in the response")
}
sort.Slice(resBody.Data, func(i, j int) bool {
@ -61,7 +62,7 @@ func (c *VirtualEnvironmentClient) ListPools() ([]*VirtualEnvironmentPoolListRes
return resBody.Data, nil
}
// UpdatePool updates an pool.
func (c *VirtualEnvironmentClient) UpdatePool(id string, d *VirtualEnvironmentPoolUpdateRequestBody) error {
return c.DoRequest(hmPUT, fmt.Sprintf("pools/%s", url.PathEscape(id)), d, nil)
// UpdatePool updates a pool.
func (c *VirtualEnvironmentClient) UpdatePool(ctx context.Context, id string, d *VirtualEnvironmentPoolUpdateRequestBody) error {
return c.DoRequest(ctx, hmPUT, fmt.Sprintf("pools/%s", url.PathEscape(id)), d, nil)
}

View File

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

View File

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

View File

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

View File

@ -5,9 +5,10 @@
package proxmox
import (
"context"
"errors"
"fmt"
"log"
"github.com/hashicorp/terraform-plugin-log/tflog"
"net/url"
"strings"
"sync"
@ -24,7 +25,7 @@ var (
)
// 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{}
var err error
@ -34,17 +35,17 @@ func (c *VirtualEnvironmentClient) CloneVM(nodeName string, vmID int, retries in
}
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 {
return err
}
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 {
return nil
@ -56,50 +57,52 @@ func (c *VirtualEnvironmentClient) CloneVM(nodeName string, vmID int, retries in
}
// CreateVM creates a virtual machine.
func (c *VirtualEnvironmentClient) CreateVM(nodeName string, d *VirtualEnvironmentVMCreateRequestBody) error {
return c.DoRequest(hmPOST, fmt.Sprintf("nodes/%s/qemu", url.PathEscape(nodeName)), d, nil)
func (c *VirtualEnvironmentClient) CreateVM(ctx context.Context, nodeName string, d *VirtualEnvironmentVMCreateRequestBody) error {
return c.DoRequest(ctx, hmPOST, fmt.Sprintf("nodes/%s/qemu", url.PathEscape(nodeName)), d, nil)
}
// DeleteVM deletes a virtual machine.
func (c *VirtualEnvironmentClient) DeleteVM(nodeName string, vmID int) error {
return c.DoRequest(hmDELETE, fmt.Sprintf("nodes/%s/qemu/%d", url.PathEscape(nodeName), vmID), nil, nil)
func (c *VirtualEnvironmentClient) DeleteVM(ctx context.Context, nodeName string, vmID int) error {
return c.DoRequest(ctx, hmDELETE, fmt.Sprintf("nodes/%s/qemu/%d", url.PathEscape(nodeName), vmID), nil, nil)
}
// 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{}
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 {
return nil, err
}
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
}
// GetVMID retrieves the next available VM identifier.
func (c *VirtualEnvironmentClient) GetVMID() (*int, error) {
func (c *VirtualEnvironmentClient) GetVMID(ctx context.Context) (*int, error) {
getVMIDCounterMutex.Lock()
defer getVMIDCounterMutex.Unlock()
if getVMIDCounter < 0 {
nextVMID, err := c.GetClusterNextID(nil)
nextVMID, err := c.GetClusterNextID(ctx, nil)
if err != nil {
return nil, err
}
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
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
}
@ -107,7 +110,7 @@ func (c *VirtualEnvironmentClient) GetVMID() (*int, error) {
vmID := getVMIDCounter
for vmID <= 2147483637 {
_, err := c.GetClusterNextID(&vmID)
_, err := c.GetClusterNextID(ctx, &vmID)
if err != nil {
vmID += getVMIDStep
@ -117,49 +120,51 @@ func (c *VirtualEnvironmentClient) GetVMID() (*int, error) {
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 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.
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{}
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 {
return nil, err
}
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
}
// 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{}
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 {
return nil, err
}
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
}
// MoveVMDisk moves a virtual machine disk.
func (c *VirtualEnvironmentClient) MoveVMDisk(nodeName string, vmID int, d *VirtualEnvironmentVMMoveDiskRequestBody, timeout int) error {
taskID, err := c.MoveVMDiskAsync(nodeName, vmID, d)
func (c *VirtualEnvironmentClient) MoveVMDisk(ctx context.Context, nodeName string, vmID int, d *VirtualEnvironmentVMMoveDiskRequestBody, timeout int) error {
taskID, err := c.MoveVMDiskAsync(ctx, nodeName, vmID, d)
if err != nil {
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
}
err = c.WaitForNodeTask(nodeName, *taskID, timeout, 5)
err = c.WaitForNodeTask(ctx, nodeName, *taskID, timeout, 5)
if err != nil {
return err
@ -180,16 +185,16 @@ func (c *VirtualEnvironmentClient) MoveVMDisk(nodeName string, vmID int, d *Virt
}
// 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{}
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 {
return nil, err
}
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
@ -197,18 +202,18 @@ func (c *VirtualEnvironmentClient) MoveVMDiskAsync(nodeName string, vmID int, d
// ListVMs retrieves a list of virtual machines.
func (c *VirtualEnvironmentClient) ListVMs() ([]*VirtualEnvironmentVMListResponseData, error) {
return nil, errors.New("Not implemented")
return nil, errors.New("not implemented")
}
// RebootVM reboots a virtual machine.
func (c *VirtualEnvironmentClient) RebootVM(nodeName string, vmID int, d *VirtualEnvironmentVMRebootRequestBody, timeout int) error {
taskID, err := c.RebootVMAsync(nodeName, vmID, d)
func (c *VirtualEnvironmentClient) RebootVM(ctx context.Context, nodeName string, vmID int, d *VirtualEnvironmentVMRebootRequestBody, timeout int) error {
taskID, err := c.RebootVMAsync(ctx, nodeName, vmID, d)
if err != nil {
return err
}
err = c.WaitForNodeTask(nodeName, *taskID, timeout, 5)
err = c.WaitForNodeTask(ctx, nodeName, *taskID, timeout, 5)
if err != nil {
return err
@ -218,45 +223,54 @@ func (c *VirtualEnvironmentClient) RebootVM(nodeName string, vmID int, d *Virtua
}
// 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{}
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 {
return nil, err
}
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
}
// 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
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++ {
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 {
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)
if ctx.Err() != nil {
return ctx.Err()
}
}
return err
}
// ShutdownVM shuts down a virtual machine.
func (c *VirtualEnvironmentClient) ShutdownVM(nodeName string, vmID int, d *VirtualEnvironmentVMShutdownRequestBody, timeout int) error {
taskID, err := c.ShutdownVMAsync(nodeName, vmID, d)
func (c *VirtualEnvironmentClient) ShutdownVM(ctx context.Context, nodeName string, vmID int, d *VirtualEnvironmentVMShutdownRequestBody, timeout int) error {
taskID, err := c.ShutdownVMAsync(ctx, nodeName, vmID, d)
if err != nil {
return err
}
err = c.WaitForNodeTask(nodeName, *taskID, timeout, 5)
err = c.WaitForNodeTask(ctx, nodeName, *taskID, timeout, 5)
if err != nil {
return err
@ -266,30 +280,30 @@ func (c *VirtualEnvironmentClient) ShutdownVM(nodeName string, vmID int, d *Virt
}
// 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{}
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 {
return nil, err
}
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
}
// StartVM starts a virtual machine.
func (c *VirtualEnvironmentClient) StartVM(nodeName string, vmID int, timeout int) error {
taskID, err := c.StartVMAsync(nodeName, vmID)
func (c *VirtualEnvironmentClient) StartVM(ctx context.Context, nodeName string, vmID int, timeout int) error {
taskID, err := c.StartVMAsync(ctx, nodeName, vmID)
if err != nil {
return err
}
err = c.WaitForNodeTask(nodeName, *taskID, timeout, 5)
err = c.WaitForNodeTask(ctx, nodeName, *taskID, timeout, 5)
if err != nil {
return err
@ -299,30 +313,30 @@ func (c *VirtualEnvironmentClient) StartVM(nodeName string, vmID int, timeout in
}
// 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{}
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 {
return nil, err
}
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
}
// StopVM stops a virtual machine.
func (c *VirtualEnvironmentClient) StopVM(nodeName string, vmID int, timeout int) error {
taskID, err := c.StopVMAsync(nodeName, vmID)
func (c *VirtualEnvironmentClient) StopVM(ctx context.Context, nodeName string, vmID int, timeout int) error {
taskID, err := c.StopVMAsync(ctx, nodeName, vmID)
if err != nil {
return err
}
err = c.WaitForNodeTask(nodeName, *taskID, timeout, 5)
err = c.WaitForNodeTask(ctx, nodeName, *taskID, timeout, 5)
if err != nil {
return err
@ -332,44 +346,44 @@ func (c *VirtualEnvironmentClient) StopVM(nodeName string, vmID int, timeout int
}
// 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{}
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 {
return nil, err
}
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
}
// UpdateVM updates a virtual machine.
func (c *VirtualEnvironmentClient) UpdateVM(nodeName string, vmID int, d *VirtualEnvironmentVMUpdateRequestBody) error {
return c.DoRequest(hmPUT, fmt.Sprintf("nodes/%s/qemu/%d/config", url.PathEscape(nodeName), vmID), d, nil)
func (c *VirtualEnvironmentClient) UpdateVM(ctx context.Context, nodeName string, vmID int, d *VirtualEnvironmentVMUpdateRequestBody) error {
return c.DoRequest(ctx, hmPUT, fmt.Sprintf("nodes/%s/qemu/%d/config", url.PathEscape(nodeName), vmID), d, nil)
}
// 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{}
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 {
return nil, err
}
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
}
// 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)
timeMax := float64(timeout)
timeStart := time.Now()
@ -377,7 +391,7 @@ func (c *VirtualEnvironmentClient) WaitForNetworkInterfacesFromVMAgent(nodeName
for timeElapsed.Seconds() < timeMax {
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 {
missingIP := false
@ -406,13 +420,17 @@ func (c *VirtualEnvironmentClient) WaitForNetworkInterfacesFromVMAgent(nodeName
time.Sleep(200 * time.Millisecond)
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.
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)
timeMax := float64(timeout)
timeStart := time.Now()
@ -420,7 +438,7 @@ func (c *VirtualEnvironmentClient) WaitForNoNetworkInterfacesFromVMAgent(nodeNam
for timeElapsed.Seconds() < timeMax {
if int64(timeElapsed.Seconds())%timeDelay == 0 {
_, err := c.GetVMNetworkInterfacesFromAgent(nodeName, vmID)
_, err := c.GetVMNetworkInterfacesFromAgent(ctx, nodeName, vmID)
if err != nil {
return nil
@ -432,13 +450,17 @@ func (c *VirtualEnvironmentClient) WaitForNoNetworkInterfacesFromVMAgent(nodeNam
time.Sleep(200 * time.Millisecond)
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.
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)
timeMax := float64(timeout)
timeStart := time.Now()
@ -446,7 +468,7 @@ func (c *VirtualEnvironmentClient) WaitForVMConfigUnlock(nodeName string, vmID i
for timeElapsed.Seconds() < timeMax {
if int64(timeElapsed.Seconds())%timeDelay == 0 {
data, err := c.GetVMStatus(nodeName, vmID)
data, err := c.GetVMStatus(ctx, nodeName, vmID)
if err != nil {
if !ignoreErrorResponse {
@ -462,13 +484,17 @@ func (c *VirtualEnvironmentClient) WaitForVMConfigUnlock(nodeName string, vmID i
time.Sleep(200 * time.Millisecond)
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.
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)
timeDelay := int64(delay)
@ -478,8 +504,7 @@ func (c *VirtualEnvironmentClient) WaitForVMState(nodeName string, vmID int, sta
for timeElapsed.Seconds() < timeMax {
if int64(timeElapsed.Seconds())%timeDelay == 0 {
data, err := c.GetVMStatus(nodeName, vmID)
data, err := c.GetVMStatus(ctx, nodeName, vmID)
if err != nil {
return err
}
@ -494,7 +519,11 @@ func (c *VirtualEnvironmentClient) WaitForVMState(nodeName string, vmID int, sta
time.Sleep(200 * time.Millisecond)
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.
func (r CustomAgent) EncodeValues(key string, v *url.Values) error {
values := []string{}
var values []string
if r.Enabled != nil {
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 {
for i, d := range r {
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.
func (r CustomCloudInitConfig) EncodeValues(key string, v *url.Values) error {
func (r CustomCloudInitConfig) EncodeValues(_ string, v *url.Values) error {
if r.Files != nil {
volumes := []string{}
var volumes []string
if r.Files.MetaVolume != nil {
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 {
config := []string{}
var config []string
if c.GatewayIPv4 != nil {
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 {
for i, d := range r {
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.
func (r CustomNUMADevices) EncodeValues(key string, v *url.Values) error {
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
@ -882,7 +891,10 @@ func (r CustomPCIDevice) EncodeValues(key string, v *url.Values) error {
// EncodeValues converts a CustomPCIDevices array to multiple URL values.
func (r CustomPCIDevices) EncodeValues(key string, v *url.Values) error {
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
@ -914,7 +926,7 @@ func (r CustomSharedMemory) EncodeValues(key string, v *url.Values) error {
// EncodeValues converts a CustomSMBIOS struct to a URL vlaue.
func (r CustomSMBIOS) EncodeValues(key string, v *url.Values) error {
values := []string{}
var values []string
if r.Base64 != nil {
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.
func (r CustomSpiceEnhancements) EncodeValues(key string, v *url.Values) error {
values := []string{}
var values []string
if r.FolderSharing != nil {
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.
func (r CustomStartupOrder) EncodeValues(key string, v *url.Values) error {
values := []string{}
var values []string
if r.Order != nil {
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.
func (r CustomStorageDevices) EncodeValues(key string, v *url.Values) error {
func (r CustomStorageDevices) EncodeValues(_ string, v *url.Values) error {
for i, d := range r {
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.
func (r CustomUSBDevices) EncodeValues(key string, v *url.Values) error {
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
@ -1093,7 +1111,7 @@ func (r CustomUSBDevices) EncodeValues(key string, v *url.Values) error {
// EncodeValues converts a CustomVGADevice struct to a URL vlaue.
func (r CustomVGADevice) EncodeValues(key string, v *url.Values) error {
values := []string{}
var values []string
if r.Memory != nil {
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 {
for i, d := range r {
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 == "" {
return errors.New("Unexpected empty string")
return errors.New("unexpected empty string")
}
pairs := strings.Split(s, ",")
@ -1337,7 +1358,7 @@ func (r *CustomCPUEmulation) UnmarshalJSON(b []byte) error {
f := strings.Split(v[1], ";")
r.Flags = &f
} else {
f := []string{}
var f []string
r.Flags = &f
}
case "hidden":

View File

@ -5,7 +5,9 @@
package proxmoxtf
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 (
@ -35,34 +37,36 @@ func dataSourceVirtualEnvironmentClusterAlias() *schema.Resource {
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)
veClient, err := config.GetVEClient()
if err != nil {
return err
return diag.FromErr(err)
}
AliasID := d.Get(mkDataSourceVirtualEnvironmentClusterAliasName).(string)
Alias, err := veClient.GetAlias(AliasID)
Alias, err := veClient.GetAlias(ctx, AliasID)
if err != nil {
return err
return diag.FromErr(err)
}
d.SetId(AliasID)
d.Set(mkDataSourceVirtualEnvironmentClusterAliasCIDR, Alias.CIDR)
err = d.Set(mkDataSourceVirtualEnvironmentClusterAliasCIDR, Alias.CIDR)
diags = append(diags, diag.FromErr(err)...)
if Alias.Comment != nil {
d.Set(mkDataSourceVirtualEnvironmentClusterAliasComment, Alias.Comment)
err = d.Set(mkDataSourceVirtualEnvironmentClusterAliasComment, Alias.Comment)
} 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 (
"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.

View File

@ -5,7 +5,9 @@
package proxmoxtf
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 (
@ -22,22 +24,20 @@ func dataSourceVirtualEnvironmentClusterAliases() *schema.Resource {
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)
veClient, err := config.GetVEClient()
if err != nil {
return err
return diag.FromErr(err)
}
list, err := veClient.ListPools()
list, err := veClient.ListPools(ctx)
if err != nil {
return err
return diag.FromErr(err)
}
aliasIDs := make([]interface{}, len(list))
@ -48,7 +48,7 @@ func dataSourceVirtualEnvironmentClusterAliasesRead(d *schema.ResourceData, m in
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 (
"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.

View File

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

View File

@ -5,9 +5,11 @@
package proxmoxtf
import (
"context"
"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 (
@ -36,34 +38,35 @@ func dataSourceVirtualEnvironmentDNS() *schema.Resource {
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)
veClient, err := config.GetVEClient()
if err != nil {
return err
return diag.FromErr(err)
}
nodeName := d.Get(mkDataSourceVirtualEnvironmentDNSNodeName).(string)
dns, err := veClient.GetDNS(nodeName)
dns, err := veClient.GetDNS(ctx, nodeName)
if err != nil {
return err
return diag.FromErr(err)
}
d.SetId(fmt.Sprintf("%s_dns", nodeName))
if dns.SearchDomain != nil {
d.Set(mkDataSourceVirtualEnvironmentDNSDomain, *dns.SearchDomain)
err = d.Set(mkDataSourceVirtualEnvironmentDNSDomain, *dns.SearchDomain)
} else {
d.Set(mkDataSourceVirtualEnvironmentDNSDomain, "")
err = d.Set(mkDataSourceVirtualEnvironmentDNSDomain, "")
}
diags = append(diags, diag.FromErr(err)...)
servers := []interface{}{}
var servers []interface{}
if dns.Server1 != nil {
servers = append(servers, *dns.Server1)
@ -77,7 +80,8 @@ func dataSourceVirtualEnvironmentDNSRead(d *schema.ResourceData, m interface{})
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
import (
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"testing"
)

View File

@ -5,7 +5,9 @@
package proxmoxtf
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 (
@ -62,34 +64,33 @@ func dataSourceVirtualEnvironmentGroup() *schema.Resource {
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)
veClient, err := config.GetVEClient()
if err != nil {
return err
return diag.FromErr(err)
}
groupID := d.Get(mkDataSourceVirtualEnvironmentGroupID).(string)
group, err := veClient.GetGroup(groupID)
group, err := veClient.GetGroup(ctx, groupID)
if err != nil {
return err
return diag.FromErr(err)
}
acl, err := veClient.GetACL()
acl, err := veClient.GetACL(ctx)
if err != nil {
return err
return diag.FromErr(err)
}
d.SetId(groupID)
aclParsed := []interface{}{}
var aclParsed []interface{}
for _, v := range acl {
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 {
d.Set(mkDataSourceVirtualEnvironmentGroupComment, group.Comment)
err = d.Set(mkDataSourceVirtualEnvironmentGroupComment, group.Comment)
} 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 (
"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.

View File

@ -5,7 +5,9 @@
package proxmoxtf
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 (
@ -29,22 +31,22 @@ func dataSourceVirtualEnvironmentGroups() *schema.Resource {
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)
veClient, err := config.GetVEClient()
if err != nil {
return err
return diag.FromErr(err)
}
list, err := veClient.ListGroups()
list, err := veClient.ListGroups(ctx)
if err != nil {
return err
return diag.FromErr(err)
}
comments := make([]interface{}, len(list))
@ -62,8 +64,10 @@ func dataSourceVirtualEnvironmentGroupsRead(d *schema.ResourceData, m interface{
d.SetId("groups")
d.Set(mkDataSourceVirtualEnvironmentGroupsComments, comments)
d.Set(mkDataSourceVirtualEnvironmentGroupsGroupIDs, groupIDs)
err = d.Set(mkDataSourceVirtualEnvironmentGroupsComments, comments)
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
import (
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"testing"
)

View File

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

View File

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

View File

@ -7,7 +7,7 @@ package proxmoxtf
import (
"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.

View File

@ -5,7 +5,9 @@
package proxmoxtf
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 (
@ -67,32 +69,33 @@ func dataSourceVirtualEnvironmentPool() *schema.Resource {
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)
veClient, err := config.GetVEClient()
if err != nil {
return err
return diag.FromErr(err)
}
poolID := d.Get(mkDataSourceVirtualEnvironmentPoolPoolID).(string)
pool, err := veClient.GetPool(poolID)
pool, err := veClient.GetPool(ctx, poolID)
if err != nil {
return err
return diag.FromErr(err)
}
d.SetId(poolID)
if pool.Comment != nil {
d.Set(mkDataSourceVirtualEnvironmentPoolComment, pool.Comment)
err = d.Set(mkDataSourceVirtualEnvironmentPoolComment, pool.Comment)
} else {
d.Set(mkDataSourceVirtualEnvironmentPoolComment, "")
err = d.Set(mkDataSourceVirtualEnvironmentPoolComment, "")
}
diags = append(diags, diag.FromErr(err)...)
members := make([]interface{}, len(pool.Members))
@ -119,7 +122,8 @@ func dataSourceVirtualEnvironmentPoolRead(d *schema.ResourceData, m interface{})
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 (
"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.

View File

@ -5,7 +5,9 @@
package proxmoxtf
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 (
@ -22,22 +24,20 @@ func dataSourceVirtualEnvironmentPools() *schema.Resource {
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)
veClient, err := config.GetVEClient()
if err != nil {
return err
return diag.FromErr(err)
}
list, err := veClient.ListPools()
list, err := veClient.ListPools(ctx)
if err != nil {
return err
return diag.FromErr(err)
}
poolIDs := make([]interface{}, len(list))
@ -48,7 +48,7 @@ func dataSourceVirtualEnvironmentPoolsRead(d *schema.ResourceData, m interface{}
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 (
"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.

View File

@ -5,7 +5,9 @@
package proxmoxtf
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 (
@ -28,23 +30,21 @@ func dataSourceVirtualEnvironmentRole() *schema.Resource {
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)
veClient, err := config.GetVEClient()
if err != nil {
return err
return diag.FromErr(err)
}
roleID := d.Get(mkDataSourceVirtualEnvironmentRoleID).(string)
accessRole, err := veClient.GetRole(roleID)
accessRole, err := veClient.GetRole(ctx, roleID)
if err != nil {
return err
return diag.FromErr(err)
}
privileges := schema.NewSet(schema.HashString, []interface{}{})
@ -57,7 +57,7 @@ func dataSourceVirtualEnvironmentRoleRead(d *schema.ResourceData, m interface{})
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 (
"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.

View File

@ -5,7 +5,9 @@
package proxmoxtf
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 (
@ -39,22 +41,22 @@ func dataSourceVirtualEnvironmentRoles() *schema.Resource {
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)
veClient, err := config.GetVEClient()
if err != nil {
return err
return diag.FromErr(err)
}
list, err := veClient.ListRoles()
list, err := veClient.ListRoles(ctx)
if err != nil {
return err
return diag.FromErr(err)
}
privileges := make([]interface{}, len(list))
@ -85,9 +87,12 @@ func dataSourceVirtualEnvironmentRolesRead(d *schema.ResourceData, m interface{}
d.SetId("roles")
d.Set(mkDataSourceVirtualEnvironmentRolesPrivileges, privileges)
d.Set(mkDataSourceVirtualEnvironmentRolesRoleIDs, roleIDs)
d.Set(mkDataSourceVirtualEnvironmentRolesSpecial, special)
err = d.Set(mkDataSourceVirtualEnvironmentRolesPrivileges, privileges)
diags = append(diags, diag.FromErr(err)...)
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
import (
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"testing"
)

View File

@ -5,10 +5,12 @@
package proxmoxtf
import (
"context"
"fmt"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"time"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)
const (
@ -42,29 +44,28 @@ func dataSourceVirtualEnvironmentTime() *schema.Resource {
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)
veClient, err := config.GetVEClient()
if err != nil {
return err
return diag.FromErr(err)
}
nodeName := d.Get(mkDataSourceVirtualEnvironmentTimeNodeName).(string)
nodeTime, err := veClient.GetNodeTime(nodeName)
nodeTime, err := veClient.GetNodeTime(ctx, nodeName)
if err != nil {
return err
return diag.FromErr(err)
}
localLocation, err := time.LoadLocation(nodeTime.TimeZone)
if err != nil {
return err
return diag.FromErr(err)
}
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())
localTime := time.Time(nodeTime.LocalTime).Add(-localTimeOffset).In(localLocation)
d.Set(mkDataSourceVirtualEnvironmentTimeLocalTime, localTime.Format(time.RFC3339))
d.Set(mkDataSourceVirtualEnvironmentTimeTimeZone, nodeTime.TimeZone)
d.Set(mkDataSourceVirtualEnvironmentTimeUTCTime, time.Time(nodeTime.UTCTime).Format(time.RFC3339))
err = d.Set(mkDataSourceVirtualEnvironmentTimeLocalTime, localTime.Format(time.RFC3339))
diags = append(diags, diag.FromErr(err)...)
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 (
"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.

View File

@ -5,9 +5,11 @@
package proxmoxtf
import (
"context"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"time"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)
const (
@ -100,34 +102,33 @@ func dataSourceVirtualEnvironmentUser() *schema.Resource {
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)
veClient, err := config.GetVEClient()
if err != nil {
return err
return diag.FromErr(err)
}
userID := d.Get(mkDataSourceVirtualEnvironmentUserUserID).(string)
v, err := veClient.GetUser(userID)
v, err := veClient.GetUser(ctx, userID)
if err != nil {
return err
return diag.FromErr(err)
}
acl, err := veClient.GetACL()
acl, err := veClient.GetACL(ctx)
if err != nil {
return err
return diag.FromErr(err)
}
d.SetId(userID)
aclParsed := []interface{}{}
var aclParsed []interface{}
for _, v := range acl {
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 {
d.Set(mkDataSourceVirtualEnvironmentUserComment, v.Comment)
err = d.Set(mkDataSourceVirtualEnvironmentUserComment, v.Comment)
} else {
d.Set(mkDataSourceVirtualEnvironmentUserComment, "")
err = d.Set(mkDataSourceVirtualEnvironmentUserComment, "")
}
diags = append(diags, diag.FromErr(err)...)
if v.Email != nil {
d.Set(mkDataSourceVirtualEnvironmentUserEmail, v.Email)
err = d.Set(mkDataSourceVirtualEnvironmentUserEmail, v.Email)
} else {
d.Set(mkDataSourceVirtualEnvironmentUserEmail, "")
err = d.Set(mkDataSourceVirtualEnvironmentUserEmail, "")
}
diags = append(diags, diag.FromErr(err)...)
if v.Enabled != nil {
d.Set(mkDataSourceVirtualEnvironmentUserEnabled, v.Enabled)
err = d.Set(mkDataSourceVirtualEnvironmentUserEnabled, v.Enabled)
} else {
d.Set(mkDataSourceVirtualEnvironmentUserEnabled, true)
err = d.Set(mkDataSourceVirtualEnvironmentUserEnabled, true)
}
diags = append(diags, diag.FromErr(err)...)
if v.ExpirationDate != nil {
t := time.Time(*v.ExpirationDate)
if t.Unix() > 0 {
d.Set(mkDataSourceVirtualEnvironmentUserExpirationDate, t.UTC().Format(time.RFC3339))
err = d.Set(mkDataSourceVirtualEnvironmentUserExpirationDate, t.UTC().Format(time.RFC3339))
} 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 {
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 {
d.Set(mkDataSourceVirtualEnvironmentUserFirstName, v.FirstName)
err = d.Set(mkDataSourceVirtualEnvironmentUserFirstName, v.FirstName)
} else {
d.Set(mkDataSourceVirtualEnvironmentUserFirstName, "")
err = d.Set(mkDataSourceVirtualEnvironmentUserFirstName, "")
}
diags = append(diags, diag.FromErr(err)...)
if v.Groups != nil {
d.Set(mkDataSourceVirtualEnvironmentUserGroups, v.Groups)
err = d.Set(mkDataSourceVirtualEnvironmentUserGroups, v.Groups)
} else {
d.Set(mkDataSourceVirtualEnvironmentUserGroups, "")
err = d.Set(mkDataSourceVirtualEnvironmentUserGroups, []string{})
}
diags = append(diags, diag.FromErr(err)...)
if v.Keys != nil {
d.Set(mkDataSourceVirtualEnvironmentUserGroups, v.Keys)
err = d.Set(mkDataSourceVirtualEnvironmentUsersKeys, v.Keys)
} else {
d.Set(mkDataSourceVirtualEnvironmentUserGroups, "")
err = d.Set(mkDataSourceVirtualEnvironmentUsersKeys, "")
}
diags = append(diags, diag.FromErr(err)...)
if v.LastName != nil {
d.Set(mkDataSourceVirtualEnvironmentUserLastName, v.LastName)
err = d.Set(mkDataSourceVirtualEnvironmentUserLastName, v.LastName)
} 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 (
"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.

View File

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

View File

@ -5,7 +5,9 @@
package proxmoxtf
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 (
@ -43,30 +45,34 @@ func dataSourceVirtualEnvironmentVersion() *schema.Resource {
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)
veClient, err := config.GetVEClient()
if err != nil {
return err
return diag.FromErr(err)
}
version, err := veClient.Version()
version, err := veClient.Version(ctx)
if err != nil {
return err
return diag.FromErr(err)
}
d.SetId("version")
d.Set(mkDataSourceVirtualEnvironmentVersionKeyboardLayout, version.Keyboard)
d.Set(mkDataSourceVirtualEnvironmentVersionRelease, version.Release)
d.Set(mkDataSourceVirtualEnvironmentVersionRepositoryID, version.RepositoryID)
d.Set(mkDataSourceVirtualEnvironmentVersionVersion, version.Version)
err = d.Set(mkDataSourceVirtualEnvironmentVersionKeyboardLayout, version.Keyboard)
diags = append(diags, diag.FromErr(err)...)
err = d.Set(mkDataSourceVirtualEnvironmentVersionRelease, version.Release)
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 (
"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.

View File

@ -5,12 +5,14 @@
package proxmoxtf
import (
"context"
"errors"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"net/url"
"os"
"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 (
@ -34,7 +36,7 @@ type providerConfiguration struct {
// Provider returns the object for this provider.
func Provider() *schema.Provider {
return &schema.Provider{
ConfigureFunc: providerConfigure,
ConfigureContextFunc: providerConfigure,
DataSourcesMap: map[string]*schema.Resource{
"proxmox_virtual_environment_cluster_alias": dataSourceVirtualEnvironmentClusterAlias(),
"proxmox_virtual_environment_cluster_aliases": dataSourceVirtualEnvironmentClusterAliases(),
@ -87,7 +89,7 @@ func Provider() *schema.Provider {
if value == "" {
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 {
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 == "" {
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 == "" {
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 veClient *proxmox.VirtualEnvironmentClient
@ -192,9 +194,8 @@ func providerConfigure(d *schema.ResourceData) (interface{}, error) {
veConfig[mkProviderVirtualEnvironmentOTP].(string),
veConfig[mkProviderVirtualEnvironmentInsecure].(bool),
)
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) {
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

View File

@ -7,7 +7,7 @@ package proxmoxtf
import (
"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.

View File

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

View File

@ -7,7 +7,7 @@ package proxmoxtf
import (
"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.

View File

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

View File

@ -7,7 +7,7 @@ package proxmoxtf
import (
"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.

View File

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

View File

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

View File

@ -5,13 +5,15 @@
package proxmoxtf
import (
"context"
"fmt"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"strconv"
"strings"
"github.com/bpg/terraform-provider-proxmox/proxmox"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
)
const (
@ -126,11 +128,11 @@ func resourceVirtualEnvironmentContainer() *schema.Resource {
Default: dvResourceVirtualEnvironmentContainerCloneNodeName,
},
mkResourceVirtualEnvironmentContainerCloneVMID: {
Type: schema.TypeInt,
Description: "The ID of the source container",
Required: true,
ForceNew: true,
ValidateFunc: getVMIDValidator(),
Type: schema.TypeInt,
Description: "The ID of the source container",
Required: true,
ForceNew: true,
ValidateDiagFunc: getVMIDValidator(),
},
},
},
@ -159,18 +161,18 @@ func resourceVirtualEnvironmentContainer() *schema.Resource {
Default: dvResourceVirtualEnvironmentContainerConsoleEnabled,
},
mkResourceVirtualEnvironmentContainerConsoleMode: {
Type: schema.TypeString,
Description: "The console mode",
Optional: true,
Default: dvResourceVirtualEnvironmentContainerConsoleMode,
ValidateFunc: resourceVirtualEnvironmentContainerGetConsoleModeValidator(),
Type: schema.TypeString,
Description: "The console mode",
Optional: true,
Default: dvResourceVirtualEnvironmentContainerConsoleMode,
ValidateDiagFunc: resourceVirtualEnvironmentContainerGetConsoleModeValidator(),
},
mkResourceVirtualEnvironmentContainerConsoleTTYCount: {
Type: schema.TypeInt,
Description: "The number of available TTY",
Optional: true,
Default: dvResourceVirtualEnvironmentContainerConsoleTTYCount,
ValidateFunc: validation.IntBetween(0, 6),
Type: schema.TypeInt,
Description: "The number of available TTY",
Optional: true,
Default: dvResourceVirtualEnvironmentContainerConsoleTTYCount,
ValidateDiagFunc: validation.ToDiagFunc(validation.IntBetween(0, 6)),
},
},
},
@ -193,25 +195,25 @@ func resourceVirtualEnvironmentContainer() *schema.Resource {
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
mkResourceVirtualEnvironmentContainerCPUArchitecture: {
Type: schema.TypeString,
Description: "The CPU architecture",
Optional: true,
Default: dvResourceVirtualEnvironmentContainerCPUArchitecture,
ValidateFunc: resourceVirtualEnvironmentContainerGetCPUArchitectureValidator(),
Type: schema.TypeString,
Description: "The CPU architecture",
Optional: true,
Default: dvResourceVirtualEnvironmentContainerCPUArchitecture,
ValidateDiagFunc: resourceVirtualEnvironmentContainerGetCPUArchitectureValidator(),
},
mkResourceVirtualEnvironmentContainerCPUCores: {
Type: schema.TypeInt,
Description: "The number of CPU cores",
Optional: true,
Default: dvResourceVirtualEnvironmentContainerCPUCores,
ValidateFunc: validation.IntBetween(1, 128),
Type: schema.TypeInt,
Description: "The number of CPU cores",
Optional: true,
Default: dvResourceVirtualEnvironmentContainerCPUCores,
ValidateDiagFunc: validation.ToDiagFunc(validation.IntBetween(1, 128)),
},
mkResourceVirtualEnvironmentContainerCPUUnits: {
Type: schema.TypeInt,
Description: "The CPU units",
Optional: true,
Default: dvResourceVirtualEnvironmentContainerCPUUnits,
ValidateFunc: validation.IntBetween(0, 500000),
Type: schema.TypeInt,
Description: "The CPU units",
Optional: true,
Default: dvResourceVirtualEnvironmentContainerCPUUnits,
ValidateDiagFunc: validation.ToDiagFunc(validation.IntBetween(0, 500000)),
},
},
},
@ -413,18 +415,18 @@ func resourceVirtualEnvironmentContainer() *schema.Resource {
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
mkResourceVirtualEnvironmentContainerMemoryDedicated: {
Type: schema.TypeInt,
Description: "The dedicated memory in megabytes",
Optional: true,
Default: dvResourceVirtualEnvironmentContainerMemoryDedicated,
ValidateFunc: validation.IntBetween(16, 268435456),
Type: schema.TypeInt,
Description: "The dedicated memory in megabytes",
Optional: true,
Default: dvResourceVirtualEnvironmentContainerMemoryDedicated,
ValidateDiagFunc: validation.ToDiagFunc(validation.IntBetween(16, 268435456)),
},
mkResourceVirtualEnvironmentContainerMemorySwap: {
Type: schema.TypeInt,
Description: "The swap size in megabytes",
Optional: true,
Default: dvResourceVirtualEnvironmentContainerMemorySwap,
ValidateFunc: validation.IntBetween(0, 268435456),
Type: schema.TypeInt,
Description: "The swap size in megabytes",
Optional: true,
Default: dvResourceVirtualEnvironmentContainerMemorySwap,
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 {
return new == ""
},
ValidateFunc: getMACAddressValidator(),
ValidateDiagFunc: getMACAddressValidator(),
},
mkResourceVirtualEnvironmentContainerNetworkInterfaceName: {
Type: schema.TypeString,
@ -498,18 +500,18 @@ func resourceVirtualEnvironmentContainer() *schema.Resource {
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
mkResourceVirtualEnvironmentContainerOperatingSystemTemplateFileID: {
Type: schema.TypeString,
Description: "The ID of an OS template file",
Required: true,
ForceNew: true,
ValidateFunc: getFileIDValidator(),
Type: schema.TypeString,
Description: "The ID of an OS template file",
Required: true,
ForceNew: true,
ValidateDiagFunc: getFileIDValidator(),
},
mkResourceVirtualEnvironmentContainerOperatingSystemType: {
Type: schema.TypeString,
Description: "The type",
Optional: true,
Default: dvResourceVirtualEnvironmentContainerOperatingSystemType,
ValidateFunc: resourceVirtualEnvironmentContainerGetOperatingSystemTypeValidator(),
Type: schema.TypeString,
Description: "The type",
Optional: true,
Default: dvResourceVirtualEnvironmentContainerOperatingSystemType,
ValidateDiagFunc: resourceVirtualEnvironmentContainerGetOperatingSystemTypeValidator(),
},
},
},
@ -540,37 +542,36 @@ func resourceVirtualEnvironmentContainer() *schema.Resource {
Default: dvResourceVirtualEnvironmentContainerTemplate,
},
mkResourceVirtualEnvironmentContainerVMID: {
Type: schema.TypeInt,
Description: "The VM identifier",
Optional: true,
ForceNew: true,
Default: dvResourceVirtualEnvironmentContainerVMID,
ValidateFunc: getVMIDValidator(),
Type: schema.TypeInt,
Description: "The VM identifier",
Optional: true,
ForceNew: true,
Default: dvResourceVirtualEnvironmentContainerVMID,
ValidateDiagFunc: getVMIDValidator(),
},
},
Create: resourceVirtualEnvironmentContainerCreate,
Read: resourceVirtualEnvironmentContainerRead,
Update: resourceVirtualEnvironmentContainerUpdate,
Delete: resourceVirtualEnvironmentContainerDelete,
CreateContext: resourceVirtualEnvironmentContainerCreate,
ReadContext: resourceVirtualEnvironmentContainerRead,
UpdateContext: resourceVirtualEnvironmentContainerUpdate,
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{})
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)
veClient, err := config.GetVEClient()
if err != nil {
return err
return diag.FromErr(err)
}
clone := d.Get(mkResourceVirtualEnvironmentContainerClone).([]interface{})
@ -594,10 +595,9 @@ func resourceVirtualEnvironmentContainerCreateClone(d *schema.ResourceData, m in
vmID := d.Get(mkResourceVirtualEnvironmentContainerVMID).(int)
if vmID == -1 {
vmIDNew, err := veClient.GetVMID()
vmIDNew, err := veClient.GetVMID(ctx)
if err != nil {
return err
return diag.FromErr(err)
}
vmID = *vmIDNew
@ -629,22 +629,21 @@ func resourceVirtualEnvironmentContainerCreateClone(d *schema.ResourceData, m in
if cloneNodeName != "" && cloneNodeName != nodeName {
cloneBody.TargetNodeName = &nodeName
err = veClient.CloneContainer(cloneNodeName, cloneVMID, cloneBody)
err = veClient.CloneContainer(ctx, cloneNodeName, cloneVMID, cloneBody)
} else {
err = veClient.CloneContainer(nodeName, cloneVMID, cloneBody)
err = veClient.CloneContainer(ctx, nodeName, cloneVMID, cloneBody)
}
if err != nil {
return err
return diag.FromErr(err)
}
d.SetId(strconv.Itoa(vmID))
// 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 {
return err
return diag.FromErr(err)
}
// 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
}
initializationIPConfigIPv4Address := []string{}
initializationIPConfigIPv4Gateway := []string{}
initializationIPConfigIPv6Address := []string{}
initializationIPConfigIPv6Gateway := []string{}
var initializationIPConfigIPv4Address []string
var initializationIPConfigIPv4Gateway []string
var initializationIPConfigIPv6Address []string
var initializationIPConfigIPv6Gateway []string
if len(initialization) > 0 {
initializationBlock := initialization[0].(map[string]interface{})
@ -774,10 +773,9 @@ func resourceVirtualEnvironmentContainerCreateClone(d *schema.ResourceData, m in
networkInterface := d.Get(mkResourceVirtualEnvironmentContainerNetworkInterface).([]interface{})
if len(networkInterface) == 0 {
networkInterface, err = resourceVirtualEnvironmentContainerGetExistingNetworkInterface(veClient, nodeName, vmID)
networkInterface, err = resourceVirtualEnvironmentContainerGetExistingNetworkInterface(ctx, veClient, nodeName, vmID)
if err != nil {
return err
return diag.FromErr(err)
}
}
@ -865,47 +863,42 @@ func resourceVirtualEnvironmentContainerCreateClone(d *schema.ResourceData, m in
updateBody.Template = &template
}
err = veClient.UpdateContainer(nodeName, vmID, updateBody)
err = veClient.UpdateContainer(ctx, nodeName, vmID, updateBody)
if err != nil {
return err
return diag.FromErr(err)
}
// 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 {
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)
veClient, err := config.GetVEClient()
if err != nil {
return err
return diag.FromErr(err)
}
nodeName := d.Get(mkResourceVirtualEnvironmentContainerNodeName).(string)
resource := resourceVirtualEnvironmentContainer()
consoleBlock, err := getSchemaBlock(resource, d, m, []string{mkResourceVirtualEnvironmentContainerConsole}, 0, true)
consoleBlock, err := getSchemaBlock(resource, d, []string{mkResourceVirtualEnvironmentContainerConsole}, 0, true)
if err != nil {
return err
return diag.FromErr(err)
}
consoleEnabled := proxmox.CustomBool(consoleBlock[mkResourceVirtualEnvironmentContainerConsoleEnabled].(bool))
consoleMode := consoleBlock[mkResourceVirtualEnvironmentContainerConsoleMode].(string)
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 {
return err
return diag.FromErr(err)
}
cpuArchitecture := cpuBlock[mkResourceVirtualEnvironmentContainerCPUArchitecture].(string)
@ -914,10 +907,9 @@ func resourceVirtualEnvironmentContainerCreateCustom(d *schema.ResourceData, m i
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 {
return err
return diag.FromErr(err)
}
diskDatastoreID := diskBlock[mkResourceVirtualEnvironmentContainerDiskDatastoreID].(string)
@ -926,10 +918,10 @@ func resourceVirtualEnvironmentContainerCreateCustom(d *schema.ResourceData, m i
initializationDNSDomain := dvResourceVirtualEnvironmentContainerInitializationDNSDomain
initializationDNSServer := dvResourceVirtualEnvironmentContainerInitializationDNSServer
initializationHostname := dvResourceVirtualEnvironmentContainerInitializationHostname
initializationIPConfigIPv4Address := []string{}
initializationIPConfigIPv4Gateway := []string{}
initializationIPConfigIPv6Address := []string{}
initializationIPConfigIPv6Gateway := []string{}
var initializationIPConfigIPv4Address []string
var initializationIPConfigIPv4Gateway []string
var initializationIPConfigIPv6Address []string
var initializationIPConfigIPv6Gateway []string
initializationUserAccountKeys := proxmox.VirtualEnvironmentContainerCustomSSHKeys{}
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 {
return err
return diag.FromErr(err)
}
memoryDedicated := memoryBlock[mkResourceVirtualEnvironmentContainerMemoryDedicated].(int)
@ -1056,7 +1047,7 @@ func resourceVirtualEnvironmentContainerCreateCustom(d *schema.ResourceData, m i
operatingSystem := d.Get(mkResourceVirtualEnvironmentContainerOperatingSystem).([]interface{})
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{})
@ -1069,10 +1060,9 @@ func resourceVirtualEnvironmentContainerCreateCustom(d *schema.ResourceData, m i
vmID := d.Get(mkResourceVirtualEnvironmentContainerVMID).(int)
if vmID == -1 {
vmIDNew, err := veClient.GetVMID()
vmIDNew, err := veClient.GetVMID(ctx)
if err != nil {
return err
return diag.FromErr(err)
}
vmID = *vmIDNew
@ -1125,87 +1115,81 @@ func resourceVirtualEnvironmentContainerCreateCustom(d *schema.ResourceData, m i
createBody.PoolID = &poolID
}
err = veClient.CreateContainer(nodeName, &createBody)
err = veClient.CreateContainer(ctx, nodeName, &createBody)
if err != nil {
return err
return diag.FromErr(err)
}
d.SetId(strconv.Itoa(vmID))
// 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 {
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)
template := d.Get(mkResourceVirtualEnvironmentContainerTemplate).(bool)
if !started || template {
return resourceVirtualEnvironmentContainerRead(d, m)
return resourceVirtualEnvironmentContainerRead(ctx, d, m)
}
config := m.(providerConfiguration)
veClient, err := config.GetVEClient()
if err != nil {
return err
return diag.FromErr(err)
}
nodeName := d.Get(mkResourceVirtualEnvironmentContainerNodeName).(string)
vmID, err := strconv.Atoi(d.Id())
if err != nil {
return err
return diag.FromErr(err)
}
// 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 {
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 {
return err
return diag.FromErr(err)
}
return resourceVirtualEnvironmentContainerRead(d, m)
return resourceVirtualEnvironmentContainerRead(ctx, d, m)
}
func resourceVirtualEnvironmentContainerGetConsoleModeValidator() schema.SchemaValidateFunc {
return validation.StringInSlice([]string{
func resourceVirtualEnvironmentContainerGetConsoleModeValidator() schema.SchemaValidateDiagFunc {
return validation.ToDiagFunc(validation.StringInSlice([]string{
"console",
"shell",
"tty",
}, false)
}, false))
}
func resourceVirtualEnvironmentContainerGetCPUArchitectureValidator() schema.SchemaValidateFunc {
return validation.StringInSlice([]string{
func resourceVirtualEnvironmentContainerGetCPUArchitectureValidator() schema.SchemaValidateDiagFunc {
return validation.ToDiagFunc(validation.StringInSlice([]string{
"amd64",
"arm64",
"armhf",
"i386",
}, false)
}, false))
}
func resourceVirtualEnvironmentContainerGetExistingNetworkInterface(client *proxmox.VirtualEnvironmentClient, nodeName string, vmID int) ([]interface{}, error) {
containerInfo, err := client.GetContainer(nodeName, vmID)
func resourceVirtualEnvironmentContainerGetExistingNetworkInterface(ctx context.Context, client *proxmox.VirtualEnvironmentClient, nodeName string, vmID int) ([]interface{}, error) {
containerInfo, err := client.GetContainer(ctx, nodeName, vmID)
if err != nil {
return []interface{}{}, err
}
networkInterfaces := []interface{}{}
var networkInterfaces []interface{}
networkInterfaceArray := []*proxmox.VirtualEnvironmentContainerCustomNetworkInterface{
containerInfo.NetworkInterface0,
containerInfo.NetworkInterface1,
@ -1258,8 +1242,8 @@ func resourceVirtualEnvironmentContainerGetExistingNetworkInterface(client *prox
return networkInterfaces, nil
}
func resourceVirtualEnvironmentContainerGetOperatingSystemTypeValidator() schema.SchemaValidateFunc {
return validation.StringInSlice([]string{
func resourceVirtualEnvironmentContainerGetOperatingSystemTypeValidator() schema.SchemaValidateDiagFunc {
return validation.ToDiagFunc(validation.StringInSlice([]string{
"alpine",
"archlinux",
"centos",
@ -1269,26 +1253,26 @@ func resourceVirtualEnvironmentContainerGetOperatingSystemTypeValidator() schema
"opensuse",
"ubuntu",
"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)
veClient, err := config.GetVEClient()
if err != nil {
return err
return diag.FromErr(err)
}
nodeName := d.Get(mkResourceVirtualEnvironmentContainerNodeName).(string)
vmID, err := strconv.Atoi(d.Id())
if err != nil {
return err
return diag.FromErr(err)
}
// 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 strings.Contains(err.Error(), "HTTP 404") ||
@ -1297,8 +1281,7 @@ func resourceVirtualEnvironmentContainerRead(d *schema.ResourceData, m interface
return nil
}
return err
return diag.FromErr(err)
}
clone := d.Get(mkResourceVirtualEnvironmentVMClone).([]interface{})
@ -1308,10 +1291,11 @@ func resourceVirtualEnvironmentContainerRead(d *schema.ResourceData, m interface
if len(clone) == 0 || currentDescription != dvResourceVirtualEnvironmentContainerDescription {
if containerConfig.Description != nil {
d.Set(mkResourceVirtualEnvironmentContainerDescription, strings.TrimSpace(*containerConfig.Description))
err = d.Set(mkResourceVirtualEnvironmentContainerDescription, strings.TrimSpace(*containerConfig.Description))
} 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.
@ -1342,13 +1326,15 @@ func resourceVirtualEnvironmentContainerRead(d *schema.ResourceData, m interface
if len(clone) > 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 ||
console[mkResourceVirtualEnvironmentContainerConsoleEnabled] != proxmox.CustomBool(dvResourceVirtualEnvironmentContainerConsoleEnabled) ||
console[mkResourceVirtualEnvironmentContainerConsoleMode] != dvResourceVirtualEnvironmentContainerConsoleMode ||
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.
@ -1379,13 +1365,15 @@ func resourceVirtualEnvironmentContainerRead(d *schema.ResourceData, m interface
if len(clone) > 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 ||
cpu[mkResourceVirtualEnvironmentContainerCPUArchitecture] != dvResourceVirtualEnvironmentContainerCPUArchitecture ||
cpu[mkResourceVirtualEnvironmentContainerCPUCores] != dvResourceVirtualEnvironmentContainerCPUCores ||
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.
@ -1404,11 +1392,13 @@ func resourceVirtualEnvironmentContainerRead(d *schema.ResourceData, m interface
if len(clone) > 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 ||
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.
@ -1430,12 +1420,14 @@ func resourceVirtualEnvironmentContainerRead(d *schema.ResourceData, m interface
if len(clone) > 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 ||
memory[mkResourceVirtualEnvironmentContainerMemoryDedicated] != dvResourceVirtualEnvironmentContainerMemoryDedicated ||
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.
@ -1465,7 +1457,7 @@ func resourceVirtualEnvironmentContainerRead(d *schema.ResourceData, m interface
initialization[mkResourceVirtualEnvironmentContainerInitializationHostname] = ""
}
ipConfigList := []interface{}{}
var ipConfigList []interface{}
networkInterfaceArray := []*proxmox.VirtualEnvironmentContainerCustomNetworkInterface{
containerConfig.NetworkInterface0,
containerConfig.NetworkInterface1,
@ -1476,7 +1468,7 @@ func resourceVirtualEnvironmentContainerRead(d *schema.ResourceData, m interface
containerConfig.NetworkInterface6,
containerConfig.NetworkInterface7,
}
networkInterfaceList := []interface{}{}
var networkInterfaceList []interface{}
for _, nv := range networkInterfaceArray {
if nv == nil {
@ -1594,25 +1586,29 @@ func resourceVirtualEnvironmentContainerRead(d *schema.ResourceData, m interface
}
if len(initialization) > 0 {
d.Set(mkResourceVirtualEnvironmentContainerInitialization, []interface{}{initialization})
err = d.Set(mkResourceVirtualEnvironmentContainerInitialization, []interface{}{initialization})
} else {
d.Set(mkResourceVirtualEnvironmentContainerInitialization, []interface{}{})
err = d.Set(mkResourceVirtualEnvironmentContainerInitialization, []interface{}{})
}
diags = append(diags, diag.FromErr(err)...)
}
currentNetworkInterface := d.Get(mkResourceVirtualEnvironmentContainerNetworkInterface).([]interface{})
if len(currentNetworkInterface) > 0 {
d.Set(mkResourceVirtualEnvironmentContainerNetworkInterface, networkInterfaceList)
err := d.Set(mkResourceVirtualEnvironmentContainerNetworkInterface, networkInterfaceList)
diags = append(diags, diag.FromErr(err)...)
}
} else {
if len(initialization) > 0 {
d.Set(mkResourceVirtualEnvironmentContainerInitialization, []interface{}{initialization})
err = d.Set(mkResourceVirtualEnvironmentContainerInitialization, []interface{}{initialization})
} 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.
@ -1635,48 +1631,49 @@ func resourceVirtualEnvironmentContainerRead(d *schema.ResourceData, m interface
if len(clone) > 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 ||
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)
if len(clone) == 0 || currentTemplate != dvResourceVirtualEnvironmentContainerTemplate {
if containerConfig.Template != nil {
d.Set(mkResourceVirtualEnvironmentContainerTemplate, bool(*containerConfig.Template))
err = d.Set(mkResourceVirtualEnvironmentContainerTemplate, bool(*containerConfig.Template))
} 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.
status, err := veClient.GetContainerStatus(nodeName, vmID)
status, err := veClient.GetContainerStatus(ctx, nodeName, vmID)
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)
veClient, err := config.GetVEClient()
if err != nil {
return err
return diag.FromErr(err)
}
nodeName := d.Get(mkResourceVirtualEnvironmentContainerNodeName).(string)
vmID, err := strconv.Atoi(d.Id())
if err != nil {
return err
return diag.FromErr(err)
}
// Prepare the new request object.
@ -1702,10 +1699,9 @@ func resourceVirtualEnvironmentContainerUpdate(d *schema.ResourceData, m interfa
// Prepare the new console configuration.
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 {
return err
return diag.FromErr(err)
}
consoleEnabled := proxmox.CustomBool(consoleBlock[mkResourceVirtualEnvironmentContainerConsoleEnabled].(bool))
@ -1721,10 +1717,9 @@ func resourceVirtualEnvironmentContainerUpdate(d *schema.ResourceData, m interfa
// Prepare the new CPU configuration.
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 {
return err
return diag.FromErr(err)
}
cpuArchitecture := cpuBlock[mkResourceVirtualEnvironmentContainerCPUArchitecture].(string)
@ -1743,10 +1738,10 @@ func resourceVirtualEnvironmentContainerUpdate(d *schema.ResourceData, m interfa
initializationDNSDomain := dvResourceVirtualEnvironmentContainerInitializationDNSDomain
initializationDNSServer := dvResourceVirtualEnvironmentContainerInitializationDNSServer
initializationHostname := dvResourceVirtualEnvironmentContainerInitializationHostname
initializationIPConfigIPv4Address := []string{}
initializationIPConfigIPv4Gateway := []string{}
initializationIPConfigIPv6Address := []string{}
initializationIPConfigIPv6Gateway := []string{}
var initializationIPConfigIPv4Address []string
var initializationIPConfigIPv4Gateway []string
var initializationIPConfigIPv6Address []string
var initializationIPConfigIPv6Gateway []string
if len(initialization) > 0 {
initializationBlock := initialization[0].(map[string]interface{})
@ -1799,10 +1794,9 @@ func resourceVirtualEnvironmentContainerUpdate(d *schema.ResourceData, m interfa
// Prepare the new memory configuration.
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 {
return err
return diag.FromErr(err)
}
memoryDedicated := memoryBlock[mkResourceVirtualEnvironmentContainerMemoryDedicated].(int)
@ -1818,10 +1812,9 @@ func resourceVirtualEnvironmentContainerUpdate(d *schema.ResourceData, m interfa
networkInterface := d.Get(mkResourceVirtualEnvironmentContainerNetworkInterface).([]interface{})
if len(networkInterface) == 0 && len(clone) > 0 {
networkInterface, err = resourceVirtualEnvironmentContainerGetExistingNetworkInterface(veClient, nodeName, vmID)
networkInterface, err = resourceVirtualEnvironmentContainerGetExistingNetworkInterface(ctx, veClient, nodeName, vmID)
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.
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 {
return err
return diag.FromErr(err)
}
operatingSystemType := operatingSystem[mkResourceVirtualEnvironmentContainerOperatingSystemType].(string)
@ -1911,10 +1903,9 @@ func resourceVirtualEnvironmentContainerUpdate(d *schema.ResourceData, m interfa
}
// 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 {
return err
return diag.FromErr(err)
}
// 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 started {
err = veClient.StartContainer(nodeName, vmID)
err = veClient.StartContainer(ctx, nodeName, vmID)
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 {
return err
return diag.FromErr(err)
}
} else {
forceStop := proxmox.CustomBool(true)
shutdownTimeout := 300
err = veClient.ShutdownContainer(nodeName, vmID, &proxmox.VirtualEnvironmentContainerShutdownRequestBody{
err = veClient.ShutdownContainer(ctx, nodeName, vmID, &proxmox.VirtualEnvironmentContainerShutdownRequestBody{
ForceStop: &forceStop,
Timeout: &shutdownTimeout,
})
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 {
return err
return diag.FromErr(err)
}
rebootRequired = false
@ -1960,61 +1947,55 @@ func resourceVirtualEnvironmentContainerUpdate(d *schema.ResourceData, m interfa
if !bool(template) && rebootRequired {
rebootTimeout := 300
err = veClient.RebootContainer(nodeName, vmID, &proxmox.VirtualEnvironmentContainerRebootRequestBody{
err = veClient.RebootContainer(ctx, nodeName, vmID, &proxmox.VirtualEnvironmentContainerRebootRequestBody{
Timeout: &rebootTimeout,
})
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)
veClient, err := config.GetVEClient()
if err != nil {
return err
return diag.FromErr(err)
}
nodeName := d.Get(mkResourceVirtualEnvironmentContainerNodeName).(string)
vmID, err := strconv.Atoi(d.Id())
if err != nil {
return err
return diag.FromErr(err)
}
// Shut down the container before deleting it.
status, err := veClient.GetContainerStatus(nodeName, vmID)
status, err := veClient.GetContainerStatus(ctx, nodeName, vmID)
if err != nil {
return err
return diag.FromErr(err)
}
if status.Status != "stopped" {
forceStop := proxmox.CustomBool(true)
shutdownTimeout := 300
err = veClient.ShutdownContainer(nodeName, vmID, &proxmox.VirtualEnvironmentContainerShutdownRequestBody{
err = veClient.ShutdownContainer(ctx, nodeName, vmID, &proxmox.VirtualEnvironmentContainerShutdownRequestBody{
ForceStop: &forceStop,
Timeout: &shutdownTimeout,
})
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 {
return err
return diag.FromErr(err)
}
}
err = veClient.DeleteContainer(nodeName, vmID)
err = veClient.DeleteContainer(ctx, nodeName, vmID)
if err != nil {
if strings.Contains(err.Error(), "HTTP 404") {
@ -2022,15 +2003,13 @@ func resourceVirtualEnvironmentContainerDelete(d *schema.ResourceData, m interfa
return nil
}
return err
return diag.FromErr(err)
}
// 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 {
return fmt.Errorf("Failed to delete container \"%d\"", vmID)
return diag.Errorf("failed to delete container \"%d\"", vmID)
}
d.SetId("")

View File

@ -7,7 +7,7 @@ package proxmoxtf
import (
"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.

View File

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

View File

@ -7,7 +7,7 @@ package proxmoxtf
import (
"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.

View File

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

View File

@ -7,7 +7,7 @@ package proxmoxtf
import (
"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.

View File

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

View File

@ -7,7 +7,7 @@ package proxmoxtf
import (
"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.

View File

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

View File

@ -7,7 +7,7 @@ package proxmoxtf
import (
"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.

View File

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

View File

@ -7,7 +7,7 @@ package proxmoxtf
import (
"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.

View File

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

View File

@ -7,7 +7,7 @@ package proxmoxtf
import (
"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.

View File

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

View File

@ -7,7 +7,7 @@ package proxmoxtf
import (
"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.

View File

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

View File

@ -7,7 +7,7 @@ package proxmoxtf
import (
"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.

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,7 @@ package proxmoxtf
import (
"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.

View File

@ -5,7 +5,10 @@
package proxmoxtf
import (
"errors"
"fmt"
"github.com/hashicorp/go-multierror"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"math"
"regexp"
"strconv"
@ -15,28 +18,28 @@ import (
"unicode"
"github.com/bpg/terraform-provider-proxmox/proxmox"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
)
func getBIOSValidator() schema.SchemaValidateFunc {
return validation.StringInSlice([]string{
func getBIOSValidator() schema.SchemaValidateDiagFunc {
return validation.ToDiagFunc(validation.StringInSlice([]string{
"ovmf",
"seabios",
}, false)
}, false))
}
func getContentTypeValidator() schema.SchemaValidateFunc {
return validation.StringInSlice([]string{
func getContentTypeValidator() schema.SchemaValidateDiagFunc {
return validation.ToDiagFunc(validation.StringInSlice([]string{
"backup",
"iso",
"snippets",
"vztmpl",
}, false)
}, false))
}
func getCPUFlagsValidator() schema.SchemaValidateFunc {
return func(i interface{}, k string) (ws []string, es []error) {
func getCPUFlagsValidator() schema.SchemaValidateDiagFunc {
return validation.ToDiagFunc(func(i interface{}, k string) (ws []string, es []error) {
list, ok := i.([]interface{})
if !ok {
@ -90,11 +93,11 @@ func getCPUFlagsValidator() schema.SchemaValidateFunc {
}
return
}
})
}
func getCPUTypeValidator() schema.SchemaValidateFunc {
return validation.StringInSlice([]string{
func getCPUTypeValidator() schema.SchemaValidateDiagFunc {
return validation.ToDiagFunc(validation.StringInSlice([]string{
"486",
"Broadwell",
"Broadwell-IBRS",
@ -140,19 +143,19 @@ func getCPUTypeValidator() schema.SchemaValidateFunc {
"phenom",
"qemu32",
"qemu64",
}, false)
}, false))
}
func getFileFormatValidator() schema.SchemaValidateFunc {
return validation.StringInSlice([]string{
func getFileFormatValidator() schema.SchemaValidateDiagFunc {
return validation.ToDiagFunc(validation.StringInSlice([]string{
"qcow2",
"raw",
"vmdk",
}, false)
}, false))
}
func getFileIDValidator() schema.SchemaValidateFunc {
return func(i interface{}, k string) (ws []string, es []error) {
func getFileIDValidator() schema.SchemaValidateDiagFunc {
return validation.ToDiagFunc(func(i interface{}, k string) (ws []string, es []error) {
v, ok := i.(string)
if !ok {
@ -161,7 +164,7 @@ func getFileIDValidator() schema.SchemaValidateFunc {
}
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)
if !ok {
@ -171,11 +174,11 @@ func getFileIDValidator() schema.SchemaValidateFunc {
}
return
}
})
}
func getKeyboardLayoutValidator() schema.SchemaValidateFunc {
return validation.StringInSlice([]string{
func getKeyboardLayoutValidator() schema.SchemaValidateDiagFunc {
return validation.ToDiagFunc(validation.StringInSlice([]string{
"da",
"de",
"de-ch",
@ -201,7 +204,7 @@ func getKeyboardLayoutValidator() schema.SchemaValidateFunc {
"sl",
"sv",
"tr",
}, false)
}, false))
}
func diskDigitPrefix(s string) string {
@ -213,8 +216,8 @@ func diskDigitPrefix(s string) string {
return s
}
func getMACAddressValidator() schema.SchemaValidateFunc {
return func(i interface{}, k string) (ws []string, es []error) {
func getMACAddressValidator() schema.SchemaValidateDiagFunc {
return validation.ToDiagFunc(func(i interface{}, k string) (ws []string, es []error) {
v, ok := i.(string)
if !ok {
@ -223,7 +226,7 @@ func getMACAddressValidator() schema.SchemaValidateFunc {
}
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)
if !ok {
@ -233,18 +236,18 @@ func getMACAddressValidator() schema.SchemaValidateFunc {
}
return
}
})
}
func getNetworkDeviceModelValidator() schema.SchemaValidateFunc {
return validation.StringInSlice([]string{"e1000", "rtl8139", "virtio", "vmxnet3"}, false)
func getNetworkDeviceModelValidator() schema.SchemaValidateDiagFunc {
return validation.ToDiagFunc(validation.StringInSlice([]string{"e1000", "rtl8139", "virtio", "vmxnet3"}, false))
}
func getQEMUAgentTypeValidator() schema.SchemaValidateFunc {
return validation.StringInSlice([]string{"isa", "virtio"}, false)
func getQEMUAgentTypeValidator() schema.SchemaValidateDiagFunc {
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 resourceData interface{}
var resourceSchema *schema.Schema
@ -257,7 +260,7 @@ func getSchemaBlock(r *schema.Resource, d *schema.ResourceData, m interface{}, k
mapValues := resourceData.([]interface{})
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{})
@ -288,8 +291,8 @@ func getSchemaBlock(r *schema.Resource, d *schema.ResourceData, m interface{}, k
return resourceBlock, nil
}
func getTimeoutValidator() schema.SchemaValidateFunc {
return func(i interface{}, k string) (ws []string, es []error) {
func getTimeoutValidator() schema.SchemaValidateDiagFunc {
return validation.ToDiagFunc(func(i interface{}, k string) (ws []string, es []error) {
v, ok := i.(string)
if !ok {
@ -305,15 +308,15 @@ func getTimeoutValidator() schema.SchemaValidateFunc {
}
return
}
})
}
func getVGAMemoryValidator() schema.SchemaValidateFunc {
return validation.IntBetween(4, 512)
func getVGAMemoryValidator() schema.SchemaValidateDiagFunc {
return validation.ToDiagFunc(validation.IntBetween(4, 512))
}
func getVGATypeValidator() schema.SchemaValidateFunc {
return validation.StringInSlice([]string{
func getVGATypeValidator() schema.SchemaValidateDiagFunc {
return validation.ToDiagFunc(validation.StringInSlice([]string{
"cirrus",
"qxl",
"qxl2",
@ -326,11 +329,11 @@ func getVGATypeValidator() schema.SchemaValidateFunc {
"std",
"virtio",
"vmware",
}, false)
}, false))
}
func getVLANIDsValidator() schema.SchemaValidateFunc {
return func(i interface{}, k string) (ws []string, es []error) {
func getVLANIDsValidator() schema.SchemaValidateDiagFunc {
return validation.ToDiagFunc(func(i interface{}, k string) (ws []string, es []error) {
min := 1
max := 4094
@ -358,11 +361,11 @@ func getVLANIDsValidator() schema.SchemaValidateFunc {
}
return
}
})
}
func getVMIDValidator() schema.SchemaValidateFunc {
return func(i interface{}, k string) (ws []string, es []error) {
func getVMIDValidator() schema.SchemaValidateDiagFunc {
return validation.ToDiagFunc(func(i interface{}, k string) (ws []string, es []error) {
min := 100
max := 2147483647
@ -381,7 +384,7 @@ func getVMIDValidator() schema.SchemaValidateFunc {
}
return
}
})
}
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 {
diskMap := v.(map[string]interface{})
diskInterface := diskMap[mkResourcevirtualEnvironmentVMDiskInterface].(string)
diskInterface := diskMap[mkResourceVirtualEnvironmentVMDiskInterface].(string)
currentDiskMap[diskInterface] = diskMap
}
@ -485,17 +488,17 @@ func parseDiskSize(size *string) (int, error) {
diskSize = int(math.Ceil(float64(diskSize) / 1024))
} else {
return -1, fmt.Errorf("Cannot parse storage size \"%s\"", *size)
return -1, fmt.Errorf("cannot parse storage size \"%s\"", *size)
}
}
return diskSize, err
}
func getCloudInitTypeValidator() schema.SchemaValidateFunc {
return validation.StringInSlice([]string{
func getCloudInitTypeValidator() schema.SchemaValidateDiagFunc {
return validation.ToDiagFunc(validation.StringInSlice([]string{
"configdrive2",
"nocloud",
}, false)
}, false))
}
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 {
schema, ok := s.Schema[key].Elem.(*schema.Resource)
sh, ok := s.Schema[key].Elem.(*schema.Resource)
if !ok {
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 schema
return sh
}
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
//goland:noinspection ALL
const (
// TerraformProviderName specifies the full name of this provider.
TerraformProviderName = "terraform-provider-proxmox"
// TerraformProviderVersion specifies the version number.
TerraformProviderVersion = "0.5.1"
TerraformProviderVersion = "0.6.0"
)

View File

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