Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f95954c83d | ||
|
|
1882beff3c | ||
|
|
807db1bef1 |
No files matched your search
@@ -2,6 +2,21 @@
|
|||||||
|
|
||||||
Canonical reference for changes, improvements, and bugfixes for the Boundary Terraform provider.
|
Canonical reference for changes, improvements, and bugfixes for the Boundary Terraform provider.
|
||||||
|
|
||||||
|
## Next
|
||||||
|
|
||||||
|
### New and Improved
|
||||||
|
|
||||||
|
* Add support for setting mapping overrides for vault credential libraries
|
||||||
|
([PR](https://github.com/hashicorp/terraform-provider-boundary/pull/287)).
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* Improve error message when authenticating to boundary
|
||||||
|
([PR](https://github.com/hashicorp/terraform-provider-boundary/pull/290)).
|
||||||
|
* Set state before returning an error when creating a resource
|
||||||
|
([PR](https://github.com/hashicorp/terraform-provider-boundary/pull/289))
|
||||||
|
|
||||||
## 1.1.1 (October 12, 2022)
|
## 1.1.1 (October 12, 2022)
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|||||||
@@ -56,6 +56,33 @@ resource "boundary_credential_library_vault" "bar" {
|
|||||||
}
|
}
|
||||||
EOT
|
EOT
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resource "boundary_credential_library_vault" "baz" {
|
||||||
|
name = "baz"
|
||||||
|
description = "vault username password credential with mapping overrides"
|
||||||
|
credential_store_id = boundary_credential_store_vault.foo.id
|
||||||
|
path = "my/secret/baz" # change to Vault backend path
|
||||||
|
http_method = "GET"
|
||||||
|
credential_type = "username_password"
|
||||||
|
credential_mapping_overrides = {
|
||||||
|
password_attribute = "alternative_password_label"
|
||||||
|
username_attribute = "alternative_username_label"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "boundary_credential_library_vault" "quz" {
|
||||||
|
name = "quz"
|
||||||
|
description = "vault ssh private key credential with mapping overrides"
|
||||||
|
credential_store_id = boundary_credential_store_vault.foo.id
|
||||||
|
path = "my/secret/quz" # change to Vault backend path
|
||||||
|
http_method = "GET"
|
||||||
|
credential_type = "ssh_private_key"
|
||||||
|
credential_mapping_overrides = {
|
||||||
|
private_key_attribute = "alternative_key_label"
|
||||||
|
private_key_passphrase_attribute = "alternative_passphrase_label"
|
||||||
|
username_attribute = "alternative_username_label"
|
||||||
|
}
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
<!-- schema generated by tfplugindocs -->
|
<!-- schema generated by tfplugindocs -->
|
||||||
@@ -68,6 +95,7 @@ EOT
|
|||||||
|
|
||||||
### Optional
|
### Optional
|
||||||
|
|
||||||
|
- `credential_mapping_overrides` (Map of String) The credential mapping override.
|
||||||
- `credential_type` (String) The type of credential the library generates.
|
- `credential_type` (String) The type of credential the library generates.
|
||||||
- `description` (String) The Vault credential library description.
|
- `description` (String) The Vault credential library description.
|
||||||
- `http_method` (String) The HTTP method the library uses when requesting credentials from Vault. Defaults to 'GET'
|
- `http_method` (String) The HTTP method the library uses when requesting credentials from Vault. Defaults to 'GET'
|
||||||
|
|||||||
@@ -41,3 +41,30 @@ resource "boundary_credential_library_vault" "bar" {
|
|||||||
}
|
}
|
||||||
EOT
|
EOT
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resource "boundary_credential_library_vault" "baz" {
|
||||||
|
name = "baz"
|
||||||
|
description = "vault username password credential with mapping overrides"
|
||||||
|
credential_store_id = boundary_credential_store_vault.foo.id
|
||||||
|
path = "my/secret/baz" # change to Vault backend path
|
||||||
|
http_method = "GET"
|
||||||
|
credential_type = "username_password"
|
||||||
|
credential_mapping_overrides = {
|
||||||
|
password_attribute = "alternative_password_label"
|
||||||
|
username_attribute = "alternative_username_label"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "boundary_credential_library_vault" "quz" {
|
||||||
|
name = "quz"
|
||||||
|
description = "vault ssh private key credential with mapping overrides"
|
||||||
|
credential_store_id = boundary_credential_store_vault.foo.id
|
||||||
|
path = "my/secret/quz" # change to Vault backend path
|
||||||
|
http_method = "GET"
|
||||||
|
credential_type = "ssh_private_key"
|
||||||
|
credential_mapping_overrides = {
|
||||||
|
private_key_attribute = "alternative_key_label"
|
||||||
|
private_key_passphrase_attribute = "alternative_passphrase_label"
|
||||||
|
username_attribute = "alternative_username_label"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/hashicorp/boundary/api"
|
"github.com/hashicorp/boundary/api"
|
||||||
@@ -176,6 +177,15 @@ func providerAuthenticate(ctx context.Context, d *schema.ResourceData, md *metaD
|
|||||||
|
|
||||||
at, err := am.Authenticate(ctx, authMethodId.(string), "login", credentials)
|
at, err := am.Authenticate(ctx, authMethodId.(string), "login", credentials)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if apiErr := api.AsServerError(err); apiErr != nil {
|
||||||
|
statusCode := apiErr.Response().StatusCode()
|
||||||
|
if statusCode == http.StatusNotFound {
|
||||||
|
return fmt.Errorf("unknown auth_method_id: %s", err.Error())
|
||||||
|
}
|
||||||
|
if statusCode == http.StatusUnauthorized {
|
||||||
|
return fmt.Errorf("invalid login name or password: %s", err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
md.client.SetToken(at.Attributes["token"].(string))
|
md.client.SetToken(at.Attributes["token"].(string))
|
||||||
|
|||||||
@@ -11,11 +11,12 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
credentialStoreIdKey = "credential_store_id"
|
credentialStoreIdKey = "credential_store_id"
|
||||||
credentialLibraryVaultHttpMethodKey = "http_method"
|
credentialLibraryVaultHttpMethodKey = "http_method"
|
||||||
credentialLibraryVaultHttpRequestBodyKey = "http_request_body"
|
credentialLibraryVaultHttpRequestBodyKey = "http_request_body"
|
||||||
credentialLibraryVaultPathKey = "path"
|
credentialLibraryVaultPathKey = "path"
|
||||||
credentialLibraryCredentialTypeKey = "credential_type"
|
credentialLibraryCredentialTypeKey = "credential_type"
|
||||||
|
credentialLibraryCredentialMappingOverridesKey = "credential_mapping_overrides"
|
||||||
)
|
)
|
||||||
|
|
||||||
var libraryVaultAttrs = []string{
|
var libraryVaultAttrs = []string{
|
||||||
@@ -78,6 +79,11 @@ func resourceCredentialLibraryVault() *schema.Resource {
|
|||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
},
|
},
|
||||||
|
credentialLibraryCredentialMappingOverridesKey: {
|
||||||
|
Description: "The credential mapping override.",
|
||||||
|
Type: schema.TypeMap,
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -93,6 +99,10 @@ func setFromVaultCredentialLibraryResponseMap(d *schema.ResourceData, raw map[st
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := d.Set(credentialLibraryCredentialMappingOverridesKey, raw[credentialLibraryCredentialMappingOverridesKey]); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if attrsVal, ok := raw["attributes"]; ok {
|
if attrsVal, ok := raw["attributes"]; ok {
|
||||||
attrs := attrsVal.(map[string]interface{})
|
attrs := attrsVal.(map[string]interface{})
|
||||||
for _, v := range libraryVaultAttrs {
|
for _, v := range libraryVaultAttrs {
|
||||||
@@ -129,6 +139,10 @@ func resourceCredentialLibraryCreateVault(ctx context.Context, d *schema.Resourc
|
|||||||
if v, ok := d.GetOk(credentialLibraryCredentialTypeKey); ok {
|
if v, ok := d.GetOk(credentialLibraryCredentialTypeKey); ok {
|
||||||
opts = append(opts, credentiallibraries.WithCredentialType(v.(string)))
|
opts = append(opts, credentiallibraries.WithCredentialType(v.(string)))
|
||||||
}
|
}
|
||||||
|
if v, ok := d.GetOk(credentialLibraryCredentialMappingOverridesKey); ok {
|
||||||
|
mappingOverrides := v.(map[string]interface{})
|
||||||
|
opts = append(opts, credentiallibraries.WithCredentialMappingOverrides(mappingOverrides))
|
||||||
|
}
|
||||||
|
|
||||||
var credentialStoreId string
|
var credentialStoreId string
|
||||||
cid, ok := d.GetOk(credentialStoreIdKey)
|
cid, ok := d.GetOk(credentialStoreIdKey)
|
||||||
@@ -216,6 +230,40 @@ func resourceCredentialLibraryUpdateVault(ctx context.Context, d *schema.Resourc
|
|||||||
opts = append(opts, credentiallibraries.WithVaultCredentialLibraryPath(v.(string)))
|
opts = append(opts, credentiallibraries.WithVaultCredentialLibraryPath(v.(string)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if d.HasChange(credentialLibraryCredentialMappingOverridesKey) {
|
||||||
|
var oldMapping, newMapping map[string]interface{}
|
||||||
|
old, new := d.GetChange(credentialLibraryCredentialMappingOverridesKey)
|
||||||
|
|
||||||
|
if old == nil {
|
||||||
|
old = map[string]interface{}{}
|
||||||
|
}
|
||||||
|
oldMapping = old.(map[string]interface{})
|
||||||
|
|
||||||
|
if new == nil {
|
||||||
|
new = map[string]interface{}{}
|
||||||
|
}
|
||||||
|
newMapping = new.(map[string]interface{})
|
||||||
|
|
||||||
|
newAttrs := []string{}
|
||||||
|
for k := range newMapping {
|
||||||
|
newAttrs = append(newAttrs, k)
|
||||||
|
}
|
||||||
|
|
||||||
|
for oldAttr := range oldMapping {
|
||||||
|
isRemoved := true
|
||||||
|
for _, newAttr := range newAttrs {
|
||||||
|
if oldAttr == newAttr {
|
||||||
|
isRemoved = false
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if isRemoved {
|
||||||
|
newMapping[oldAttr] = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
opts = append(opts, credentiallibraries.WithCredentialMappingOverrides(newMapping))
|
||||||
|
}
|
||||||
|
|
||||||
if len(opts) > 0 {
|
if len(opts) > 0 {
|
||||||
opts = append(opts, credentiallibraries.WithAutomaticVersioning(true))
|
opts = append(opts, credentiallibraries.WithAutomaticVersioning(true))
|
||||||
|
|||||||
@@ -16,24 +16,26 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
vaultCredResc = "boundary_credential_library_vault.example"
|
vaultCredResc = "boundary_credential_library_vault.example"
|
||||||
vaultCredTypedResc = "boundary_credential_library_vault.typed_example"
|
vaultCredTypedResc = "boundary_credential_library_vault.typed_example"
|
||||||
vaultCredLibName = "foo"
|
vaultCredUsernamePasswordResc = "boundary_credential_library_vault.username_password_mapping_override"
|
||||||
vaultCredLibDesc = "the foo"
|
vaultCredSshPrivateKeyResc = "boundary_credential_library_vault.ssh_private_key_mapping_override"
|
||||||
vaultCredLibPath = "/foo/bar"
|
vaultCredLibName = "foo"
|
||||||
vaultCredLibMethodGet = "GET"
|
vaultCredLibDesc = "the foo"
|
||||||
vaultCredLibMethodPost = "POST"
|
vaultCredLibPath = "/foo/bar"
|
||||||
vaultCredLibRequestBody = "foobar"
|
vaultCredLibMethodGet = "GET"
|
||||||
vaultCredLibStringUpdate = "_random"
|
vaultCredLibMethodPost = "POST"
|
||||||
|
vaultCredLibRequestBody = "foobar"
|
||||||
|
vaultCredLibStringUpdate = "_random"
|
||||||
)
|
)
|
||||||
|
|
||||||
var vaultCredLibResource = fmt.Sprintf(`
|
var vaultCredLibResource = fmt.Sprintf(`
|
||||||
resource "boundary_credential_library_vault" "example" {
|
resource "boundary_credential_library_vault" "example" {
|
||||||
name = "%s"
|
name = "%s"
|
||||||
description = "%s"
|
description = "%s"
|
||||||
credential_store_id = boundary_credential_store_vault.example.id
|
credential_store_id = boundary_credential_store_vault.example.id
|
||||||
path = "%s"
|
path = "%s"
|
||||||
http_method = "%s"
|
http_method = "%s"
|
||||||
}`, vaultCredLibName,
|
}`, vaultCredLibName,
|
||||||
vaultCredLibDesc,
|
vaultCredLibDesc,
|
||||||
vaultCredLibPath,
|
vaultCredLibPath,
|
||||||
@@ -41,12 +43,12 @@ resource "boundary_credential_library_vault" "example" {
|
|||||||
|
|
||||||
var vaultCredLibResourceUpdate = fmt.Sprintf(`
|
var vaultCredLibResourceUpdate = fmt.Sprintf(`
|
||||||
resource "boundary_credential_library_vault" "example" {
|
resource "boundary_credential_library_vault" "example" {
|
||||||
name = "%s"
|
name = "%s"
|
||||||
description = "%s"
|
description = "%s"
|
||||||
credential_store_id = boundary_credential_store_vault.example.id
|
credential_store_id = boundary_credential_store_vault.example.id
|
||||||
path = "%s"
|
path = "%s"
|
||||||
http_method = "%s"
|
http_method = "%s"
|
||||||
http_request_body = "%s"
|
http_request_body = "%s"
|
||||||
}`, vaultCredLibName+vaultCredLibStringUpdate,
|
}`, vaultCredLibName+vaultCredLibStringUpdate,
|
||||||
vaultCredLibDesc+vaultCredLibStringUpdate,
|
vaultCredLibDesc+vaultCredLibStringUpdate,
|
||||||
vaultCredLibPath+vaultCredLibStringUpdate,
|
vaultCredLibPath+vaultCredLibStringUpdate,
|
||||||
@@ -66,6 +68,71 @@ resource "boundary_credential_library_vault" "typed_example" {
|
|||||||
vaultCredLibPath,
|
vaultCredLibPath,
|
||||||
vaultCredLibMethodGet)
|
vaultCredLibMethodGet)
|
||||||
|
|
||||||
|
var vaultUsernamePasswordMappingOverrideCredLibResource = fmt.Sprintf(`
|
||||||
|
resource "boundary_credential_library_vault" "username_password_mapping_override" {
|
||||||
|
name = "%s"
|
||||||
|
description = "%s"
|
||||||
|
credential_store_id = boundary_credential_store_vault.example.id
|
||||||
|
path = "%s"
|
||||||
|
http_method = "%s"
|
||||||
|
credential_type = "username_password"
|
||||||
|
credential_mapping_overrides = {
|
||||||
|
password_attribute = "alternative_password_label"
|
||||||
|
username_attribute = "alternative_username_label"
|
||||||
|
}
|
||||||
|
}`, vaultCredLibName,
|
||||||
|
vaultCredLibDesc,
|
||||||
|
vaultCredLibPath,
|
||||||
|
vaultCredLibMethodGet)
|
||||||
|
|
||||||
|
var vaultUsernamePasswordMappingOverrideCredLibResourceUpdate = fmt.Sprintf(`
|
||||||
|
resource "boundary_credential_library_vault" "username_password_mapping_override" {
|
||||||
|
name = "%s"
|
||||||
|
description = "%s"
|
||||||
|
credential_store_id = boundary_credential_store_vault.example.id
|
||||||
|
path = "%s"
|
||||||
|
http_method = "%s"
|
||||||
|
credential_type = "username_password"
|
||||||
|
credential_mapping_overrides = {
|
||||||
|
password_attribute = "updated_password_label"
|
||||||
|
username_attribute = "updated_username_label"
|
||||||
|
}
|
||||||
|
}`, vaultCredLibName,
|
||||||
|
vaultCredLibDesc,
|
||||||
|
vaultCredLibPath,
|
||||||
|
vaultCredLibMethodGet)
|
||||||
|
|
||||||
|
var vaultUsernamePasswordMappingOverrideCredLibResourceRemove = fmt.Sprintf(`
|
||||||
|
resource "boundary_credential_library_vault" "username_password_mapping_override" {
|
||||||
|
name = "%s"
|
||||||
|
description = "%s"
|
||||||
|
credential_store_id = boundary_credential_store_vault.example.id
|
||||||
|
path = "%s"
|
||||||
|
http_method = "%s"
|
||||||
|
credential_type = "username_password"
|
||||||
|
}`, vaultCredLibName,
|
||||||
|
vaultCredLibDesc,
|
||||||
|
vaultCredLibPath,
|
||||||
|
vaultCredLibMethodGet)
|
||||||
|
|
||||||
|
var vaultSshPrivateKeyMappingOverrideCredLibResource = fmt.Sprintf(`
|
||||||
|
resource "boundary_credential_library_vault" "ssh_private_key_mapping_override" {
|
||||||
|
name = "%s"
|
||||||
|
description = "%s"
|
||||||
|
credential_store_id = boundary_credential_store_vault.example.id
|
||||||
|
path = "%s"
|
||||||
|
http_method = "%s"
|
||||||
|
credential_type = "ssh_private_key"
|
||||||
|
credential_mapping_overrides = {
|
||||||
|
private_key_attribute = "alternative_key_label"
|
||||||
|
private_key_passphrase_attribute = "alternative_passphrase_label"
|
||||||
|
username_attribute = "alternative_username_label"
|
||||||
|
}
|
||||||
|
}`, vaultCredLibName,
|
||||||
|
vaultCredLibDesc,
|
||||||
|
vaultCredLibPath,
|
||||||
|
vaultCredLibMethodGet)
|
||||||
|
|
||||||
func TestAccCredentialLibraryVault(t *testing.T) {
|
func TestAccCredentialLibraryVault(t *testing.T) {
|
||||||
tc := controller.NewTestController(t, tcConfig...)
|
tc := controller.NewTestController(t, tcConfig...)
|
||||||
defer tc.Shutdown()
|
defer tc.Shutdown()
|
||||||
@@ -132,6 +199,74 @@ func TestAccCredentialLibraryVault(t *testing.T) {
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
importStep(vaultCredResc),
|
importStep(vaultCredResc),
|
||||||
|
|
||||||
|
{
|
||||||
|
Config: testConfig(url, fooOrg, firstProjectFoo, credStoreRes, vaultCredLibResourceUpdate, vaultUsernamePasswordMappingOverrideCredLibResource),
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
resource.TestCheckResourceAttr(vaultCredUsernamePasswordResc, NameKey, vaultCredLibName),
|
||||||
|
resource.TestCheckResourceAttr(vaultCredUsernamePasswordResc, DescriptionKey, vaultCredLibDesc),
|
||||||
|
resource.TestCheckResourceAttr(vaultCredUsernamePasswordResc, credentialLibraryVaultPathKey, vaultCredLibPath),
|
||||||
|
resource.TestCheckResourceAttr(vaultCredUsernamePasswordResc, credentialLibraryVaultHttpMethodKey, vaultCredLibMethodGet),
|
||||||
|
resource.TestCheckResourceAttr(vaultCredUsernamePasswordResc, credentialLibraryVaultHttpRequestBodyKey, ""),
|
||||||
|
resource.TestCheckResourceAttr(vaultCredUsernamePasswordResc, credentialLibraryCredentialTypeKey, "username_password"),
|
||||||
|
resource.TestCheckResourceAttr(vaultCredUsernamePasswordResc, "credential_mapping_overrides.password_attribute", "alternative_password_label"),
|
||||||
|
resource.TestCheckResourceAttr(vaultCredUsernamePasswordResc, "credential_mapping_overrides.username_attribute", "alternative_username_label"),
|
||||||
|
|
||||||
|
testAccCheckCredentialLibraryVaultResourceExists(provider, vaultCredUsernamePasswordResc),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
importStep(vaultCredResc),
|
||||||
|
|
||||||
|
{
|
||||||
|
Config: testConfig(url, fooOrg, firstProjectFoo, credStoreRes, vaultCredLibResourceUpdate, vaultUsernamePasswordMappingOverrideCredLibResourceUpdate),
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
resource.TestCheckResourceAttr(vaultCredUsernamePasswordResc, NameKey, vaultCredLibName),
|
||||||
|
resource.TestCheckResourceAttr(vaultCredUsernamePasswordResc, DescriptionKey, vaultCredLibDesc),
|
||||||
|
resource.TestCheckResourceAttr(vaultCredUsernamePasswordResc, credentialLibraryVaultPathKey, vaultCredLibPath),
|
||||||
|
resource.TestCheckResourceAttr(vaultCredUsernamePasswordResc, credentialLibraryVaultHttpMethodKey, vaultCredLibMethodGet),
|
||||||
|
resource.TestCheckResourceAttr(vaultCredUsernamePasswordResc, credentialLibraryVaultHttpRequestBodyKey, ""),
|
||||||
|
resource.TestCheckResourceAttr(vaultCredUsernamePasswordResc, credentialLibraryCredentialTypeKey, "username_password"),
|
||||||
|
resource.TestCheckResourceAttr(vaultCredUsernamePasswordResc, "credential_mapping_overrides.password_attribute", "updated_password_label"),
|
||||||
|
resource.TestCheckResourceAttr(vaultCredUsernamePasswordResc, "credential_mapping_overrides.username_attribute", "updated_username_label"),
|
||||||
|
|
||||||
|
testAccCheckCredentialLibraryVaultResourceExists(provider, vaultCredUsernamePasswordResc),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
importStep(vaultCredResc),
|
||||||
|
|
||||||
|
{
|
||||||
|
Config: testConfig(url, fooOrg, firstProjectFoo, credStoreRes, vaultCredLibResourceUpdate, vaultUsernamePasswordMappingOverrideCredLibResourceRemove),
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
resource.TestCheckResourceAttr(vaultCredUsernamePasswordResc, NameKey, vaultCredLibName),
|
||||||
|
resource.TestCheckResourceAttr(vaultCredUsernamePasswordResc, DescriptionKey, vaultCredLibDesc),
|
||||||
|
resource.TestCheckResourceAttr(vaultCredUsernamePasswordResc, credentialLibraryVaultPathKey, vaultCredLibPath),
|
||||||
|
resource.TestCheckResourceAttr(vaultCredUsernamePasswordResc, credentialLibraryVaultHttpMethodKey, vaultCredLibMethodGet),
|
||||||
|
resource.TestCheckResourceAttr(vaultCredUsernamePasswordResc, credentialLibraryVaultHttpRequestBodyKey, ""),
|
||||||
|
resource.TestCheckResourceAttr(vaultCredUsernamePasswordResc, credentialLibraryCredentialTypeKey, "username_password"),
|
||||||
|
resource.TestCheckResourceAttr(vaultCredUsernamePasswordResc, credentialLibraryCredentialMappingOverridesKey+".%", "0"),
|
||||||
|
|
||||||
|
testAccCheckCredentialLibraryVaultResourceExists(provider, vaultCredUsernamePasswordResc),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
importStep(vaultCredResc),
|
||||||
|
|
||||||
|
{
|
||||||
|
Config: testConfig(url, fooOrg, firstProjectFoo, credStoreRes, vaultCredLibResourceUpdate, vaultSshPrivateKeyMappingOverrideCredLibResource),
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
resource.TestCheckResourceAttr(vaultCredSshPrivateKeyResc, NameKey, vaultCredLibName),
|
||||||
|
resource.TestCheckResourceAttr(vaultCredSshPrivateKeyResc, DescriptionKey, vaultCredLibDesc),
|
||||||
|
resource.TestCheckResourceAttr(vaultCredSshPrivateKeyResc, credentialLibraryVaultPathKey, vaultCredLibPath),
|
||||||
|
resource.TestCheckResourceAttr(vaultCredSshPrivateKeyResc, credentialLibraryVaultHttpMethodKey, vaultCredLibMethodGet),
|
||||||
|
resource.TestCheckResourceAttr(vaultCredSshPrivateKeyResc, credentialLibraryVaultHttpRequestBodyKey, ""),
|
||||||
|
resource.TestCheckResourceAttr(vaultCredSshPrivateKeyResc, credentialLibraryCredentialTypeKey, "ssh_private_key"),
|
||||||
|
resource.TestCheckResourceAttr(vaultCredSshPrivateKeyResc, "credential_mapping_overrides.private_key_attribute", "alternative_key_label"),
|
||||||
|
resource.TestCheckResourceAttr(vaultCredSshPrivateKeyResc, "credential_mapping_overrides.private_key_passphrase_attribute", "alternative_passphrase_label"),
|
||||||
|
resource.TestCheckResourceAttr(vaultCredSshPrivateKeyResc, "credential_mapping_overrides.username_attribute", "alternative_username_label"),
|
||||||
|
|
||||||
|
testAccCheckCredentialLibraryVaultResourceExists(provider, vaultCredSshPrivateKeyResc),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
importStep(vaultCredResc),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ func setFromGroupResponseMap(d *schema.ResourceData, raw map[string]interface{})
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func resourceGroupCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
func resourceGroupCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) (errs diag.Diagnostics) {
|
||||||
md := meta.(*metaData)
|
md := meta.(*metaData)
|
||||||
|
|
||||||
var scopeId string
|
var scopeId string
|
||||||
@@ -108,7 +108,12 @@ func resourceGroupCreate(ctx context.Context, d *schema.ResourceData, meta inter
|
|||||||
if gcr == nil {
|
if gcr == nil {
|
||||||
return diag.Errorf("group nil after create")
|
return diag.Errorf("group nil after create")
|
||||||
}
|
}
|
||||||
raw := gcr.GetResponse().Map
|
apiResponse := gcr.GetResponse().Map
|
||||||
|
defer func() {
|
||||||
|
if err := setFromGroupResponseMap(d, apiResponse); err != nil {
|
||||||
|
errs = append(errs, diag.FromErr(err)...)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
if val, ok := d.GetOk(groupMemberIdsKey); ok {
|
if val, ok := d.GetOk(groupMemberIdsKey); ok {
|
||||||
list := val.(*schema.Set).List()
|
list := val.(*schema.Set).List()
|
||||||
@@ -118,16 +123,12 @@ func resourceGroupCreate(ctx context.Context, d *schema.ResourceData, meta inter
|
|||||||
}
|
}
|
||||||
gcsmr, err := grps.SetMembers(ctx, gcr.Item.Id, gcr.Item.Version, memberIds)
|
gcsmr, err := grps.SetMembers(ctx, gcr.Item.Id, gcr.Item.Version, memberIds)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return diag.Errorf("error setting principals on role: %v", err)
|
return diag.Errorf("error setting members on group: %v", err)
|
||||||
}
|
}
|
||||||
if gcsmr == nil {
|
if gcsmr == nil {
|
||||||
return diag.Errorf("group nil after setting members")
|
return diag.Errorf("group nil after setting members")
|
||||||
}
|
}
|
||||||
raw = gcsmr.GetResponse().Map
|
apiResponse = gcsmr.GetResponse().Map
|
||||||
}
|
|
||||||
|
|
||||||
if err := setFromGroupResponseMap(d, raw); err != nil {
|
|
||||||
return diag.FromErr(err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ func setFromHostSetStaticResponseMap(d *schema.ResourceData, raw map[string]inte
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func resourceHostSetStaticCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
func resourceHostSetStaticCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) (errs diag.Diagnostics) {
|
||||||
md := meta.(*metaData)
|
md := meta.(*metaData)
|
||||||
|
|
||||||
var hostsetHostCatalogId string
|
var hostsetHostCatalogId string
|
||||||
@@ -195,7 +195,12 @@ func resourceHostSetStaticCreate(ctx context.Context, d *schema.ResourceData, me
|
|||||||
if hscr == nil {
|
if hscr == nil {
|
||||||
return diag.Errorf("nil host set after create")
|
return diag.Errorf("nil host set after create")
|
||||||
}
|
}
|
||||||
raw := hscr.GetResponse().Map
|
apiResponse := hscr.GetResponse().Map
|
||||||
|
defer func() {
|
||||||
|
if err := setFromHostSetStaticResponseMap(d, apiResponse); err != nil {
|
||||||
|
errs = append(errs, diag.FromErr(err)...)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
if hostIds != nil {
|
if hostIds != nil {
|
||||||
hsshr, err := hsClient.SetHosts(ctx, hscr.Item.Id, hscr.Item.Version, hostIds)
|
hsshr, err := hsClient.SetHosts(ctx, hscr.Item.Id, hscr.Item.Version, hostIds)
|
||||||
@@ -205,11 +210,7 @@ func resourceHostSetStaticCreate(ctx context.Context, d *schema.ResourceData, me
|
|||||||
if hsshr == nil {
|
if hsshr == nil {
|
||||||
return diag.Errorf("nil host set after setting hosts")
|
return diag.Errorf("nil host set after setting hosts")
|
||||||
}
|
}
|
||||||
raw = hsshr.GetResponse().Map
|
apiResponse = hsshr.GetResponse().Map
|
||||||
}
|
|
||||||
|
|
||||||
if err := setFromHostSetStaticResponseMap(d, raw); err != nil {
|
|
||||||
return diag.FromErr(err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ func setFromRoleResponseMap(d *schema.ResourceData, raw map[string]interface{})
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func resourceRoleCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
func resourceRoleCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) (errs diag.Diagnostics) {
|
||||||
md := meta.(*metaData)
|
md := meta.(*metaData)
|
||||||
|
|
||||||
var scopeId string
|
var scopeId string
|
||||||
@@ -151,18 +151,22 @@ func resourceRoleCreate(ctx context.Context, d *schema.ResourceData, meta interf
|
|||||||
if tcr == nil {
|
if tcr == nil {
|
||||||
return diag.Errorf("nil role after create")
|
return diag.Errorf("nil role after create")
|
||||||
}
|
}
|
||||||
raw := tcr.GetResponse().Map
|
apiResponse := tcr.GetResponse().Map
|
||||||
|
defer func() {
|
||||||
|
if err := setFromRoleResponseMap(d, apiResponse); err != nil {
|
||||||
|
errs = append(errs, diag.FromErr(err)...)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
var diags diag.Diagnostics
|
|
||||||
if principalIds != nil {
|
if principalIds != nil {
|
||||||
tspr, err := rc.SetPrincipals(ctx, tcr.Item.Id, 0, principalIds, roles.WithAutomaticVersioning(true))
|
tspr, err := rc.SetPrincipals(ctx, tcr.Item.Id, 0, principalIds, roles.WithAutomaticVersioning(true))
|
||||||
switch {
|
switch {
|
||||||
case err != nil:
|
case err != nil:
|
||||||
diags = append(diags, diag.Diagnostic{Severity: diag.Error, Summary: "error setting principals", Detail: err.Error()})
|
errs = append(errs, diag.Diagnostic{Severity: diag.Error, Summary: "error setting principals", Detail: err.Error()})
|
||||||
case tspr == nil:
|
case tspr == nil:
|
||||||
diags = append(diags, diag.Diagnostic{Severity: diag.Error, Summary: "nil role after setting principal IDs"})
|
errs = append(errs, diag.Diagnostic{Severity: diag.Error, Summary: "nil role after setting principals"})
|
||||||
default:
|
default:
|
||||||
raw = tspr.GetResponse().Map
|
apiResponse = tspr.GetResponse().Map
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,19 +174,15 @@ func resourceRoleCreate(ctx context.Context, d *schema.ResourceData, meta interf
|
|||||||
tsgr, err := rc.SetGrants(ctx, tcr.Item.Id, 0, grantStrings, roles.WithAutomaticVersioning(true))
|
tsgr, err := rc.SetGrants(ctx, tcr.Item.Id, 0, grantStrings, roles.WithAutomaticVersioning(true))
|
||||||
switch {
|
switch {
|
||||||
case err != nil:
|
case err != nil:
|
||||||
diags = append(diags, diag.Diagnostic{Severity: diag.Error, Summary: "error setting grants", Detail: err.Error()})
|
errs = append(errs, diag.Diagnostic{Severity: diag.Error, Summary: "error setting grants", Detail: err.Error()})
|
||||||
case tsgr == nil:
|
case tsgr == nil:
|
||||||
diags = append(diags, diag.Diagnostic{Severity: diag.Error, Summary: "nil role after setting grant strings"})
|
errs = append(errs, diag.Diagnostic{Severity: diag.Error, Summary: "nil role after setting grants"})
|
||||||
default:
|
default:
|
||||||
raw = tsgr.GetResponse().Map
|
apiResponse = tsgr.GetResponse().Map
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := setFromRoleResponseMap(d, raw); err != nil {
|
return errs
|
||||||
return diag.FromErr(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return diags
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func resourceRoleRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
func resourceRoleRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
||||||
|
|||||||
@@ -155,7 +155,7 @@ func setFromTargetResponseMap(d *schema.ResourceData, raw map[string]interface{}
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func resourceTargetCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
func resourceTargetCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) (errs diag.Diagnostics) {
|
||||||
md := meta.(*metaData)
|
md := meta.(*metaData)
|
||||||
|
|
||||||
var scopeId string
|
var scopeId string
|
||||||
@@ -256,7 +256,6 @@ func resourceTargetCreate(ctx context.Context, d *schema.ResourceData, meta inte
|
|||||||
}
|
}
|
||||||
|
|
||||||
tc := targets.NewClient(md.client)
|
tc := targets.NewClient(md.client)
|
||||||
|
|
||||||
tcr, err := tc.Create(ctx, typeStr, scopeId, opts...)
|
tcr, err := tc.Create(ctx, typeStr, scopeId, opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return diag.Errorf("error creating target: %v", err)
|
return diag.Errorf("error creating target: %v", err)
|
||||||
@@ -264,7 +263,12 @@ func resourceTargetCreate(ctx context.Context, d *schema.ResourceData, meta inte
|
|||||||
if tcr == nil {
|
if tcr == nil {
|
||||||
return diag.Errorf("target nil after create")
|
return diag.Errorf("target nil after create")
|
||||||
}
|
}
|
||||||
raw := tcr.GetResponse().Map
|
apiResponse := tcr.GetResponse().Map
|
||||||
|
defer func() {
|
||||||
|
if err := setFromTargetResponseMap(d, apiResponse); err != nil {
|
||||||
|
errs = append(errs, diag.FromErr(err)...)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
version := tcr.Item.Version
|
version := tcr.Item.Version
|
||||||
if hostSourceIds != nil {
|
if hostSourceIds != nil {
|
||||||
@@ -272,7 +276,10 @@ func resourceTargetCreate(ctx context.Context, d *schema.ResourceData, meta inte
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return diag.Errorf("error setting host sources on target: %v", err)
|
return diag.Errorf("error setting host sources on target: %v", err)
|
||||||
}
|
}
|
||||||
raw = tur.GetResponse().Map
|
if tur == nil {
|
||||||
|
return diag.Errorf("nil target after setting host sources")
|
||||||
|
}
|
||||||
|
apiResponse = tur.GetResponse().Map
|
||||||
version = tur.Item.Version
|
version = tur.Item.Version
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -288,11 +295,10 @@ func resourceTargetCreate(ctx context.Context, d *schema.ResourceData, meta inte
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return diag.Errorf("error setting credential sources on target: %v", err)
|
return diag.Errorf("error setting credential sources on target: %v", err)
|
||||||
}
|
}
|
||||||
raw = tur.GetResponse().Map
|
if tur == nil {
|
||||||
}
|
return diag.Errorf("nil target after setting credential sources")
|
||||||
|
}
|
||||||
if err := setFromTargetResponseMap(d, raw); err != nil {
|
apiResponse = tur.GetResponse().Map
|
||||||
return diag.FromErr(err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"regexp"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/hashicorp/boundary/api"
|
"github.com/hashicorp/boundary/api"
|
||||||
@@ -130,6 +131,21 @@ resource "boundary_target" "foo" {
|
|||||||
session_connection_limit = 7
|
session_connection_limit = 7
|
||||||
worker_filter = "type == \"bar\""
|
worker_filter = "type == \"bar\""
|
||||||
}`, fooTargetDescriptionUpdate)
|
}`, fooTargetDescriptionUpdate)
|
||||||
|
|
||||||
|
fooTargetPartialSuccess = fmt.Sprintf(`
|
||||||
|
resource "boundary_target" "foo" {
|
||||||
|
name = "expected_to_fail"
|
||||||
|
description = "%s"
|
||||||
|
type = "tcp"
|
||||||
|
scope_id = boundary_scope.proj1.id
|
||||||
|
default_port = 80
|
||||||
|
depends_on = [boundary_role.proj1_admin]
|
||||||
|
session_max_seconds = 7000
|
||||||
|
session_connection_limit = 7
|
||||||
|
injected_application_credential_source_ids = [
|
||||||
|
boundary_credential_library_vault.bar.id
|
||||||
|
]
|
||||||
|
}`, fooTargetDescription)
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestAccTarget(t *testing.T) {
|
func TestAccTarget(t *testing.T) {
|
||||||
@@ -200,6 +216,37 @@ func TestAccTarget(t *testing.T) {
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
importStep("boundary_target.foo"),
|
importStep("boundary_target.foo"),
|
||||||
|
{
|
||||||
|
// test updating state file when the target is created, but fails on associating an invalid injected credential source to a tcp target type
|
||||||
|
Config: testConfig(url, fooOrg, firstProjectFoo, credStoreRes, fooBarCredLibs, fooTargetPartialSuccess),
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckTargetResourceExists(provider, "boundary_target.foo"),
|
||||||
|
resource.TestCheckResourceAttr("boundary_target.foo", DescriptionKey, ""),
|
||||||
|
resource.TestCheckResourceAttr("boundary_target.foo", targetDefaultPortKey, "80"),
|
||||||
|
resource.TestCheckResourceAttr("boundary_target.foo", targetSessionMaxSecondsKey, "7000"),
|
||||||
|
resource.TestCheckResourceAttr("boundary_target.foo", targetSessionConnectionLimitKey, "7"),
|
||||||
|
resource.TestCheckResourceAttr("boundary_target.foo", targetHostSourceIdsKey+".%", "0"),
|
||||||
|
resource.TestCheckResourceAttr("boundary_target.foo", targetInjectedAppCredentialSourceIdsKey+".%", "0"),
|
||||||
|
),
|
||||||
|
ExpectError: regexp.MustCompile("Unable to set credential sources in target: tcp.VetCredentialSources: tcp.Target only supports credential purpose"),
|
||||||
|
},
|
||||||
|
importStep("boundary_target.foo", targetInjectedAppCredentialSourceIdsKey),
|
||||||
|
{
|
||||||
|
// test resolving invalid injected credential source error without raising duplicate name error, due to state file not being in sync.
|
||||||
|
Config: testConfig(url, fooOrg, firstProjectFoo, credStoreRes, fooBarCredLibs, fooTargetUpdateUnsetHostAndCredSources),
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckTargetResourceExists(provider, "boundary_target.foo"),
|
||||||
|
resource.TestCheckResourceAttr("boundary_target.foo", DescriptionKey, fooTargetDescriptionUpdate),
|
||||||
|
resource.TestCheckResourceAttr("boundary_target.foo", targetDefaultPortKey, "80"),
|
||||||
|
resource.TestCheckResourceAttr("boundary_target.foo", targetSessionMaxSecondsKey, "7000"),
|
||||||
|
resource.TestCheckResourceAttr("boundary_target.foo", targetSessionConnectionLimitKey, "7"),
|
||||||
|
resource.TestCheckResourceAttr("boundary_target.foo", targetWorkerFilterKey, `type == "bar"`),
|
||||||
|
resource.TestCheckResourceAttr("boundary_target.foo", targetHostSourceIdsKey+".%", "0"),
|
||||||
|
resource.TestCheckResourceAttr("boundary_target.foo", targetInjectedAppCredentialSourceIdsKey+".%", "0"),
|
||||||
|
resource.TestCheckResourceAttr("boundary_target.foo", targetBrokeredCredentialSourceIdsKey+".%", "0"),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
importStep("boundary_target.foo"),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ func setFromUserResponseMap(d *schema.ResourceData, raw map[string]interface{})
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func resourceUserCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
|
func resourceUserCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) (errs diag.Diagnostics) {
|
||||||
md := meta.(*metaData)
|
md := meta.(*metaData)
|
||||||
|
|
||||||
var scopeId string
|
var scopeId string
|
||||||
@@ -106,7 +106,12 @@ func resourceUserCreate(ctx context.Context, d *schema.ResourceData, meta interf
|
|||||||
if ucr == nil {
|
if ucr == nil {
|
||||||
return diag.Errorf("user nil after create")
|
return diag.Errorf("user nil after create")
|
||||||
}
|
}
|
||||||
raw := ucr.GetResponse().Map
|
apiResponse := ucr.GetResponse().Map
|
||||||
|
defer func() {
|
||||||
|
if err := setFromUserResponseMap(d, apiResponse); err != nil {
|
||||||
|
errs = append(errs, diag.FromErr(err)...)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
if val, ok := d.GetOk(userAccountIDsKey); ok {
|
if val, ok := d.GetOk(userAccountIDsKey); ok {
|
||||||
list := val.(*schema.Set).List()
|
list := val.(*schema.Set).List()
|
||||||
@@ -121,11 +126,7 @@ func resourceUserCreate(ctx context.Context, d *schema.ResourceData, meta interf
|
|||||||
if usrac == nil {
|
if usrac == nil {
|
||||||
return diag.Errorf("user nil after setting accounts")
|
return diag.Errorf("user nil after setting accounts")
|
||||||
}
|
}
|
||||||
raw = usrac.GetResponse().Map
|
apiResponse = usrac.GetResponse().Map
|
||||||
}
|
|
||||||
|
|
||||||
if err := setFromUserResponseMap(d, raw); err != nil {
|
|
||||||
return diag.FromErr(err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
Reference in new issue
Block a user