Add credential library resource for Vault (#114)
* Integrate with Vault to retrieve and manage per session credentials Co-authored-by: Louis Ruch <louisruch@gmail.com>
This commit is contained in:
1 parent
7c73927d17
commit
4f0509c55d
20 files changed
+1433
-99
No files matched your search
@@ -0,0 +1,86 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "boundary_credential_library_vault Resource - terraform-provider-boundary"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
The credential library for Vault resource allows you to configure a Boundary credential library for Vault.
|
||||
---
|
||||
|
||||
# boundary_credential_library_vault (Resource)
|
||||
|
||||
The credential library for Vault resource allows you to configure a Boundary credential library for Vault.
|
||||
|
||||
## Example Usage
|
||||
|
||||
```terraform
|
||||
resource "boundary_scope" "org" {
|
||||
name = "organization_one"
|
||||
description = "My first scope!"
|
||||
scope_id = "global"
|
||||
auto_create_admin_role = true
|
||||
auto_create_default_role = true
|
||||
}
|
||||
|
||||
resource "boundary_scope" "project" {
|
||||
name = "project_one"
|
||||
description = "My first scope!"
|
||||
scope_id = boundary_scope.org.id
|
||||
auto_create_admin_role = true
|
||||
}
|
||||
|
||||
resource "boundary_credential_store_vault" "foo" {
|
||||
name = "foo"
|
||||
description = "My first Vault credential store!"
|
||||
address = "127.0.0.1"
|
||||
token = "s.0ufRo6XEGU2jOqnIr7OlFYP5"
|
||||
scope_id = boundary_scope.project.id
|
||||
}
|
||||
|
||||
resource "boundary_credential_library_vault" "foo" {
|
||||
name = "foo"
|
||||
description = "My first Vault credential library!"
|
||||
credential_store_id = boundary_credential_store_vault.foo.id
|
||||
path = "my/secret/foo"
|
||||
http_method = "GET"
|
||||
}
|
||||
|
||||
resource "boundary_credential_library_vault" "bar" {
|
||||
name = "bar"
|
||||
description = "My second Vault credential library!"
|
||||
credential_store_id = boundary_credential_store_vault.foo.id
|
||||
path = "my/secret/bar"
|
||||
http_method = "POST"
|
||||
request_body = <<EOT
|
||||
{
|
||||
"key": "Value",
|
||||
}
|
||||
EOT
|
||||
}
|
||||
```
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- **credential_store_id** (String) The ID of the credential store that this library belongs to.
|
||||
- **path** (String) The Vault path to query
|
||||
|
||||
### Optional
|
||||
|
||||
- **description** (String) The Vault credential library description.
|
||||
- **http_method** (String) The HTTP method to use when contacting Vault
|
||||
- **http_request_body** (String) The raw string to use in HTTP request to Vault
|
||||
- **name** (String) The Vault credential library name. Defaults to the resource name.
|
||||
|
||||
### Read-Only
|
||||
|
||||
- **id** (String) The ID of the Vault credential library.
|
||||
|
||||
## Import
|
||||
|
||||
Import is supported using the following syntax:
|
||||
|
||||
```shell
|
||||
terraform import boundary_credential_library_vault.foo <my-id>
|
||||
```
|
||||
@@ -0,0 +1,72 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "boundary_credential_store_vault Resource - terraform-provider-boundary"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
The credential store for Vault resource allows you to configure a Boundary credential store for Vault.
|
||||
---
|
||||
|
||||
# boundary_credential_store_vault (Resource)
|
||||
|
||||
The credential store for Vault resource allows you to configure a Boundary credential store for Vault.
|
||||
|
||||
## Example Usage
|
||||
|
||||
```terraform
|
||||
resource "boundary_scope" "org" {
|
||||
name = "organization_one"
|
||||
description = "My first scope!"
|
||||
scope_id = "global"
|
||||
auto_create_admin_role = true
|
||||
auto_create_default_role = true
|
||||
}
|
||||
|
||||
resource "boundary_scope" "project" {
|
||||
name = "project_one"
|
||||
description = "My first scope!"
|
||||
scope_id = boundary_scope.org.id
|
||||
auto_create_admin_role = true
|
||||
}
|
||||
|
||||
resource "boundary_credential_store_vault" "example" {
|
||||
name = "foo"
|
||||
description = "My first Vault credential store!"
|
||||
address = "127.0.0.1"
|
||||
token = "s.0ufRo6XEGU2jOqnIr7OlFYP5"
|
||||
scope_id = boundary_scope.project.id
|
||||
}
|
||||
```
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- **address** (String) The address to Vault server
|
||||
- **scope_id** (String) The scope for this credential store
|
||||
- **token** (String, Sensitive) The Vault token
|
||||
|
||||
### Optional
|
||||
|
||||
- **ca_cert** (String) The Vault CA certificate to use
|
||||
- **client_certificate** (String) The Vault client certificate
|
||||
- **client_certificate_key** (String, Sensitive) The Vault client certificate key
|
||||
- **description** (String) The Vault credential store description.
|
||||
- **name** (String) The Vault credential store name. Defaults to the resource name.
|
||||
- **namespace** (String) The namespace within Vault to use
|
||||
- **tls_server_name** (String) The Vault TLS server name
|
||||
- **tls_skip_verify** (Boolean) Whether or not to skip TLS verification
|
||||
|
||||
### Read-Only
|
||||
|
||||
- **client_certificate_key_hmac** (String) The Vault client certificate key hmac
|
||||
- **id** (String) The ID of the Vault credential store.
|
||||
- **token_hmac** (String) The Vault token hmac
|
||||
|
||||
## Import
|
||||
|
||||
Import is supported using the following syntax:
|
||||
|
||||
```shell
|
||||
terraform import boundary_credential_store_vault.foo <my-id>
|
||||
```
|
||||
@@ -33,6 +33,22 @@ resource "boundary_scope" "project" {
|
||||
auto_create_admin_role = true
|
||||
}
|
||||
|
||||
resource "boundary_credential_store_vault" "foo" {
|
||||
name = "vault_store"
|
||||
description = "My first Vault credential store!"
|
||||
address = "http://localhost:55001"
|
||||
token = "s.0ufRo6XEGU2jOqnIr7OlFYP5"
|
||||
scope_id = boundary_scope.project.id
|
||||
}
|
||||
|
||||
resource "boundary_credential_library_vault" "foo" {
|
||||
name = "vault_library"
|
||||
description = "My first Vault credential library!"
|
||||
credential_store_id = boundary_credential_store_vault.foo.id
|
||||
path = "database/creds/opened"
|
||||
http_method = "GET"
|
||||
}
|
||||
|
||||
resource "boundary_host_catalog" "foo" {
|
||||
name = "test"
|
||||
description = "test catalog"
|
||||
@@ -72,6 +88,9 @@ resource "boundary_target" "foo" {
|
||||
host_set_ids = [
|
||||
boundary_host_set.foo.id
|
||||
]
|
||||
credential_library_ids = [
|
||||
boundary_credential_library_vault.foo.id
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -85,6 +104,7 @@ resource "boundary_target" "foo" {
|
||||
|
||||
### Optional
|
||||
|
||||
- **credential_library_ids** (Set of String) A list of credential library ID's.
|
||||
- **default_port** (Number) The default port for this target.
|
||||
- **description** (String) The target description.
|
||||
- **host_set_ids** (Set of String) A list of host set ID's.
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
terraform import boundary_credential_library_vault.foo <my-id>
|
||||
@@ -0,0 +1,43 @@
|
||||
resource "boundary_scope" "org" {
|
||||
name = "organization_one"
|
||||
description = "My first scope!"
|
||||
scope_id = "global"
|
||||
auto_create_admin_role = true
|
||||
auto_create_default_role = true
|
||||
}
|
||||
|
||||
resource "boundary_scope" "project" {
|
||||
name = "project_one"
|
||||
description = "My first scope!"
|
||||
scope_id = boundary_scope.org.id
|
||||
auto_create_admin_role = true
|
||||
}
|
||||
|
||||
resource "boundary_credential_store_vault" "foo" {
|
||||
name = "foo"
|
||||
description = "My first Vault credential store!"
|
||||
address = "127.0.0.1"
|
||||
token = "s.0ufRo6XEGU2jOqnIr7OlFYP5"
|
||||
scope_id = boundary_scope.project.id
|
||||
}
|
||||
|
||||
resource "boundary_credential_library_vault" "foo" {
|
||||
name = "foo"
|
||||
description = "My first Vault credential library!"
|
||||
credential_store_id = boundary_credential_store_vault.foo.id
|
||||
path = "my/secret/foo"
|
||||
http_method = "GET"
|
||||
}
|
||||
|
||||
resource "boundary_credential_library_vault" "bar" {
|
||||
name = "bar"
|
||||
description = "My second Vault credential library!"
|
||||
credential_store_id = boundary_credential_store_vault.foo.id
|
||||
path = "my/secret/bar"
|
||||
http_method = "POST"
|
||||
request_body = <<EOT
|
||||
{
|
||||
"key": "Value",
|
||||
}
|
||||
EOT
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
terraform import boundary_credential_store_vault.foo <my-id>
|
||||
@@ -0,0 +1,22 @@
|
||||
resource "boundary_scope" "org" {
|
||||
name = "organization_one"
|
||||
description = "My first scope!"
|
||||
scope_id = "global"
|
||||
auto_create_admin_role = true
|
||||
auto_create_default_role = true
|
||||
}
|
||||
|
||||
resource "boundary_scope" "project" {
|
||||
name = "project_one"
|
||||
description = "My first scope!"
|
||||
scope_id = boundary_scope.org.id
|
||||
auto_create_admin_role = true
|
||||
}
|
||||
|
||||
resource "boundary_credential_store_vault" "example" {
|
||||
name = "foo"
|
||||
description = "My first Vault credential store!"
|
||||
address = "127.0.0.1"
|
||||
token = "s.0ufRo6XEGU2jOqnIr7OlFYP5"
|
||||
scope_id = boundary_scope.project.id
|
||||
}
|
||||
@@ -18,6 +18,22 @@ resource "boundary_scope" "project" {
|
||||
auto_create_admin_role = true
|
||||
}
|
||||
|
||||
resource "boundary_credential_store_vault" "foo" {
|
||||
name = "vault_store"
|
||||
description = "My first Vault credential store!"
|
||||
address = "http://localhost:55001"
|
||||
token = "s.0ufRo6XEGU2jOqnIr7OlFYP5"
|
||||
scope_id = boundary_scope.project.id
|
||||
}
|
||||
|
||||
resource "boundary_credential_library_vault" "foo" {
|
||||
name = "vault_library"
|
||||
description = "My first Vault credential library!"
|
||||
credential_store_id = boundary_credential_store_vault.foo.id
|
||||
path = "database/creds/opened"
|
||||
http_method = "GET"
|
||||
}
|
||||
|
||||
resource "boundary_host_catalog" "foo" {
|
||||
name = "test"
|
||||
description = "test catalog"
|
||||
@@ -57,4 +73,7 @@ resource "boundary_target" "foo" {
|
||||
host_set_ids = [
|
||||
boundary_host_set.foo.id
|
||||
]
|
||||
credential_library_ids = [
|
||||
boundary_credential_library_vault.foo.id
|
||||
]
|
||||
}
|
||||
@@ -13,17 +13,15 @@ require (
|
||||
github.com/agext/levenshtein v1.2.3 // indirect
|
||||
github.com/aliyun/alibaba-cloud-sdk-go v1.61.545 // indirect
|
||||
github.com/aws/aws-sdk-go v1.35.4 // indirect
|
||||
github.com/cenkalti/backoff/v3 v3.2.2 // indirect
|
||||
github.com/circonus-labs/circonusllhist v0.1.4 // indirect
|
||||
github.com/containerd/continuity v0.0.0-20200710164510-efbc4488d8fe // indirect
|
||||
github.com/coreos/go-oidc v2.2.1+incompatible // indirect
|
||||
github.com/golang/snappy v0.0.2 // indirect
|
||||
github.com/hashicorp/boundary v0.2.2
|
||||
github.com/hashicorp/boundary/api v0.0.10
|
||||
github.com/hashicorp/boundary/sdk v0.0.4
|
||||
github.com/hashicorp/cap v0.0.0-20210518163718-e72205e8eaae
|
||||
github.com/hashicorp/boundary v0.3.1-0.20210623022626-df35699c4ef2
|
||||
github.com/hashicorp/boundary/api v0.0.12-0.20210623022626-df35699c4ef2
|
||||
github.com/hashicorp/boundary/sdk v0.0.5-0.20210623022626-df35699c4ef2
|
||||
github.com/hashicorp/cap v0.1.0
|
||||
github.com/hashicorp/go-immutable-radix v1.3.0 // indirect
|
||||
github.com/hashicorp/go-kms-wrapping v0.6.1
|
||||
github.com/hashicorp/go-kms-wrapping v0.6.2
|
||||
github.com/hashicorp/golang-lru v0.5.4 // indirect
|
||||
github.com/hashicorp/hcl/v2 v2.6.0 // indirect
|
||||
github.com/hashicorp/terraform-plugin-docs v0.4.0
|
||||
@@ -33,11 +31,10 @@ require (
|
||||
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
|
||||
github.com/oklog/run v1.1.0 // indirect
|
||||
github.com/oracle/oci-go-sdk v24.3.0+incompatible // indirect
|
||||
github.com/pquerna/cachecontrol v0.0.0-20201205024021-ac21108117ac // indirect
|
||||
github.com/prometheus/common v0.14.0 // indirect
|
||||
github.com/prometheus/procfs v0.2.0 // indirect
|
||||
github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c // indirect
|
||||
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
gopkg.in/ini.v1 v1.62.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
)
|
||||
@@ -158,10 +158,8 @@ github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmV
|
||||
github.com/armon/go-metrics v0.3.0/go.mod h1:zXjbSimjXTd7vOpY8B0/2LpvNvDoXBuplAD+gJD3GYs=
|
||||
github.com/armon/go-metrics v0.3.3/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc=
|
||||
github.com/armon/go-metrics v0.3.4/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc=
|
||||
github.com/armon/go-metrics v0.3.6 h1:x/tmtOF9cDBoXH7XoAGOz2qqm1DknFD1590XmD/DUJ8=
|
||||
github.com/armon/go-metrics v0.3.6/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc=
|
||||
github.com/armon/go-metrics v0.3.8 h1:oOxq3KPj0WhCuy50EhzwiyMyG2ovRQZpZLXQuOh2a/M=
|
||||
github.com/armon/go-metrics v0.3.8/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc=
|
||||
github.com/armon/go-metrics v0.3.9 h1:O2sNqxBdvq8Eq5xmzljcYzAORli6RWCvEym4cJf9m18=
|
||||
github.com/armon/go-metrics v0.3.9/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc=
|
||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||
github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI=
|
||||
github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||
@@ -198,8 +196,6 @@ github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
|
||||
github.com/cenkalti/backoff/v3 v3.0.0/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs=
|
||||
github.com/cenkalti/backoff/v3 v3.2.2 h1:cfUAAO3yvKMYKPrvhDuHSwQnhZNk/RMHKdZqKTxfm6M=
|
||||
github.com/cenkalti/backoff/v3 v3.2.2/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs=
|
||||
github.com/cenkalti/backoff/v4 v4.0.2/go.mod h1:eEew/i+1Q6OrCDZh3WiXYv3+nJwBASZ8Bog/87DQnVg=
|
||||
github.com/cenkalti/backoff/v4 v4.1.0 h1:c8LkOFQTzuO0WBM/ae5HdGQuZPfPxp7lqBRwQRm4fSc=
|
||||
github.com/cenkalti/backoff/v4 v4.1.0/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
|
||||
@@ -246,8 +242,6 @@ github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDG
|
||||
github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc=
|
||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/go-oidc v2.2.1+incompatible h1:mh48q/BqXqgjVHpy2ZY7WnWAbenxRjsz9N1i1YxjHAk=
|
||||
github.com/coreos/go-oidc v2.2.1+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
|
||||
github.com/coreos/go-oidc/v3 v3.0.0 h1:/mAA0XMgYJw2Uqm7WKGCsKnjitE/+A0FFbOmiRJm7LQ=
|
||||
github.com/coreos/go-oidc/v3 v3.0.0/go.mod h1:rEJ/idjfUyfkBit1eI1fvyr+64/g9dcKpAm8MJMesvo=
|
||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
@@ -261,6 +255,7 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:ma
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw=
|
||||
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/cznic/mathutil v0.0.0-20180504122225-ca4c9f2c1369/go.mod h1:e6NPNENfs9mPDVNRekM7lKScauxd5kXTr1Mfyig6TDM=
|
||||
github.com/danieljoos/wincred v1.0.2/go.mod h1:SnuYRW9lp1oJrZX/dXJqr0cPK5gYXqx3EJbmjhLdK9U=
|
||||
@@ -310,10 +305,9 @@ github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 h1:Yzb9+7DP
|
||||
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
|
||||
github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg=
|
||||
github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
|
||||
github.com/fatih/color v1.11.0 h1:l4iX0RqNnx/pU7rY2DB/I+znuYY0K3x6Ywac6EIr0PA=
|
||||
github.com/fatih/color v1.11.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
|
||||
github.com/fatih/color v1.12.0 h1:mRhaKNwANqRgUBGKmnI5ZxEk7QXmjQeCcuYFMX2bfcc=
|
||||
github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
|
||||
github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
|
||||
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
|
||||
github.com/favadi/protoc-go-inject-tag v1.1.0/go.mod h1:13goAxKedbu5IbfI0n2wIKh1CCgZOwPNZQd0igDWvko=
|
||||
@@ -364,8 +358,9 @@ github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LB
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/go-test/deep v1.0.2-0.20181118220953-042da051cf31/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
|
||||
github.com/go-test/deep v1.0.2/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
|
||||
github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68=
|
||||
github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
|
||||
github.com/go-test/deep v1.0.4 h1:u2CU3YKy9I2pmu9pX0eq50wCgjfGIt539SqR7FbHiho=
|
||||
github.com/go-test/deep v1.0.4/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
|
||||
github.com/gobuffalo/here v0.6.0/go.mod h1:wAG085dHOYqUpf+Ap+WOdrPTp5IYcDAs/x7PLa8Y5fM=
|
||||
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo=
|
||||
github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
|
||||
@@ -441,8 +436,9 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
|
||||
github.com/google/go-metrics-stackdriver v0.2.0 h1:rbs2sxHAPn2OtUj9JdR/Gij1YKGl0BTVD0augB+HEjE=
|
||||
github.com/google/go-metrics-stackdriver v0.2.0/go.mod h1:KLcPyp3dWJAFD+yHisGlJSZktIsTjb50eB72U2YZ9K0=
|
||||
@@ -490,18 +486,16 @@ github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.3.0 h1:IvO4FbbQL6n3v3M1rQNobZ61SGL0gJLdvKA5KETM7Xs=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.3.0/go.mod h1:d2gYTOTUQklu06xp0AJYYmRdTVU1VKrqhkYfYag2L08=
|
||||
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4=
|
||||
github.com/hashicorp/boundary v0.2.1 h1:I4O1BrqR1R6O449k1b7FGCOFXwgRKxhZoK8CltvsBoo=
|
||||
github.com/hashicorp/boundary v0.2.1/go.mod h1:FwX0UmYaj3OFlKrhhaMcT8FvEZk/y/1AnZgxsk4xQQM=
|
||||
github.com/hashicorp/boundary v0.2.2 h1:Gel7cjlcild1AZGVfR+4d28MmqnTQ6F/CTOAyEAFyis=
|
||||
github.com/hashicorp/boundary v0.2.2/go.mod h1:Gd+jRjPuPqFHZLlA7+llzK4BlHxilp37cJDp7xswAGU=
|
||||
github.com/hashicorp/boundary/api v0.0.10 h1:WdKR5dZ7FvAW0QG05jyKWt9ESu1vT/4E2LIDiSVJ1ZI=
|
||||
github.com/hashicorp/boundary/api v0.0.10/go.mod h1:mZfLjpD0hU2YMopuobjh+ZmWMRLl9sooiPr46gi64i4=
|
||||
github.com/hashicorp/boundary/sdk v0.0.4 h1:l3uuXOL5ZQwYc63Bm8sLY36XGUlIN/4Q2r2SqkmGTyw=
|
||||
github.com/hashicorp/boundary v0.3.1-0.20210623022626-df35699c4ef2 h1:hJ8qTqevchi/REQy7JEDS1phXlAWs+2j1Kl8b3XfCiI=
|
||||
github.com/hashicorp/boundary v0.3.1-0.20210623022626-df35699c4ef2/go.mod h1:wTfjDEGdal4/942BfnJ5yXDjB+LFhsrYY0aah4Q6FOk=
|
||||
github.com/hashicorp/boundary/api v0.0.11/go.mod h1:mZfLjpD0hU2YMopuobjh+ZmWMRLl9sooiPr46gi64i4=
|
||||
github.com/hashicorp/boundary/api v0.0.12-0.20210623022626-df35699c4ef2 h1:UTlcgB8eCeyPX7HrsmyNmsBHTuLM9/ZNgwvEMYgrd2s=
|
||||
github.com/hashicorp/boundary/api v0.0.12-0.20210623022626-df35699c4ef2/go.mod h1:mZfLjpD0hU2YMopuobjh+ZmWMRLl9sooiPr46gi64i4=
|
||||
github.com/hashicorp/boundary/sdk v0.0.4/go.mod h1:MQ8FJhseJrKpwvFDTn+AUAcJ1vdk1NKUxk7DxQgH7oQ=
|
||||
github.com/hashicorp/cap v0.0.0-20210408110729-0dd65efe5473 h1:qEikB8/ychrgsll9feuGjVLt0qo5oktfyTWi7BLsUrg=
|
||||
github.com/hashicorp/cap v0.0.0-20210408110729-0dd65efe5473/go.mod h1:hjMYKmFvk9AOL69NbqrahCHoMPZHRWqvRcdr7ciPU7g=
|
||||
github.com/hashicorp/cap v0.0.0-20210518163718-e72205e8eaae h1:8tmylghjLoNNQdJdDddF54L38LakfoC/YfxJ7dGsAIE=
|
||||
github.com/hashicorp/cap v0.0.0-20210518163718-e72205e8eaae/go.mod h1:VfBvK2ULRyqsuqAnjgZl7HJ7/CGMC7ro4H5eXiZuun8=
|
||||
github.com/hashicorp/boundary/sdk v0.0.5-0.20210623022626-df35699c4ef2 h1:CPkNe8ipxlewl9UJ8GABAEBzm2ira5F9B8VK7CpkBTI=
|
||||
github.com/hashicorp/boundary/sdk v0.0.5-0.20210623022626-df35699c4ef2/go.mod h1:MQ8FJhseJrKpwvFDTn+AUAcJ1vdk1NKUxk7DxQgH7oQ=
|
||||
github.com/hashicorp/cap v0.1.0 h1:uBDfu9NDvmotza/mJW6vtQId+VYid9ztlTnDCW6YUWU=
|
||||
github.com/hashicorp/cap v0.1.0/go.mod h1:VfBvK2ULRyqsuqAnjgZl7HJ7/CGMC7ro4H5eXiZuun8=
|
||||
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
|
||||
github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE=
|
||||
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
|
||||
@@ -511,8 +505,9 @@ github.com/hashicorp/dbassert v0.0.0-20200930125617-6218396928df/go.mod h1:+B5eZ
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
|
||||
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/go-bexpr v0.1.7 h1:z48qzCgJkvdnMO/LDy3XHNyCyxnHiFGx9uTKLv0jW2Y=
|
||||
github.com/hashicorp/go-bexpr v0.1.7/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0=
|
||||
github.com/hashicorp/eventlogger v0.0.0-20210523164657-c216620e1746/go.mod h1:LG0lqGlYKC9FD5m5Umh7FW8SeJlciNUZv400J4+j094=
|
||||
github.com/hashicorp/go-bexpr v0.1.8 h1:ETfuLF1bBAuHW/Qg6l1xCdV8WJ7lfatLtJ1N1w0IsfE=
|
||||
github.com/hashicorp/go-bexpr v0.1.8/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0=
|
||||
github.com/hashicorp/go-checkpoint v0.5.0 h1:MFYpPZCnQqQTE18jFwSII6eUQrD/oxMFp3mlgcqk5mU=
|
||||
github.com/hashicorp/go-checkpoint v0.5.0/go.mod h1:7nfLNL10NsxqO4iWuW6tWW0HjZuDrwkBuEQsVcpCOgg=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
||||
@@ -531,8 +526,6 @@ github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39
|
||||
github.com/hashicorp/go-hclog v0.13.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
|
||||
github.com/hashicorp/go-hclog v0.14.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
|
||||
github.com/hashicorp/go-hclog v0.15.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
|
||||
github.com/hashicorp/go-hclog v0.16.0 h1:uCeOEwSWGMwhJUdpUjk+1cVKIEfGu2/1nFXukimi2MU=
|
||||
github.com/hashicorp/go-hclog v0.16.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
|
||||
github.com/hashicorp/go-hclog v0.16.1 h1:IVQwpTGNRRIHafnTs2dQLIk4ENtneRIEEJWOVDqz99o=
|
||||
github.com/hashicorp/go-hclog v0.16.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
|
||||
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||
@@ -540,8 +533,9 @@ github.com/hashicorp/go-immutable-radix v1.1.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjh
|
||||
github.com/hashicorp/go-immutable-radix v1.3.0 h1:8exGP7ego3OmkfksihtSouGMZ+hQrhxx+FVELeXpVPE=
|
||||
github.com/hashicorp/go-immutable-radix v1.3.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||
github.com/hashicorp/go-kms-wrapping v0.5.12/go.mod h1:yVIWtGOTh/cdGc++/NOlXLus0hJ19Lz4iFrpF6WsZh4=
|
||||
github.com/hashicorp/go-kms-wrapping v0.6.1 h1:QwG2nGi3BXa8xpU5BRWKY5z6Xg1aqAErC9tAvDfMA3Y=
|
||||
github.com/hashicorp/go-kms-wrapping v0.6.1/go.mod h1:lxD7e9q7ZyCtDEP+tnMevsEvw3M0gmZnneAgv8BaO1Q=
|
||||
github.com/hashicorp/go-kms-wrapping v0.6.2 h1:ryj5jVvecszFG4yL4/0jQxGK6g1LCNVLWRH8ZXjrYbY=
|
||||
github.com/hashicorp/go-kms-wrapping v0.6.2/go.mod h1:aUzqzg9WEm5mEcQcNI431QLmxKzGL80cvwGQyVSP15Y=
|
||||
github.com/hashicorp/go-kms-wrapping/entropy v0.1.0/go.mod h1:d1g9WGtAunDNpek8jUIEJnBlbgKS1N2Q61QkHiZyR1g=
|
||||
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
|
||||
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
||||
@@ -555,7 +549,6 @@ github.com/hashicorp/go-plugin v1.4.0/go.mod h1:5fGEH17QVwTTcR0zV7yhDPLLmFX9YSZ3
|
||||
github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=
|
||||
github.com/hashicorp/go-retryablehttp v0.6.2/go.mod h1:gEx6HMUGxYYhJScX7W1Il64m6cc2C1mDaW3NQ9sY1FY=
|
||||
github.com/hashicorp/go-retryablehttp v0.6.6/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
|
||||
github.com/hashicorp/go-retryablehttp v0.6.8 h1:92lWxgpa+fF3FozM4B3UZtHZMJX8T5XT+TFdCxsPyWs=
|
||||
github.com/hashicorp/go-retryablehttp v0.6.8/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
|
||||
github.com/hashicorp/go-retryablehttp v0.7.0 h1:eu1EI/mbirUgP5C8hVsTNaGZreBDlYiwC1FZWkvQPQ4=
|
||||
github.com/hashicorp/go-retryablehttp v0.7.0/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
|
||||
@@ -596,8 +589,8 @@ github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0m
|
||||
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
|
||||
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
|
||||
github.com/hashicorp/shared-secure-libs v0.0.4/go.mod h1:xhtA0FH6AYYFOy0sir7u0O0zzdLi7ofU6oWxy+gjnuc=
|
||||
github.com/hashicorp/shared-secure-libs v0.0.5 h1:qHd+wxqgvW+INIMU0uzF/Sw3+iaqAOk5SrcXzsThlvY=
|
||||
github.com/hashicorp/shared-secure-libs v0.0.5/go.mod h1:xhtA0FH6AYYFOy0sir7u0O0zzdLi7ofU6oWxy+gjnuc=
|
||||
github.com/hashicorp/shared-secure-libs v0.0.6 h1:QH22a9VbBP3b7v/e5In7uHTanimGPzq4oj0QHtVHhWI=
|
||||
github.com/hashicorp/shared-secure-libs v0.0.6/go.mod h1:PH51kNtHA6kYV5Z8E3TOJM634iyp7IIxAMfLh0Dp35o=
|
||||
github.com/hashicorp/terraform-exec v0.12.0/go.mod h1:SGhto91bVRlgXQWcJ5znSz+29UZIa8kpBbkGwQ+g9E8=
|
||||
github.com/hashicorp/terraform-exec v0.13.3 h1:R6L2mNpDGSEqtLrSONN8Xth0xYwNrnEVzDz6LF/oJPk=
|
||||
github.com/hashicorp/terraform-exec v0.13.3/go.mod h1:SSg6lbUsVB3DmFyCPjBPklqf6EYGX0TlQ6QTxOlikDU=
|
||||
@@ -612,8 +605,9 @@ github.com/hashicorp/terraform-plugin-sdk/v2 v2.6.1 h1:OZ+Q7irJBDhb71XzMSPGJvTIW
|
||||
github.com/hashicorp/terraform-plugin-sdk/v2 v2.6.1/go.mod h1:72j8cKfs9IirGhPMXJJWLTvRUK4zATtrCOvs2avDlo8=
|
||||
github.com/hashicorp/vault/api v1.0.5-0.20200514164214-89b1987e38c2/go.mod h1:P8A7gn1a6j/7qQ4zOaWI6FC/Q9jQWEBRTOwZH33tC9o=
|
||||
github.com/hashicorp/vault/api v1.0.5-0.20200519221902-385fac77e20f/go.mod h1:euTFbi2YJgwcju3imEt919lhJKF68nN1cQPq3aA+kBE=
|
||||
github.com/hashicorp/vault/api v1.0.5-0.20200805123347-1ef507638af6 h1:ChHpobQse3kjVX7GmbpUFVqaMTf4lb1gcLrJltsUmS4=
|
||||
github.com/hashicorp/vault/api v1.0.5-0.20200805123347-1ef507638af6/go.mod h1:R3Umvhlxi2TN7Ex2hzOowyeNb+SfbVWI973N+ctaFMk=
|
||||
github.com/hashicorp/vault/api v1.1.0 h1:QcxC7FuqEl0sZaIjcXB/kNEeBa0DH5z57qbWBvZwLC4=
|
||||
github.com/hashicorp/vault/api v1.1.0/go.mod h1:R3Umvhlxi2TN7Ex2hzOowyeNb+SfbVWI973N+ctaFMk=
|
||||
github.com/hashicorp/vault/sdk v0.1.13/go.mod h1:B+hVj7TpuQY1Y/GPbCpffmgd+tSEwvhkWnjtSYCaS2M=
|
||||
github.com/hashicorp/vault/sdk v0.1.14-0.20200514144402-4bfac290c352/go.mod h1:WX57W2PwkrOPQ6rVQk+dy5/htHIaB4aBM70EwKThu10=
|
||||
github.com/hashicorp/vault/sdk v0.1.14-0.20200514164214-89b1987e38c2/go.mod h1:WX57W2PwkrOPQ6rVQk+dy5/htHIaB4aBM70EwKThu10=
|
||||
@@ -762,8 +756,6 @@ github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.6.0/go.mod h1:4vXEAYvW1fRQ2/FhZ78H73A60MHw1geSm145z2mdY1g=
|
||||
github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lib/pq v1.10.0 h1:Zx5DJFEYQXio93kgXnQ09fXNiUKsqv4OUEu2UtGcB1E=
|
||||
github.com/lib/pq v1.10.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lib/pq v1.10.2 h1:AqzbZs4ZoCBp+GtejcpCpcxM3zlSMx29dXbUSeVtJb8=
|
||||
github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
|
||||
@@ -900,7 +892,6 @@ github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnh
|
||||
github.com/oracle/oci-go-sdk v12.5.0+incompatible/go.mod h1:VQb79nF8Z2cwLkLS35ukwStZIg5F66tcBccjip/j888=
|
||||
github.com/oracle/oci-go-sdk v24.3.0+incompatible h1:x4mcfb4agelf1O4/1/auGlZ1lr97jXRSSN5MxTgG/zU=
|
||||
github.com/oracle/oci-go-sdk v24.3.0+incompatible/go.mod h1:VQb79nF8Z2cwLkLS35ukwStZIg5F66tcBccjip/j888=
|
||||
github.com/ory/dockertest/v3 v3.6.0 h1:I6KNJ6izxGduLACQii2SP/g7GN0JM9Xfaik6aAVaw6Y=
|
||||
github.com/ory/dockertest/v3 v3.6.0/go.mod h1:4ZOpj8qBUmh8fcBSVzkH2bws2s91JdGvHUqan4GHEuQ=
|
||||
github.com/ory/dockertest/v3 v3.6.5 h1:mhNKFeVEHuvaYW+/u+59mLzM/6XXGjpaet/yApgv+yc=
|
||||
github.com/ory/dockertest/v3 v3.6.5/go.mod h1:iYKQSRlYrt/2s5fJWYdB98kCQG6g/LjBMvzEYii63vg=
|
||||
@@ -932,8 +923,6 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
|
||||
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
||||
github.com/posener/complete v1.2.3 h1:NP0eAhjcjImqslEwo/1hq7gpajME0fTLTezBKDqfXqo=
|
||||
github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s=
|
||||
github.com/pquerna/cachecontrol v0.0.0-20201205024021-ac21108117ac h1:jWKYCNlX4J5s8M0nHYkh7Y7c9gRVDEb3mq51j5J0F5M=
|
||||
github.com/pquerna/cachecontrol v0.0.0-20201205024021-ac21108117ac/go.mod h1:hoLfEwdY11HjRfKFH6KqnPsfxlo3BP6bJehpDv8t6sQ=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=
|
||||
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
|
||||
@@ -1023,6 +1012,7 @@ github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkU
|
||||
github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||
github.com/spf13/cobra v1.0.1-0.20201006035406-b97b5ead31f7/go.mod h1:yk5b0mALVusDL5fMM6Rd1wgnoO5jUPhwsQ6LQAJTidQ=
|
||||
github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI=
|
||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||
github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
@@ -1048,6 +1038,7 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||
github.com/tencentcloud/tencentcloud-sdk-go v1.0.162/go.mod h1:asUz5BPXxgoPGaRgZaVm1iGcUAuHyYUo1nXqKa83cvI=
|
||||
github.com/tencentcloud/tencentcloud-sdk-go v3.0.171+incompatible/go.mod h1:0PfYow01SHPMhKY31xa+EFz2RStxIqj6JFAJS+IkCi4=
|
||||
github.com/tidwall/pretty v0.0.0-20180105212114-65a9db5fad51/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
github.com/tj/assert v0.0.0-20171129193455-018094318fb0/go.mod h1:mZ9/Rh9oLWpLLDRpvE+3b7gP/C2YyLFYxNmcLnPTMe0=
|
||||
@@ -1118,8 +1109,10 @@ go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/atomic v1.8.0 h1:CUhrE4N1rqSE6FM9ecihEjRkLQu8cDfgDyoOs83mEY4=
|
||||
go.uber.org/atomic v1.8.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/goleak v1.0.0/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
|
||||
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
|
||||
@@ -1155,7 +1148,6 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
|
||||
golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 h1:It14KIkyBFYkHkwZ7k45minvA9aorojkyjGk9KJ5B/w=
|
||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a h1:kr2P4QFmQr29mSLA43kwrOcgcReGTfbE9N577tCTuBc=
|
||||
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
|
||||
@@ -1190,8 +1182,8 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB
|
||||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.0 h1:8pl+sMODzuvGJkmj2W4kZihvVb5mKm8pB/X44PIQHv8=
|
||||
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180530234432-1e491301e022/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@@ -1245,7 +1237,6 @@ golang.org/x/net v0.0.0-20201029221708-28c70e62bb1d/go.mod h1:sp8m0HH+o8qH0wwXwY
|
||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210326060303-6b1517762897 h1:KrsHThm5nFk34YtATK1LsThyGhGbGe1olrte/HInHvs=
|
||||
golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20210510120150-4163338589ed h1:p9UgmWI9wKpfYmgaV/IZKGdXc5qEK45tDwwwDyjS26I=
|
||||
@@ -1331,27 +1322,24 @@ 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-20201029080932-201ba4db2418/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210324051608-47abb6519492 h1:Paq34FxTluEPvVyayQqMPgHm+vTOrIifmcYxFBx9TLg=
|
||||
golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210514084401-e8d321eab015 h1:hZR0X1kPW+nwyJ9xRxqZk1vx5RUObAPBdKVvXPDUH/E=
|
||||
golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE=
|
||||
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210503060354-a79de5458b56 h1:b8jxX3zqjpqb2LklXPzKSGJhzyxCOZSz8ncv8Nv+y7w=
|
||||
golang.org/x/term v0.0.0-20210503060354-a79de5458b56/go.mod h1:tfny5GFUkzUvx4ps4ajbZsCe5lw1metzhBm9T3x7oIY=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ=
|
||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
@@ -1386,6 +1374,7 @@ golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtn
|
||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
@@ -1426,9 +1415,8 @@ golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82u
|
||||
golang.org/x/tools v0.0.0-20201002184944-ecd9fd270d5d/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
|
||||
golang.org/x/tools v0.0.0-20210101214203-2dba1e4ea05c/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY=
|
||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.3 h1:L69ShwSZEyCsLKoAxDKeMvLDZkumEe8gXUZAjab0tX8=
|
||||
golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
@@ -1541,10 +1529,8 @@ google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv
|
||||
google.golang.org/grpc v1.35.0-dev.0.20201218190559-666aea1fb34c/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.37.0 h1:uSZWeQJX5j11bIQ4AJoj+McDBo29cY1MCoC1wO3ts+c=
|
||||
google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
||||
google.golang.org/grpc v1.37.1 h1:ARnQJNWxGyYJpdf/JXscNlQr/uv607ZPU9Z7ogHi+iI=
|
||||
google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
||||
google.golang.org/grpc v1.38.0 h1:/9BgsAsa5nWe26HqOlvlgJnqBuktYOLCgjCPqsa56W0=
|
||||
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.0.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
|
||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
package provider
|
||||
|
||||
const (
|
||||
// Key used for common SDK ID resource attribute
|
||||
// IDKey is used for common SDK ID resource attribute
|
||||
IDKey = "id"
|
||||
// Key used for common "name" resource attribute
|
||||
// NameKey is used for common "name" resource attribute
|
||||
NameKey = "name"
|
||||
// Key used for common "description" resource attribute
|
||||
// DescriptionKey is used for common "description" resource attribute
|
||||
DescriptionKey = "description"
|
||||
// Key used for common "scope_id" resource attribute
|
||||
// ScopeIdKey is used for common "scope_id" resource attribute
|
||||
ScopeIdKey = "scope_id"
|
||||
// Key used for common "type" resource attribute
|
||||
// TypeKey is used for common "type" resource attribute
|
||||
TypeKey = "type"
|
||||
// Key used for common "host_catalog_id" resource attribute
|
||||
// HostCatalogIdKey is used for common "host_catalog_id" resource attribute
|
||||
HostCatalogIdKey = "host_catalog_id"
|
||||
// Key used for common "auth_method_id" resource attribute
|
||||
// AuthMethodIdKey is used for common "auth_method_id" resource attribute
|
||||
AuthMethodIdKey = "auth_method_id"
|
||||
)
|
||||
@@ -54,20 +54,22 @@ func New() *schema.Provider {
|
||||
},
|
||||
},
|
||||
ResourcesMap: map[string]*schema.Resource{
|
||||
"boundary_account": resourceAccount(),
|
||||
"boundary_account_password": resourceAccountPassword(),
|
||||
"boundary_account_oidc": resourceAccountOidc(),
|
||||
"boundary_auth_method": resourceAuthMethod(),
|
||||
"boundary_auth_method_password": resourceAuthMethodPassword(),
|
||||
"boundary_auth_method_oidc": resourceAuthMethodOidc(),
|
||||
"boundary_group": resourceGroup(),
|
||||
"boundary_host": resourceHost(),
|
||||
"boundary_host_catalog": resourceHostCatalog(),
|
||||
"boundary_host_set": resourceHostset(),
|
||||
"boundary_role": resourceRole(),
|
||||
"boundary_scope": resourceScope(),
|
||||
"boundary_target": resourceTarget(),
|
||||
"boundary_user": resourceUser(),
|
||||
"boundary_account": resourceAccount(),
|
||||
"boundary_account_password": resourceAccountPassword(),
|
||||
"boundary_account_oidc": resourceAccountOidc(),
|
||||
"boundary_auth_method": resourceAuthMethod(),
|
||||
"boundary_auth_method_password": resourceAuthMethodPassword(),
|
||||
"boundary_auth_method_oidc": resourceAuthMethodOidc(),
|
||||
"boundary_credential_library_vault": resourceCredentialLibraryVault(),
|
||||
"boundary_credential_store_vault": resourceCredentialStoreVault(),
|
||||
"boundary_group": resourceGroup(),
|
||||
"boundary_host": resourceHost(),
|
||||
"boundary_host_catalog": resourceHostCatalog(),
|
||||
"boundary_host_set": resourceHostset(),
|
||||
"boundary_role": resourceRole(),
|
||||
"boundary_scope": resourceScope(),
|
||||
"boundary_target": resourceTarget(),
|
||||
"boundary_user": resourceUser(),
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ var (
|
||||
tcPassword = "passpass"
|
||||
tcPAUM = "ampw_0000000000"
|
||||
tcConfig = []controller.Option{
|
||||
controller.WithDefaultAuthMethodId(tcPAUM),
|
||||
controller.WithDefaultPasswordAuthMethodId(tcPAUM),
|
||||
controller.WithDefaultLoginName(tcLoginName),
|
||||
controller.WithDefaultPassword(tcPassword),
|
||||
}
|
||||
|
||||
@@ -0,0 +1,237 @@
|
||||
package provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/hashicorp/boundary/api"
|
||||
"github.com/hashicorp/boundary/api/credentiallibraries"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
)
|
||||
|
||||
const (
|
||||
credentialStoreIdKey = "credential_store_id"
|
||||
credentialLibraryVaultHttpMethodKey = "http_method"
|
||||
credentialLibraryVaultHttpRequestBodyKey = "http_request_body"
|
||||
credentialLibraryVaultPathKey = "path"
|
||||
)
|
||||
|
||||
var libraryVaultAttrs = []string{
|
||||
credentialLibraryVaultHttpMethodKey,
|
||||
credentialLibraryVaultHttpRequestBodyKey,
|
||||
credentialLibraryVaultPathKey,
|
||||
}
|
||||
|
||||
func resourceCredentialLibraryVault() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
Description: "The credential library for Vault resource allows you to configure a Boundary credential library for Vault.",
|
||||
|
||||
CreateContext: resourceCredentialLibraryCreateVault,
|
||||
ReadContext: resourceCredentialLibraryReadVault,
|
||||
UpdateContext: resourceCredentialLibraryUpdateVault,
|
||||
DeleteContext: resourceCredentialLibraryDeleteVault,
|
||||
Importer: &schema.ResourceImporter{
|
||||
StateContext: schema.ImportStatePassthroughContext,
|
||||
},
|
||||
|
||||
Schema: map[string]*schema.Schema{
|
||||
IDKey: {
|
||||
Description: "The ID of the Vault credential library.",
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
NameKey: {
|
||||
Description: "The Vault credential library name. Defaults to the resource name.",
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
DescriptionKey: {
|
||||
Description: "The Vault credential library description.",
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
credentialStoreIdKey: {
|
||||
Description: "The ID of the credential store that this library belongs to.",
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
credentialLibraryVaultHttpMethodKey: {
|
||||
Description: "The HTTP method to use when contacting Vault",
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
credentialLibraryVaultHttpRequestBodyKey: {
|
||||
Description: "The raw string to use in HTTP request to Vault",
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
credentialLibraryVaultPathKey: {
|
||||
Description: "The Vault path to query",
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func setFromVaultCredentialLibraryResponseMap(d *schema.ResourceData, raw map[string]interface{}) error {
|
||||
if err := d.Set(NameKey, raw[NameKey]); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := d.Set(DescriptionKey, raw[DescriptionKey]); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := d.Set(credentialStoreIdKey, raw[credentialStoreIdKey]); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if attrsVal, ok := raw["attributes"]; ok {
|
||||
attrs := attrsVal.(map[string]interface{})
|
||||
for _, v := range libraryVaultAttrs {
|
||||
if err := d.Set(v, attrs[v]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
d.SetId(raw["id"].(string))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceCredentialLibraryCreateVault(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
md := meta.(*metaData)
|
||||
|
||||
var opts []credentiallibraries.Option
|
||||
if v, ok := d.GetOk(NameKey); ok {
|
||||
opts = append(opts, credentiallibraries.WithName(v.(string)))
|
||||
}
|
||||
if v, ok := d.GetOk(DescriptionKey); ok {
|
||||
opts = append(opts, credentiallibraries.WithDescription(v.(string)))
|
||||
}
|
||||
if v, ok := d.GetOk(credentialLibraryVaultHttpMethodKey); ok {
|
||||
opts = append(opts, credentiallibraries.WithVaultCredentialLibraryHttpMethod(v.(string)))
|
||||
}
|
||||
if v, ok := d.GetOk(credentialLibraryVaultHttpRequestBodyKey); ok {
|
||||
opts = append(opts, credentiallibraries.WithVaultCredentialLibraryHttpRequestBody(v.(string)))
|
||||
}
|
||||
if v, ok := d.GetOk(credentialLibraryVaultPathKey); ok {
|
||||
opts = append(opts, credentiallibraries.WithVaultCredentialLibraryPath(v.(string)))
|
||||
}
|
||||
|
||||
var credentialStoreId string
|
||||
cid, ok := d.GetOk(credentialStoreIdKey)
|
||||
if ok {
|
||||
credentialStoreId = cid.(string)
|
||||
} else {
|
||||
return diag.Errorf("no credential store ID is set")
|
||||
}
|
||||
|
||||
client := credentiallibraries.NewClient(md.client)
|
||||
cr, err := client.Create(ctx, credentialStoreId, opts...)
|
||||
if err != nil {
|
||||
return diag.Errorf("error creating credential library: %v", err)
|
||||
}
|
||||
if cr == nil {
|
||||
return diag.Errorf("nil credential library after create")
|
||||
}
|
||||
|
||||
if err := setFromVaultCredentialLibraryResponseMap(d, cr.GetResponse().Map); err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceCredentialLibraryReadVault(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
md := meta.(*metaData)
|
||||
client := credentiallibraries.NewClient(md.client)
|
||||
|
||||
cr, err := client.Read(ctx, d.Id())
|
||||
if err != nil {
|
||||
if apiErr := api.AsServerError(err); apiErr != nil && apiErr.Response().StatusCode() == http.StatusNotFound {
|
||||
d.SetId("")
|
||||
return nil
|
||||
}
|
||||
return diag.Errorf("error reading credential library: %v", err)
|
||||
}
|
||||
if cr == nil {
|
||||
return diag.Errorf("credential library nil after read")
|
||||
}
|
||||
|
||||
if err := setFromVaultCredentialLibraryResponseMap(d, cr.GetResponse().Map); err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceCredentialLibraryUpdateVault(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
md := meta.(*metaData)
|
||||
client := credentiallibraries.NewClient(md.client)
|
||||
|
||||
var opts []credentiallibraries.Option
|
||||
if d.HasChange(NameKey) {
|
||||
opts = append(opts, credentiallibraries.DefaultName())
|
||||
nameVal, ok := d.GetOk(NameKey)
|
||||
if ok {
|
||||
opts = append(opts, credentiallibraries.WithName(nameVal.(string)))
|
||||
}
|
||||
}
|
||||
if d.HasChange(DescriptionKey) {
|
||||
opts = append(opts, credentiallibraries.DefaultDescription())
|
||||
descVal, ok := d.GetOk(DescriptionKey)
|
||||
if ok {
|
||||
opts = append(opts, credentiallibraries.WithDescription(descVal.(string)))
|
||||
}
|
||||
}
|
||||
if d.HasChange(credentialLibraryVaultHttpMethodKey) {
|
||||
opts = append(opts, credentiallibraries.DefaultVaultCredentialLibraryHttpMethod())
|
||||
v, ok := d.GetOk(credentialLibraryVaultHttpMethodKey)
|
||||
if ok {
|
||||
opts = append(opts, credentiallibraries.WithVaultCredentialLibraryHttpMethod(v.(string)))
|
||||
}
|
||||
}
|
||||
if d.HasChange(credentialLibraryVaultHttpRequestBodyKey) {
|
||||
opts = append(opts, credentiallibraries.DefaultVaultCredentialLibraryHttpRequestBody())
|
||||
v, ok := d.GetOk(credentialLibraryVaultHttpRequestBodyKey)
|
||||
if ok {
|
||||
opts = append(opts, credentiallibraries.WithVaultCredentialLibraryHttpRequestBody(v.(string)))
|
||||
}
|
||||
}
|
||||
if d.HasChange(credentialLibraryVaultPathKey) {
|
||||
v, ok := d.GetOk(credentialLibraryVaultPathKey)
|
||||
if ok {
|
||||
opts = append(opts, credentiallibraries.WithVaultCredentialLibraryPath(v.(string)))
|
||||
}
|
||||
}
|
||||
|
||||
if len(opts) > 0 {
|
||||
opts = append(opts, credentiallibraries.WithAutomaticVersioning(true))
|
||||
aur, err := client.Update(ctx, d.Id(), 0, opts...)
|
||||
if err != nil {
|
||||
return diag.Errorf("error updating credential library: %v", err)
|
||||
}
|
||||
|
||||
if err := setFromVaultCredentialLibraryResponseMap(d, aur.GetResponse().Map); err != nil {
|
||||
return diag.Errorf("error setting credential library from response: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceCredentialLibraryDeleteVault(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
md := meta.(*metaData)
|
||||
client := credentiallibraries.NewClient(md.client)
|
||||
|
||||
_, err := client.Delete(ctx, d.Id())
|
||||
if err != nil {
|
||||
return diag.Errorf("error deleting credential library: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
package provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/boundary/api"
|
||||
"github.com/hashicorp/boundary/api/credentiallibraries"
|
||||
"github.com/hashicorp/boundary/testing/controller"
|
||||
"github.com/hashicorp/boundary/testing/vault"
|
||||
"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"
|
||||
)
|
||||
|
||||
const (
|
||||
vaultCredResc = "boundary_credential_library_vault.example"
|
||||
vaultCredLibName = "foo"
|
||||
vaultCredLibDesc = "the foo"
|
||||
vaultCredLibPath = "/foo/bar"
|
||||
vaultCredLibMethodGet = "GET"
|
||||
vaultCredLibMethodPost = "POST"
|
||||
vaultCredLibRequestBody = "foobar"
|
||||
vaultCredLibStringUpdate = "_random"
|
||||
)
|
||||
|
||||
var vaultCredLibResource = fmt.Sprintf(`
|
||||
resource "boundary_credential_library_vault" "example" {
|
||||
name = "%s"
|
||||
description = "%s"
|
||||
credential_store_id = boundary_credential_store_vault.example.id
|
||||
path = "%s"
|
||||
http_method = "%s"
|
||||
}`, vaultCredLibName,
|
||||
vaultCredLibDesc,
|
||||
vaultCredLibPath,
|
||||
vaultCredLibMethodGet)
|
||||
|
||||
var vaultCredLibResourceUpdate = fmt.Sprintf(`
|
||||
resource "boundary_credential_library_vault" "example" {
|
||||
name = "%s"
|
||||
description = "%s"
|
||||
credential_store_id = boundary_credential_store_vault.example.id
|
||||
path = "%s"
|
||||
http_method = "%s"
|
||||
http_request_body = "%s"
|
||||
}`, vaultCredLibName+vaultCredLibStringUpdate,
|
||||
vaultCredLibDesc+vaultCredLibStringUpdate,
|
||||
vaultCredLibPath+vaultCredLibStringUpdate,
|
||||
vaultCredLibMethodPost,
|
||||
vaultCredLibRequestBody)
|
||||
|
||||
func TestAccCredentialLibraryVault(t *testing.T) {
|
||||
tc := controller.NewTestController(t, tcConfig...)
|
||||
defer tc.Shutdown()
|
||||
url := tc.ApiAddrs()[0]
|
||||
|
||||
vc := vault.NewTestVaultServer(t)
|
||||
_, token := vc.CreateToken(t)
|
||||
credStoreRes := vaultCredStoreResource(vc,
|
||||
vaultCredStoreName,
|
||||
vaultCredStoreDesc,
|
||||
vaultCredStoreNamespace,
|
||||
"www.original.com",
|
||||
token,
|
||||
true)
|
||||
|
||||
var provider *schema.Provider
|
||||
resource.Test(t, resource.TestCase{
|
||||
ProviderFactories: providerFactories(&provider),
|
||||
CheckDestroy: testAccCheckAuthMethodResourceDestroy(t, provider),
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
// create
|
||||
Config: testConfig(url, fooOrg, firstProjectFoo, credStoreRes, vaultCredLibResource),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
resource.TestCheckResourceAttr(vaultCredResc, NameKey, vaultCredLibName),
|
||||
resource.TestCheckResourceAttr(vaultCredResc, DescriptionKey, vaultCredLibDesc),
|
||||
resource.TestCheckResourceAttr(vaultCredResc, credentialLibraryVaultPathKey, vaultCredLibPath),
|
||||
resource.TestCheckResourceAttr(vaultCredResc, credentialLibraryVaultHttpMethodKey, vaultCredLibMethodGet),
|
||||
resource.TestCheckResourceAttr(vaultCredResc, credentialLibraryVaultHttpRequestBodyKey, ""),
|
||||
|
||||
testAccCheckCredentialLibraryVaultResourceExists(provider, vaultCredResc),
|
||||
),
|
||||
},
|
||||
importStep(vaultCredResc),
|
||||
|
||||
{
|
||||
// update
|
||||
Config: testConfig(url, fooOrg, firstProjectFoo, credStoreRes, vaultCredLibResourceUpdate),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
resource.TestCheckResourceAttr(vaultCredResc, NameKey, vaultCredLibName+vaultCredLibStringUpdate),
|
||||
resource.TestCheckResourceAttr(vaultCredResc, DescriptionKey, vaultCredLibDesc+vaultCredLibStringUpdate),
|
||||
resource.TestCheckResourceAttr(vaultCredResc, credentialLibraryVaultPathKey, vaultCredLibPath+vaultCredLibStringUpdate),
|
||||
resource.TestCheckResourceAttr(vaultCredResc, credentialLibraryVaultHttpMethodKey, vaultCredLibMethodPost),
|
||||
resource.TestCheckResourceAttr(vaultCredResc, credentialLibraryVaultHttpRequestBodyKey, vaultCredLibRequestBody),
|
||||
|
||||
testAccCheckCredentialLibraryVaultResourceExists(provider, vaultCredResc),
|
||||
),
|
||||
},
|
||||
importStep(vaultCredResc),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func testAccCheckCredentialLibraryVaultResourceExists(testProvider *schema.Provider, name string) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
rs, ok := s.RootModule().Resources[name]
|
||||
if !ok {
|
||||
return fmt.Errorf("not found: %s", name)
|
||||
}
|
||||
|
||||
id := rs.Primary.ID
|
||||
if id == "" {
|
||||
return fmt.Errorf("no ID is set")
|
||||
}
|
||||
|
||||
md := testProvider.Meta().(*metaData)
|
||||
c := credentiallibraries.NewClient(md.client)
|
||||
if _, err := c.Read(context.Background(), id); err != nil {
|
||||
return fmt.Errorf("got an error reading %q: %w", id, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func testAccCheckCredentialLibraryVaultResourceDestroy(t *testing.T, testProvider *schema.Provider) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
if testProvider.Meta() == nil {
|
||||
t.Fatal("got nil provider metadata")
|
||||
}
|
||||
md := testProvider.Meta().(*metaData)
|
||||
|
||||
for _, rs := range s.RootModule().Resources {
|
||||
switch rs.Type {
|
||||
case "boundary_credential_library_vault":
|
||||
id := rs.Primary.ID
|
||||
|
||||
c := credentiallibraries.NewClient(md.client)
|
||||
_, err := c.Read(context.Background(), id)
|
||||
if apiErr := api.AsServerError(err); apiErr == nil || apiErr.Response().StatusCode() != http.StatusNotFound {
|
||||
return fmt.Errorf("didn't get a 404 when reading destroyed vault credential library %q: %v", id, err)
|
||||
}
|
||||
|
||||
default:
|
||||
continue
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,346 @@
|
||||
package provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/hashicorp/boundary/api"
|
||||
"github.com/hashicorp/boundary/api/credentialstores"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
)
|
||||
|
||||
const (
|
||||
credentialStoreVaultAddressKey = "address"
|
||||
credentialStoreVaultNamespaceKey = "namespace"
|
||||
credentialStoreVaultCaCertKey = "ca_cert"
|
||||
credentialStoreVaultTlsServerNameKey = "tls_server_name"
|
||||
credentialStoreVaultTlsSkipVerifyKey = "tls_skip_verify"
|
||||
credentialStoreVaultTokenKey = "token"
|
||||
credentialStoreVaultTokenHmacKey = "token_hmac"
|
||||
credentialStoreVaultClientCertificateKey = "client_certificate"
|
||||
credentialStoreVaultClientCertificateKeyKey = "client_certificate_key"
|
||||
credentialStoreVaultClientCertificateKeyHmacKey = "client_certificate_key_hmac"
|
||||
credentialStoreType = "vault"
|
||||
)
|
||||
|
||||
var storeVaultAttrs = []string{
|
||||
credentialStoreVaultAddressKey,
|
||||
credentialStoreVaultNamespaceKey,
|
||||
credentialStoreVaultCaCertKey,
|
||||
credentialStoreVaultTlsServerNameKey,
|
||||
credentialStoreVaultTlsSkipVerifyKey,
|
||||
credentialStoreVaultTokenHmacKey,
|
||||
credentialStoreVaultClientCertificateKey,
|
||||
credentialStoreVaultClientCertificateKeyHmacKey,
|
||||
}
|
||||
|
||||
func resourceCredentialStoreVault() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
Description: "The credential store for Vault resource allows you to configure a Boundary credential store for Vault.",
|
||||
|
||||
CreateContext: resourceCredentialStoreVaultCreate,
|
||||
ReadContext: resourceCredentialStoreVaultRead,
|
||||
UpdateContext: resourceCredentialStoreVaultUpdate,
|
||||
DeleteContext: resourceCredentialStoreVaultDelete,
|
||||
Importer: &schema.ResourceImporter{
|
||||
StateContext: schema.ImportStatePassthroughContext,
|
||||
},
|
||||
|
||||
Schema: map[string]*schema.Schema{
|
||||
IDKey: {
|
||||
Description: "The ID of the Vault credential store.",
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
NameKey: {
|
||||
Description: "The Vault credential store name. Defaults to the resource name.",
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
DescriptionKey: {
|
||||
Description: "The Vault credential store description.",
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
ScopeIdKey: {
|
||||
Description: "The scope for this credential store",
|
||||
Type: schema.TypeString,
|
||||
ForceNew: true,
|
||||
Required: true,
|
||||
},
|
||||
credentialStoreVaultAddressKey: {
|
||||
Description: "The address to Vault server",
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
},
|
||||
credentialStoreVaultNamespaceKey: {
|
||||
Description: "The namespace within Vault to use",
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
credentialStoreVaultCaCertKey: {
|
||||
Description: "The Vault CA certificate to use",
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
credentialStoreVaultTlsServerNameKey: {
|
||||
Description: "The Vault TLS server name",
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
credentialStoreVaultTlsSkipVerifyKey: {
|
||||
Description: "Whether or not to skip TLS verification",
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
},
|
||||
credentialStoreVaultTokenKey: {
|
||||
Description: "The Vault token",
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
Sensitive: true,
|
||||
},
|
||||
credentialStoreVaultTokenHmacKey: {
|
||||
Description: "The Vault token hmac",
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
credentialStoreVaultClientCertificateKey: {
|
||||
Description: "The Vault client certificate",
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
credentialStoreVaultClientCertificateKeyKey: {
|
||||
Description: "The Vault client certificate key",
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Sensitive: true,
|
||||
},
|
||||
credentialStoreVaultClientCertificateKeyHmacKey: {
|
||||
Description: "The Vault client certificate key hmac",
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func setFromVaultCredentialStoreResponseMap(d *schema.ResourceData, raw map[string]interface{}) error {
|
||||
if err := d.Set(NameKey, raw[NameKey]); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := d.Set(DescriptionKey, raw[DescriptionKey]); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := d.Set(ScopeIdKey, raw[ScopeIdKey]); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if attrsVal, ok := raw["attributes"]; ok {
|
||||
attrs := attrsVal.(map[string]interface{})
|
||||
for _, v := range storeVaultAttrs {
|
||||
if err := d.Set(v, attrs[v]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
d.SetId(raw["id"].(string))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceCredentialStoreVaultCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
md := meta.(*metaData)
|
||||
|
||||
var opts []credentialstores.Option
|
||||
if v, ok := d.GetOk(NameKey); ok {
|
||||
opts = append(opts, credentialstores.WithName(v.(string)))
|
||||
}
|
||||
if v, ok := d.GetOk(DescriptionKey); ok {
|
||||
opts = append(opts, credentialstores.WithDescription(v.(string)))
|
||||
}
|
||||
if v, ok := d.GetOk(credentialStoreVaultAddressKey); ok {
|
||||
opts = append(opts, credentialstores.WithVaultCredentialStoreAddress(v.(string)))
|
||||
}
|
||||
if v, ok := d.GetOk(credentialStoreVaultNamespaceKey); ok {
|
||||
opts = append(opts, credentialstores.WithVaultCredentialStoreNamespace(v.(string)))
|
||||
}
|
||||
if v, ok := d.GetOk(credentialStoreVaultCaCertKey); ok {
|
||||
opts = append(opts, credentialstores.WithVaultCredentialStoreCaCert(v.(string)))
|
||||
}
|
||||
if v, ok := d.GetOk(credentialStoreVaultTlsServerNameKey); ok {
|
||||
opts = append(opts, credentialstores.WithVaultCredentialStoreTlsServerName(v.(string)))
|
||||
}
|
||||
if v, ok := d.GetOk(credentialStoreVaultTlsSkipVerifyKey); ok {
|
||||
opts = append(opts, credentialstores.WithVaultCredentialStoreTlsSkipVerify(v.(bool)))
|
||||
}
|
||||
if v, ok := d.GetOk(credentialStoreVaultClientCertificateKey); ok {
|
||||
opts = append(opts, credentialstores.WithVaultCredentialStoreClientCertificate(v.(string)))
|
||||
}
|
||||
if v, ok := d.GetOk(credentialStoreVaultClientCertificateKeyKey); ok {
|
||||
opts = append(opts, credentialstores.WithVaultCredentialStoreClientCertificateKey(v.(string)))
|
||||
}
|
||||
if v, ok := d.GetOk(credentialStoreVaultTokenKey); ok {
|
||||
opts = append(opts, credentialstores.WithVaultCredentialStoreToken(v.(string)))
|
||||
}
|
||||
|
||||
var scope string
|
||||
gotScope, ok := d.GetOk(ScopeIdKey)
|
||||
if ok {
|
||||
scope = gotScope.(string)
|
||||
} else {
|
||||
return diag.Errorf("no scope is set")
|
||||
}
|
||||
|
||||
client := credentialstores.NewClient(md.client)
|
||||
cr, err := client.Create(ctx, credentialStoreType, scope, opts...)
|
||||
if err != nil {
|
||||
return diag.Errorf("error creating credential store: %v", err)
|
||||
}
|
||||
if cr == nil {
|
||||
return diag.Errorf("nil credential store after create")
|
||||
}
|
||||
|
||||
if err := setFromVaultCredentialStoreResponseMap(d, cr.GetResponse().Map); err != nil {
|
||||
return diag.Errorf("error generating credential store from response map: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceCredentialStoreVaultRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
md := meta.(*metaData)
|
||||
client := credentialstores.NewClient(md.client)
|
||||
|
||||
cr, err := client.Read(ctx, d.Id())
|
||||
if err != nil {
|
||||
if apiErr := api.AsServerError(err); apiErr != nil && apiErr.Response().StatusCode() == http.StatusNotFound {
|
||||
d.SetId("")
|
||||
return nil
|
||||
}
|
||||
return diag.Errorf("error reading credential store: %v", err)
|
||||
}
|
||||
if cr == nil {
|
||||
return diag.Errorf("credential store nil after read")
|
||||
}
|
||||
|
||||
if err := setFromVaultCredentialStoreResponseMap(d, cr.GetResponse().Map); err != nil {
|
||||
return diag.Errorf("error generating credential store from response map: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceCredentialStoreVaultUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
md := meta.(*metaData)
|
||||
client := credentialstores.NewClient(md.client)
|
||||
|
||||
var opts []credentialstores.Option
|
||||
if d.HasChange(NameKey) {
|
||||
opts = append(opts, credentialstores.DefaultName())
|
||||
nameVal, ok := d.GetOk(NameKey)
|
||||
if ok {
|
||||
opts = append(opts, credentialstores.WithName(nameVal.(string)))
|
||||
}
|
||||
}
|
||||
|
||||
if d.HasChange(DescriptionKey) {
|
||||
opts = append(opts, credentialstores.DefaultDescription())
|
||||
descVal, ok := d.GetOk(DescriptionKey)
|
||||
if ok {
|
||||
opts = append(opts, credentialstores.WithDescription(descVal.(string)))
|
||||
}
|
||||
}
|
||||
|
||||
if d.HasChange(credentialStoreVaultAddressKey) {
|
||||
v, ok := d.GetOk(credentialStoreVaultAddressKey)
|
||||
if ok {
|
||||
opts = append(opts, credentialstores.WithVaultCredentialStoreAddress(v.(string)))
|
||||
}
|
||||
}
|
||||
|
||||
if d.HasChange(credentialStoreVaultNamespaceKey) {
|
||||
opts = append(opts, credentialstores.DefaultVaultCredentialStoreNamespace())
|
||||
v, ok := d.GetOk(credentialStoreVaultNamespaceKey)
|
||||
if ok {
|
||||
opts = append(opts, credentialstores.WithVaultCredentialStoreNamespace(v.(string)))
|
||||
}
|
||||
}
|
||||
|
||||
if d.HasChange(credentialStoreVaultCaCertKey) {
|
||||
opts = append(opts, credentialstores.DefaultVaultCredentialStoreCaCert())
|
||||
v, ok := d.GetOk(credentialStoreVaultCaCertKey)
|
||||
if ok {
|
||||
opts = append(opts, credentialstores.WithVaultCredentialStoreCaCert(v.(string)))
|
||||
}
|
||||
}
|
||||
|
||||
if d.HasChange(credentialStoreVaultTlsServerNameKey) {
|
||||
opts = append(opts, credentialstores.DefaultVaultCredentialStoreTlsServerName())
|
||||
v, ok := d.GetOk(credentialStoreVaultTlsServerNameKey)
|
||||
if ok {
|
||||
opts = append(opts, credentialstores.WithVaultCredentialStoreTlsServerName(v.(string)))
|
||||
}
|
||||
}
|
||||
|
||||
if d.HasChange(credentialStoreVaultTlsSkipVerifyKey) {
|
||||
opts = append(opts, credentialstores.DefaultVaultCredentialStoreTlsSkipVerify())
|
||||
v, ok := d.GetOk(credentialStoreVaultTlsSkipVerifyKey)
|
||||
if ok {
|
||||
opts = append(opts, credentialstores.WithVaultCredentialStoreTlsSkipVerify(v.(bool)))
|
||||
}
|
||||
}
|
||||
|
||||
if d.HasChange(credentialStoreVaultTokenKey) {
|
||||
v, ok := d.GetOk(credentialStoreVaultTokenKey)
|
||||
if ok {
|
||||
opts = append(opts, credentialstores.WithVaultCredentialStoreToken(v.(string)))
|
||||
}
|
||||
}
|
||||
|
||||
if d.HasChange(credentialStoreVaultClientCertificateKey) {
|
||||
opts = append(opts, credentialstores.DefaultVaultCredentialStoreClientCertificate())
|
||||
v, ok := d.GetOk(credentialStoreVaultClientCertificateKey)
|
||||
if ok {
|
||||
opts = append(opts, credentialstores.WithVaultCredentialStoreClientCertificate(v.(string)))
|
||||
}
|
||||
}
|
||||
|
||||
if d.HasChange(credentialStoreVaultClientCertificateKeyKey) {
|
||||
opts = append(opts, credentialstores.DefaultVaultCredentialStoreClientCertificateKey())
|
||||
v, ok := d.GetOk(credentialStoreVaultClientCertificateKeyKey)
|
||||
if ok {
|
||||
opts = append(opts, credentialstores.WithVaultCredentialStoreClientCertificateKey(v.(string)))
|
||||
}
|
||||
}
|
||||
|
||||
if len(opts) > 0 {
|
||||
opts = append(opts, credentialstores.WithAutomaticVersioning(true))
|
||||
crUpdate, err := client.Update(ctx, d.Id(), 0, opts...)
|
||||
if err != nil {
|
||||
return diag.Errorf("error updating credential store: %v", err)
|
||||
}
|
||||
if crUpdate == nil {
|
||||
return diag.Errorf("credential store nil after update")
|
||||
}
|
||||
|
||||
if err = setFromVaultCredentialStoreResponseMap(d, crUpdate.GetResponse().Map); err != nil {
|
||||
return diag.Errorf("error generating credential store from response map: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceCredentialStoreVaultDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||
md := meta.(*metaData)
|
||||
client := credentialstores.NewClient(md.client)
|
||||
|
||||
_, err := client.Delete(ctx, d.Id())
|
||||
if err != nil {
|
||||
return diag.Errorf("error deleting credential store: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,191 @@
|
||||
package provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/hmac"
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/boundary/api"
|
||||
"github.com/hashicorp/boundary/api/credentialstores"
|
||||
"github.com/hashicorp/boundary/testing/controller"
|
||||
"github.com/hashicorp/boundary/testing/vault"
|
||||
"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"
|
||||
"golang.org/x/crypto/blake2b"
|
||||
)
|
||||
|
||||
const (
|
||||
vaultCredStoreResc = "boundary_credential_store_vault.example"
|
||||
vaultCredStoreName = "foo"
|
||||
vaultCredStoreDesc = "the foo"
|
||||
vaultCredStoreNamespace = "default"
|
||||
vaultCredStoreUpdate = "_random"
|
||||
)
|
||||
|
||||
func vaultCredStoreResource(vc *vault.TestVaultServer, name, description, namespace, tlsServer, token string, skipVerify bool) string {
|
||||
caCert := fmt.Sprintf("\"%s\"", strings.Replace(string(vc.CaCert), "\n", `\n`, -1))
|
||||
clientCert := fmt.Sprintf("\"%s\"", strings.Replace(string(vc.ClientCert), "\n", `\n`, -1))
|
||||
clientKey := fmt.Sprintf("\"%s\"", strings.Replace(string(vc.ClientKey), "\n", `\n`, -1))
|
||||
|
||||
return fmt.Sprintf(`
|
||||
resource "boundary_credential_store_vault" "example" {
|
||||
name = "%s"
|
||||
description = "%s"
|
||||
scope_id = boundary_scope.proj1.id
|
||||
address = "%s"
|
||||
namespace = "%s"
|
||||
ca_cert = %s
|
||||
tls_server_name = "%s"
|
||||
tls_skip_verify = "%v"
|
||||
token = "%s"
|
||||
client_certificate = %s
|
||||
client_certificate_key = %s
|
||||
depends_on = [boundary_role.proj1_admin]
|
||||
}`, name,
|
||||
description,
|
||||
vc.Addr,
|
||||
namespace,
|
||||
caCert,
|
||||
tlsServer,
|
||||
skipVerify,
|
||||
token,
|
||||
clientCert,
|
||||
clientKey)
|
||||
}
|
||||
|
||||
func tokenHmac(token, accessor string) string {
|
||||
key := blake2b.Sum256([]byte(accessor))
|
||||
mac := hmac.New(sha256.New, key[:])
|
||||
_, _ = mac.Write([]byte(token))
|
||||
hmac := mac.Sum(nil)
|
||||
return base64.RawURLEncoding.EncodeToString(hmac)
|
||||
}
|
||||
|
||||
func TestAccCredentialStoreVault(t *testing.T) {
|
||||
tc := controller.NewTestController(t, tcConfig...)
|
||||
defer tc.Shutdown()
|
||||
url := tc.ApiAddrs()[0]
|
||||
|
||||
vc := vault.NewTestVaultServer(t)
|
||||
secret, token := vc.CreateToken(t)
|
||||
tHmac := tokenHmac(token, secret.Auth.Accessor)
|
||||
res := vaultCredStoreResource(vc,
|
||||
vaultCredStoreName,
|
||||
vaultCredStoreDesc,
|
||||
vaultCredStoreNamespace,
|
||||
"www.original.com",
|
||||
token,
|
||||
true)
|
||||
|
||||
vcUpdate := vault.NewTestVaultServer(t, vault.WithTestVaultTLS(vault.TestClientTLS))
|
||||
secret, tokenUpdate := vcUpdate.CreateToken(t)
|
||||
tHmacUpdate := tokenHmac(tokenUpdate, secret.Auth.Accessor)
|
||||
resUpdate := vaultCredStoreResource(vcUpdate,
|
||||
vaultCredStoreName+vaultCredStoreUpdate,
|
||||
vaultCredStoreDesc+vaultCredStoreUpdate,
|
||||
vaultCredStoreNamespace+vaultCredStoreUpdate,
|
||||
"www.updated.com",
|
||||
tokenUpdate,
|
||||
false)
|
||||
|
||||
var provider *schema.Provider
|
||||
resource.Test(t, resource.TestCase{
|
||||
ProviderFactories: providerFactories(&provider),
|
||||
CheckDestroy: testAccCheckCredentialStoreVaultResourceDestroy(t, provider),
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
// create
|
||||
Config: testConfig(url, fooOrg, firstProjectFoo, res),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
resource.TestCheckResourceAttr(vaultCredStoreResc, NameKey, vaultCredStoreName),
|
||||
resource.TestCheckResourceAttr(vaultCredStoreResc, DescriptionKey, vaultCredStoreDesc),
|
||||
resource.TestCheckResourceAttr(vaultCredStoreResc, credentialStoreVaultAddressKey, vc.Addr),
|
||||
resource.TestCheckResourceAttr(vaultCredStoreResc, credentialStoreVaultNamespaceKey, vaultCredStoreNamespace),
|
||||
resource.TestCheckResourceAttr(vaultCredStoreResc, credentialStoreVaultCaCertKey, ""),
|
||||
resource.TestCheckResourceAttr(vaultCredStoreResc, credentialStoreVaultTlsServerNameKey, "www.original.com"),
|
||||
resource.TestCheckResourceAttr(vaultCredStoreResc, credentialStoreVaultTlsSkipVerifyKey, "true"),
|
||||
resource.TestCheckResourceAttr(vaultCredStoreResc, credentialStoreVaultTokenKey, token),
|
||||
resource.TestCheckResourceAttr(vaultCredStoreResc, credentialStoreVaultTokenHmacKey, tHmac),
|
||||
resource.TestCheckResourceAttr(vaultCredStoreResc, credentialStoreVaultClientCertificateKey, ""),
|
||||
resource.TestCheckResourceAttr(vaultCredStoreResc, credentialStoreVaultClientCertificateKeyKey, ""),
|
||||
|
||||
testAccCheckCredentialStoreVaultResourceExists(provider, vaultCredStoreResc),
|
||||
),
|
||||
},
|
||||
importStep(vaultCredStoreResc, credentialStoreVaultTokenKey, credentialStoreVaultClientCertificateKeyKey),
|
||||
{
|
||||
// update
|
||||
Config: testConfig(url, fooOrg, firstProjectFoo, resUpdate),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
resource.TestCheckResourceAttr(vaultCredStoreResc, NameKey, vaultCredStoreName+vaultCredStoreUpdate),
|
||||
resource.TestCheckResourceAttr(vaultCredStoreResc, DescriptionKey, vaultCredStoreDesc+vaultCredStoreUpdate),
|
||||
resource.TestCheckResourceAttr(vaultCredStoreResc, credentialStoreVaultAddressKey, vcUpdate.Addr),
|
||||
resource.TestCheckResourceAttr(vaultCredStoreResc, credentialStoreVaultNamespaceKey, vaultCredStoreNamespace+vaultCredStoreUpdate),
|
||||
resource.TestCheckResourceAttr(vaultCredStoreResc, credentialStoreVaultCaCertKey, string(vcUpdate.CaCert)),
|
||||
resource.TestCheckResourceAttr(vaultCredStoreResc, credentialStoreVaultTlsServerNameKey, "www.updated.com"),
|
||||
resource.TestCheckResourceAttr(vaultCredStoreResc, credentialStoreVaultTlsSkipVerifyKey, "false"),
|
||||
resource.TestCheckResourceAttr(vaultCredStoreResc, credentialStoreVaultTokenKey, tokenUpdate),
|
||||
resource.TestCheckResourceAttr(vaultCredStoreResc, credentialStoreVaultTokenHmacKey, tHmacUpdate),
|
||||
resource.TestCheckResourceAttr(vaultCredStoreResc, credentialStoreVaultClientCertificateKey, string(vcUpdate.ClientCert)),
|
||||
resource.TestCheckResourceAttr(vaultCredStoreResc, credentialStoreVaultClientCertificateKeyKey, string(vcUpdate.ClientKey)),
|
||||
|
||||
testAccCheckCredentialStoreVaultResourceExists(provider, vaultCredStoreResc),
|
||||
),
|
||||
},
|
||||
importStep(vaultCredStoreResc, credentialStoreVaultTokenKey, credentialStoreVaultClientCertificateKeyKey),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func testAccCheckCredentialStoreVaultResourceExists(testProvider *schema.Provider, name string) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
rs, ok := s.RootModule().Resources[name]
|
||||
if !ok {
|
||||
return fmt.Errorf("not found: %s", name)
|
||||
}
|
||||
|
||||
id := rs.Primary.ID
|
||||
if id == "" {
|
||||
return fmt.Errorf("no ID is set")
|
||||
}
|
||||
|
||||
md := testProvider.Meta().(*metaData)
|
||||
c := credentialstores.NewClient(md.client)
|
||||
if _, err := c.Read(context.Background(), id); err != nil {
|
||||
return fmt.Errorf("got an error reading %q: %w", id, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func testAccCheckCredentialStoreVaultResourceDestroy(t *testing.T, testProvider *schema.Provider) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
if testProvider.Meta() == nil {
|
||||
t.Fatal("got nil provider metadata")
|
||||
}
|
||||
md := testProvider.Meta().(*metaData)
|
||||
|
||||
for _, rs := range s.RootModule().Resources {
|
||||
switch rs.Type {
|
||||
case "boundary_credential_store_vault":
|
||||
id := rs.Primary.ID
|
||||
|
||||
c := credentialstores.NewClient(md.client)
|
||||
_, err := c.Read(context.Background(), id)
|
||||
if apiErr := api.AsServerError(err); apiErr == nil || apiErr.Response().StatusCode() != http.StatusNotFound {
|
||||
return fmt.Errorf("didn't get a 404 when reading destroyed Vault credential store %q: %v", id, err)
|
||||
}
|
||||
default:
|
||||
continue
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@@ -196,13 +196,11 @@ func resourceGroupUpdate(ctx context.Context, d *schema.ResourceData, meta inter
|
||||
if err := d.Set(NameKey, name); err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
}
|
||||
if d.HasChange(DescriptionKey) {
|
||||
if err := d.Set(DescriptionKey, desc); err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// The above call may not actually happen, so we use d.Id() and automatic
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
|
||||
const (
|
||||
targetHostSetIdsKey = "host_set_ids"
|
||||
targetCredentialLibraryIdsKey = "credential_library_ids"
|
||||
targetDefaultPortKey = "default_port"
|
||||
targetSessionMaxSecondsKey = "session_max_seconds"
|
||||
targetSessionConnectionLimitKey = "session_connection_limit"
|
||||
@@ -72,6 +73,12 @@ func resourceTarget() *schema.Resource {
|
||||
Optional: true,
|
||||
Elem: &schema.Schema{Type: schema.TypeString},
|
||||
},
|
||||
targetCredentialLibraryIdsKey: {
|
||||
Description: "A list of credential library ID's.",
|
||||
Type: schema.TypeSet,
|
||||
Optional: true,
|
||||
Elem: &schema.Schema{Type: schema.TypeString},
|
||||
},
|
||||
targetSessionMaxSecondsKey: {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
@@ -107,6 +114,9 @@ func setFromTargetResponseMap(d *schema.ResourceData, raw map[string]interface{}
|
||||
if err := d.Set(targetHostSetIdsKey, raw["host_set_ids"]); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := d.Set(targetCredentialLibraryIdsKey, raw["credential_library_ids"]); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := d.Set(targetSessionMaxSecondsKey, raw["session_max_seconds"]); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -206,6 +216,15 @@ func resourceTargetCreate(ctx context.Context, d *schema.ResourceData, meta inte
|
||||
}
|
||||
}
|
||||
|
||||
var credentialLibraryIds []string
|
||||
if credentialLibraryIdsVal, ok := d.GetOk(targetCredentialLibraryIdsKey); ok {
|
||||
list := credentialLibraryIdsVal.(*schema.Set).List()
|
||||
credentialLibraryIds = make([]string, 0, len(list))
|
||||
for _, i := range list {
|
||||
credentialLibraryIds = append(credentialLibraryIds, i.(string))
|
||||
}
|
||||
}
|
||||
|
||||
workerFilterVal, ok := d.GetOk(targetWorkerFilterKey)
|
||||
if ok {
|
||||
workerFilterStr := workerFilterVal.(string)
|
||||
@@ -223,12 +242,22 @@ func resourceTargetCreate(ctx context.Context, d *schema.ResourceData, meta inte
|
||||
}
|
||||
raw := tcr.GetResponse().Map
|
||||
|
||||
version := tcr.Item.Version
|
||||
if hostSetIds != nil {
|
||||
tur, err := tc.SetHostSets(ctx, tcr.Item.Id, tcr.Item.Version, hostSetIds)
|
||||
tur, err := tc.SetHostSets(ctx, tcr.Item.Id, version, hostSetIds)
|
||||
if err != nil {
|
||||
return diag.Errorf("error setting host sets on target: %v", err)
|
||||
}
|
||||
raw = tur.GetResponse().Map
|
||||
version = tur.Item.Version
|
||||
}
|
||||
|
||||
if credentialLibraryIds != nil {
|
||||
tur, err := tc.SetCredentialLibraries(ctx, tcr.Item.Id, version, credentialLibraryIds)
|
||||
if err != nil {
|
||||
return diag.Errorf("error setting credential libraries on target: %v", err)
|
||||
}
|
||||
raw = tur.GetResponse().Map
|
||||
}
|
||||
|
||||
if err := setFromTargetResponseMap(d, raw); err != nil {
|
||||
@@ -400,6 +429,23 @@ func resourceTargetUpdate(ctx context.Context, d *schema.ResourceData, meta inte
|
||||
}
|
||||
}
|
||||
|
||||
if d.HasChange(targetCredentialLibraryIdsKey) {
|
||||
var credentialLibraryIds []string
|
||||
if credentialLibraryIdsVal, ok := d.GetOk(targetCredentialLibraryIdsKey); ok {
|
||||
credLibsIds := credentialLibraryIdsVal.(*schema.Set).List()
|
||||
for _, credLibId := range credLibsIds {
|
||||
credentialLibraryIds = append(credentialLibraryIds, credLibId.(string))
|
||||
}
|
||||
}
|
||||
_, err := tc.SetCredentialLibraries(ctx, d.Id(), 0, credentialLibraryIds, targets.WithAutomaticVersioning(true))
|
||||
if err != nil {
|
||||
return diag.Errorf("error updating credential libraries in target: %v", err)
|
||||
}
|
||||
if err := d.Set(targetCredentialLibraryIdsKey, credentialLibraryIds); err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@ import (
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/boundary/testing/vault"
|
||||
|
||||
"github.com/hashicorp/boundary/api"
|
||||
"github.com/hashicorp/boundary/api/targets"
|
||||
"github.com/hashicorp/boundary/testing/controller"
|
||||
@@ -20,7 +22,7 @@ const (
|
||||
)
|
||||
|
||||
var (
|
||||
fooHostSet = `
|
||||
fooBarHostSet = `
|
||||
resource "boundary_host_catalog" "foo" {
|
||||
type = "static"
|
||||
name = "test"
|
||||
@@ -49,10 +51,36 @@ resource "boundary_host_set" "foo" {
|
||||
host_catalog_id = boundary_host_catalog.foo.id
|
||||
host_ids = [
|
||||
boundary_host.foo.id,
|
||||
]
|
||||
}
|
||||
|
||||
resource "boundary_host_set" "bar" {
|
||||
name = "bar"
|
||||
type = "static"
|
||||
host_catalog_id = boundary_host_catalog.foo.id
|
||||
host_ids = [
|
||||
boundary_host.bar.id,
|
||||
]
|
||||
}`
|
||||
|
||||
fooBarCredLibs = `
|
||||
resource "boundary_credential_library_vault" "foo" {
|
||||
name = "foo"
|
||||
description = "foo library"
|
||||
credential_store_id = boundary_credential_store_vault.example.id
|
||||
path = "foo/bar"
|
||||
http_method = "GET"
|
||||
}
|
||||
|
||||
resource "boundary_credential_library_vault" "bar" {
|
||||
name = "bar"
|
||||
description = "bar library"
|
||||
credential_store_id = boundary_credential_store_vault.example.id
|
||||
path = "bar/foo"
|
||||
http_method = "GET"
|
||||
}
|
||||
`
|
||||
|
||||
fooTarget = fmt.Sprintf(`
|
||||
resource "boundary_target" "foo" {
|
||||
name = "test"
|
||||
@@ -62,6 +90,9 @@ resource "boundary_target" "foo" {
|
||||
host_set_ids = [
|
||||
boundary_host_set.foo.id
|
||||
]
|
||||
credential_library_ids = [
|
||||
boundary_credential_library_vault.foo.id
|
||||
]
|
||||
default_port = 22
|
||||
depends_on = [boundary_role.proj1_admin]
|
||||
session_max_seconds = 6000
|
||||
@@ -76,7 +107,10 @@ resource "boundary_target" "foo" {
|
||||
type = "tcp"
|
||||
scope_id = boundary_scope.proj1.id
|
||||
host_set_ids = [
|
||||
boundary_host_set.foo.id
|
||||
boundary_host_set.bar.id
|
||||
]
|
||||
credential_library_ids = [
|
||||
boundary_credential_library_vault.bar.id
|
||||
]
|
||||
default_port = 80
|
||||
depends_on = [boundary_role.proj1_admin]
|
||||
@@ -92,6 +126,16 @@ func TestAccTarget(t *testing.T) {
|
||||
defer tc.Shutdown()
|
||||
url := tc.ApiAddrs()[0]
|
||||
|
||||
vc := vault.NewTestVaultServer(t)
|
||||
_, token := vc.CreateToken(t)
|
||||
credStoreRes := vaultCredStoreResource(vc,
|
||||
vaultCredStoreName,
|
||||
vaultCredStoreDesc,
|
||||
vaultCredStoreNamespace,
|
||||
"www.original.com",
|
||||
token,
|
||||
true)
|
||||
|
||||
var provider *schema.Provider
|
||||
resource.Test(t, resource.TestCase{
|
||||
ProviderFactories: providerFactories(&provider),
|
||||
@@ -99,7 +143,7 @@ func TestAccTarget(t *testing.T) {
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
// test create
|
||||
Config: testConfig(url, fooOrg, firstProjectFoo, fooHostSet, fooTarget),
|
||||
Config: testConfig(url, fooOrg, firstProjectFoo, credStoreRes, fooBarCredLibs, fooBarHostSet, fooTarget),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckTargetResourceExists(provider, "boundary_target.foo"),
|
||||
resource.TestCheckResourceAttr("boundary_target.foo", DescriptionKey, fooTargetDescription),
|
||||
@@ -108,12 +152,14 @@ func TestAccTarget(t *testing.T) {
|
||||
resource.TestCheckResourceAttr("boundary_target.foo", targetSessionMaxSecondsKey, "6000"),
|
||||
resource.TestCheckResourceAttr("boundary_target.foo", targetSessionConnectionLimitKey, "6"),
|
||||
resource.TestCheckResourceAttr("boundary_target.foo", targetWorkerFilterKey, `type == "foo"`),
|
||||
testAccCheckTargetResourceHostSet(provider, "boundary_target.foo", []string{"boundary_host_set.foo"}),
|
||||
testAccCheckTargetResourceCredLibs(provider, "boundary_target.foo", []string{"boundary_credential_library_vault.foo"}),
|
||||
),
|
||||
},
|
||||
importStep("boundary_target.foo"),
|
||||
{
|
||||
// test update
|
||||
Config: testConfig(url, fooOrg, firstProjectFoo, fooHostSet, fooTargetUpdate),
|
||||
Config: testConfig(url, fooOrg, firstProjectFoo, credStoreRes, fooBarCredLibs, fooBarHostSet, fooTargetUpdate),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckTargetResourceExists(provider, "boundary_target.foo"),
|
||||
resource.TestCheckResourceAttr("boundary_target.foo", DescriptionKey, fooTargetDescriptionUpdate),
|
||||
@@ -121,6 +167,8 @@ func TestAccTarget(t *testing.T) {
|
||||
resource.TestCheckResourceAttr("boundary_target.foo", targetSessionMaxSecondsKey, "7000"),
|
||||
resource.TestCheckResourceAttr("boundary_target.foo", targetSessionConnectionLimitKey, "7"),
|
||||
resource.TestCheckResourceAttr("boundary_target.foo", targetWorkerFilterKey, `type == "bar"`),
|
||||
testAccCheckTargetResourceHostSet(provider, "boundary_target.foo", []string{"boundary_host_set.bar"}),
|
||||
testAccCheckTargetResourceCredLibs(provider, "boundary_target.foo", []string{"boundary_credential_library_vault.bar"}),
|
||||
),
|
||||
},
|
||||
importStep("boundary_target.foo"),
|
||||
@@ -128,7 +176,7 @@ func TestAccTarget(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func testAccCheckTargetResourceMembersSet(testProvider *schema.Provider, name string, hostSets []string) resource.TestCheckFunc {
|
||||
func testAccCheckTargetResourceHostSet(testProvider *schema.Provider, name string, hostSets []string) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
rs, ok := s.RootModule().Resources[name]
|
||||
if !ok {
|
||||
@@ -141,7 +189,7 @@ func testAccCheckTargetResourceMembersSet(testProvider *schema.Provider, name st
|
||||
}
|
||||
|
||||
// ensure host sets are declared in state
|
||||
hostSetIDs := []string{}
|
||||
var hostSetIDs []string
|
||||
for _, hostSetResourceID := range hostSets {
|
||||
hs, ok := s.RootModule().Resources[hostSetResourceID]
|
||||
if !ok {
|
||||
@@ -169,15 +217,80 @@ func testAccCheckTargetResourceMembersSet(testProvider *schema.Provider, name st
|
||||
return fmt.Errorf("no hostSets found on target")
|
||||
}
|
||||
|
||||
for _, stateHostSet := range t.Item.HostSetIds {
|
||||
if len(t.Item.HostSetIds) != len(hostSetIDs) {
|
||||
return fmt.Errorf("tf state and boundary have different number of host sets")
|
||||
}
|
||||
|
||||
for _, stateHostSetId := range t.Item.HostSetIds {
|
||||
ok := false
|
||||
for _, gotHostSetID := range hostSetIDs {
|
||||
if gotHostSetID == stateHostSet {
|
||||
if gotHostSetID == stateHostSetId {
|
||||
ok = true
|
||||
}
|
||||
}
|
||||
if !ok {
|
||||
return fmt.Errorf("host set in state not set in boundary: %s", stateHostSet)
|
||||
return fmt.Errorf("host set id in state not set in boundary: %s", stateHostSetId)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func testAccCheckTargetResourceCredLibs(testProvider *schema.Provider, name string, credLibs []string) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
rs, ok := s.RootModule().Resources[name]
|
||||
if !ok {
|
||||
return fmt.Errorf("target resource not found: %s", name)
|
||||
}
|
||||
|
||||
id := rs.Primary.ID
|
||||
if id == "" {
|
||||
return fmt.Errorf("target resource ID is not set")
|
||||
}
|
||||
|
||||
// ensure host sets are declared in state
|
||||
var credLibIDs []string
|
||||
for _, credLibResourceID := range credLibs {
|
||||
cl, ok := s.RootModule().Resources[credLibResourceID]
|
||||
if !ok {
|
||||
return fmt.Errorf("credential library resource not found: %s", credLibResourceID)
|
||||
}
|
||||
|
||||
credLibID := cl.Primary.ID
|
||||
if id == "" {
|
||||
return fmt.Errorf("credential library resource ID not set")
|
||||
}
|
||||
|
||||
credLibIDs = append(credLibIDs, credLibID)
|
||||
}
|
||||
|
||||
// check boundary to ensure it matches
|
||||
md := testProvider.Meta().(*metaData)
|
||||
tgtsClient := targets.NewClient(md.client)
|
||||
|
||||
t, err := tgtsClient.Read(context.Background(), id)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Got an error when reading target %q: %v", id, err)
|
||||
}
|
||||
|
||||
if len(t.Item.CredentialLibraries) == 0 {
|
||||
return fmt.Errorf("no credential libraries found on target")
|
||||
}
|
||||
|
||||
if len(t.Item.CredentialLibraries) != len(credLibIDs) {
|
||||
return fmt.Errorf("tf state and boundary have different number of credential libraries")
|
||||
}
|
||||
|
||||
for _, stateCredLibId := range t.Item.CredentialLibraryIds {
|
||||
ok := false
|
||||
for _, gotCredLibID := range credLibIDs {
|
||||
if gotCredLibID == stateCredLibId {
|
||||
ok = true
|
||||
}
|
||||
}
|
||||
if !ok {
|
||||
return fmt.Errorf("credential library id in state not set in boundary: %s", stateCredLibId)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user