diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index d84110f0..11324624 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -16,7 +16,8 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v3
with:
- go-version: 1.16
+ go-version-file: "go.mod"
+ cache: true
- name: Import GPG key
id: import_gpg
diff --git a/.github/workflows/terraform-provider-checks.yml b/.github/workflows/terraform-provider-checks.yml
index f1f817bf..fdf7dbce 100644
--- a/.github/workflows/terraform-provider-checks.yml
+++ b/.github/workflows/terraform-provider-checks.yml
@@ -2,17 +2,55 @@ name: Terraform Provider Checks
on: [pull_request]
jobs:
+
+ golangci:
+ name: golangci-lint
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+
+ - uses: actions/setup-go@v3
+ with:
+ go-version-file: "go.mod"
+ cache: true
+
+ - name: golangci-lint
+ uses: golangci/golangci-lint-action@v3
+ with:
+ # Optional: version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version
+ version: latest
+
+ # Optional: working directory, useful for monorepos
+ # working-directory: somedir
+
+ # Optional: golangci-lint command line arguments.
+ # args: --issues-exit-code=0
+
+ # Optional: show only new issues if it's a pull request. The default value is `false`.
+ # only-new-issues: true
+
+ # Optional: if set to true then the all caching functionality will be complete disabled,
+ # takes precedence over all other caching options.
+ # skip-cache: true
+
+ # Optional: if set to true then the action don't cache or restore ~/go/pkg.
+ # skip-pkg-cache: true
+
+ # Optional: if set to true then the action don't cache or restore ~/.cache/go-build.
+ # skip-build-cache: true
+
build:
name: Build
runs-on: ubuntu-latest
steps:
+ - name: Check out code into the Go module directory
+ uses: actions/checkout@v3.0.2
+
- name: Set up Go 1.x
uses: actions/setup-go@v3
with:
- go-version: ^1.16
-
- - name: Check out code into the Go module directory
- uses: actions/checkout@v3.0.2
+ go-version-file: "go.mod"
+ cache: true
- name: Setup dependency cache
uses: actions/cache@v3.0.1
@@ -34,5 +72,4 @@ jobs:
- name: Test
run: |
- make lint
make test
diff --git a/.go-version b/.go-version
index 0d92a102..0150af13 100644
--- a/.go-version
+++ b/.go-version
@@ -1 +1 @@
-1.16.5
+1.18.10
diff --git a/.golangci.yml b/.golangci.yml
index e996d5fb..168503c9 100644
--- a/.golangci.yml
+++ b/.golangci.yml
@@ -8,7 +8,6 @@ issues:
linters:
disable-all: true
enable:
- - deadcode
- errcheck
- gofmt
- gomnd
@@ -19,11 +18,9 @@ linters:
- nakedret
- nilerr
- staticcheck
- - structcheck
- unconvert
- unused
- unparam
- - varcheck
- vet
linters-settings:
diff --git a/README.md b/README.md
index 7471c883..620e2d0b 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@
## Requirements
- [Terraform](https://www.terraform.io/downloads.html) 1.0.1
-- [Go](https://golang.org/doc/install) 1.16 (to build the provider plugin)
+- [Go](https://golang.org/doc/install) 1.18 (to build the provider plugin)
## Example Usage
@@ -22,7 +22,7 @@ Please see the Go documentation for the most up to date information about using
To add a new dependency `github.com/author/dependency` to your Terraform provider:
-```
+```shell
go get github.com/author/dependency
go mod tidy
```
@@ -66,7 +66,7 @@ to your `~/.terraformrc` file. This is valid for Terraform 0.14+. Please see
[Terraform's documentation](https://www.terraform.io/docs/cli/config/config-file.html#development-overrides-for-provider-developers)
for more details.
-```
+```hcl
provider_installation {
# Use /home/$USER/go/bin as an overridden package directory
diff --git a/docs/index.md b/docs/index.md
index 1cf2f684..1332f0c1 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -21,11 +21,8 @@ provider "jupiterone" {
## Schema
-### Required
+### Optional
- `account_id` (String) JupiterOne account ID to create resources in
- `api_key` (String, Sensitive) API Key used to make requests to the JupiterOne APIs
-
-### Optional
-
- `region` (String)
\ No newline at end of file
diff --git a/docs/resources/question.md b/docs/resources/question.md
index 46add889..b211b527 100644
--- a/docs/resources/question.md
+++ b/docs/resources/question.md
@@ -3,12 +3,12 @@
page_title: "jupiterone_question Resource - terraform-provider-jupiterone"
subcategory: ""
description: |-
-
+ A saved JupiterOne Question
---
# jupiterone_question (Resource)
-
+A saved JupiterOne Question
## Example Usage
@@ -32,41 +32,41 @@ resource "jupiterone_question" "unencrypted_critical_data_stores" {
### Required
- `description` (String)
-- `query` (Block List, Min: 1) (see [below for nested schema](#nestedblock--query))
- `title` (String) The title of the question
### Optional
- `compliance` (Block List) (see [below for nested schema](#nestedblock--compliance))
+- `query` (Block List) (see [below for nested schema](#nestedblock--query))
- `tags` (List of String)
### Read-Only
- `id` (String) The ID of this resource.
-
-### Nested Schema for `query`
+
+### Nested Schema for `compliance`
Required:
-- `query` (String)
-- `version` (String)
+- `standard` (String)
Optional:
-- `name` (String)
+- `controls` (List of String)
+- `requirements` (List of String)
-
-### Nested Schema for `compliance`
+
+### Nested Schema for `query`
Required:
-- `standard` (String)
+- `query` (String)
+- `version` (String)
Optional:
-- `controls` (List of String)
-- `requirements` (List of String)
+- `name` (String)
diff --git a/docs/resources/rule.md b/docs/resources/rule.md
index f9e911b0..c88a7bef 100644
--- a/docs/resources/rule.md
+++ b/docs/resources/rule.md
@@ -3,12 +3,12 @@
page_title: "jupiterone_rule Resource - terraform-provider-jupiterone"
subcategory: ""
description: |-
-
+ A saved JupiterOne question based alert
---
# jupiterone_rule (Resource)
-
+A saved JupiterOne question based alert
## Example Usage
@@ -108,7 +108,7 @@ resource "jupiterone_rule" "users_without_mfa" {
- `outputs` (List of String) Names of properties that can be used throughout the rule evaluation process and will be included in each record of a rule evaluation. (e.g. queries.query0.total)
- `polling_interval` (String) Frequency of automated rule evaluation. Defaults to ONE_DAY.
-- `question` (Block List, Max: 1) Contains properties related to queries used in the rule evaluation. (see [below for nested schema](#nestedblock--question))
+- `question` (Block List) Contains properties related to queries used in the rule evaluation. (see [below for nested schema](#nestedblock--question))
- `question_id` (String) Specifies the ID of a question to be used in rule evaluation.
- `question_name` (String, Deprecated) Specifies the name of a question to be used in rule evaluation.
- `spec_version` (Number) Rule evaluation specification version in the case of breaking changes.
@@ -117,15 +117,15 @@ resource "jupiterone_rule" "users_without_mfa" {
### Read-Only
-- `id` (String) The ID of this resource.
+- `id` (String) Unique id that identifies the rule
- `version` (Number) Computed current version of the rule. Incremented each time the rule is updated.
### Nested Schema for `question`
-Required:
+Optional:
-- `queries` (Block List, Min: 1) (see [below for nested schema](#nestedblock--question--queries))
+- `queries` (Block List) Contains properties related to queries used in the rule evaluation. (see [below for nested schema](#nestedblock--question--queries))
### Nested Schema for `question.queries`
diff --git a/go.mod b/go.mod
index 87b0c1c9..5e59a23a 100644
--- a/go.mod
+++ b/go.mod
@@ -1,6 +1,6 @@
module github.com/jupiterone/terraform-provider-jupiterone
-go 1.16
+go 1.18
require (
github.com/client9/misspell v0.3.4
@@ -8,8 +8,212 @@ require (
github.com/golangci/golangci-lint v1.46.2
github.com/hashicorp/go-cleanhttp v0.5.2
github.com/hashicorp/terraform-plugin-docs v0.13.0
+ github.com/hashicorp/terraform-plugin-framework v1.1.1
+ github.com/hashicorp/terraform-plugin-framework-validators v0.9.0
+ github.com/hashicorp/terraform-plugin-go v0.14.3
+ github.com/hashicorp/terraform-plugin-log v0.7.0
+ github.com/hashicorp/terraform-plugin-sdk v1.17.2
github.com/hashicorp/terraform-plugin-sdk/v2 v2.19.0
github.com/machinebox/graphql v0.2.2
github.com/mitchellh/mapstructure v1.5.0
github.com/stretchr/testify v1.8.0
)
+
+require (
+ 4d63.com/gochecknoglobals v0.1.0 // indirect
+ github.com/Antonboom/errname v0.1.6 // indirect
+ github.com/Antonboom/nilnil v0.1.1 // indirect
+ github.com/BurntSushi/toml v1.1.0 // indirect
+ github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 // indirect
+ github.com/GaijinEntertainment/go-exhaustruct/v2 v2.1.0 // indirect
+ github.com/Masterminds/goutils v1.1.1 // indirect
+ github.com/Masterminds/semver v1.5.0 // indirect
+ github.com/Masterminds/semver/v3 v3.1.1 // indirect
+ github.com/Masterminds/sprig/v3 v3.2.2 // indirect
+ github.com/OpenPeeDeeP/depguard v1.1.0 // indirect
+ github.com/agext/levenshtein v1.2.2 // indirect
+ github.com/alexkohler/prealloc v1.0.0 // indirect
+ github.com/apparentlymart/go-cidr v1.1.0 // indirect
+ github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
+ github.com/armon/go-radix v1.0.0 // indirect
+ github.com/ashanbrown/forbidigo v1.3.0 // indirect
+ github.com/ashanbrown/makezero v1.1.1 // indirect
+ github.com/beorn7/perks v1.0.1 // indirect
+ github.com/bgentry/speakeasy v0.1.0 // indirect
+ github.com/bkielbasa/cyclop v1.2.0 // indirect
+ github.com/blizzy78/varnamelen v0.8.0 // indirect
+ github.com/bombsimon/wsl/v3 v3.3.0 // indirect
+ github.com/breml/bidichk v0.2.3 // indirect
+ github.com/breml/errchkjson v0.3.0 // indirect
+ github.com/butuzov/ireturn v0.1.1 // indirect
+ github.com/cespare/xxhash/v2 v2.1.2 // indirect
+ github.com/charithe/durationcheck v0.0.9 // indirect
+ github.com/chavacava/garif v0.0.0-20220316182200-5cad0b5181d4 // indirect
+ github.com/daixiang0/gci v0.3.3 // indirect
+ github.com/davecgh/go-spew v1.1.1 // indirect
+ github.com/denis-tingaikin/go-header v0.4.3 // indirect
+ github.com/esimonov/ifshort v1.0.4 // indirect
+ github.com/ettle/strcase v0.1.1 // indirect
+ github.com/fatih/color v1.13.0 // indirect
+ github.com/fatih/structtag v1.2.0 // indirect
+ github.com/firefart/nonamedreturns v1.0.1 // indirect
+ github.com/fsnotify/fsnotify v1.5.4 // indirect
+ github.com/fzipp/gocyclo v0.5.1 // indirect
+ github.com/go-critic/go-critic v0.6.3 // indirect
+ github.com/go-toolsmith/astcast v1.0.0 // indirect
+ github.com/go-toolsmith/astcopy v1.0.0 // indirect
+ github.com/go-toolsmith/astequal v1.0.1 // indirect
+ github.com/go-toolsmith/astfmt v1.0.0 // indirect
+ github.com/go-toolsmith/astp v1.0.0 // indirect
+ github.com/go-toolsmith/strparse v1.0.0 // indirect
+ github.com/go-toolsmith/typep v1.0.2 // indirect
+ github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b // indirect
+ github.com/gobwas/glob v0.2.3 // indirect
+ github.com/gofrs/flock v0.8.1 // indirect
+ github.com/golang/protobuf v1.5.2 // indirect
+ github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 // indirect
+ github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a // indirect
+ github.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe // indirect
+ github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a // indirect
+ github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0 // indirect
+ github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca // indirect
+ github.com/golangci/misspell v0.3.5 // indirect
+ github.com/golangci/revgrep v0.0.0-20210930125155-c22e5001d4f2 // indirect
+ github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 // indirect
+ github.com/google/go-cmp v0.5.9 // indirect
+ github.com/google/uuid v1.3.0 // indirect
+ github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8 // indirect
+ github.com/gostaticanalysis/analysisutil v0.7.1 // indirect
+ github.com/gostaticanalysis/comment v1.4.2 // indirect
+ github.com/gostaticanalysis/forcetypeassert v0.1.0 // indirect
+ github.com/gostaticanalysis/nilerr v0.1.1 // indirect
+ github.com/hashicorp/errwrap v1.1.0 // indirect
+ github.com/hashicorp/go-checkpoint v0.5.0 // indirect
+ github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 // indirect
+ github.com/hashicorp/go-hclog v1.2.1 // indirect
+ github.com/hashicorp/go-multierror v1.1.1 // indirect
+ github.com/hashicorp/go-plugin v1.4.8 // indirect
+ github.com/hashicorp/go-uuid v1.0.3 // indirect
+ github.com/hashicorp/go-version v1.6.0 // indirect
+ github.com/hashicorp/hc-install v0.4.0 // indirect
+ github.com/hashicorp/hcl v1.0.0 // indirect
+ github.com/hashicorp/hcl/v2 v2.13.0 // indirect
+ github.com/hashicorp/logutils v1.0.0 // indirect
+ github.com/hashicorp/terraform-exec v0.17.2 // indirect
+ github.com/hashicorp/terraform-json v0.14.0 // indirect
+ github.com/hashicorp/terraform-registry-address v0.1.0 // indirect
+ github.com/hashicorp/terraform-svchost v0.0.0-20200729002733-f050f53b9734 // indirect
+ github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d // indirect
+ github.com/hexops/gotextdiff v1.0.3 // indirect
+ github.com/huandu/xstrings v1.3.2 // indirect
+ github.com/imdario/mergo v0.3.13 // indirect
+ github.com/inconshreveable/mousetrap v1.0.0 // indirect
+ github.com/jgautheron/goconst v1.5.1 // indirect
+ github.com/jingyugao/rowserrcheck v1.1.1 // indirect
+ github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af // indirect
+ github.com/julz/importas v0.1.0 // indirect
+ github.com/kisielk/errcheck v1.6.0 // indirect
+ github.com/kisielk/gotool v1.0.0 // indirect
+ github.com/kulti/thelper v0.6.2 // indirect
+ github.com/kunwardeep/paralleltest v1.0.3 // indirect
+ github.com/kyoh86/exportloopref v0.1.8 // indirect
+ github.com/ldez/gomoddirectives v0.2.3 // indirect
+ github.com/ldez/tagliatelle v0.3.1 // indirect
+ github.com/leonklingele/grouper v1.1.0 // indirect
+ github.com/lufeee/execinquery v1.2.1 // indirect
+ github.com/magiconair/properties v1.8.6 // indirect
+ github.com/maratori/testpackage v1.0.1 // indirect
+ github.com/matoous/godox v0.0.0-20210227103229-6504466cf951 // indirect
+ github.com/mattn/go-colorable v0.1.12 // indirect
+ github.com/mattn/go-isatty v0.0.14 // indirect
+ github.com/mattn/go-runewidth v0.0.9 // indirect
+ github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
+ github.com/mbilski/exhaustivestruct v1.2.0 // indirect
+ github.com/mgechev/revive v1.2.1 // indirect
+ github.com/mitchellh/cli v1.1.4 // indirect
+ github.com/mitchellh/copystructure v1.2.0 // indirect
+ github.com/mitchellh/go-homedir v1.1.0 // indirect
+ github.com/mitchellh/go-testing-interface v1.14.1 // indirect
+ github.com/mitchellh/go-wordwrap v1.0.0 // indirect
+ github.com/mitchellh/reflectwalk v1.0.2 // indirect
+ github.com/moricho/tparallel v0.2.1 // indirect
+ github.com/nakabonne/nestif v0.3.1 // indirect
+ github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 // indirect
+ github.com/nishanths/exhaustive v0.7.11 // indirect
+ github.com/nishanths/predeclared v0.2.2 // indirect
+ github.com/oklog/run v1.0.0 // indirect
+ github.com/olekukonko/tablewriter v0.0.5 // indirect
+ github.com/pelletier/go-toml v1.9.5 // indirect
+ github.com/pelletier/go-toml/v2 v2.0.0 // indirect
+ github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d // indirect
+ github.com/pkg/errors v0.9.1 // indirect
+ github.com/pmezard/go-difflib v1.0.0 // indirect
+ github.com/polyfloyd/go-errorlint v1.0.0 // indirect
+ github.com/posener/complete v1.2.3 // indirect
+ github.com/prometheus/client_golang v1.12.1 // indirect
+ github.com/prometheus/client_model v0.2.0 // indirect
+ github.com/prometheus/common v0.32.1 // indirect
+ github.com/prometheus/procfs v0.7.3 // indirect
+ github.com/quasilyte/go-ruleguard v0.3.16-0.20220213074421-6aa060fab41a // indirect
+ github.com/quasilyte/gogrep v0.0.0-20220120141003-628d8b3623b5 // indirect
+ github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95 // indirect
+ github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect
+ github.com/russross/blackfriday v1.6.0 // indirect
+ github.com/ryancurrah/gomodguard v1.2.3 // indirect
+ github.com/ryanrolds/sqlclosecheck v0.3.0 // indirect
+ github.com/sanposhiho/wastedassign/v2 v2.0.6 // indirect
+ github.com/securego/gosec/v2 v2.11.0 // indirect
+ github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c // indirect
+ github.com/shopspring/decimal v1.3.1 // indirect
+ github.com/sirupsen/logrus v1.8.1 // indirect
+ github.com/sivchari/containedctx v1.0.2 // indirect
+ github.com/sivchari/tenv v1.5.0 // indirect
+ github.com/sonatard/noctx v0.0.1 // indirect
+ github.com/sourcegraph/go-diff v0.6.1 // indirect
+ github.com/spf13/afero v1.8.2 // indirect
+ github.com/spf13/cast v1.5.0 // indirect
+ github.com/spf13/cobra v1.4.0 // indirect
+ github.com/spf13/jwalterweatherman v1.1.0 // indirect
+ github.com/spf13/pflag v1.0.5 // indirect
+ github.com/spf13/viper v1.11.0 // indirect
+ github.com/ssgreg/nlreturn/v2 v2.2.1 // indirect
+ github.com/stbenjam/no-sprintf-host-port v0.1.1 // indirect
+ github.com/stretchr/objx v0.4.0 // indirect
+ github.com/subosito/gotenv v1.2.0 // indirect
+ github.com/sylvia7788/contextcheck v1.0.4 // indirect
+ github.com/tdakkota/asciicheck v0.1.1 // indirect
+ github.com/tetafro/godot v1.4.11 // indirect
+ github.com/timakin/bodyclose v0.0.0-20210704033933-f49887972144 // indirect
+ github.com/tomarrell/wrapcheck/v2 v2.6.1 // indirect
+ github.com/tommy-muehle/go-mnd/v2 v2.5.0 // indirect
+ github.com/ultraware/funlen v0.0.3 // indirect
+ github.com/ultraware/whitespace v0.0.5 // indirect
+ github.com/uudashr/gocognit v1.0.5 // 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/yagipy/maintidx v1.0.0 // indirect
+ github.com/yeya24/promlinter v0.2.0 // indirect
+ github.com/zclconf/go-cty v1.10.0 // indirect
+ gitlab.com/bosi/decorder v0.2.1 // indirect
+ golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d // indirect
+ golang.org/x/exp/typeparams v0.0.0-20220218215828-6cf2b201936e // indirect
+ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
+ golang.org/x/net v0.0.0-20220722155237-a158d28d115b // indirect
+ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect
+ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f // indirect
+ golang.org/x/text v0.4.0 // indirect
+ golang.org/x/tools v0.1.12 // indirect
+ google.golang.org/appengine v1.6.7 // indirect
+ google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac // indirect
+ google.golang.org/grpc v1.51.0 // indirect
+ google.golang.org/protobuf v1.28.1 // indirect
+ gopkg.in/ini.v1 v1.66.4 // indirect
+ gopkg.in/yaml.v2 v2.4.0 // indirect
+ gopkg.in/yaml.v3 v3.0.1 // indirect
+ honnef.co/go/tools v0.3.1 // indirect
+ mvdan.cc/gofumpt v0.3.1 // indirect
+ mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed // indirect
+ mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b // indirect
+ mvdan.cc/unparam v0.0.0-20211214103731-d0ef000c54e5 // indirect
+)
diff --git a/go.sum b/go.sum
index 31335738..707a9e12 100644
--- a/go.sum
+++ b/go.sum
@@ -31,7 +31,6 @@ cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aD
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.98.0/go.mod h1:ua6Ush4NALrHk5QXDWnjvZHN93OuF0HfuEPq9I1X0cM=
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/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
@@ -65,7 +64,6 @@ github.com/Antonboom/errname v0.1.6/go.mod h1:7lz79JAnuoMNDAWE9MeeIr1/c/VpSUWatB
github.com/Antonboom/nilnil v0.1.1 h1:PHhrh5ANKFWRBh7TdYmyyq2gyT2lotnvFvvFbylF81Q=
github.com/Antonboom/nilnil v0.1.1/go.mod h1:L1jBqoWM7AOeTD+tSquifKSesRHs4ZdaxvZR+xdJEaI=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
-github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/BurntSushi/toml v1.1.0 h1:ksErzDEI1khOiGPgpwuI7x2ebx/uXQNw7xJpn9Eq1+I=
github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
@@ -83,7 +81,6 @@ github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF0
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.15.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=
-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=
@@ -101,6 +98,8 @@ github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ
github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
github.com/agext/levenshtein v1.2.2 h1:0S/Yg6LYmFJ5stwQeRp6EeOcCbj7xiqQSdNelsXvaqE=
github.com/agext/levenshtein v1.2.2/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/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
@@ -108,8 +107,7 @@ github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRF
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
github.com/alexkohler/prealloc v1.0.0 h1:Hbq0/3fJPQhNkN0dR95AVrr6R7tou91y0uHG5pOcUuw=
github.com/alexkohler/prealloc v1.0.0/go.mod h1:VetnK3dIgFBBKmg0YnD9F9x6Icjd+9cvfHR56wJVlKE=
-github.com/andybalholm/brotli v1.0.2/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
-github.com/andybalholm/brotli v1.0.3/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
+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 v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
@@ -119,7 +117,6 @@ github.com/apparentlymart/go-cidr v1.1.0/go.mod h1:EBcsNrHc3zQeuaeCeCtQruQm+n9/Y
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=
@@ -136,13 +133,16 @@ github.com/ashanbrown/forbidigo v1.3.0 h1:VkYIwb/xxdireGAdJNZoo24O4lmnEWkactplBl
github.com/ashanbrown/forbidigo v1.3.0/go.mod h1:vVW7PEdqEFqapJe95xHkTfB1+XvZXBFg8t0sG2FIxmI=
github.com/ashanbrown/makezero v1.1.1 h1:iCQ87C0V0vSyO+M9E/FZYbu65auqH0lnsOkf5FcB28s=
github.com/ashanbrown/makezero v1.1.1/go.mod h1:i1bJLCRSCHOcOa9Y6MyF2FTfMZMFdHvxKHxgO5Z1axI=
+github.com/aws/aws-sdk-go v1.15.78/go.mod h1:E3/ieXAlvM0XWO57iftYVDLLvQ824smPP3ATZkfNZeM=
github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/aws/aws-sdk-go v1.25.37/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/aws/aws-sdk-go v1.36.30/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
+github.com/aws/aws-sdk-go v1.37.0/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
+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/bkielbasa/cyclop v1.2.0 h1:7Jmnh0yL2DjKfw28p86YTd/B4lRGcNuu12sKE35sM7A=
@@ -158,8 +158,6 @@ github.com/breml/errchkjson v0.3.0/go.mod h1:9Cogkyv9gcT8HREpzi3TiqBxCqDzo8awa92
github.com/butuzov/ireturn v0.1.1 h1:QvrO2QF2+/Cx1WA/vETCIYBKtRjc30vesdoPUNo1EbY=
github.com/butuzov/ireturn v0.1.1/go.mod h1:Wh6Zl3IMtTpaIKbmwzqi6olnM9ptYQxxVacMsOEFPoc=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
-github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
-github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
@@ -168,6 +166,7 @@ github.com/charithe/durationcheck v0.0.9 h1:mPP4ucLrf/rKZiIG/a9IPXHGlh8p4CzgpyTy
github.com/charithe/durationcheck v0.0.9/go.mod h1:SSbRIBVfMjCi/kEB6K65XEA83D6prSM8ap1UCpNKtgg=
github.com/chavacava/garif v0.0.0-20220316182200-5cad0b5181d4 h1:tFXjAxje9thrTF4h57Ckik+scJjTWdwAtZqZPtOT48M=
github.com/chavacava/garif v0.0.0-20220316182200-5cad0b5181d4/go.mod h1:W8EnPSQ8Nv4fUjc/v1/8tHFqhuOJXnRub0dTfuAQktU=
+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=
@@ -182,9 +181,7 @@ github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XP
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=
-github.com/cncf/xds/go v0.0.0-20211130200136-a8f946100490/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
@@ -224,11 +221,8 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m
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.1/go.mod h1:AY7fTTXNdv/aJ2O5jwpxAPOWUZ7hQAEvzN5Pf27BkQQ=
-github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=
github.com/envoyproxy/protoc-gen-validate v0.0.14/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
-github.com/envoyproxy/protoc-gen-validate v0.6.2/go.mod h1:2t7qjJNvHPx8IjnBOzl9E9/baC+qXE/TeeyBRzgJDws=
github.com/esimonov/ifshort v1.0.4 h1:6SID4yGWfRae/M7hkVDVVyppy8q/v9OuxNdmjLQStBA=
github.com/esimonov/ifshort v1.0.4/go.mod h1:Pe8zjlRrJ80+q2CxHLfEOfTwxCZ4O+MuhcHcfgNWTk0=
github.com/ettle/strcase v0.1.1 h1:htFueZyVeE1XNnMEfbqp5r67qAN/4r6ya1ysq8Q+Zcw=
@@ -243,9 +237,7 @@ github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4
github.com/firefart/nonamedreturns v1.0.1 h1:fSvcq6ZpK/uBAgJEGMvzErlzyM4NELLqqdTofVjVNag=
github.com/firefart/nonamedreturns v1.0.1/go.mod h1:D3dpIBojGGNh5UfElmwPu73SwDCm+VKhHYqwlNOk2uQ=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
-github.com/frankban/quicktest v1.14.2/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps=
github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE=
-github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU=
@@ -260,10 +252,14 @@ github.com/go-critic/go-critic v0.6.3 h1:abibh5XYBTASawfTQ0rA7dVtQT+6KzpGqb/J+Dx
github.com/go-critic/go-critic v0.6.3/go.mod h1:c6b3ZP1MQ7o6lPR7Rv3lEf7pYQUmAcx8ABHgdZCQt/k=
github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4=
github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E=
+github.com/go-git/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-billy/v5 v5.2.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
github.com/go-git/go-billy/v5 v5.3.1 h1:CPiOUAzKtMRvolEKw+bG1PLRpT7D3LIs3/3ey4Aiu34=
github.com/go-git/go-billy/v5 v5.3.1/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
+github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw=
github.com/go-git/go-git-fixtures/v4 v4.2.1/go.mod h1:K8zd3kDUAykwTdDCr+I0per6Y6vMiRR/nnVTBtavnB0=
+github.com/go-git/go-git/v5 v5.3.0/go.mod h1:xdX4bWJ48aOrdhnl2XqHYstHbbp6+LFS4r4X+lNVprw=
github.com/go-git/go-git/v5 v5.4.2 h1:BXyZu9t0VkbiHtqrsvdq39UDhGJTl1h55VW6CSC4aY4=
github.com/go-git/go-git/v5 v5.4.2/go.mod h1:gQ1kArt6d+n+BGd+/B/I74HwRTLhth2+zti4ihgckDc=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
@@ -275,7 +271,6 @@ github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vb
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
-github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-redis/redis v6.15.8+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
@@ -346,6 +341,7 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS
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/golangci/check v0.0.0-20180506172741-cfe4005ccda2 h1:23T5iq8rbUYlhpt5DB4XJkc6BU31uODLD1o1gKvZmD0=
github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2/go.mod h1:k9Qvh+8juN+UKMCS/3jFtGICgW8O96FVaZsaxdzDkR4=
@@ -384,8 +380,9 @@ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
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-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
+github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
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=
@@ -434,7 +431,6 @@ github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/ad
github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE=
github.com/gostaticanalysis/analysisutil v0.0.3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE=
github.com/gostaticanalysis/analysisutil v0.1.0/go.mod h1:dMhHRU9KTiDcuLGdy87/2gTR8WruwYZrKdRq9m1O6uw=
-github.com/gostaticanalysis/analysisutil v0.4.1/go.mod h1:18U/DLpRgIUd459wGxVHE0fRgmo1UgHDcbw7F5idXu0=
github.com/gostaticanalysis/analysisutil v0.7.1 h1:ZMCjoue3DtDWQ5WyU16YbjbQEQ3VuzwxALrpYd+HeKk=
github.com/gostaticanalysis/analysisutil v0.7.1/go.mod h1:v21E3hY37WKMGSnbsw2S/ojApNWb6C1//mXO48CXbVc=
github.com/gostaticanalysis/comment v1.3.0/go.mod h1:xMicKDx7XRXYdVwY9f9wQpDJVnqWxw9wCauCMKp+IBI=
@@ -447,7 +443,6 @@ github.com/gostaticanalysis/nilerr v0.1.1 h1:ThE+hJP0fEp4zWLkWHWcRyI2Od0p7DlgYG3
github.com/gostaticanalysis/nilerr v0.1.1/go.mod h1:wZYb6YI5YAxxq0i1+VJbY0s2YONW0HU0GPE3+5PWN4A=
github.com/gostaticanalysis/testutil v0.3.1-0.20210208050101-bfb5c8eec0e4/go.mod h1:D+FIZ+7OahH3ePw/izIEeH5I06eKs1IKI4Xr64/Am3M=
github.com/gostaticanalysis/testutil v0.4.0 h1:nhdCmubdmDF6VEatUNjgUZBJKWRqugoISdUv3PPQgHY=
-github.com/gostaticanalysis/testutil v0.4.0/go.mod h1:bLIoPefWXrRi/ssLFWX1dx7Repi5x3CuviD3dgAZaBU=
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI=
@@ -455,7 +450,6 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgf
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/grpc-ecosystem/grpc-gateway v1.12.1/go.mod h1:8XEsbTttt/W+VvjtQhLACqCisSPWTxCZ7sBRjU6iH9c=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
-github.com/hashicorp/consul/api v1.11.0/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M=
github.com/hashicorp/consul/api v1.12.0/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0=
github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
@@ -469,9 +463,10 @@ github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9n
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 h1:1/D3zfFHttUKaCaGKZ/dR2roBXv0vKbSCnssIldfQdI=
github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320/go.mod h1:EiZBMaudVLy8fmjf9Npq1dq9RalhveqZG5w/yz3mHWs=
+github.com/hashicorp/go-getter v1.5.3/go.mod h1:BrrV/1clo8cCYu6mxvboYg+KutTiFnXjMEgDD8+i7ZI=
+github.com/hashicorp/go-hclog 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.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
-github.com/hashicorp/go-hclog v0.14.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
-github.com/hashicorp/go-hclog v1.0.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
github.com/hashicorp/go-hclog v1.2.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
github.com/hashicorp/go-hclog v1.2.1 h1:YQsLlGDJgwhXFpucSPyVbCBviQtjlHv3jLTlp8YmtEw=
github.com/hashicorp/go-hclog v1.2.1/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
@@ -482,19 +477,22 @@ github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHh
github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA=
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.4.4 h1:NVdrSdFRt3SkZtNckJ6tog7gbpRrcbOjQi/rgF7JYWQ=
-github.com/hashicorp/go-plugin v1.4.4/go.mod h1:viDMjcLJuDui6pXb8U4HVfb8AamCWhHGUjr2IrTF67s=
+github.com/hashicorp/go-plugin v1.3.0/go.mod h1:F9eH4LrE/ZsRdbwhfjs9k9HoDUwAHnYtXdgmf1AVNs0=
+github.com/hashicorp/go-plugin v1.4.8 h1:CHGwpxYDOttQOY7HOWgETU9dyVjOXzniXDqJcYJE1zM=
+github.com/hashicorp/go-plugin v1.4.8/go.mod h1:viDMjcLJuDui6pXb8U4HVfb8AamCWhHGUjr2IrTF67s=
github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=
github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
+github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I=
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
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.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
-github.com/hashicorp/go-version v1.4.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/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek=
github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
@@ -503,33 +501,43 @@ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hashicorp/hc-install v0.4.0 h1:cZkRFr1WVa0Ty6x5fTvL1TuO1flul231rWkGH92oYYk=
github.com/hashicorp/hc-install v0.4.0/go.mod h1:5d155H8EC5ewegao9A4PUTMNPZaq+TbOzkJJZ4vrXeI=
+github.com/hashicorp/hcl v0.0.0-20170504190234-a4b07c25de5f/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
+github.com/hashicorp/hcl/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.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/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY=
github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc=
-github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE=
github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE=
-github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk=
github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4=
github.com/hashicorp/serf v0.9.7/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4=
+github.com/hashicorp/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-exec v0.17.2 h1:EU7i3Fh7vDUI9nNRdMATCEfnm9axzTnad8zszYZ73Go=
github.com/hashicorp/terraform-exec v0.17.2/go.mod h1:tuIbsL2l4MlwwIZx9HPM+LOV9vVyEfBYu2GsO1uH3/8=
+github.com/hashicorp/terraform-json v0.10.0/go.mod h1:3defM4kkMfttwiE7VakJDwCd4R+umhSQnvJwORXbprE=
github.com/hashicorp/terraform-json v0.14.0 h1:sh9iZ1Y8IFJLx+xQiKHGud6/TSUCM0N8e17dKDpqV7s=
github.com/hashicorp/terraform-json v0.14.0/go.mod h1:5A9HIWPkk4e5aeeXIBbkcOvaZbIYnAIkEyqP2pNSckM=
github.com/hashicorp/terraform-plugin-docs v0.13.0 h1:6e+VIWsVGb6jYJewfzq2ok2smPzZrt1Wlm9koLeKazY=
github.com/hashicorp/terraform-plugin-docs v0.13.0/go.mod h1:W0oCmHAjIlTHBbvtppWHe8fLfZ2BznQbuv8+UD8OucQ=
-github.com/hashicorp/terraform-plugin-go v0.12.0 h1:6wW9mT1dSs0Xq4LR6HXj1heQ5ovr5GxXNJwkErZzpJw=
-github.com/hashicorp/terraform-plugin-go v0.12.0/go.mod h1:kwhmaWHNDvT1B3QiSJdAtrB/D4RaKSY/v3r2BuoWK4M=
-github.com/hashicorp/terraform-plugin-log v0.6.0 h1:/Vq78uSIdUSZ3iqDc9PESKtwt8YqNKN6u+khD+lLjuw=
-github.com/hashicorp/terraform-plugin-log v0.6.0/go.mod h1:p4R1jWBXRTvL4odmEkFfDdhUjHf9zcs/BCoNHAc7IK4=
+github.com/hashicorp/terraform-plugin-framework v1.1.1 h1:PbnEKHsIU8KTTzoztHQGgjZUWx7Kk8uGtpGMMc1p+oI=
+github.com/hashicorp/terraform-plugin-framework v1.1.1/go.mod h1:DyZPxQA+4OKK5ELxFIIcqggcszqdWWUpTLPHAhS/tkY=
+github.com/hashicorp/terraform-plugin-framework-validators v0.9.0 h1:LYz4bXh3t7bTEydXOmPDPupRRnA480B/9+jV8yZvxBA=
+github.com/hashicorp/terraform-plugin-framework-validators v0.9.0/go.mod h1:+BVERsnfdlhYR2YkXMBtPnmn9UsL19U3qUtSZ+Y/5MY=
+github.com/hashicorp/terraform-plugin-go v0.14.3 h1:nlnJ1GXKdMwsC8g1Nh05tK2wsC3+3BL/DBBxFEki+j0=
+github.com/hashicorp/terraform-plugin-go v0.14.3/go.mod h1:7ees7DMZ263q8wQ6E4RdIdR6nHHJtrdt4ogX5lPkX1A=
+github.com/hashicorp/terraform-plugin-log v0.7.0 h1:SDxJUyT8TwN4l5b5/VkiTIaQgY6R+Y2BQ0sRZftGKQs=
+github.com/hashicorp/terraform-plugin-log v0.7.0/go.mod h1:p4R1jWBXRTvL4odmEkFfDdhUjHf9zcs/BCoNHAc7IK4=
+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-sdk/v2 v2.19.0 h1:7gDAcfto/C4Cjtf90SdukQshsxdMxJ/P69QxiF3digI=
github.com/hashicorp/terraform-plugin-sdk/v2 v2.19.0/go.mod h1:/WYikYjhKB7c2j1HmXZhRsAARldRb4M38bLCLOhC3so=
-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-plugin-test/v2 v2.2.1/go.mod h1:eZ9JL3O69Cb71Skn6OhHyj17sLmHRb+H6VrDcJjKrYU=
+github.com/hashicorp/terraform-registry-address v0.1.0 h1:W6JkV9wbum+m516rCl5/NjKxCyTVaaUBbzYcMzBDO3U=
+github.com/hashicorp/terraform-registry-address v0.1.0/go.mod h1:EnyO2jYO6j29DTHbJcm00E5nQTFeTtyZH3H5ycydQ5A=
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=
@@ -543,7 +551,6 @@ github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63
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/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
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.4/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
@@ -566,13 +573,13 @@ github.com/jingyugao/rowserrcheck v1.1.1 h1:zibz55j/MJtLsjP1OF4bSdgXxwL1b+Vn7Tjz
github.com/jingyugao/rowserrcheck v1.1.1/go.mod h1:4yvlZSDb3IyDTUZJUmpZfm2Hwok+Dtp+nu2qOq+er9c=
github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af h1:KA9BjwUk7KlCh6S9EAGWBt1oExIUv9WyNCiRz5amv48=
github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0=
+github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/jonboulle/clockwork v0.2.0/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8=
-github.com/josharian/txtarfs v0.0.0-20210218200122-0702f000015a/go.mod h1:izVPOvVRsHiKkeGCT6tYBNWyDVuzj9wAaBb5R9qamfw=
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
@@ -590,6 +597,7 @@ github.com/julz/importas v0.1.0/go.mod h1:oSFU2R4XK/P7kNBrnL/FEQlDGN1/6WoxXEjSSX
github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k=
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 h1:DowS9hvgyYSX4TO5NpyC606/Z4SxnNYbT+WX27or6Ck=
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/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
@@ -597,8 +605,7 @@ github.com/kisielk/errcheck v1.6.0 h1:YTDO4pNy7AUN/021p+JGHycQyYNIyMoenM1YDVK6Rl
github.com/kisielk/errcheck v1.6.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
-github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
-github.com/klauspost/compress v1.13.5/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
+github.com/klauspost/compress v1.11.2/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
@@ -608,7 +615,6 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
-github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
@@ -635,12 +641,9 @@ github.com/lib/pq v1.9.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/lufeee/execinquery v1.2.1 h1:hf0Ems4SHcUGBxpGN7Jz78z1ppVkP/837ZlETPCEtOM=
github.com/lufeee/execinquery v1.2.1/go.mod h1:EC7DrEKView09ocscGHC+apXMIaorh4xqSxS/dy8SbM=
-github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
-github.com/lyft/protoc-gen-star v0.5.3/go.mod h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc87/1qhoTACD8w=
github.com/machinebox/graphql v0.2.2 h1:dWKpJligYKhYKO5A2gvNhkJdQMNZeChZYyBbrZkBZfo=
github.com/machinebox/graphql v0.2.2/go.mod h1:F+kbVMHuwrQ5tYgU9JXlnskM8nOaFxCAEolaQybkjWA=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
-github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo=
github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
github.com/maratori/testpackage v1.0.1 h1:QtJ5ZjqapShm0w5DosRjg0PRlSdAdlx+W6cCKoALdbQ=
@@ -651,6 +654,7 @@ github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlW
github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE=
github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU=
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.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
@@ -659,6 +663,7 @@ github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZb
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.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
@@ -678,23 +683,25 @@ github.com/mbilski/exhaustivestruct v1.2.0/go.mod h1:OeTBVxQWoEmB2J2JCHmXWPJ0aks
github.com/mgechev/dots v0.0.0-20210922191527-e955255bf517/go.mod h1:KQ7+USdGKfpPjXk4Ga+5XxQM4Lm4e3gAogrreFAYpOg=
github.com/mgechev/revive v1.2.1 h1:GjFml7ZsoR0IrQ2E2YIvWFNS5GPDV7xNwvA5GM1HZC4=
github.com/mgechev/revive v1.2.1/go.mod h1:+Ro3wqY4vakcYNtkBWdZC7dBg1xSB6sp054wWwmeFm0=
-github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
github.com/miekg/dns v1.1.35/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
github.com/miekg/pkcs11 v1.0.2/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI=
+github.com/mitchellh/cli v1.1.2/go.mod h1:6iaV0fGdElS6dPBx0EApTxHrcWvmJphyh2n8YBLPPZ4=
github.com/mitchellh/cli v1.1.4 h1:qj8czE26AU4PbiaPXK5uVmMSM+V5BYsFBiM9HhGRLUA=
github.com/mitchellh/cli v1.1.4/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-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg=
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=
@@ -734,8 +741,6 @@ github.com/nishanths/exhaustive v0.7.11/go.mod h1:gX+MP7DWMKJmNa1HfMozK+u04hQd3n
github.com/nishanths/predeclared v0.0.0-20190419143655-18a43bb90ffc/go.mod h1:62PewwiQTlm/7Rj+cxVYqZvDIUc+JjZq6GHAC1fsObQ=
github.com/nishanths/predeclared v0.2.2 h1:V2EPdZPliZymNAn79T8RkNApBjMmVKh5XRpLm/w98Vk=
github.com/nishanths/predeclared v0.2.2/go.mod h1:RROzoN6TnGQupbC+lqggsOlcgysk3LMK/HI84Mp280c=
-github.com/nsf/jsondiff v0.0.0-20200515183724-f29ed568f4ce h1:RPclfga2SEJmgMmz2k+Mg7cowZ8yv4Trqw9UsJby758=
-github.com/nsf/jsondiff v0.0.0-20200515183724-f29ed568f4ce/go.mod h1:uFMI8w+ref4v2r9jz+c9i1IfIttS/OkmLfrk1jne5hs=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw=
@@ -777,12 +782,12 @@ github.com/pelletier/go-toml/v2 v2.0.0/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZO
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d h1:CdDQnGF8Nq9ocOS/xlSptM1N3BbrA6/kmaep5ggwaIA=
github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d/go.mod h1:3OzsM7FXDQlpCiw2j81fOmAwQLnZnLGXVKUzeKQXIAw=
+github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
-github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=
github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
@@ -790,9 +795,9 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
github.com/polyfloyd/go-errorlint v1.0.0 h1:pDrQG0lrh68e602Wfp68BlUTRFoHn8PZYAjLgt2LFsM=
github.com/polyfloyd/go-errorlint v1.0.0/go.mod h1:KZy4xxPJyy88/gldCe5OdW6OQRtNO3EZE7hXzmnebgA=
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/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
@@ -825,7 +830,6 @@ github.com/quasilyte/go-ruleguard v0.3.16-0.20220213074421-6aa060fab41a h1:sWFav
github.com/quasilyte/go-ruleguard v0.3.16-0.20220213074421-6aa060fab41a/go.mod h1:VMX+OnnSw4LicdiEGtRSD/1X8kW7GuEscjYNr4cOIT4=
github.com/quasilyte/go-ruleguard/dsl v0.3.0/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU=
github.com/quasilyte/go-ruleguard/dsl v0.3.16/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU=
-github.com/quasilyte/go-ruleguard/dsl v0.3.19/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU=
github.com/quasilyte/go-ruleguard/rules v0.0.0-20201231183845-9e62ed36efe1/go.mod h1:7JTjp89EGyU1d6XfBiXihJNG37wB2VRkd125Q1u7Plc=
github.com/quasilyte/go-ruleguard/rules v0.0.0-20211022131956-028d6511ab71/go.mod h1:4cgAphtvu7Ftv7vOT2ZOYhC6CvBxZixcasr8qIOTA50=
github.com/quasilyte/gogrep v0.0.0-20220120141003-628d8b3623b5 h1:PDWGei+Rf2bBiuZIbZmM20J2ftEy9IeUCHA8HbQqed8=
@@ -834,13 +838,9 @@ github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95 h1:L8QM9bvf
github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0=
github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 h1:M8mH9eK4OUR4lu7Gd+PU1fV2/qnDNfzT635KRSObncs=
github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567/go.mod h1:DWNGW8A4Y+GyBgPuaQJuWiy0XYftx4Xm/y5Jqk9I6VQ=
-github.com/remyoudompheng/go-dbus v0.0.0-20121104212943-b7232d34b1d5/go.mod h1:+u151txRmLpwxBmpYn9z3d1sdJdjRPQpsXuYeY9jNls=
-github.com/remyoudompheng/go-liblzma v0.0.0-20190506200333-81bf2d431b96/go.mod h1:90HvCY7+oHHUKkbeMCiHt1WuFR2/hPJ9QrljDG+v6ls=
-github.com/remyoudompheng/go-misc v0.0.0-20190427085024-2d6ac652a50e/go.mod h1:80FQABjoFzZ2M5uEa6FUaJYEmqU2UOKojlFVak1UAwI=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
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/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg=
github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o=
github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
@@ -854,7 +854,6 @@ github.com/ryancurrah/gomodguard v1.2.3/go.mod h1:rYbA/4Tg5c54mV1sv4sQTP5WOPBcoL
github.com/ryanrolds/sqlclosecheck v0.3.0 h1:AZx+Bixh8zdUBxUA1NxbxVAS78vTPq4rCb8OUZI9xFw=
github.com/ryanrolds/sqlclosecheck v0.3.0/go.mod h1:1gREqxyTGR3lVtpngyFo3hZAgk0KCtEdgEkHwDbigdA=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
-github.com/sagikazarmark/crypt v0.3.0/go.mod h1:uD/D+6UF4SrIR1uGEv7bBNkNqLGqUr43MRiaGWX1Nig=
github.com/sagikazarmark/crypt v0.5.0/go.mod h1:l+nzl7KWh51rpzp2h7t4MZWyiEWdhNpOAnclKvg+mdA=
github.com/sanposhiho/wastedassign/v2 v2.0.6 h1:+6/hQIHKNJAUixEj6EmOngGIisyeI+T3335lYTyxRoA=
github.com/sanposhiho/wastedassign/v2 v2.0.6/go.mod h1:KyZ0MWTwxxBmfwn33zh3k1dmsbF2ud9pAAGfoLfjhtI=
@@ -868,7 +867,6 @@ 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/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c h1:W65qqJCIOVP4jpqPQ0YvHYKwcMEMVWIzWC5iNQQfBTU=
github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAxekIXwN8qQyfc5gl2NlkB3CQlkizAbOkeBs=
-github.com/shirou/gopsutil/v3 v3.22.4/go.mod h1:D01hZJ4pVHPpCTZ3m3T2+wDF2YAGfd+H4ifUguaQzHM=
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=
@@ -893,8 +891,7 @@ github.com/sourcegraph/go-diff v0.6.1 h1:hmA1LzxW0n1c3Q4YbrFgg4P99GSnebYa3x8gr0H
github.com/sourcegraph/go-diff v0.6.1/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
-github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4=
-github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
+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.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
@@ -904,7 +901,6 @@ github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU=
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
-github.com/spf13/cobra v1.3.0/go.mod h1:BrRVncBjOJa/eUcVVm9CE+oC6as8k+VYr4NY7WCi9V4=
github.com/spf13/cobra v1.4.0 h1:y+wJpx64xcgO1V+RcnwW0LEHxTKRi2ZDPSBjWnrg88Q=
github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
@@ -916,7 +912,6 @@ github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
-github.com/spf13/viper v1.10.0/go.mod h1:SoyBPwAtKDzypXNDFKN5kzH7ppppbGZtls1UpIy5AsM=
github.com/spf13/viper v1.11.0 h1:7OX/1FS6n7jHD1zGrZTM7WtY13ZELRyosK4k93oPr44=
github.com/spf13/viper v1.11.0/go.mod h1:djo0X/bA5+tYVoCn+C7cAYJGcVn/qYLFTG8gdUsX7Zk=
github.com/ssgreg/nlreturn/v2 v2.2.1 h1:X4XDI7jstt3ySqGU86YGAURbxw3oTDPK9sPEi6YEwQ0=
@@ -953,8 +948,6 @@ github.com/tetafro/godot v1.4.11 h1:BVoBIqAf/2QdbFmSwAWnaIqDivZdOV0ZRwEm6jivLKw=
github.com/tetafro/godot v1.4.11/go.mod h1:LR3CJpxDVGlYOWn3ZZg1PgNZdTUvzsZWu8xaEohUpn8=
github.com/timakin/bodyclose v0.0.0-20210704033933-f49887972144 h1:kl4KhGNsJIbDHS9/4U9yQo1UcPQM0kOMJHn29EoH/Ro=
github.com/timakin/bodyclose v0.0.0-20210704033933-f49887972144/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk=
-github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk=
-github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ=
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tmc/grpc-websocket-proxy v0.0.0-20200427203606-3cfed13b9966/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
@@ -965,6 +958,7 @@ github.com/tommy-muehle/go-mnd/v2 v2.5.0 h1:iAj0a8e6+dXSL7Liq0aXPox36FiN1dBbjA6l
github.com/tommy-muehle/go-mnd/v2 v2.5.0/go.mod h1:WsUAkMJMYww6l/ufffCD3m+P7LEvr8TnZn9lwVDlgzw=
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
+github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
github.com/ultraware/funlen v0.0.3 h1:5ylVWm8wsNwH5aWo9438pwvsK0QiqVuUrt9bn7S/iLA=
github.com/ultraware/funlen v0.0.3/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA=
github.com/ultraware/whitespace v0.0.5 h1:hh+/cpIcopyMYbZNVov9iSxvJU3OYQg78Sfaqzi/CzI=
@@ -973,18 +967,15 @@ github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijb
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/uudashr/gocognit v1.0.5 h1:rrSex7oHr3/pPLQ0xoWq108XMU8s678FJcQ+aSfOHa4=
github.com/uudashr/gocognit v1.0.5/go.mod h1:wgYz0mitoKOTysqxTDMOUXg+Jb5SvtihkfmugIZYpEA=
-github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
-github.com/valyala/fasthttp v1.30.0/go.mod h1:2rsYD01CKFrjjsvFxx75KlEUNpWNBY9JWD3K/7o2Cus=
-github.com/valyala/quicktemplate v1.7.0/go.mod h1:sqKJnoaOF88V07vkO+9FL8fb9uZg/VPSJnLYn+LmLk8=
-github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
github.com/viki-org/dnscache v0.0.0-20130720023526-c70c1f23c5d8/go.mod h1:dniwbG03GafCjFohMDmz6Zc6oCuiqgH6tGNyXTkHzXE=
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 h1:quXMXlA39OCbd2wAdTsGDlK9RkOk6Wuw+x37wVyIuWY=
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 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI=
github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
@@ -1004,23 +995,22 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
-github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
+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.8.0/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk=
+github.com/zclconf/go-cty v1.2.1/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8=
+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/go.mod h1:IP3Ylp0wQpYm50IHK8OZWKMu6sPJIUgKa8XhiVHura0=
gitlab.com/bosi/decorder v0.2.1 h1:ehqZe8hI4w7O4b1vgsDZw1YU1PE7iJXrQWFMsocbQ1w=
gitlab.com/bosi/decorder v0.2.1/go.mod h1:6C/nhLSbF6qZbYD8bRmISBwc6vcWdNsiIBkRvjJFrH0=
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
go.etcd.io/etcd v0.0.0-20200513171258-e048e166ab9c/go.mod h1:xCI7ZzBfRuGgBXyXO6yfWfDmlWd35khcWpUa4L0xI/k=
-go.etcd.io/etcd/api/v3 v3.5.1/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=
go.etcd.io/etcd/api/v3 v3.5.2/go.mod h1:5GB2vv4A4AOn3yk7MftYGHkUfGtDHnEraIjym4dYz5A=
-go.etcd.io/etcd/client/pkg/v3 v3.5.1/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
go.etcd.io/etcd/client/pkg/v3 v3.5.2/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
-go.etcd.io/etcd/client/v2 v2.305.1/go.mod h1:pMEacxZW7o8pg4CrFE7pquyCJJzZvkvdD2RibOCCCGs=
go.etcd.io/etcd/client/v2 v2.305.2/go.mod h1:2D7ZejHVMIfog1221iLSYlQRzrtECw3kz4I4VAQm3qI=
go.mozilla.org/mozlog v0.0.0-20170222151521-4bb13139d403/go.mod h1:jHoPAGnDrCy6kaI2tAze5Prf0Nr0w/oNkROt2lw3n3o=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
@@ -1045,13 +1035,12 @@ go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
golang.org/x/crypto v0.0.0-20180501155221-613d6eafa307/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
-golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-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-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
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=
@@ -1060,14 +1049,11 @@ golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
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-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
-golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220313003712-b769efc7c000/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
-golang.org/x/crypto v0.0.0-20220517005047-85d78b3ac167/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=
@@ -1080,7 +1066,6 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
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/exp v0.0.0-20200331195152-e8c3332aa8e5 h1:FR+oGxGfbQu1d+jglI3rCkjAjUnhRSZcUxr+DqlDLNo=
golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw=
golang.org/x/exp/typeparams v0.0.0-20220218215828-6cf2b201936e h1:qyrTQ++p1afMkO4DPEeLGq/3oTsdlvdH4vqZUBWzUKM=
golang.org/x/exp/typeparams v0.0.0-20220218215828-6cf2b201936e/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
@@ -1109,16 +1094,15 @@ 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/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
-golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 h1:kQgndtyPBW/JIYERgdxfwMYh3AVStj88WQTlNDi2a+o=
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
+golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
+golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
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=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -1165,17 +1149,16 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b
golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8=
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
-golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
-golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/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 h1:bRb386wvrE+oBNdF1d/Xh9mQrfQ4ecYhW5qJ5GvTGT4=
golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0=
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b/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=
@@ -1207,13 +1190,13 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ
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 h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw=
+golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -1223,6 +1206,7 @@ golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/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=
@@ -1262,7 +1246,6 @@ golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7w
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-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -1288,7 +1271,6 @@ golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBc
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-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/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=
@@ -1296,7 +1278,6 @@ golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211105183446-c75c47738b0c/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-20211205182925-97ca703d548d/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-20211213223007-03aa0b5f6827/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -1304,15 +1285,12 @@ golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBc
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-20220319134239-a9b59b0215f8/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-20220403020550-483a9cbc67c0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220406163625-3f8b81556e12/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-20220422013727-9388b58f7150/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-20220627191245-f75cf1eec38b h1:2n253B2r0pYSmEV+UNCQoPfU/FiaizQEK5Gu4Bq4JE8=
-golang.org/x/sys v0.0.0-20220627191245-f75cf1eec38b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s=
+golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
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=
@@ -1325,8 +1303,9 @@ 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/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg=
+golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
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=
@@ -1338,7 +1317,6 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/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-20190228203856-589c23e65e65/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190307163923-6a08e3108db3/go.mod h1:25r3+/G6/xytQM8iWZKq3Hn0kr0rgFKPUNVEL/dr3z4=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190311215038-5c2858a9cfe5/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
@@ -1398,7 +1376,6 @@ golang.org/x/tools v0.0.0-20200625211823-6506e20df31f/go.mod h1:EkVYQZoAsY45+roY
golang.org/x/tools v0.0.0-20200626171337-aa94e735be7f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200630154851-b2d8b0336632/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200706234117-b22de6825cf7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
-golang.org/x/tools v0.0.0-20200713011307-fd294ab11aed/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200724022722-7017fd6b1305/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
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=
@@ -1410,7 +1387,7 @@ golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82u
golang.org/x/tools v0.0.0-20201001104356-43ebab892c4c/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
golang.org/x/tools v0.0.0-20201002184944-ecd9fd270d5d/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
golang.org/x/tools v0.0.0-20201023174141-c8cfbd0f21e6/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
-golang.org/x/tools v0.0.0-20201028025901-8cd080b735b3/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+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=
@@ -1432,13 +1409,12 @@ golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
golang.org/x/tools v0.1.9-0.20211228192929-ee1ca4ffc4da/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
-golang.org/x/tools v0.1.11-0.20220316014157-77aa08bb151a h1:ofrrl6c6NG5/IOSx/R1cyiQxxjqlur0h/TvbUhkH0II=
-golang.org/x/tools v0.1.11-0.20220316014157-77aa08bb151a/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
+golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
+golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
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 h1:GGU+dLjvlC3qDwqYgL6UgRmHXhOOgns0bZu2Ty5mm6U=
golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
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=
@@ -1457,6 +1433,7 @@ google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M
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=
@@ -1472,7 +1449,6 @@ google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqiv
google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI=
google.golang.org/api v0.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUbuZU=
google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I=
-google.golang.org/api v0.62.0/go.mod h1:dKmwPCydfsad4qCH08MSdgWjfHOyfpd4VtDGgRFdavw=
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=
@@ -1520,7 +1496,6 @@ google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEY
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
google.golang.org/genproto v0.0.0-20200626011028-ee7919e894b5/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200707001353-8e8330bf89df/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20200711021454-869866162049/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
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=
@@ -1555,8 +1530,6 @@ google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ6
google.golang.org/genproto v0.0.0-20211008145708-270636b82663/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/genproto v0.0.0-20211028162531-8db9c33dc351/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
-google.golang.org/genproto v0.0.0-20211129164237-f09f9a12af12/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
-google.golang.org/genproto v0.0.0-20211203200212-54befc351ae9/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=
@@ -1586,6 +1559,7 @@ google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3Iji
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=
@@ -1599,13 +1573,11 @@ google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnD
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.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
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.48.0 h1:rQOsyJ/8+ufEDJd/Gdsz7HG220Mh9HAhFHRGnIjda0w=
-google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
+google.golang.org/grpc v1.51.0 h1:E1eGv1FTqoLIdnBCZufiSHgKjlqG6fKFf6pPWtMTh8U=
+google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
-google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.2.0/go.mod h1:DNq5QpG7LJqD2AamLZ7zvKE0DEpVl2BSEVjFycAAjRY=
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=
@@ -1619,8 +1591,9 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
-google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
+google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
+google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
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=
@@ -1629,11 +1602,11 @@ gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8
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.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
+gopkg.in/cheggaaa/pb.v1 v1.0.27/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
gopkg.in/cheggaaa/pb.v1 v1.0.28/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
-gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.66.4 h1:SsAcf+mM7mRZo2nJNGt8mZCjG8ZRaNGMURJw7BsIST4=
gopkg.in/ini.v1 v1.66.4/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
diff --git a/jupiterone/internal/client/client.go b/jupiterone/internal/client/client.go
index 092737d6..d004ad6e 100644
--- a/jupiterone/internal/client/client.go
+++ b/jupiterone/internal/client/client.go
@@ -1,8 +1,10 @@
package client
import (
+ "context"
"log"
"net/http"
+ "os"
"time"
"github.com/machinebox/graphql"
@@ -11,9 +13,11 @@ import (
const DefaultRegion string = "us"
type JupiterOneClientConfig struct {
- APIKey string
- AccountID string
- Region string
+ APIKey string
+ AccountID string
+ Region string
+ // Client is mostly used to inject the `go-vcr` transport recorder
+ // for testing
HTTPClient *http.Client
}
@@ -42,7 +46,6 @@ func (c *JupiterOneClientConfig) Client() (*JupiterOneClient, error) {
endpoint := c.getGraphQLEndpoint()
var client *graphql.Client
-
if c.HTTPClient != nil {
client = graphql.NewClient(endpoint, graphql.WithHTTPClient(c.HTTPClient))
} else {
@@ -59,6 +62,19 @@ func (c *JupiterOneClientConfig) Client() (*JupiterOneClient, error) {
return jupiterOneClient, nil
}
+// NewClientFromEnv configures the J1 client itself from the environment
+// variables for use in testing.
+func NewClientFromEnv(ctx context.Context, client *http.Client) (*JupiterOneClient, error) {
+ config := JupiterOneClientConfig{
+ APIKey: os.Getenv("JUPITERONE_API_KEY"),
+ AccountID: os.Getenv("JUPITERONE_ACCOUNT_ID"),
+ Region: os.Getenv("JUPITERONE_REGION"),
+ HTTPClient: client,
+ }
+
+ return config.Client()
+}
+
func (c *JupiterOneClient) prepareRequest(query string) *graphql.Request {
req := graphql.NewRequest(query)
diff --git a/jupiterone/internal/client/question.go b/jupiterone/internal/client/question.go
index 30751302..478ed9cf 100644
--- a/jupiterone/internal/client/question.go
+++ b/jupiterone/internal/client/question.go
@@ -18,16 +18,8 @@ type QuestionComplianceMetaData struct {
Controls []string `json:"controls"`
}
-type QuestionProperties struct {
- Title string `json:"title"`
- Description string `json:"description"`
- Tags []string `json:"tags"`
- Queries []QuestionQuery `json:"queries"`
- Compliance []QuestionComplianceMetaData `json:"compliance"`
-}
-
type Question struct {
- Id string `json:"id"`
+ Id string `json:"id,omitempty"`
Title string `json:"title"`
Description string `json:"description"`
Tags []string `json:"tags"`
@@ -78,7 +70,7 @@ func (c *JupiterOneClient) GetQuestion(id string) (*Question, error) {
return &question, nil
}
-func (c *JupiterOneClient) CreateQuestion(properties QuestionProperties) (*Question, error) {
+func (c *JupiterOneClient) CreateQuestion(question *Question) (*Question, error) {
req := c.prepareRequest(`
mutation CreateQuestion($question: CreateQuestionInput!) {
createQuestion(question: $question) {
@@ -107,24 +99,22 @@ func (c *JupiterOneClient) CreateQuestion(properties QuestionProperties) (*Quest
}
`)
- req.Var("question", properties)
+ req.Var("question", question)
var respData map[string]interface{}
-
+ var created *Question
if err := c.graphqlClient.Run(context.Background(), req, &respData); err != nil {
return nil, err
}
- var question Question
-
- if err := mapstructure.Decode(respData["createQuestion"], &question); err != nil {
+ if err := mapstructure.Decode(respData["createQuestion"], &created); err != nil {
return nil, err
}
- return &question, nil
+ return created, nil
}
-func (c *JupiterOneClient) UpdateQuestion(id string, properties QuestionProperties) (*Question, error) {
+func (c *JupiterOneClient) UpdateQuestion(id string, q *Question) (*Question, error) {
req := c.prepareRequest(`
mutation UpdateQuestion ($id: ID!, $update: QuestionUpdate!) {
updateQuestion(id: $id, update: $update) {
@@ -154,21 +144,19 @@ func (c *JupiterOneClient) UpdateQuestion(id string, properties QuestionProperti
`)
req.Var("id", id)
- req.Var("update", properties)
+ req.Var("update", q)
var respData map[string]interface{}
-
+ var updated *Question
if err := c.graphqlClient.Run(context.Background(), req, &respData); err != nil {
return nil, err
}
- var question Question
-
- if err := mapstructure.Decode(respData["updateQuestion"], &question); err != nil {
+ if err := mapstructure.Decode(respData["updateQuestion"], &updated); err != nil {
return nil, err
}
- return &question, nil
+ return q, nil
}
func (c *JupiterOneClient) DeleteQuestion(id string) error {
diff --git a/jupiterone/internal/client/rule.go b/jupiterone/internal/client/rule.go
index 90c1239f..330d60f9 100644
--- a/jupiterone/internal/client/rule.go
+++ b/jupiterone/internal/client/rule.go
@@ -7,23 +7,24 @@ import (
)
type QuestionRuleInstance struct {
- Id string `json:"id,omitempty"`
- AccountId string `json:"accountId,omitempty"`
- Name string `json:"name"`
- Description string `json:"description"`
- Version int `json:"version,omitempty"`
- SpecVersion int `json:"specVersion,omitempty"`
- Latest bool `json:"latest,omitempty"`
- Deleted bool `json:"deleted,omitempty"`
- Type string `json:"type,omitempty"`
- PollingInterval string `json:"pollingInterval"`
- Templates interface{} `json:"templates"`
- Question map[string]interface{} `json:"question,omitempty"`
- QuestionId string `json:"questionId,omitempty"`
- QuestionName string `json:"questionName,omitempty"`
- Operations []RuleOperation `json:"operations"`
- Outputs []string `json:"outputs"`
- Tags []string `json:"tags"`
+ Id string `json:"id,omitempty"`
+ AccountId string `json:"accountId,omitempty"`
+ Name string `json:"name"`
+ Description string `json:"description"`
+ Version int `json:"version,omitempty"`
+ SpecVersion int `json:"specVersion,omitempty"`
+ Latest bool `json:"latest,omitempty"`
+ Deleted bool `json:"deleted,omitempty"`
+ Type string `json:"type,omitempty"`
+ PollingInterval string `json:"pollingInterval"`
+ Templates map[string]string `json:"templates"`
+ // Question: TODO: make into structs
+ Question map[string][]map[string]string `json:"question,omitempty"`
+ QuestionId string `json:"questionId,omitempty"`
+ QuestionName string `json:"questionName,omitempty"`
+ Operations []RuleOperation `json:"operations"`
+ Outputs []string `json:"outputs"`
+ Tags []string `json:"tags"`
}
type RuleOperation struct {
@@ -79,7 +80,7 @@ func (c *JupiterOneClient) GetQuestionRuleInstanceByID(id string) (*QuestionRule
return &resp.QuestionRuleInstance, nil
}
-func (c *JupiterOneClient) CreateQuestionRuleInstance(questionRuleInstance QuestionRuleInstance) (*QuestionRuleInstance, error) {
+func (c *JupiterOneClient) CreateQuestionRuleInstance(questionRuleInstance *QuestionRuleInstance) (*QuestionRuleInstance, error) {
var req *graphql.Request
if questionRuleInstance.QuestionId != "" || questionRuleInstance.QuestionName != "" {
req = c.prepareRequest(`
@@ -156,7 +157,6 @@ func (c *JupiterOneClient) CreateQuestionRuleInstance(questionRuleInstance Quest
return nil, err
}
return resp.CreateQuestionRuleInstance, nil
-
}
func (c *JupiterOneClient) UpdateQuestionRuleInstance(instance *QuestionRuleInstance) (*QuestionRuleInstance, error) {
diff --git a/jupiterone/provider.go b/jupiterone/provider.go
index 15df72de..6adefacc 100644
--- a/jupiterone/provider.go
+++ b/jupiterone/provider.go
@@ -4,65 +4,158 @@ import (
// "errors"
"context"
"log"
+ "os"
- "github.com/hashicorp/terraform-plugin-sdk/v2/diag"
- "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
+ "github.com/hashicorp/terraform-plugin-framework/datasource"
+ "github.com/hashicorp/terraform-plugin-framework/provider"
+ "github.com/hashicorp/terraform-plugin-framework/provider/schema"
+ "github.com/hashicorp/terraform-plugin-framework/resource"
+ "github.com/hashicorp/terraform-plugin-framework/types/basetypes"
"github.com/jupiterone/terraform-provider-jupiterone/jupiterone/internal/client"
)
-// Provider - Exported function that creates the JupiterOne Terraform
-// resource provider
-func Provider() *schema.Provider {
- return &schema.Provider{
- Schema: map[string]*schema.Schema{
- "api_key": {
- Type: schema.TypeString,
- Required: true,
- DefaultFunc: schema.EnvDefaultFunc("JUPITERONE_API_KEY", nil),
- Description: "API Key used to make requests to the JupiterOne APIs",
- Sensitive: true,
- },
- "account_id": {
- Type: schema.TypeString,
- Required: true,
- DefaultFunc: schema.EnvDefaultFunc("JUPITERONE_ACCOUNT_ID", nil),
- Description: "JupiterOne account ID to create resources in",
- },
- "region": {
- Type: schema.TypeString,
- Optional: true,
- DefaultFunc: schema.EnvDefaultFunc("JUPITERONE_REGION", nil),
- },
- },
- ResourcesMap: map[string]*schema.Resource{
- "jupiterone_rule": resourceQuestionRuleInstance(),
- "jupiterone_question": resourceQuestion(),
- },
- ConfigureContextFunc: providerConfigure,
- }
+// JupiterOneProvider contains the initialized API client to communicate with the JupiterOne API
+type JupiterOneProvider struct {
+ // version is set to the provider version on release, "dev" when the
+ // provider is built and ran locally, and "test" when running acceptance
+ // testing.
+ version string
+ Client *client.JupiterOneClient
}
-// ProviderConfiguration contains the initialized API client to communicate with the JupiterOne API
-type ProviderConfiguration struct {
- Client *client.JupiterOneClient
+type JupiterOneProviderModel struct {
+ APIKey basetypes.StringValue `tfsdk:"api_key"`
+ AccountID basetypes.StringValue `tfsdk:"account_id"`
+ Region basetypes.StringValue `tfsdk:"region"`
}
-func providerConfigure(_ context.Context, d *schema.ResourceData) (interface{}, diag.Diagnostics) {
- log.Println("[INFO] JupiterOne client successfully initialized")
+var _ provider.Provider = &JupiterOneProvider{}
+
+func New(version string) func() provider.Provider {
+ return func() provider.Provider {
+ return &JupiterOneProvider{
+ version: version,
+ }
+ }
+}
+
+// Configure implements provider.Provider
+func (p *JupiterOneProvider) Configure(ctx context.Context, req provider.ConfigureRequest, resp *provider.ConfigureResponse) {
+ var data JupiterOneProviderModel
+
+ resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ // NOTE: One important use case here is client already being set at part
+ // of the acceptance tests to use the preconfigured `go-vcr` transport.
+ if p.Client == nil {
+ apiKey := data.APIKey.ValueString()
+ accountId := data.AccountID.ValueString()
+ region := data.Region.ValueString()
+
+ // Check environment variables. Performing this as part of Configure is
+ // the current de-facto way of "merging" defaults:
+ // https://github.com/hashicorp/terraform-plugin-framework/issues/539#issuecomment-1334470425
+ if apiKey == "" {
+ apiKey = os.Getenv("JUPITERONE_API_KEY")
+ }
+ if accountId == "" {
+ accountId = os.Getenv("JUPITERONE_ACCOUNT_ID")
+ }
+ if region == "" {
+ region = os.Getenv("JUPITERONE_REGION")
+ }
+
+ if apiKey == "" {
+ resp.Diagnostics.AddError(
+ "Missing API key Configuration",
+ "While configuring the provider, the API key was not found in "+
+ "the JUPITERONE_API_KEY environment variable or provider "+
+ "configuration block api_key attribute.",
+ )
+ // Not returning early allows the logic to collect all errors.
+ }
- config := client.JupiterOneClientConfig{
- APIKey: d.Get("api_key").(string),
- AccountID: d.Get("account_id").(string),
- Region: d.Get("region").(string),
+ if accountId == "" {
+ resp.Diagnostics.AddError(
+ "Missing Account ID Configuration",
+ "While configuring the provider, the account id was not found in "+
+ "the JUPITERONE_ACCOUNT_ID variable or provider "+
+ "configuration block account_id attribute.",
+ )
+ // Not returning early allows the logic to collect all errors.
+ }
+
+ if region == "" {
+ resp.Diagnostics.AddError(
+ "Missing region Configuration",
+ "While configuring the provider, the region was not found in "+
+ "the JUPITERONE_REGION variable or provider "+
+ "configuration block region attribute.",
+ )
+ // Not returning early allows the logic to collect all errors.
+ }
+
+ config := client.JupiterOneClientConfig{
+ APIKey: apiKey,
+ AccountID: accountId,
+ Region: region,
+ }
+
+ var err error
+ p.Client, err = config.Client()
+ if err != nil {
+ resp.Diagnostics.AddError("failed to create JupiterOne client in provider configuration: %s", err.Error())
+ return
+ }
+ log.Println("[INFO] JupiterOne client successfully initialized")
+ } else {
+ log.Println("[INFO] Using already configured client")
}
- client, err := config.Client()
+ resp.DataSourceData = p
+ resp.ResourceData = p
+}
+
+// DataSources implements provider.Provider
+func (*JupiterOneProvider) DataSources(context.Context) []func() datasource.DataSource {
+ return []func() datasource.DataSource{}
+}
+
+// Metadata implements provider.Provider
+func (p *JupiterOneProvider) Metadata(ctx context.Context, req provider.MetadataRequest, resp *provider.MetadataResponse) {
+ resp.TypeName = "jupiterone"
+ resp.Version = p.version
+}
- if err != nil {
- return nil, diag.Errorf("failed to create JupiterOne client in provider configuration: %s", err.Error())
+// Resources implements provider.Provider
+func (*JupiterOneProvider) Resources(context.Context) []func() resource.Resource {
+ return []func() resource.Resource{
+ NewQuestionResource,
+ NewQuestionRuleResource,
}
+}
- return &ProviderConfiguration{
- Client: client,
- }, nil
+// Schema implements provider.Provider
+func (*JupiterOneProvider) Schema(ctx context.Context, req provider.SchemaRequest, resp *provider.SchemaResponse) {
+ resp.Schema = schema.Schema{
+ Attributes: map[string]schema.Attribute{
+ "api_key": schema.StringAttribute{
+ // TODO: needs to be optional to use env vars in Configure
+ Optional: true,
+ Description: "API Key used to make requests to the JupiterOne APIs",
+ Sensitive: true,
+ },
+ "account_id": schema.StringAttribute{
+ // TODO: needs to be optional to use env vars in Configure
+ Optional: true,
+ Description: "JupiterOne account ID to create resources in",
+ },
+ "region": schema.StringAttribute{
+ Optional: true,
+ },
+ },
+ }
}
diff --git a/jupiterone/provider_test.go b/jupiterone/provider_test.go
index 30d528b1..56a5f4cb 100644
--- a/jupiterone/provider_test.go
+++ b/jupiterone/provider_test.go
@@ -1,7 +1,6 @@
package jupiterone
import (
- "context"
"fmt"
"log"
"net/http"
@@ -11,13 +10,31 @@ import (
"github.com/dnaeon/go-vcr/cassette"
"github.com/dnaeon/go-vcr/recorder"
- "github.com/hashicorp/go-cleanhttp"
- "github.com/hashicorp/terraform-plugin-sdk/v2/diag"
- "github.com/hashicorp/terraform-plugin-sdk/v2/helper/logging"
- "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
+ "github.com/hashicorp/terraform-plugin-framework/provider"
+ "github.com/hashicorp/terraform-plugin-framework/providerserver"
+ "github.com/hashicorp/terraform-plugin-go/tfprotov6"
"github.com/jupiterone/terraform-provider-jupiterone/jupiterone/internal/client"
)
+// testAccProtoV6ProviderFactories are used to instantiate a provider during
+// acceptance testing. The factory function will be invoked for every Terraform
+// CLI command executed to create a provider server to which the CLI can
+// reattach.
+func testAccProtoV6ProviderFactories(j1Client *client.JupiterOneClient) map[string]func() (tfprotov6.ProviderServer, error) {
+ return map[string]func() (tfprotov6.ProviderServer, error){
+ "jupiterone": providerserver.NewProtocol6WithError(NewTestProvider(j1Client)()),
+ }
+}
+
+func NewTestProvider(j1Client *client.JupiterOneClient) func() provider.Provider {
+ return func() provider.Provider {
+ return &JupiterOneProvider{
+ version: "test",
+ Client: j1Client,
+ }
+ }
+}
+
func isRecording() bool {
return os.Getenv("RECORD") == "true"
}
@@ -44,7 +61,7 @@ func stripHeadersFromCassetteInteraction(i *cassette.Interaction) {
i.Response.Headers.Del("X-Cache")
}
-func initAccProvider(t *testing.T) (*schema.Provider, func(t *testing.T)) {
+func setupCassettes(name string) (*recorder.Recorder, func(t *testing.T)) {
var mode recorder.Mode
if isRecording() {
mode = recorder.ModeRecording
@@ -54,7 +71,7 @@ func initAccProvider(t *testing.T) (*schema.Provider, func(t *testing.T)) {
mode = recorder.ModeDisabled
}
- rec, err := recorder.NewAsMode(fmt.Sprintf("cassettes/%s", t.Name()), mode, nil)
+ rec, err := recorder.NewAsMode(fmt.Sprintf("cassettes/%s", name), mode, nil)
if err != nil {
log.Fatal(err)
}
@@ -73,67 +90,10 @@ func initAccProvider(t *testing.T) (*schema.Provider, func(t *testing.T)) {
stripHeadersFromCassetteInteraction(i)
return nil
})
-
- p := Provider()
- ctx := context.Background()
- p.ConfigureContextFunc = testProviderConfigure(ctx, rec)
-
cleanup := func(t *testing.T) {
_ = rec.Stop()
}
- return p, cleanup
-}
-
-func testProviderConfigure(_ context.Context, recorder *recorder.Recorder) schema.ConfigureContextFunc {
- return func(_ context.Context, d *schema.ResourceData) (interface{}, diag.Diagnostics) {
- testHTTPClient := cleanhttp.DefaultClient()
- testHTTPClient.Transport = logging.NewTransport("JupiterOne", recorder)
-
- config := client.JupiterOneClientConfig{
- APIKey: d.Get("api_key").(string),
- AccountID: d.Get("account_id").(string),
- Region: d.Get("region").(string),
- HTTPClient: testHTTPClient,
- }
-
- client, err := config.Client()
-
- if err != nil {
- return nil, diag.Errorf("Failed to create JupiterOne client in provider configuration: %s", err.Error())
- }
-
- return &ProviderConfiguration{
- Client: client,
- }, nil
- }
-}
-
-func testAccProviders(t *testing.T) (map[string]*schema.Provider, func(t *testing.T)) {
- provider, cleanup := initAccProvider(t)
- return map[string]*schema.Provider{
- "jupiterone": provider,
- }, cleanup
-}
-
-func testAccProvider(t *testing.T, accProviders map[string]*schema.Provider) *schema.Provider {
- accProvider, ok := accProviders["jupiterone"]
- if !ok {
- t.Fatal("Could not find jupiterone provider")
- }
- return accProvider
-}
-
-func TestProvider(t *testing.T) {
- accProvider, cleanup := initAccProvider(t)
- defer cleanup(t)
-
- if err := accProvider.InternalValidate(); err != nil {
- t.Fatalf("err: %s", err)
- }
-}
-
-func TestProvider_impl(t *testing.T) {
- var _ = Provider()
+ return rec, cleanup
}
func testAccPreCheck(t *testing.T) {
diff --git a/jupiterone/resource_question.go b/jupiterone/resource_question.go
index 30bfd792..439d00b5 100644
--- a/jupiterone/resource_question.go
+++ b/jupiterone/resource_question.go
@@ -2,227 +2,318 @@ package jupiterone
import (
"context"
-
- "github.com/hashicorp/terraform-plugin-sdk/v2/diag"
- "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
+ "fmt"
+
+ "github.com/hashicorp/terraform-plugin-framework-validators/listvalidator"
+ "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
+ "github.com/hashicorp/terraform-plugin-framework/resource"
+ "github.com/hashicorp/terraform-plugin-framework/resource/schema"
+ "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
+ "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
+ "github.com/hashicorp/terraform-plugin-framework/schema/validator"
+ "github.com/hashicorp/terraform-plugin-framework/types"
+ "github.com/hashicorp/terraform-plugin-log/tflog"
"github.com/jupiterone/terraform-provider-jupiterone/jupiterone/internal/client"
- "github.com/mitchellh/mapstructure"
)
-func resourceQuestion() *schema.Resource {
- return &schema.Resource{
- CreateContext: resourceQuestionCreate,
- ReadContext: resourceQuestionRead,
- UpdateContext: resourceQuestionUpdate,
- DeleteContext: resourceQuestionDelete,
- Schema: map[string]*schema.Schema{
- "title": {
- Type: schema.TypeString,
+// Ensure provider defined types fully satisfy framework interfaces
+var _ resource.Resource = &QuestionResource{}
+var _ resource.ResourceWithConfigure = &QuestionResource{}
+
+type QuestionResource struct {
+ version string
+ client *client.JupiterOneClient
+}
+
+type QuestionComplianceModel struct {
+ Standard string `json:"standard" tfsdk:"standard"`
+ Requirements []string `json:"requirements,omitempty" tfsdk:"requirements"`
+ Controls []string `json:"controls,omitempty" tfsdk:"controls"`
+}
+
+// QueryModel represents the terraform HCL `query` elements.
+//
+// This only exists as different from the client QuestionQuery due to the need
+// to strip out CRs before sending to the server.
+type QueryModel struct {
+ // Query tests must be cleaned of carriage returns before being sent to
+ // the server.
+ Query string `json:"query" tfsdk:"query"`
+ Version string `json:"version" tfsdk:"version"`
+ Name string `json:"name" tfsdk:"name"`
+}
+
+// QuestionModel is the terraform HCL representation of a question. This
+// currently has to be different from the `client.Question`:
+//
+// 1. allow the use of the `types.String` for ID being computed and the optional values
+// 2. make it clearer where the line breaks are being stripped from the input
+// and state
+//
+// TODO: Unify the client types and the state model if possible
+type QuestionModel struct {
+ Id types.String `json:"id,omitempty" tfsdk:"id"`
+ Title types.String `json:"title,omitempty" tfsdk:"title"`
+ Description types.String `json:"description,omitempty" tfsdk:"description"`
+ Tags []string `json:"tags,omitempty" tfsdk:"tags"`
+ Query []*QueryModel `json:"query,omitempty" tfsdk:"query"`
+ Compliance []*QuestionComplianceModel `json:"compliance,omitempty" tfsdk:"compliance"`
+}
+
+func NewQuestionResource() resource.Resource {
+ return &QuestionResource{}
+}
+
+// Metadata implements resource.Resource
+func (*QuestionResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
+ resp.TypeName = req.ProviderTypeName + "_question"
+}
+
+// Schema implements resource.Resource
+func (*QuestionResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
+ resp.Schema = schema.Schema{
+ Description: "A saved JupiterOne Question",
+ Attributes: map[string]schema.Attribute{
+ "id": schema.StringAttribute{
+ Computed: true,
+ PlanModifiers: []planmodifier.String{
+ stringplanmodifier.UseStateForUnknown(),
+ },
+ },
+ "title": schema.StringAttribute{
Required: true,
Description: "The title of the question",
},
- "description": {
- Type: schema.TypeString,
+ "description": schema.StringAttribute{
Required: true,
},
- "tags": {
- Type: schema.TypeList,
- Optional: true,
- Elem: &schema.Schema{
- Type: schema.TypeString,
- },
+ "tags": schema.ListAttribute{
+ Optional: true,
+ ElementType: types.StringType,
},
- "query": {
- Type: schema.TypeList,
- Required: true,
- Elem: &schema.Resource{
- // from resource_question_rule_instance.go
- Schema: getQuestionQuerySchema(),
+ },
+ // TODO: Deprecate the use of blocks following new framework guidance:
+ // https://developer.hashicorp.com/terraform/plugin/framework/handling-data/blocks
+ Blocks: map[string]schema.Block{
+ "query": schema.ListNestedBlock{
+ NestedObject: schema.NestedBlockObject{
+ Attributes: questionQuerySchemaAttributes(),
+ },
+ Validators: []validator.List{
+ listvalidator.SizeAtLeast(1),
},
},
- "compliance": {
- Type: schema.TypeList,
- Optional: true,
- Elem: &schema.Resource{
- Schema: getQuestionComplianceSchema(),
+ "compliance": schema.ListNestedBlock{
+ NestedObject: schema.NestedBlockObject{
+ Attributes: map[string]schema.Attribute{
+ "standard": schema.StringAttribute{
+ Required: true,
+ },
+ "requirements": schema.ListAttribute{
+ Optional: true,
+ ElementType: types.StringType,
+ },
+ "controls": schema.ListAttribute{
+ Optional: true,
+ ElementType: types.StringType,
+ },
+ },
},
},
},
}
}
-func buildQuestionQueryList(terraformQuestionQueryList []interface{}) (*[]client.QuestionQuery, error) {
- questionQueryList := make([]client.QuestionQuery, len(terraformQuestionQueryList))
-
- for i, terraformQuestionQuery := range terraformQuestionQueryList {
- var query client.QuestionQuery
-
- if err := mapstructure.Decode(terraformQuestionQuery, &query); err != nil {
- return nil, err
- }
-
- query.Query = removeCRFromString(query.Query)
-
- questionQueryList[i] = query
+func questionQuerySchemaAttributes() map[string]schema.Attribute {
+ return map[string]schema.Attribute{
+ "name": schema.StringAttribute{
+ Optional: true,
+ Validators: []validator.String{
+ stringvalidator.LengthBetween(MIN_RULE_NAME_LENGTH, MAX_RULE_NAME_LENGTH),
+ },
+ },
+ "query": schema.StringAttribute{
+ Required: true,
+ Validators: []validator.String{
+ stringvalidator.LengthAtLeast(1),
+ },
+ },
+ "version": schema.StringAttribute{
+ Required: true,
+ Validators: []validator.String{
+ stringvalidator.LengthBetween(MIN_RULE_NAME_LENGTH, MAX_RULE_NAME_LENGTH),
+ },
+ },
}
-
- return &questionQueryList, nil
}
-func buildQuestionComplianceMetaDataList(terraformComplianceList []interface{}) (*[]client.QuestionComplianceMetaData, error) {
- complianceMetaDataList := make([]client.QuestionComplianceMetaData, len(terraformComplianceList))
+// Configure implements resource.ResourceWithConfigure
+func (r *QuestionResource) Configure(ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) {
+ // Prevent panic if the provider has not been configured.
+ if req.ProviderData == nil {
+ return
+ }
- for i, terraformComplianceMetaData := range terraformComplianceList {
- var complianceMetaData client.QuestionComplianceMetaData
+ p, ok := req.ProviderData.(*JupiterOneProvider)
- if err := mapstructure.Decode(terraformComplianceMetaData, &complianceMetaData); err != nil {
- return nil, err
- }
+ if !ok {
+ resp.Diagnostics.AddError(
+ "Unexpected Resource Configure Type",
+ fmt.Sprintf("Expected JupiterOneProvider, got: %T. Please report this issue to the provider developers.", req.ProviderData),
+ )
- complianceMetaDataList[i] = complianceMetaData
+ return
}
- return &complianceMetaDataList, nil
+ r.version = p.version
+ r.client = p.Client
}
-func buildQuestionProperties(d *schema.ResourceData) (*client.QuestionProperties, error) {
- var question client.QuestionProperties
+// Create implements resource.Resource
+func (r *QuestionResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
+ var data QuestionModel
- if v, ok := d.GetOk("title"); ok {
- question.Title = v.(string)
- }
+ // Read Terraform plan data into the model
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
- if v, ok := d.GetOk("description"); ok {
- question.Description = v.(string)
+ if resp.Diagnostics.HasError() {
+ return
}
- if v, ok := d.GetOk("tags"); ok {
- question.Tags = interfaceSliceToStringSlice(v.([]interface{}))
- }
-
- if v, ok := d.GetOk("query"); ok {
- queries, err := buildQuestionQueryList(v.([]interface{}))
-
- if err != nil {
- return nil, err
- }
+ q := data.BuildQuestion()
- question.Queries = *queries
+ var err error
+ q, err = r.client.CreateQuestion(q)
+ if err != nil {
+ resp.Diagnostics.AddError("failed to create question", err.Error())
+ return
}
- if v, ok := d.GetOk("compliance"); ok {
- complianceList, err := buildQuestionComplianceMetaDataList(v.([]interface{}))
+ data.Id = types.StringValue(q.Id)
- if err != nil {
- return nil, err
- }
+ tflog.Trace(ctx, "Created question",
+ map[string]interface{}{"title": data.Title, "id": data.Id})
- question.Compliance = *complianceList
- }
-
- return &question, nil
+ resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
}
-func resourceQuestionCreate(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
- questionProperties, err := buildQuestionProperties(d)
- if err != nil {
- return diag.Errorf("failed to build question: %s", err.Error())
+// Delete implements resource.Resource
+func (r *QuestionResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
+ var data QuestionModel
+
+ // Read Terraform ste into the model
+ resp.Diagnostics.Append(req.State.Get(ctx, &data)...)
+
+ if resp.Diagnostics.HasError() {
+ return
}
- createdQuestion, err := m.(*ProviderConfiguration).Client.CreateQuestion(*questionProperties)
- if err != nil {
- return diag.Errorf("failed to create question: %s", err.Error())
+ if err := r.client.DeleteQuestion(data.Id.ValueString()); err != nil {
+ resp.Diagnostics.AddError("failed to delete question", err.Error())
}
+}
- d.SetId(createdQuestion.Id)
+// Read implements resource.Resource
+func (r *QuestionResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
+ var data QuestionModel
- return nil
-}
+ // Read Terraform state into the model
+ resp.Diagnostics.Append(req.State.Get(ctx, &data)...)
-func resourceQuestionRead(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
- question, err := m.(*ProviderConfiguration).Client.GetQuestion(d.Id())
- if err != nil {
- return diag.Errorf("failed to read existing question: %s", err.Error())
- }
- err = d.Set("title", question.Title)
- if err != nil {
- return diag.FromErr(err)
+ if resp.Diagnostics.HasError() {
+ return
}
- err = d.Set("description", question.Description)
+ q, err := r.client.GetQuestion(data.Id.ValueString())
if err != nil {
- return diag.FromErr(err)
+ resp.Diagnostics.AddError("failed to get question", err.Error())
+ return
}
- err = d.Set("tags", question.Tags)
- if err != nil {
- return diag.FromErr(err)
+ // the API response fields are 1:1 with the state except for the queries
+ // themselves, which may have been stripped of line breaks
+ data = QuestionModel{
+ Id: types.StringValue(q.Id),
+ Title: types.StringValue(q.Title),
+ Description: types.StringValue(q.Description),
+ Tags: q.Tags,
}
- convertedQueries, err := queriesToMapStringInterface(question.Queries)
- if err != nil {
- return diag.FromErr(err)
+ data.Query = make([]*QueryModel, 0, len(q.Queries))
+ for _, query := range q.Queries {
+ data.Query = append(data.Query, &QueryModel{
+ Query: query.Query,
+ Version: query.Version,
+ Name: query.Name,
+ })
}
- err = d.Set("query", convertedQueries)
- if err != nil {
- return diag.FromErr(err)
+ data.Compliance = make([]*QuestionComplianceModel, 0, len(q.Compliance))
+ for _, compliance := range q.Compliance {
+ data.Compliance = append(data.Compliance, &QuestionComplianceModel{
+ Standard: compliance.Standard,
+ Requirements: compliance.Requirements,
+ Controls: compliance.Controls,
+ })
}
- /*
- TODO @zemberdotnet: read updates once compliance is actually supported in the
- internal client
- err = d.Set("compliance", question.Compliance)
- if err != nil {
- return diag.FromErr(err)
- }
- */
-
- d.SetId(question.Id)
- return nil
+ // Save updated data into Terraform state
+ resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
}
-func resourceQuestionUpdate(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
- questionProperties, err := buildQuestionProperties(d)
- if err != nil {
- return diag.Errorf("failed to build question: %s", err.Error())
+// Update implements resource.Resource
+func (r *QuestionResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
+ var data QuestionModel
+
+ // Read Terraform plan data into the model
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
+
+ if resp.Diagnostics.HasError() {
+ return
}
- if _, err := m.(*ProviderConfiguration).Client.UpdateQuestion(d.Id(), *questionProperties); err != nil {
- return diag.Errorf("failed to update question: %s", err.Error())
+ q := data.BuildQuestion()
+ id := q.Id
+ // question id must be empty when sending update object
+ q.Id = ""
+
+ _, err := r.client.UpdateQuestion(id, q)
+ if err != nil {
+ resp.Diagnostics.AddError("failed to update question", err.Error())
+ return
}
- return nil
+ tflog.Trace(ctx, "Updated question",
+ map[string]interface{}{"title": data.Title, "id": data.Id})
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
}
-func resourceQuestionDelete(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
- if err := m.(*ProviderConfiguration).Client.DeleteQuestion(d.Id()); err != nil {
- return diag.Errorf("failed to delete question: %s", err.Error())
+func (qm *QuestionModel) BuildQuestion() *client.Question {
+ q := &client.Question{
+ Id: qm.Id.ValueString(),
+ Title: qm.Title.ValueString(),
+ Description: qm.Description.ValueString(),
+ Tags: qm.Tags,
}
- d.SetId("")
- return nil
-}
+ q.Queries = make([]client.QuestionQuery, 0, len(qm.Query))
+ for _, query := range qm.Query {
+ query.Query = removeCRFromString(query.Query)
+ q.Queries = append(q.Queries, client.QuestionQuery{
+ Query: query.Query,
+ Version: query.Version,
+ Name: query.Name,
+ })
+ }
-func getQuestionComplianceSchema() map[string]*schema.Schema {
- return map[string]*schema.Schema{
- "standard": {
- Type: schema.TypeString,
- Required: true,
- },
- "requirements": {
- Type: schema.TypeList,
- Optional: true,
- Elem: &schema.Schema{
- Type: schema.TypeString,
- },
- },
- "controls": {
- Type: schema.TypeList,
- Optional: true,
- Elem: &schema.Schema{
- Type: schema.TypeString,
- },
- },
+ q.Compliance = make([]client.QuestionComplianceMetaData, 0, len(qm.Compliance))
+ for _, compliance := range qm.Compliance {
+ q.Compliance = append(q.Compliance, client.QuestionComplianceMetaData{
+ Standard: compliance.Standard,
+ Requirements: compliance.Requirements,
+ Controls: compliance.Controls,
+ })
}
+ return q
}
diff --git a/jupiterone/resource_question_test.go b/jupiterone/resource_question_test.go
index b6e13d3f..a7cd3056 100644
--- a/jupiterone/resource_question_test.go
+++ b/jupiterone/resource_question_test.go
@@ -7,29 +7,37 @@ import (
"testing"
"time"
+ "github.com/hashicorp/go-cleanhttp"
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/logging"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
- "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
"github.com/jupiterone/terraform-provider-jupiterone/jupiterone/internal/client"
)
func TestQuestion_Basic(t *testing.T) {
- accProviders, cleanup := testAccProviders(t)
+ ctx := context.TODO()
+
+ recorder, cleanup := setupCassettes(t.Name())
defer cleanup(t)
- accProvider := testAccProvider(t, accProviders)
+ testHttpClient := cleanhttp.DefaultClient()
+ testHttpClient.Transport = logging.NewTransport("JupiterOne", recorder)
+ // testJ1Client is used for direct calls for CheckDestroy/etc.
+ testJ1Client, err := client.NewClientFromEnv(ctx, testHttpClient)
+ if err != nil {
+ t.Fatal("error configuring check client", err)
+ }
+
resourceName := "jupiterone_question.test"
title := "tf-test-question"
- ctx := context.Background()
-
resource.Test(t, resource.TestCase{
- PreCheck: func() { testAccPreCheck(t) },
- Providers: accProviders,
- CheckDestroy: testAccCheckQuestionDestroy(ctx, accProvider),
+ PreCheck: func() { testAccPreCheck(t) },
+ ProtoV6ProviderFactories: testAccProtoV6ProviderFactories(testJ1Client),
+ CheckDestroy: testAccCheckQuestionDestroy(ctx, testJ1Client),
Steps: []resource.TestStep{
{
Config: testQuestionBasicConfigWithTags(title, "testing-tag-1"),
Check: resource.ComposeTestCheckFunc(
- testAccCheckQuestionExists(ctx, accProvider),
+ testAccCheckQuestionExists(ctx, testJ1Client),
resource.TestCheckResourceAttrSet(resourceName, "id"),
resource.TestCheckResourceAttr(resourceName, "title", title),
resource.TestCheckResourceAttr(resourceName, "description", "Test"),
@@ -44,7 +52,7 @@ func TestQuestion_Basic(t *testing.T) {
{
Config: testQuestionBasicConfigWithTags(title, "testing-tag-2"),
Check: resource.ComposeTestCheckFunc(
- testAccCheckQuestionExists(ctx, accProvider),
+ testAccCheckQuestionExists(ctx, testJ1Client),
resource.TestCheckResourceAttrSet(resourceName, "id"),
resource.TestCheckResourceAttr(resourceName, "title", title),
resource.TestCheckResourceAttr(resourceName, "description", "Test"),
@@ -60,11 +68,8 @@ func TestQuestion_Basic(t *testing.T) {
})
}
-func testAccCheckQuestionExists(ctx context.Context, accProvider *schema.Provider) resource.TestCheckFunc {
+func testAccCheckQuestionExists(ctx context.Context, client *client.JupiterOneClient) resource.TestCheckFunc {
return func(s *terraform.State) error {
- providerConf := accProvider.Meta().(*ProviderConfiguration)
- client := providerConf.Client
-
if err := questionExistsHelper(ctx, s, client); err != nil {
return err
}
@@ -97,11 +102,8 @@ func questionExistsHelper(ctx context.Context, s *terraform.State, client *clien
return nil
}
-func testAccCheckQuestionDestroy(ctx context.Context, accProvider *schema.Provider) func(*terraform.State) error {
+func testAccCheckQuestionDestroy(ctx context.Context, client *client.JupiterOneClient) func(*terraform.State) error {
return func(s *terraform.State) error {
- providerConf := accProvider.Meta().(*ProviderConfiguration)
- client := providerConf.Client
-
if err := questionDestroyHelper(ctx, s, client); err != nil {
return err
}
@@ -135,6 +137,8 @@ func questionDestroyHelper(ctx context.Context, s *terraform.State, client *clie
func testQuestionBasicConfigWithTags(rName string, tag string) string {
return fmt.Sprintf(`
+ provider "jupiterone" {}
+
resource "jupiterone_question" "test" {
title = %q
description = "Test"
diff --git a/jupiterone/resource_rule.go b/jupiterone/resource_rule.go
index f58d1e7d..def89f47 100644
--- a/jupiterone/resource_rule.go
+++ b/jupiterone/resource_rule.go
@@ -4,342 +4,638 @@ import (
"bytes"
"context"
"encoding/json"
-
- "github.com/hashicorp/terraform-plugin-sdk/v2/diag"
- "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
- "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
+ "fmt"
+ "reflect"
+
+ "github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag"
+ "github.com/hashicorp/terraform-plugin-framework-validators/listvalidator"
+ "github.com/hashicorp/terraform-plugin-framework-validators/resourcevalidator"
+ "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
+ "github.com/hashicorp/terraform-plugin-framework/path"
+ "github.com/hashicorp/terraform-plugin-framework/resource"
+ "github.com/hashicorp/terraform-plugin-framework/resource/schema"
+ "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64planmodifier"
+ "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
+ "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
+ "github.com/hashicorp/terraform-plugin-framework/schema/validator"
+ "github.com/hashicorp/terraform-plugin-framework/types"
+ "github.com/hashicorp/terraform-plugin-log/tflog"
"github.com/jupiterone/terraform-provider-jupiterone/jupiterone/internal/client"
)
const MIN_RULE_NAME_LENGTH = 1
const MAX_RULE_NAME_LENGTH = 255
-func resourceQuestionRuleInstance() *schema.Resource {
+// Ensure provider defined types fully satisfy framework interfaces
+var _ resource.Resource = &QuestionRuleResource{}
+var _ resource.ResourceWithConfigure = &QuestionRuleResource{}
+var _ resource.ResourceWithConfigValidators = &QuestionRuleResource{}
+var _ resource.ResourceWithModifyPlan = &QuestionRuleResource{}
+
+type QuestionRuleResource struct {
+ version string
+ client *client.JupiterOneClient
+}
+
+type RuleQuestion struct {
+ Queries []*QueryModel `json:"queries" tfsdk:"queries"`
+}
+
+// RuleModel represents the terraform representation of the rule
+type RuleModel struct {
+ Id types.String `json:"id,omitempty" tfsdk:"id"`
+ Name string `json:"name" tfsdk:"name"`
+ Description string `json:"description" tfsdk:"description"`
+ Version types.Int64 `json:"version,omitempty" tfsdk:"version"`
+ SpecVersion types.Int64 `json:"specVersion,omitempty" tfsdk:"spec_version"`
+ PollingInterval string `json:"pollingInterval" tfsdk:"polling_interval"`
+ Templates map[string]string `json:"templates" tfsdk:"templates"`
+ Question []*RuleQuestion `json:"question,omitempty" tfsdk:"question"`
+ QuestionId types.String `json:"questionId,omitempty" tfsdk:"question_id"`
+ QuestionName types.String `json:"questionName,omitempty" tfsdk:"question_name"`
+ // Operations TODO: breaking change for new version to do more in the
+ // HCL and/or make better use of things like jsonencode
+ Operations string `json:"operations" tfsdk:"operations"`
+ Outputs []string `json:"outputs" tfsdk:"outputs"`
+ Tags []string `json:"tags" tfsdk:"tags"`
+}
+
+func NewQuestionRuleResource() resource.Resource {
+ return &QuestionRuleResource{}
+}
+
+// Metadata implements resource.Resource
+func (*QuestionRuleResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
+ resp.TypeName = req.ProviderTypeName + "_rule"
+}
+
+// Configure implements resource.ResourceWithConfigure
+func (r *QuestionRuleResource) Configure(ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) {
+ // Prevent panic if the provider has not been configured.
+ if req.ProviderData == nil {
+ return
+ }
+
+ p, ok := req.ProviderData.(*JupiterOneProvider)
+
+ if !ok {
+ resp.Diagnostics.AddError(
+ "Unexpected Resource Configure Type",
+ fmt.Sprintf("Expected JupiterOneProvider, got: %T. Please report this issue to the provider developers.", req.ProviderData),
+ )
+
+ return
+ }
+
+ r.version = p.version
+ r.client = p.Client
+}
+
+// Schema implements resource.ResourceWithConfigure
+func (*QuestionRuleResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
var RulePollingIntervals = []string{"DISABLED", "THIRTY_MINUTES", "ONE_HOUR", "ONE_DAY", "ONE_WEEK"}
- return &schema.Resource{
- CreateContext: createQuestionRuleInstanceResource,
- ReadContext: resourceQuestionRuleInstanceRead,
- UpdateContext: resourceQuestionRuleInstanceUpdate,
- DeleteContext: resourceQuestionRuleInstanceDelete,
- Schema: map[string]*schema.Schema{
- "name": {
- Type: schema.TypeString,
- Required: true,
- Description: "Name of the rule, which is unique to each account.",
- ValidateFunc: validation.StringLenBetween(MIN_RULE_NAME_LENGTH, MAX_RULE_NAME_LENGTH),
+ resp.Schema = schema.Schema{
+ Description: "A saved JupiterOne question based alert",
+ Attributes: map[string]schema.Attribute{
+ "id": schema.StringAttribute{
+ Computed: true,
+ Description: "Unique id that identifies the rule",
+ PlanModifiers: []planmodifier.String{
+ stringplanmodifier.UseStateForUnknown(),
+ },
+ },
+ "version": schema.Int64Attribute{
+ Description: "Computed current version of the rule. Incremented each time the rule is updated.",
+ Computed: true,
+ PlanModifiers: []planmodifier.Int64{
+ // This works with ModifyPlan() prevent planned changes
+ // to this computed value
+ int64planmodifier.UseStateForUnknown(),
+ },
},
- "description": {
- Type: schema.TypeString,
+ "name": schema.StringAttribute{
+ Required: true,
+ Description: "Name of the rule, which is unique to each account.",
+ Validators: []validator.String{
+ stringvalidator.LengthBetween(MIN_RULE_NAME_LENGTH, MAX_RULE_NAME_LENGTH),
+ },
+ },
+ "description": schema.StringAttribute{
Description: "Description of the rule",
Required: true,
},
- "spec_version": {
- Type: schema.TypeInt,
+ "spec_version": schema.Int64Attribute{
Description: "Rule evaluation specification version in the case of breaking changes.",
- Default: 1,
+ Computed: true,
Optional: true,
+ PlanModifiers: []planmodifier.Int64{
+ Int64DefaultValue(types.Int64Value(1)),
+ },
},
- "version": {
- Type: schema.TypeInt,
- Description: "Computed current version of the rule. Incremented each time the rule is updated.",
+ "polling_interval": schema.StringAttribute{
+ Description: "Frequency of automated rule evaluation. Defaults to ONE_DAY.",
Computed: true,
- },
- "polling_interval": {
- Type: schema.TypeString,
- Description: "Frequency of automated rule evaluation. Defaults to ONE_DAY.",
- Default: RulePollingIntervals[3],
- ValidateFunc: validation.StringInSlice(RulePollingIntervals, false),
- Optional: true,
- },
- "templates": {
- Type: schema.TypeMap,
- Description: "Optional key/value pairs of template name to template",
Optional: true,
- Elem: &schema.Schema{
- Type: schema.TypeString,
+ PlanModifiers: []planmodifier.String{
+ StringDefaultValue(RulePollingIntervals[3]),
},
- },
- "question": {
- Type: schema.TypeList,
- Description: "Contains properties related to queries used in the rule evaluation.",
- MaxItems: 1,
- Elem: &schema.Resource{
- Schema: getRuleQuestionSchema(),
+ Validators: []validator.String{
+ stringvalidator.OneOf(RulePollingIntervals...),
},
- AtLeastOneOf: []string{"question", "question_id", "question_name"},
- ConflictsWith: []string{"question_id", "question_name"},
- Optional: true,
},
- "question_id": {
- Type: schema.TypeString,
- Description: "Specifies the ID of a question to be used in rule evaluation.",
+ "templates": schema.MapAttribute{
+ Description: "Optional key/value pairs of template name to template",
+ ElementType: types.StringType,
Optional: true,
},
- "question_name": {
- Type: schema.TypeString,
- Description: "Specifies the name of a question to be used in rule evaluation.",
+ "question_id": schema.StringAttribute{
+ Description: "Specifies the ID of a question to be used in rule evaluation.",
Optional: true,
- Deprecated: "The question_name identifier is deprecated. Prefer to use a question's id property with question_id to reference a jupiterone_question in a jupiterone_rule.",
},
- "operations": {
- Type: schema.TypeString,
- Description: "Actions that are executed when a corresponding condition is met.",
- ValidateFunc: validation.StringIsJSON,
- Required: true,
- DiffSuppressFunc: jsonDiffSuppressFunc,
+ "question_name": schema.StringAttribute{
+ Description: "Specifies the name of a question to be used in rule evaluation.",
+ DeprecationMessage: "The question_name identifier is deprecated. Prefer to use a question's id property with question_id to reference a jupiterone_question in a jupiterone_rule.",
+ Optional: true,
+ },
+ "operations": schema.StringAttribute{
+ Description: "Actions that are executed when a corresponding condition is met.",
+ Required: true,
+ // PlanModifiers currently tries to diff the json objects and
+ // ignore formatting changes, but long term should probably
+ // be a TODO for a more complete schema and encouraging
+ // jsonencode() usage instead.
+ PlanModifiers: []planmodifier.String{
+ jsonIgnoreDiffPlanModifier(),
+ },
+ // TODO: similar to above, longer term is to define more of the
+ // schema for HCL and encourage use of jsonencode()
+ // Alternative: Look for a JSONString CustomType that comes
+ // with it's own validation in it's marshalling
+ Validators: []validator.String{
+ jsonValidator{},
+ },
},
- "outputs": {
- Type: schema.TypeList,
+ "outputs": schema.ListAttribute{
Description: "Names of properties that can be used throughout the rule evaluation process and will be included in each record of a rule evaluation. (e.g. queries.query0.total)",
+ ElementType: types.StringType,
Optional: true,
- Elem: &schema.Schema{
- Type: schema.TypeString,
- },
},
- "tags": {
- Type: schema.TypeList,
+ "tags": schema.ListAttribute{
Description: "Comma separated list of tags to apply to the rule.",
+ ElementType: types.StringType,
Optional: true,
- Elem: &schema.Schema{
- Type: schema.TypeString,
- },
},
},
- }
-}
-
-func getRuleQuestionSchema() map[string]*schema.Schema {
- return map[string]*schema.Schema{
- "queries": {
- Type: schema.TypeList,
- Required: true,
- Elem: &schema.Resource{
- Schema: getQuestionQuerySchema(),
+ // TODO: Deprecate the use of blocks following new framework guidance:
+ // https://developer.hashicorp.com/terraform/plugin/framework/handling-data/blocks
+ Blocks: map[string]schema.Block{
+ "question": schema.ListNestedBlock{
+ Description: "Contains properties related to queries used in the rule evaluation.",
+ NestedObject: schema.NestedBlockObject{
+ Blocks: map[string]schema.Block{
+ "queries": schema.ListNestedBlock{
+ Description: "Contains properties related to queries used in the rule evaluation.",
+ NestedObject: schema.NestedBlockObject{
+ Attributes: questionQuerySchemaAttributes(),
+ },
+ Validators: []validator.List{
+ listvalidator.SizeAtLeast(1),
+ },
+ },
+ },
+ },
+ Validators: []validator.List{
+ listvalidator.SizeAtMost(1),
+ },
},
},
}
}
-func getQuestionQuerySchema() map[string]*schema.Schema {
- return map[string]*schema.Schema{
- "name": {
- Type: schema.TypeString,
- Optional: true,
- },
- "query": {
- Type: schema.TypeString,
- Required: true,
- },
- "version": {
- Type: schema.TypeString,
- Required: true,
- },
+// ConfigValidators implements resource.ResourceWithConfigValidators
+func (*QuestionRuleResource) ConfigValidators(context.Context) []resource.ConfigValidator {
+ return []resource.ConfigValidator{
+ resourcevalidator.Conflicting(
+ path.MatchRoot("question"),
+ path.MatchRoot("question_id"),
+ path.MatchRoot("question_name"),
+ ),
+ resourcevalidator.AtLeastOneOf(
+ path.MatchRoot("question"),
+ path.MatchRoot("question_id"),
+ path.MatchRoot("question_name"),
+ ),
}
}
-func newQuestionRuleInstance(d *schema.ResourceData) (*client.QuestionRuleInstance, error) {
- questionRuleInstance := &client.QuestionRuleInstance{}
- if v, ok := d.GetOk("name"); ok {
- questionRuleInstance.Name = v.(string)
+// ModifyPlan is a workaround for unexpected behavior in the framework around
+// the `computed: true` `version` field to make sure that it is only part of
+// the plan if there is some other change in the resource.
+//
+// Based on the implementation of the Time resource:
+// https://github.com/hashicorp/terraform-provider-time/blob/main/internal/provider/resource_time_rotating.go#L189-L234
+//
+// This may be a bug in the framework, if so, this can be removed when fixed:
+// https://github.com/hashicorp/terraform-plugin-framework/issues/628
+func (*QuestionRuleResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) {
+ // Plan does not need to be modified when the resource is being destroyed.
+ if req.Plan.Raw.IsNull() {
+ return
}
- if v, ok := d.GetOk("description"); ok {
- questionRuleInstance.Description = v.(string)
+ // Plan only needs modifying if the resource already exists as the purpose of
+ // the plan modifier is to show updated attribute values on CLI.
+ if req.State.Raw.IsNull() {
+ return
}
- if v, ok := d.GetOk("spec_version"); ok {
- questionRuleInstance.SpecVersion = v.(int)
- }
+ var plan, state *RuleModel
- if v, ok := d.GetOk("polling_interval"); ok {
- questionRuleInstance.PollingInterval = v.(string)
- }
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
+ resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
- if v, ok := d.GetOk("outputs"); ok {
- questionRuleInstance.Outputs = interfaceSliceToStringSlice(v.([]interface{}))
+ if resp.Diagnostics.HasError() {
+ return
}
- if v, ok := d.GetOk("operations"); ok {
- ops := make([]client.RuleOperation, 0)
- err := json.Unmarshal([]byte(v.(string)), &ops)
- if err != nil {
- return nil, err
- }
- questionRuleInstance.Operations = ops
+ if !reflect.DeepEqual(plan, state) {
+ resp.Diagnostics.Append(resp.Plan.SetAttribute(ctx, path.Root("version"),
+ types.Int64Unknown())...)
}
+}
- if v, ok := d.GetOk("question"); ok {
- v := v.([]interface{})
- if len(v) == 0 {
- questionRuleInstance.Question = map[string]interface{}{}
- } else {
- // Question MaxItems is 1. Enforced at schema level.
- questionRuleInstance.Question = v[0].(map[string]interface{})
- }
- }
+// Create implements resource.ResourceWithConfigure
+func (r *QuestionRuleResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
+ var data *RuleModel
- if v, ok := d.GetOk("question_id"); ok {
- questionRuleInstance.QuestionId = v.(string)
- }
+ // Read Terraform plan data into the model
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
- if v, ok := d.GetOk("question_name"); ok {
- questionRuleInstance.QuestionName = v.(string)
+ if resp.Diagnostics.HasError() {
+ return
}
- if v, ok := d.GetOk("templates"); ok {
- questionRuleInstance.Templates = v.(map[string]interface{})
+ // TODO: in future versions, make operations more explicit in the schema
+ // TODO: This map can probably be replaces by existing structs as well
+ rule, err := data.BuildQuestionRuleInstance()
+ if err != nil {
+ resp.Diagnostics.AddError("failed to build rule from configuration", err.Error())
+ return
}
- if v, ok := d.GetOk("tags"); ok {
- questionRuleInstance.Tags = interfaceSliceToStringSlice(v.([]interface{}))
+ rule, err = r.client.CreateQuestionRuleInstance(rule)
+ if err != nil {
+ resp.Diagnostics.AddError("failed to create rule", err.Error())
+ return
}
- if v, ok := d.GetOk("version"); ok {
- questionRuleInstance.Version = v.(int)
+ data.Id = types.StringValue(rule.Id)
+ data.Version = types.Int64Value(int64(rule.Version))
+
+ // TODO: This should _probably_ be done whenever values are read from the server
+ // and stored back to state, but version 0.5.0 didn't do this and relied
+ // solely on the suppress diff func, so leave this out for test/state
+ // compatibility until more improvements worth upgrading the state for are
+ // implemented
+ /* data.Operations, err = processOperationsState(rule.Operations)
+ if err != nil {
+ resp.Diagnostics.AddError("failed to save operations state", err.Error())
+ return
+ } */
+
+ tflog.Trace(ctx, "Created rule",
+ map[string]interface{}{"title": data.Name, "id": data.Id})
+
+ resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
+}
+
+// Delete implements resource.ResourceWithConfigure
+func (r *QuestionRuleResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
+ var data RuleModel
+
+ // Read Terraform ste into the model
+ resp.Diagnostics.Append(req.State.Get(ctx, &data)...)
+
+ if resp.Diagnostics.HasError() {
+ return
}
- if d.Id() != "" {
- questionRuleInstance.Id = d.Id()
+ if err := r.client.DeleteQuestionRuleInstance(data.Id.ValueString()); err != nil {
+ resp.Diagnostics.AddError("failed to delete rule", err.Error())
}
+}
- return questionRuleInstance, nil
+// Read implements resource.ResourceWithConfigure
+func (r *QuestionRuleResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
+ var data RuleModel
-}
+ // Read Terraform ste into the model
+ resp.Diagnostics.Append(req.State.Get(ctx, &data)...)
-func createQuestionRuleInstanceResource(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
- questionRuleInstance, err := newQuestionRuleInstance(d)
- if err != nil {
- return diag.Errorf("failed to build question rule instance: %s", err.Error())
+ if resp.Diagnostics.HasError() {
+ return
}
- createdQuestion, err := m.(*ProviderConfiguration).Client.CreateQuestionRuleInstance(*questionRuleInstance)
+ rule, err := r.client.GetQuestionRuleInstanceByID(data.Id.ValueString())
if err != nil {
- return diag.Errorf("failed to create question rule instance: %s", err.Error())
+ resp.Diagnostics.AddError("failed to get rule", err.Error())
+ return
+ }
+
+ data = RuleModel{
+ Id: types.StringValue(rule.Id),
+ Name: rule.Name,
+ Description: rule.Description,
+ Version: types.Int64Value(int64(rule.Version)),
+ SpecVersion: types.Int64Value(int64(rule.SpecVersion)),
+ PollingInterval: rule.PollingInterval,
+ Templates: rule.Templates,
+ Outputs: rule.Outputs,
+ Tags: rule.Tags,
+ }
+
+ if rule.QuestionId != "" {
+ data.QuestionId = types.StringValue(rule.QuestionId)
+ }
+ if rule.QuestionName != "" {
+ data.QuestionName = types.StringValue(rule.QuestionName)
+ }
+ if queries := rule.Question["queries"]; len(queries) > 0 {
+ data.Question = []*RuleQuestion{{Queries: []*QueryModel{
+ {
+ Name: queries[0]["name"],
+ Query: queries[0]["query"],
+ Version: queries[0]["version"],
+ },
+ }}}
}
- if err := d.Set("version", createdQuestion.Version); err != nil {
- return diag.FromErr(err)
+ data.Operations, err = processOperationsState(rule.Operations)
+ if err != nil {
+ resp.Diagnostics.AddError("failed to process operations for rule", err.Error())
+ return
}
- d.SetId(createdQuestion.Id)
- return nil
+ // Save updated data into Terraform state
+ resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
}
-func resourceQuestionRuleInstanceUpdate(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
- questionRuleInstance, err := newQuestionRuleInstance(d)
- if err != nil {
- return diag.Errorf("failed to build question rule instance: %s", err.Error())
+// Update implements resource.ResourceWithConfigure
+func (r *QuestionRuleResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
+ var data RuleModel
+
+ // Read Terraform plan data into the model
+ resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
+
+ // The UpdateRule operation needs the most current version of the rule to update it.
+ // We fetch it from the state if it is not specified by the user.
+ if data.Version.IsUnknown() {
+ var state RuleModel
+ resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+ data.Version = state.Version
}
- updatedQuestionRuleInstance, err := m.(*ProviderConfiguration).Client.UpdateQuestionRuleInstance(questionRuleInstance)
+ if resp.Diagnostics.HasError() {
+ return
+ }
+
+ // TODO: in future versions, make operations more explicit in the schema
+ // TODO: This map can probably be replaces by existing structs as well
+ rule, err := data.BuildQuestionRuleInstance()
if err != nil {
- return diag.Errorf("failed to update question rule instance: %s", err.Error())
+ resp.Diagnostics.AddError("failed to create rule", err.Error())
+ return
}
- if err := d.Set("version", updatedQuestionRuleInstance.Version); err != nil {
- return diag.FromErr(err)
+ rule, err = r.client.UpdateQuestionRuleInstance(rule)
+ if err != nil {
+ resp.Diagnostics.AddError("failed to create rule", err.Error())
+ return
}
- return nil
-}
+ data.Id = types.StringValue(rule.Id)
+ data.Version = types.Int64Value(int64(rule.Version))
-func resourceQuestionRuleInstanceDelete(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
- if err := m.(*ProviderConfiguration).Client.DeleteQuestionRuleInstance(d.Id()); err != nil {
- return diag.Errorf("failed to delete question rule instance: %s", err.Error())
- }
+ // TODO: This should _probably_ be done whenever values are read from the server
+ // and stored back to state, but version 0.5.0 only did this on Read and relied
+ // solely on the suppress diff func, so leave this out for test/state
+ // compatibility until more improvements worth upgrading the state for are
+ // implemented
+ //data.Operations, err = processOperationsState(rule.Operations)
+ //if err != nil {
+ // resp.Diagnostics.AddError("failed to save operations state", err.Error())
+ // return
+ //}
- d.SetId("")
- return nil
-}
+ tflog.Trace(ctx, "Updated rule",
+ map[string]interface{}{"title": data.Name, "id": data.Id})
-func resourceQuestionRuleInstanceRead(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
- questionRuleInstance, err := m.(*ProviderConfiguration).Client.GetQuestionRuleInstanceByID(d.Id())
+ resp.Diagnostics.Append(resp.State.Set(ctx, data)...)
+}
- if err != nil {
- return diag.Errorf("failed to read existing question rule instance: %s", err.Error())
+func processOperationsState(ruleOperations []client.RuleOperation) (string, error) {
+ // Because we store the Operations as a raw string. The id property, which
+ // is set after the creation of the question creates a diff that would cause
+ // the Operations to update on every terraform apply
+ for _, op := range ruleOperations {
+ for _, action := range op.Actions {
+ delete(action, "id")
+ }
}
- err = d.Set("name", questionRuleInstance.Name)
+ buf := new(bytes.Buffer)
+ encoder := json.NewEncoder(buf)
+ encoder.SetEscapeHTML(false)
+ err := encoder.Encode(ruleOperations)
if err != nil {
- return diag.FromErr(err)
+ return "", err
}
+ return buf.String(), nil
+}
- err = d.Set("description", questionRuleInstance.Description)
+func (r *RuleModel) BuildQuestionRuleInstance() (*client.QuestionRuleInstance, error) {
+ rule := &client.QuestionRuleInstance{
+ Id: r.Id.ValueString(),
+ Name: r.Name,
+ Description: r.Description,
+ SpecVersion: int(r.SpecVersion.ValueInt64()),
+ Version: int(r.Version.ValueInt64()),
+ PollingInterval: r.PollingInterval,
+ Templates: r.Templates,
+ QuestionId: r.QuestionId.ValueString(),
+ QuestionName: r.QuestionName.ValueString(),
+ Outputs: r.Outputs,
+ Tags: r.Tags,
+ }
+
+ ops := make([]client.RuleOperation, 0)
+ err := json.Unmarshal([]byte(r.Operations), &ops)
if err != nil {
- return diag.FromErr(err)
+ return nil, err
}
+ rule.Operations = ops
- err = d.Set("version", questionRuleInstance.Version)
- if err != nil {
- return diag.FromErr(err)
+ if len(r.Question) > 0 && len(r.Question[0].Queries) > 0 {
+ rule.Question = map[string][]map[string]string{
+ "queries": {
+ {
+ "name": r.Question[0].Queries[0].Name,
+ "query": r.Question[0].Queries[0].Query,
+ "version": r.Question[0].Queries[0].Version,
+ },
+ },
+ }
}
- err = d.Set("polling_interval", questionRuleInstance.PollingInterval)
- if err != nil {
- return diag.FromErr(err)
+
+ return rule, nil
+}
+
+func jsonIgnoreDiffPlanModifier() planmodifier.String {
+ return jsonIgnoreDiff{}
+}
+
+type jsonIgnoreDiff struct {
+}
+
+// Description implements planmodifier.String
+func (jsonIgnoreDiff) Description(context.Context) string {
+ return "Compares json for object equality to ignore formatting changes"
+}
+
+// MarkdownDescription implements planmodifier.String
+func (j jsonIgnoreDiff) MarkdownDescription(ctx context.Context) string {
+ return j.Description(ctx)
+}
+
+// PlanModifyString implements planmodifier.String
+func (jsonIgnoreDiff) PlanModifyString(ctx context.Context, req planmodifier.StringRequest, resp *planmodifier.StringResponse) {
+ // always apply new values
+ if req.StateValue.ValueString() == "" {
+ return
}
- err = d.Set("templates", questionRuleInstance.Templates)
+ var oldValue interface{}
+ err := json.Unmarshal([]byte(req.StateValue.ValueString()), &oldValue)
if err != nil {
- return diag.FromErr(err)
+ resp.Diagnostics.AddError("Invalid operations json in old state", err.Error())
+ return
}
- questionSlice := []map[string]interface{}{questionRuleInstance.Question}
- err = d.Set("question", questionSlice)
+ var newValue interface{}
+ err = json.Unmarshal([]byte(req.PlanValue.ValueString()), &newValue)
if err != nil {
- return diag.FromErr(err)
+ resp.Diagnostics.AddError("Invalid operations json in old state", err.Error())
+ return
}
- err = d.Set("question_id", questionRuleInstance.QuestionId)
- if err != nil {
- return diag.FromErr(err)
+ if reflect.DeepEqual(oldValue, newValue) {
+ resp.PlanValue = req.StateValue
}
+}
- err = d.Set("question_name", questionRuleInstance.QuestionName)
- if err != nil {
- return diag.FromErr(err)
+func Int64DefaultValue(v types.Int64) planmodifier.Int64 {
+ return &int64DefaultValuePlanModifier{v}
+}
+
+// int64DefaultValuePlanModifier is based on the example at:
+// https://developer.hashicorp.com/terraform/plugin/framework/migrating/attributes-blocks/default-values
+type int64DefaultValuePlanModifier struct {
+ DefaultValue types.Int64
+}
+
+var _ planmodifier.Int64 = (*int64DefaultValuePlanModifier)(nil)
+
+func (apm *int64DefaultValuePlanModifier) Description(ctx context.Context) string {
+ return "sets a default value for an int64 value"
+}
+
+func (apm *int64DefaultValuePlanModifier) MarkdownDescription(ctx context.Context) string {
+ return apm.Description(ctx)
+}
+
+func (apm *int64DefaultValuePlanModifier) PlanModifyInt64(ctx context.Context, req planmodifier.Int64Request, res *planmodifier.Int64Response) {
+ // If the attribute configuration is not null, we are done here
+ if !req.ConfigValue.IsNull() {
+ return
}
- ops, err := processOperationsState(questionRuleInstance.Operations)
- if err != nil {
- return diag.FromErr(err)
+ // If the attribute plan is "known" and "not null", then a previous plan modifier in the sequence
+ // has already been applied, and we don't want to interfere.
+ if !req.PlanValue.IsUnknown() && !req.PlanValue.IsNull() {
+ return
}
- err = d.Set("operations", ops)
- if err != nil {
- return diag.FromErr(err)
+ res.PlanValue = apm.DefaultValue
+}
+
+func StringDefaultValue(v string) planmodifier.String {
+ return &stringDefaultValuePlanModifier{
+ DefaultValue: types.StringValue(v),
}
+}
- err = d.Set("outputs", questionRuleInstance.Outputs)
- if err != nil {
- return diag.FromErr(err)
+type stringDefaultValuePlanModifier struct {
+ DefaultValue types.String
+}
+
+var _ planmodifier.String = (*stringDefaultValuePlanModifier)(nil)
+
+func (apm *stringDefaultValuePlanModifier) Description(ctx context.Context) string {
+ return "sets a default value for an string value"
+}
+
+func (apm *stringDefaultValuePlanModifier) MarkdownDescription(ctx context.Context) string {
+ return apm.Description(ctx)
+}
+
+func (apm *stringDefaultValuePlanModifier) PlanModifyString(ctx context.Context, req planmodifier.StringRequest, res *planmodifier.StringResponse) {
+ // If the attribute configuration is not null, we are done here
+ if !req.ConfigValue.IsNull() {
+ return
}
- err = d.Set("tags", questionRuleInstance.Tags)
- if err != nil {
- return diag.FromErr(err)
+ // If the attribute plan is "known" and "not null", then a previous plan modifier in the sequence
+ // has already been applied, and we don't want to interfere.
+ if !req.PlanValue.IsUnknown() && !req.PlanValue.IsNull() {
+ return
}
- d.SetId(questionRuleInstance.Id)
- return nil
+ res.PlanValue = apm.DefaultValue
}
-func processOperationsState(ruleOperations []client.RuleOperation) (string, error) {
- // Because we store the Operations as a raw string. The id property, which
- // is set after the creation of the question creates a diff that would cause
- // the Operations to update on every terraform apply
- for _, op := range ruleOperations {
- for _, action := range op.Actions {
- delete(action, "id")
- }
+var _ validator.String = jsonValidator{}
+
+// oneOfValidator validates that the value matches one of expected values.
+type jsonValidator struct {
+}
+
+// Description implements validator.String
+func (jsonValidator) Description(context.Context) string {
+ return "string value must be valid JSON"
+}
+
+// MarkdownDescription implements validator.String
+func (v jsonValidator) MarkdownDescription(ctx context.Context) string {
+ return v.Description(ctx)
+}
+
+// ValidateString implements validator.String
+func (v jsonValidator) ValidateString(ctx context.Context, req validator.StringRequest, resp *validator.StringResponse) {
+ if req.ConfigValue.IsUnknown() {
+ return
}
- buf := new(bytes.Buffer)
- encoder := json.NewEncoder(buf)
- encoder.SetEscapeHTML(false)
- err := encoder.Encode(ruleOperations)
+ var d interface{}
+ err := json.Unmarshal([]byte(req.ConfigValue.ValueString()), &d)
if err != nil {
- return "", err
+ resp.Diagnostics.Append(validatordiag.InvalidAttributeValueDiagnostic(
+ req.Path,
+ v.Description(ctx),
+ req.ConfigValue.String(),
+ ))
}
- return buf.String(), nil
}
diff --git a/jupiterone/resource_rule_test.go b/jupiterone/resource_rule_test.go
index 916ed330..9c90b19f 100644
--- a/jupiterone/resource_rule_test.go
+++ b/jupiterone/resource_rule_test.go
@@ -8,34 +8,40 @@ import (
"testing"
"time"
- "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
+ "github.com/hashicorp/go-cleanhttp"
+ "github.com/hashicorp/terraform-plugin-sdk/helper/acctest"
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/logging"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
- "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
"github.com/jupiterone/terraform-provider-jupiterone/jupiterone/internal/client"
)
func TestRuleInstance_Basic(t *testing.T) {
- accProviders, cleanup := testAccProviders(t)
+ ctx := context.TODO()
+
+ recorder, cleanup := setupCassettes(t.Name())
defer cleanup(t)
- accProvider := testAccProvider(t, accProviders)
+ testHttpClient := cleanhttp.DefaultClient()
+ testHttpClient.Transport = logging.NewTransport("JupiterOne", recorder)
+ // testJ1Client is used for direct calls for CheckDestroy/etc.
+ testJ1Client, err := client.NewClientFromEnv(ctx, testHttpClient)
+ if err != nil {
+ t.Fatal("error configuring check client", err)
+ }
+
ruleName := "tf-provider-rule"
resourceName := "jupiterone_rule.test"
-
operations := getValidOperations()
operationsUpdate := getValidOperationsWithoutConditions()
-
- ctx := context.Background()
-
resource.Test(t, resource.TestCase{
- PreCheck: func() { testAccPreCheck(t) },
- Providers: accProviders,
- CheckDestroy: testAccCheckRuleInstanceDestroy(ctx, resourceName, accProvider),
+ PreCheck: func() { testAccPreCheck(t) },
+ ProtoV6ProviderFactories: testAccProtoV6ProviderFactories(testJ1Client),
+ CheckDestroy: testAccCheckRuleInstanceDestroy(ctx, resourceName, testJ1Client),
Steps: []resource.TestStep{
{
Config: testRuleInstanceBasicConfigWithOperations(ruleName, operations),
Check: resource.ComposeTestCheckFunc(
- testAccCheckRuleExists(ctx, resourceName, accProvider),
+ testAccCheckRuleExists(ctx, resourceName, testJ1Client),
resource.TestCheckResourceAttrSet(resourceName, "id"),
resource.TestCheckResourceAttr(resourceName, "version", "1"),
resource.TestCheckResourceAttr(resourceName, "name", ruleName),
@@ -59,7 +65,7 @@ func TestRuleInstance_Basic(t *testing.T) {
{
Config: testRuleInstanceBasicConfigWithOperations(ruleName, operationsUpdate),
Check: resource.ComposeTestCheckFunc(
- testAccCheckRuleExists(ctx, resourceName, accProvider),
+ testAccCheckRuleExists(ctx, resourceName, testJ1Client),
resource.TestCheckResourceAttrSet(resourceName, "id"),
resource.TestCheckResourceAttr(resourceName, "version", "2"),
resource.TestCheckResourceAttr(resourceName, "name", ruleName),
@@ -85,29 +91,36 @@ func TestRuleInstance_Basic(t *testing.T) {
}
func TestRuleInstance_Config_Errors(t *testing.T) {
- accProviders, cleanup := testAccProviders(t)
+ ctx := context.TODO()
+
+ recorder, cleanup := setupCassettes(t.Name())
defer cleanup(t)
- accProvider := testAccProvider(t, accProviders)
+ testHttpClient := cleanhttp.DefaultClient()
+ testHttpClient.Transport = logging.NewTransport("JupiterOne", recorder)
+ // testJ1Client is used for direct calls for CheckDestroy/etc.
+ testJ1Client, err := client.NewClientFromEnv(ctx, testHttpClient)
+ if err != nil {
+ t.Fatal("error configuring check client", err)
+ }
+
rName := acctest.RandomWithPrefix("tf-acc-test")
- ctx := context.Background()
resourceName := "jupiterone_rule.test"
-
resource.ParallelTest(t, resource.TestCase{
- PreCheck: func() { testAccPreCheck(t) },
- Providers: accProviders,
- CheckDestroy: testAccCheckRuleInstanceDestroy(ctx, resourceName, accProvider),
+ PreCheck: func() { testAccPreCheck(t) },
+ ProtoV6ProviderFactories: testAccProtoV6ProviderFactories(testJ1Client),
+ CheckDestroy: testAccCheckRuleInstanceDestroy(ctx, resourceName, testJ1Client),
Steps: []resource.TestStep{
{
Config: testRuleInstanceBasicConfigWithOperations(rName, "not json"),
- ExpectError: regexp.MustCompile(`"operations" contains an invalid JSON`),
+ ExpectError: regexp.MustCompile(`string value must be valid JSON`),
},
{
Config: testRuleInstanceBasicConfigWithOperations("", getValidOperations()),
- ExpectError: regexp.MustCompile(`expected length of name to be in the range \(1 - 255\)`),
+ ExpectError: regexp.MustCompile(`Attribute name string length must be between 1 and 255, got: 0`),
},
{
Config: testRuleInstanceBasicConfigWithPollingInterval(rName, "INVALID_POLLING_INTERVAL"),
- ExpectError: regexp.MustCompile(`expected polling_interval to be one of \[DISABLED THIRTY_MINUTES ONE_HOUR ONE_DAY ONE_WEEK\], got INVALID_POLLING_INTERVAL`),
+ ExpectError: regexp.MustCompile(`Attribute polling_interval value must be one of:`),
},
},
})
@@ -121,11 +134,9 @@ func getValidOperationsWithoutConditions() string {
return `[{"actions":[{"targetValue":"HIGH","type":"SET_PROPERTY","targetProperty":"alertLevel"},{"type":"CREATE_ALERT"}]}]`
}
-func testAccCheckRuleExists(ctx context.Context, ruleName string, accProvider *schema.Provider) resource.TestCheckFunc {
+func testAccCheckRuleExists(ctx context.Context, ruleName string, client *client.JupiterOneClient) resource.TestCheckFunc {
return func(s *terraform.State) error {
resource := s.RootModule().Resources[ruleName]
- providerConf := accProvider.Meta().(*ProviderConfiguration)
- client := providerConf.Client
err := ruleExistsHelper(ctx, resource.Primary.ID, client)
if err != nil {
@@ -157,11 +168,9 @@ func ruleExistsHelper(ctx context.Context, id string, client *client.JupiterOneC
return nil
}
-func testAccCheckRuleInstanceDestroy(ctx context.Context, resourceName string, accProvider *schema.Provider) func(*terraform.State) error {
+func testAccCheckRuleInstanceDestroy(ctx context.Context, resourceName string, client *client.JupiterOneClient) func(*terraform.State) error {
return func(s *terraform.State) error {
resource := s.RootModule().Resources[resourceName]
- providerConf := accProvider.Meta().(*ProviderConfiguration)
- client := providerConf.Client
if err := ruleInstanceDestroyHelper(ctx, resource.Primary.ID, client); err != nil {
return err
diff --git a/jupiterone/util.go b/jupiterone/util.go
index b9927ad0..9bbf56fa 100644
--- a/jupiterone/util.go
+++ b/jupiterone/util.go
@@ -1,60 +1,9 @@
package jupiterone
import (
- "bytes"
- "encoding/json"
- "reflect"
"strings"
-
- "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
- "github.com/jupiterone/terraform-provider-jupiterone/jupiterone/internal/client"
)
func removeCRFromString(s string) string {
return strings.ReplaceAll(s, "\r", "")
}
-
-func interfaceSliceToStringSlice(l []interface{}) []string {
- ret := make([]string, len(l))
-
- for i, tag := range l {
- ret[i] = tag.(string)
- }
-
- return ret
-}
-
-func jsonDiffSuppressFunc(k, oldValue, newValue string, d *schema.ResourceData) bool {
- var old, new interface{}
- // Errors during json.Unmarshal likely mean that newValue is empty or deleted.
- // In this case we shouldn't suppress the diff and let downstream code
- // handle the changes and updates.
- err := json.Unmarshal([]byte(oldValue), &old)
- if err != nil {
- return false
- }
-
- err = json.Unmarshal([]byte(newValue), &new)
- if err != nil {
- return false
- }
-
- return reflect.DeepEqual(old, new)
-}
-
-func queriesToMapStringInterface(c []client.QuestionQuery) ([]map[string]interface{}, error) {
- buf := new(bytes.Buffer)
- enc := json.NewEncoder(buf)
- enc.SetEscapeHTML(false)
- err := enc.Encode(c)
- if err != nil {
- return nil, err
- }
-
- msi := []map[string]interface{}{}
- err = json.Unmarshal(buf.Bytes(), &msi)
- if err != nil {
- return nil, err
- }
- return msi, nil
-}
diff --git a/main.go b/main.go
index 6d15f546..ef0c0798 100644
--- a/main.go
+++ b/main.go
@@ -1,12 +1,34 @@
package main
import (
- "github.com/hashicorp/terraform-plugin-sdk/v2/plugin"
+ "context"
+ "log"
+
+ "github.com/hashicorp/terraform-plugin-framework/providerserver"
"github.com/jupiterone/terraform-provider-jupiterone/jupiterone"
)
//go:generate go run github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs
+
+var (
+ // these will be set by the goreleaser configuration
+ // to appropriate values for the compiled binary
+ version string = "dev"
+
+ // goreleaser can also pass the specific commit if you want
+ // commit string = ""
+)
+
func main() {
- plugin.Serve(&plugin.ServeOpts{
- ProviderFunc: jupiterone.Provider})
+ err := providerserver.Serve(
+ context.Background(),
+ jupiterone.New(version),
+ providerserver.ServeOpts{
+ Address: "registry.terraform.io/jupiterone/jupiterone",
+ },
+ )
+
+ if err != nil {
+ log.Fatal(err)
+ }
}