Move core provider factory functionality to the provider package. (#1884)

Currently, it is not possible to test meta.NewProviderMeta since it
depends the vault.Provider(), which creates a cyclical dependency. It
also makes sense that the provider factory would be in the lower level
'provider' package.

* Update NewProvider(), make arg names more distinct
This commit is contained in:
Ben Ash 2023-06-02 22:51:33 -04:00 committed by GitHub
parent f9ab0c6616
commit 6c32245a2a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
155 changed files with 479 additions and 444 deletions

View file

@ -12,8 +12,10 @@ import (
"os"
"sort"
"github.com/hashicorp/terraform-provider-vault/vault"
"github.com/hashicorp/vault/sdk/framework"
"github.com/hashicorp/terraform-provider-vault/internal/provider"
"github.com/hashicorp/terraform-provider-vault/vault"
)
var pathToOpenAPIDoc = flag.String("openapi-doc", "", "path/to/openapi.json")
@ -89,7 +91,7 @@ func main() {
}
}
func checkRegistry(registryType string, registry map[string]*vault.Description, vaultPaths map[string]map[string]bool) {
func checkRegistry(registryType string, registry map[string]*provider.Description, vaultPaths map[string]map[string]bool) {
for _, desc := range registry {
for _, path := range desc.PathInventory {
if path == vault.GenericPath || path == vault.UnknownPath {

View file

@ -15,14 +15,13 @@ import (
"github.com/hashicorp/terraform-provider-vault/internal/provider"
"github.com/hashicorp/terraform-provider-vault/util"
"github.com/hashicorp/terraform-provider-vault/vault"
)
const roleNameEndpoint = "/transform/decode/{role_name}"
func RoleNameDataSource() *schema.Resource {
return &schema.Resource{
Read: vault.ReadWrapper(readRoleNameResource),
Read: provider.ReadWrapper(readRoleNameResource),
Schema: map[string]*schema.Schema{
"path": {
Type: schema.TypeString,

View file

@ -15,14 +15,13 @@ import (
"github.com/hashicorp/terraform-provider-vault/internal/provider"
"github.com/hashicorp/terraform-provider-vault/util"
"github.com/hashicorp/terraform-provider-vault/vault"
)
const roleNameEndpoint = "/transform/encode/{role_name}"
func RoleNameDataSource() *schema.Resource {
return &schema.Resource{
Read: vault.ReadWrapper(readRoleNameResource),
Read: provider.ReadWrapper(readRoleNameResource),
Schema: map[string]*schema.Schema{
"path": {
Type: schema.TypeString,

View file

@ -15,7 +15,6 @@ import (
"github.com/hashicorp/terraform-provider-vault/internal/provider"
"github.com/hashicorp/terraform-provider-vault/util"
"github.com/hashicorp/terraform-provider-vault/vault"
)
const nameEndpoint = "/transform/alphabet/{name}"
@ -46,7 +45,7 @@ func NameResource() *schema.Resource {
return &schema.Resource{
Create: createNameResource,
Update: updateNameResource,
Read: vault.ReadWrapper(readNameResource),
Read: provider.ReadWrapper(readNameResource),
Exists: resourceNameExists,
Delete: deleteNameResource,
Importer: &schema.ResourceImporter{

View file

@ -15,7 +15,6 @@ import (
"github.com/hashicorp/terraform-provider-vault/internal/provider"
"github.com/hashicorp/terraform-provider-vault/util"
"github.com/hashicorp/terraform-provider-vault/vault"
)
const nameEndpoint = "/transform/role/{name}"
@ -47,7 +46,7 @@ func NameResource() *schema.Resource {
return &schema.Resource{
Create: createNameResource,
Update: updateNameResource,
Read: vault.ReadWrapper(readNameResource),
Read: provider.ReadWrapper(readNameResource),
Exists: resourceNameExists,
Delete: deleteNameResource,
Importer: &schema.ResourceImporter{

View file

@ -15,7 +15,6 @@ import (
"github.com/hashicorp/terraform-provider-vault/internal/provider"
"github.com/hashicorp/terraform-provider-vault/util"
"github.com/hashicorp/terraform-provider-vault/vault"
)
const (
@ -89,7 +88,7 @@ Only applicable to FPE transformations.`,
return &schema.Resource{
Create: createNameResource,
Update: updateNameResource,
Read: vault.ReadWrapper(readNameResource),
Read: provider.ReadWrapper(readNameResource),
Exists: resourceNameExists,
Delete: deleteNameResource,
Importer: &schema.ResourceImporter{

View file

@ -15,7 +15,6 @@ import (
"github.com/hashicorp/terraform-provider-vault/internal/provider"
"github.com/hashicorp/terraform-provider-vault/util"
"github.com/hashicorp/terraform-provider-vault/vault"
)
const nameEndpoint = "/transform/transformation/{name}"
@ -81,7 +80,7 @@ func NameResource() *schema.Resource {
return &schema.Resource{
Create: createNameResource,
Update: updateNameResource,
Read: vault.ReadWrapper(readNameResource),
Read: provider.ReadWrapper(readNameResource),
Exists: resourceNameExists,
Delete: deleteNameResource,
Importer: &schema.ResourceImporter{

View file

@ -0,0 +1,297 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package provider
import (
"context"
"fmt"
"log"
"os"
"github.com/hashicorp/go-multierror"
"github.com/hashicorp/go-version"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/vault/api"
"github.com/hashicorp/terraform-provider-vault/internal/consts"
)
const DefaultMaxHTTPRetriesCCC = 10
// Description is essentially a DataSource or Resource with some additional metadata
// that helps with maintaining the Terraform Vault Provider.
type Description struct {
// PathInventory is used for taking an inventory of the supported endpoints in the
// Terraform Vault Provider and comparing them to the endpoints noted as available in
// Vault's OpenAPI description. A list of Vault's endpoints can be obtained by,
// from Vault's home directory, running "$ ./scripts/gen_openapi.sh", and then by
// drilling into the paths with "$ cat openapi.json | jq ".paths" | jq 'keys[]'".
// Here's a short example of how paths and their path variables should be represented:
// "/transit/keys/{name}/config"
// "/transit/random"
// "/transit/random/{urlbytes}"
// "/transit/sign/{name}/{urlalgorithm}"
PathInventory []string
// EnterpriseOnly defaults to false, but should be marked true if a resource is enterprise only.
EnterpriseOnly bool
Resource *schema.Resource
}
type ResourceRegistry map[string]*Description
type ResourcesMap map[string]*schema.Resource
func NewProvider(
dataRegistry ResourceRegistry,
resourceRegistry ResourceRegistry,
extraResourcesMaps ...ResourcesMap,
) *schema.Provider {
dataSourcesMap, err := parse(dataRegistry)
if err != nil {
panic(err)
}
coreResourcesMap, err := parse(resourceRegistry)
if err != nil {
panic(err)
}
for _, m := range extraResourcesMaps {
MustAddSchemaResource(m, coreResourcesMap, nil)
}
r := &schema.Provider{
Schema: map[string]*schema.Schema{
consts.FieldAddress: {
Type: schema.TypeString,
Required: true,
DefaultFunc: schema.EnvDefaultFunc(api.EnvVaultAddress, nil),
Description: "URL of the root of the target Vault server.",
},
"add_address_to_env": {
Type: schema.TypeString,
Optional: true,
Default: false,
Description: "If true, adds the value of the `address` argument to the Terraform process environment.",
},
"token": {
Type: schema.TypeString,
Required: true,
DefaultFunc: schema.EnvDefaultFunc(api.EnvVaultToken, ""),
Description: "Token to use to authenticate to Vault.",
},
"token_name": {
Type: schema.TypeString,
Optional: true,
DefaultFunc: schema.EnvDefaultFunc("VAULT_TOKEN_NAME", ""),
Description: "Token name to use for creating the Vault child token.",
},
"skip_child_token": {
Type: schema.TypeBool,
Optional: true,
DefaultFunc: schema.EnvDefaultFunc("TERRAFORM_VAULT_SKIP_CHILD_TOKEN", false),
// Setting to true will cause max_lease_ttl_seconds and token_name to be ignored (not used).
// Note that this is strongly discouraged due to the potential of exposing sensitive secret data.
Description: "Set this to true to prevent the creation of ephemeral child token used by this provider.",
},
consts.FieldCACertFile: {
Type: schema.TypeString,
Optional: true,
DefaultFunc: schema.EnvDefaultFunc(api.EnvVaultCACert, ""),
Description: "Path to a CA certificate file to validate the server's certificate.",
},
consts.FieldCACertDir: {
Type: schema.TypeString,
Optional: true,
DefaultFunc: schema.EnvDefaultFunc(api.EnvVaultCAPath, ""),
Description: "Path to directory containing CA certificate files to validate the server's certificate.",
},
consts.FieldClientAuth: {
Type: schema.TypeList,
Optional: true,
Description: "Client authentication credentials.",
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
consts.FieldCertFile: {
Type: schema.TypeString,
Required: true,
DefaultFunc: schema.EnvDefaultFunc(api.EnvVaultClientCert, ""),
Description: "Path to a file containing the client certificate.",
},
consts.FieldKeyFile: {
Type: schema.TypeString,
Required: true,
DefaultFunc: schema.EnvDefaultFunc(api.EnvVaultClientKey, ""),
Description: "Path to a file containing the private key that the certificate was issued for.",
},
},
},
},
consts.FieldSkipTLSVerify: {
Type: schema.TypeBool,
Optional: true,
DefaultFunc: schema.EnvDefaultFunc("VAULT_SKIP_VERIFY", false),
Description: "Set this to true only if the target Vault server is an insecure development instance.",
},
consts.FieldTLSServerName: {
Type: schema.TypeString,
Optional: true,
DefaultFunc: schema.EnvDefaultFunc(api.EnvVaultTLSServerName, ""),
Description: "Name to use as the SNI host when connecting via TLS.",
},
"max_lease_ttl_seconds": {
Type: schema.TypeInt,
Optional: true,
// Default is 20min, which is intended to be enough time for
// a reasonable Terraform run can complete but not
// significantly longer, so that any leases are revoked shortly
// after Terraform has finished running.
DefaultFunc: schema.EnvDefaultFunc("TERRAFORM_VAULT_MAX_TTL", 1200),
Description: "Maximum TTL for secret leases requested by this provider.",
},
"max_retries": {
Type: schema.TypeInt,
Optional: true,
DefaultFunc: schema.EnvDefaultFunc("VAULT_MAX_RETRIES", DefaultMaxHTTPRetries),
Description: "Maximum number of retries when a 5xx error code is encountered.",
},
"max_retries_ccc": {
Type: schema.TypeInt,
Optional: true,
DefaultFunc: schema.EnvDefaultFunc("VAULT_MAX_RETRIES_CCC", DefaultMaxHTTPRetriesCCC),
Description: "Maximum number of retries for Client Controlled Consistency related operations",
},
consts.FieldNamespace: {
Type: schema.TypeString,
Optional: true,
DefaultFunc: schema.EnvDefaultFunc("VAULT_NAMESPACE", ""),
Description: "The namespace to use. Available only for Vault Enterprise.",
},
"headers": {
Type: schema.TypeList,
Optional: true,
Sensitive: true,
Description: "The headers to send with each Vault request.",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
Description: "The header name",
},
"value": {
Type: schema.TypeString,
Required: true,
Description: "The header value",
},
},
},
},
consts.FieldSkipGetVaultVersion: {
Type: schema.TypeBool,
Optional: true,
Default: false,
Description: "Skip the dynamic fetching of the Vault server version.",
},
consts.FieldVaultVersionOverride: {
Type: schema.TypeString,
Optional: true,
Description: "Override the Vault server version, " +
"which is normally determined dynamically from the target Vault server",
ValidateDiagFunc: ValidateDiagSemVer,
},
},
ConfigureFunc: NewProviderMeta,
DataSourcesMap: dataSourcesMap,
ResourcesMap: coreResourcesMap,
}
MustAddAuthLoginSchema(r.Schema)
return r
}
func parse(descs map[string]*Description) (map[string]*schema.Resource, error) {
var errs error
resourceMap := make(map[string]*schema.Resource)
for k, desc := range descs {
resourceMap[k] = desc.Resource
if len(desc.PathInventory) == 0 {
errs = multierror.Append(errs, fmt.Errorf("%q needs its paths inventoried", k))
}
}
return resourceMap, errs
}
// ReadWrapper provides common read operations to the wrapped schema.ReadFunc.
func ReadWrapper(f schema.ReadFunc) schema.ReadFunc {
return func(d *schema.ResourceData, i interface{}) error {
if err := importNamespace(d); err != nil {
return err
}
return f(d, i)
}
}
// ReadContextWrapper provides common read operations to the wrapped schema.ReadContextFunc.
func ReadContextWrapper(f schema.ReadContextFunc) schema.ReadContextFunc {
return func(ctx context.Context, d *schema.ResourceData, i interface{}) diag.Diagnostics {
if err := importNamespace(d); err != nil {
return diag.FromErr(err)
}
return f(ctx, d, i)
}
}
// MountCreateContextWrapper performs a minimum version requirement check prior to the
// wrapped schema.CreateContextFunc.
func MountCreateContextWrapper(f schema.CreateContextFunc, minVersion *version.Version) schema.CreateContextFunc {
return func(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
currentVersion := meta.(*ProviderMeta).GetVaultVersion()
if !IsAPISupported(meta, minVersion) {
return diag.Errorf("feature not enabled on current Vault version. min version required=%s; "+
"current vault version=%s", minVersion, currentVersion)
}
return f(ctx, d, meta)
}
}
func importNamespace(d *schema.ResourceData) error {
if ns := os.Getenv(consts.EnvVarVaultNamespaceImport); ns != "" {
s := d.State()
var attemptNamespaceImport bool
if s.Empty() {
// state does not yet exist or is empty
// import is acceptable
attemptNamespaceImport = true
} else {
// only import if namespace
// is not already set in state
s.Lock()
defer s.Unlock()
_, ok := s.Attributes[consts.FieldNamespace]
attemptNamespaceImport = !ok
}
if attemptNamespaceImport {
log.Printf(`[INFO] Environment variable %s set, `+
`attempting TF state import "%s=%s"`,
consts.EnvVarVaultNamespaceImport, consts.FieldNamespace, ns)
if err := d.Set(consts.FieldNamespace, ns); err != nil {
return fmt.Errorf("failed to import %q, err=%w",
consts.EnvVarVaultNamespaceImport, err)
}
}
}
return nil
}

View file

@ -92,7 +92,7 @@ var (
func identityEntityDataSource() *schema.Resource {
return &schema.Resource{
Read: ReadWrapper(identityEntityDataSourceRead),
Read: provider.ReadWrapper(identityEntityDataSourceRead),
Schema: map[string]*schema.Schema{
"entity_name": {

View file

@ -46,7 +46,7 @@ var (
func identityGroupDataSource() *schema.Resource {
return &schema.Resource{
Read: ReadWrapper(identityGroupDataSourceRead),
Read: provider.ReadWrapper(identityGroupDataSourceRead),
Schema: map[string]*schema.Schema{
"group_name": {

View file

@ -14,7 +14,7 @@ import (
func identityOIDCClientCredsDataSource() *schema.Resource {
return &schema.Resource{
Read: ReadWrapper(readOIDCClientCredsResource),
Read: provider.ReadWrapper(readOIDCClientCredsResource),
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,

View file

@ -18,7 +18,7 @@ const identityOIDCOpenIDConfigPathSuffix = "/.well-known/openid-configuration"
func identityOIDCOpenIDConfigDataSource() *schema.Resource {
return &schema.Resource{
Read: ReadWrapper(readOIDCOpenIDConfigResource),
Read: provider.ReadWrapper(readOIDCOpenIDConfigResource),
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,

View file

@ -18,7 +18,7 @@ const identityOIDCPublicKeysPathSuffix = "/.well-known/keys"
func identityOIDCPublicKeysDataSource() *schema.Resource {
return &schema.Resource{
Read: ReadWrapper(readOIDCPublicKeysResource),
Read: provider.ReadWrapper(readOIDCPublicKeysResource),
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,

View file

@ -15,7 +15,7 @@ import (
func adAccessCredentialsDataSource() *schema.Resource {
return &schema.Resource{
DeprecationMessage: `This data source is replaced by "vault_ldap_static_credentials" and will be removed in the next major release.`,
Read: ReadWrapper(readCredsResource),
Read: provider.ReadWrapper(readCredsResource),
Schema: map[string]*schema.Schema{
"backend": {
Type: schema.TypeString,

View file

@ -15,7 +15,7 @@ import (
func approleAuthBackendRoleIDDataSource() *schema.Resource {
return &schema.Resource{
Read: ReadWrapper(approleAuthBackendRoleIDRead),
Read: provider.ReadWrapper(approleAuthBackendRoleIDRead),
Schema: map[string]*schema.Schema{
"role_name": {

View file

@ -14,7 +14,7 @@ import (
func authBackendDataSource() *schema.Resource {
return &schema.Resource{
Read: ReadWrapper(authBackendDataSourceRead),
Read: provider.ReadWrapper(authBackendDataSourceRead),
Schema: map[string]*schema.Schema{
"path": {
Type: schema.TypeString,

View file

@ -8,13 +8,14 @@ import (
"strings"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-provider-vault/internal/consts"
"github.com/hashicorp/terraform-provider-vault/internal/provider"
)
func authBackendsDataSource() *schema.Resource {
return &schema.Resource{
Read: ReadWrapper(authBackendsDataSourceRead),
Read: provider.ReadWrapper(authBackendsDataSourceRead),
Schema: map[string]*schema.Schema{
consts.FieldPaths: {
Type: schema.TypeList,

View file

@ -43,7 +43,7 @@ const (
func awsAccessCredentialsDataSource() *schema.Resource {
return &schema.Resource{
Read: ReadWrapper(awsAccessCredentialsDataSourceRead),
Read: provider.ReadWrapper(awsAccessCredentialsDataSourceRead),
Schema: map[string]*schema.Schema{
"backend": {

View file

@ -24,7 +24,7 @@ import (
func azureAccessCredentialsDataSource() *schema.Resource {
return &schema.Resource{
Read: ReadWrapper(azureAccessCredentialsDataSourceRead),
Read: provider.ReadWrapper(azureAccessCredentialsDataSourceRead),
Schema: map[string]*schema.Schema{
"backend": {

View file

@ -106,7 +106,7 @@ func gcpAuthBackendRoleDataSource() *schema.Resource {
addTokenFields(fields, &addTokenFieldsConfig{})
return &schema.Resource{
Read: ReadWrapper(gcpAuthBackendRoleRead),
Read: provider.ReadWrapper(gcpAuthBackendRoleRead),
Schema: fields,
}
}

View file

@ -17,7 +17,7 @@ import (
func genericSecretDataSource() *schema.Resource {
return &schema.Resource{
Read: ReadWrapper(genericSecretDataSourceRead),
Read: provider.ReadWrapper(genericSecretDataSourceRead),
Schema: map[string]*schema.Schema{
consts.FieldPath: {

View file

@ -15,7 +15,7 @@ import (
func kubernetesAuthBackendConfigDataSource() *schema.Resource {
return &schema.Resource{
Read: ReadWrapper(kubernetesAuthBackendConfigDataSourceRead),
Read: provider.ReadWrapper(kubernetesAuthBackendConfigDataSourceRead),
Schema: map[string]*schema.Schema{
"backend": {
Type: schema.TypeString,

View file

@ -61,7 +61,7 @@ func kubernetesAuthBackendRoleDataSource() *schema.Resource {
addTokenFields(fields, &addTokenFieldsConfig{})
return &schema.Resource{
Read: ReadWrapper(kubernetesAuthBackendRoleDataSourceRead),
Read: provider.ReadWrapper(kubernetesAuthBackendRoleDataSourceRead),
Schema: fields,
}
}

View file

@ -9,6 +9,7 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-provider-vault/internal/consts"
"github.com/hashicorp/terraform-provider-vault/internal/provider"
)
@ -22,7 +23,7 @@ const (
func kubernetesServiceAccountTokenDataSource() *schema.Resource {
return &schema.Resource{
ReadContext: ReadContextWrapper(readKubernetesServiceAccountToken),
ReadContext: provider.ReadContextWrapper(readKubernetesServiceAccountToken),
Schema: map[string]*schema.Schema{
consts.FieldBackend: {
Type: schema.TypeString,

View file

@ -17,7 +17,7 @@ import (
func kvSecretDataSource() *schema.Resource {
return &schema.Resource{
ReadContext: ReadContextWrapper(kvSecretDataSourceRead),
ReadContext: provider.ReadContextWrapper(kvSecretDataSourceRead),
Schema: map[string]*schema.Schema{
consts.FieldPath: {

View file

@ -19,7 +19,7 @@ import (
func kvSecretV2DataSource() *schema.Resource {
return &schema.Resource{
ReadContext: ReadContextWrapper(kvSecretV2DataSourceRead),
ReadContext: provider.ReadContextWrapper(kvSecretV2DataSourceRead),
Schema: map[string]*schema.Schema{
consts.FieldMount: {

View file

@ -15,7 +15,7 @@ import (
func kvSecretListDataSource() *schema.Resource {
return &schema.Resource{
ReadContext: ReadContextWrapper(kvSecretListDataSourceRead),
ReadContext: provider.ReadContextWrapper(kvSecretListDataSourceRead),
Schema: map[string]*schema.Schema{
consts.FieldPath: {

View file

@ -15,7 +15,7 @@ import (
func kvSecretListDataSourceV2() *schema.Resource {
return &schema.Resource{
ReadContext: ReadContextWrapper(kvSecretV2ListDataSourceRead),
ReadContext: provider.ReadContextWrapper(kvSecretV2ListDataSourceRead),
Schema: map[string]*schema.Schema{
consts.FieldMount: {

View file

@ -18,7 +18,7 @@ import (
func kvSecretSubkeysV2DataSource() *schema.Resource {
return &schema.Resource{
ReadContext: ReadContextWrapper(kvSecretSubkeysDataSourceRead),
ReadContext: provider.ReadContextWrapper(kvSecretSubkeysDataSourceRead),
Schema: map[string]*schema.Schema{
consts.FieldMount: {

View file

@ -18,7 +18,7 @@ import (
func ldapDynamicCredDataSource() *schema.Resource {
return &schema.Resource{
ReadContext: ReadContextWrapper(readLDAPDynamicCreds),
ReadContext: provider.ReadContextWrapper(readLDAPDynamicCreds),
Schema: map[string]*schema.Schema{
consts.FieldMount: {
Type: schema.TypeString,
@ -120,9 +120,7 @@ type lDAPDynamicCredResponse struct {
}
func parseLDAPDynamicCredSecret(secret *api.Secret) (lDAPDynamicCredResponse, error) {
var (
distinguishedNames []string
)
var distinguishedNames []string
if distinguishedNamesRaw, ok := secret.Data[consts.FieldDistinguishedNames]; ok {
for _, dnRaw := range distinguishedNamesRaw.([]interface{}) {
distinguishedNames = append(distinguishedNames, dnRaw.(string))

View file

@ -19,7 +19,7 @@ import (
func ldapStaticCredDataSource() *schema.Resource {
return &schema.Resource{
ReadContext: ReadContextWrapper(readLDAPStaticCreds),
ReadContext: provider.ReadContextWrapper(readLDAPStaticCreds),
Schema: map[string]*schema.Schema{
consts.FieldMount: {
Type: schema.TypeString,

View file

@ -14,7 +14,7 @@ import (
func nomadAccessCredentialsDataSource() *schema.Resource {
return &schema.Resource{
Read: ReadWrapper(readNomadCredsResource),
Read: provider.ReadWrapper(readNomadCredsResource),
Schema: map[string]*schema.Schema{
"backend": {
Type: schema.TypeString,

View file

@ -12,6 +12,7 @@ import (
"github.com/hashicorp/terraform-provider-vault/helper"
"github.com/hashicorp/terraform-provider-vault/internal/consts"
"github.com/hashicorp/terraform-provider-vault/internal/provider"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)
@ -44,7 +45,7 @@ var allowedCapabilities = []string{
func policyDocumentDataSource() *schema.Resource {
return &schema.Resource{
Read: ReadWrapper(policyDocumentDataSourceRead),
Read: provider.ReadWrapper(policyDocumentDataSourceRead),
Schema: map[string]*schema.Schema{
"rule": {
Type: schema.TypeList,

View file

@ -100,7 +100,7 @@ func raftAutopilotStateDataSource() *schema.Resource {
},
}
return &schema.Resource{
Read: ReadWrapper(raftAutopilotStateDataSourceRead),
Read: provider.ReadWrapper(raftAutopilotStateDataSourceRead),
Schema: fields,
}
}

View file

@ -14,7 +14,7 @@ import (
func transitDecryptDataSource() *schema.Resource {
return &schema.Resource{
Read: ReadWrapper(transitDecryptDataSourceRead),
Read: provider.ReadWrapper(transitDecryptDataSourceRead),
Schema: map[string]*schema.Schema{
"key": {

View file

@ -14,7 +14,7 @@ import (
func transitEncryptDataSource() *schema.Resource {
return &schema.Resource{
Read: ReadWrapper(transitEncryptDataSourceRead),
Read: provider.ReadWrapper(transitEncryptDataSourceRead),
Schema: map[string]*schema.Schema{
"key": {

View file

@ -4,18 +4,8 @@
package vault
import (
"context"
"fmt"
"log"
"os"
"github.com/hashicorp/go-multierror"
"github.com/hashicorp/go-version"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/vault/api"
"github.com/hashicorp/terraform-provider-vault/internal/consts"
"github.com/hashicorp/terraform-provider-vault/internal/identity/mfa"
"github.com/hashicorp/terraform-provider-vault/internal/provider"
)
@ -35,20 +25,10 @@ const (
// DefaultMaxHTTPRetriesCCC is used for configuring the api.Client's MaxRetries
// for Client Controlled Consistency related operations.
DefaultMaxHTTPRetriesCCC = 10
DefaultMaxHTTPRetriesCCC = provider.DefaultMaxHTTPRetriesCCC
)
func Provider() *schema.Provider {
dataSourcesMap, err := parse(DataSourceRegistry)
if err != nil {
panic(err)
}
resourcesMap, err := parse(ResourceRegistry)
if err != nil {
panic(err)
}
// TODO: add support path inventory, probably means
// reworking the registry init entirely.
mfaResources, err := mfa.GetResources()
@ -56,185 +36,11 @@ func Provider() *schema.Provider {
panic(err)
}
provider.MustAddSchemaResource(mfaResources, resourcesMap, nil)
r := &schema.Provider{
Schema: map[string]*schema.Schema{
consts.FieldAddress: {
Type: schema.TypeString,
Required: true,
DefaultFunc: schema.EnvDefaultFunc(api.EnvVaultAddress, nil),
Description: "URL of the root of the target Vault server.",
},
"add_address_to_env": {
Type: schema.TypeString,
Optional: true,
Default: false,
Description: "If true, adds the value of the `address` argument to the Terraform process environment.",
},
"token": {
Type: schema.TypeString,
Required: true,
DefaultFunc: schema.EnvDefaultFunc(api.EnvVaultToken, ""),
Description: "Token to use to authenticate to Vault.",
},
"token_name": {
Type: schema.TypeString,
Optional: true,
DefaultFunc: schema.EnvDefaultFunc("VAULT_TOKEN_NAME", ""),
Description: "Token name to use for creating the Vault child token.",
},
"skip_child_token": {
Type: schema.TypeBool,
Optional: true,
DefaultFunc: schema.EnvDefaultFunc("TERRAFORM_VAULT_SKIP_CHILD_TOKEN", false),
// Setting to true will cause max_lease_ttl_seconds and token_name to be ignored (not used).
// Note that this is strongly discouraged due to the potential of exposing sensitive secret data.
Description: "Set this to true to prevent the creation of ephemeral child token used by this provider.",
},
consts.FieldCACertFile: {
Type: schema.TypeString,
Optional: true,
DefaultFunc: schema.EnvDefaultFunc(api.EnvVaultCACert, ""),
Description: "Path to a CA certificate file to validate the server's certificate.",
},
consts.FieldCACertDir: {
Type: schema.TypeString,
Optional: true,
DefaultFunc: schema.EnvDefaultFunc(api.EnvVaultCAPath, ""),
Description: "Path to directory containing CA certificate files to validate the server's certificate.",
},
consts.FieldClientAuth: {
Type: schema.TypeList,
Optional: true,
Description: "Client authentication credentials.",
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
consts.FieldCertFile: {
Type: schema.TypeString,
Required: true,
DefaultFunc: schema.EnvDefaultFunc(api.EnvVaultClientCert, ""),
Description: "Path to a file containing the client certificate.",
},
consts.FieldKeyFile: {
Type: schema.TypeString,
Required: true,
DefaultFunc: schema.EnvDefaultFunc(api.EnvVaultClientKey, ""),
Description: "Path to a file containing the private key that the certificate was issued for.",
},
},
},
},
consts.FieldSkipTLSVerify: {
Type: schema.TypeBool,
Optional: true,
DefaultFunc: schema.EnvDefaultFunc("VAULT_SKIP_VERIFY", false),
Description: "Set this to true only if the target Vault server is an insecure development instance.",
},
consts.FieldTLSServerName: {
Type: schema.TypeString,
Optional: true,
DefaultFunc: schema.EnvDefaultFunc(api.EnvVaultTLSServerName, ""),
Description: "Name to use as the SNI host when connecting via TLS.",
},
"max_lease_ttl_seconds": {
Type: schema.TypeInt,
Optional: true,
// Default is 20min, which is intended to be enough time for
// a reasonable Terraform run can complete but not
// significantly longer, so that any leases are revoked shortly
// after Terraform has finished running.
DefaultFunc: schema.EnvDefaultFunc("TERRAFORM_VAULT_MAX_TTL", 1200),
Description: "Maximum TTL for secret leases requested by this provider.",
},
"max_retries": {
Type: schema.TypeInt,
Optional: true,
DefaultFunc: schema.EnvDefaultFunc("VAULT_MAX_RETRIES", provider.DefaultMaxHTTPRetries),
Description: "Maximum number of retries when a 5xx error code is encountered.",
},
"max_retries_ccc": {
Type: schema.TypeInt,
Optional: true,
DefaultFunc: schema.EnvDefaultFunc("VAULT_MAX_RETRIES_CCC", DefaultMaxHTTPRetriesCCC),
Description: "Maximum number of retries for Client Controlled Consistency related operations",
},
consts.FieldNamespace: {
Type: schema.TypeString,
Optional: true,
DefaultFunc: schema.EnvDefaultFunc("VAULT_NAMESPACE", ""),
Description: "The namespace to use. Available only for Vault Enterprise.",
},
"headers": {
Type: schema.TypeList,
Optional: true,
Sensitive: true,
Description: "The headers to send with each Vault request.",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
Description: "The header name",
},
"value": {
Type: schema.TypeString,
Required: true,
Description: "The header value",
},
},
},
},
consts.FieldSkipGetVaultVersion: {
Type: schema.TypeBool,
Optional: true,
Default: false,
Description: "Skip the dynamic fetching of the Vault server version.",
},
consts.FieldVaultVersionOverride: {
Type: schema.TypeString,
Optional: true,
Description: "Override the Vault server version, " +
"which is normally determined dynamically from the target Vault server",
ValidateDiagFunc: provider.ValidateDiagSemVer,
},
},
ConfigureFunc: provider.NewProviderMeta,
DataSourcesMap: dataSourcesMap,
ResourcesMap: resourcesMap,
}
provider.MustAddAuthLoginSchema(r.Schema)
return r
}
// Description is essentially a DataSource or Resource with some additional metadata
// that helps with maintaining the Terraform Vault Provider.
type Description struct {
// PathInventory is used for taking an inventory of the supported endpoints in the
// Terraform Vault Provider and comparing them to the endpoints noted as available in
// Vault's OpenAPI description. A list of Vault's endpoints can be obtained by,
// from Vault's home directory, running "$ ./scripts/gen_openapi.sh", and then by
// drilling into the paths with "$ cat openapi.json | jq ".paths" | jq 'keys[]'".
// Here's a short example of how paths and their path variables should be represented:
// "/transit/keys/{name}/config"
// "/transit/random"
// "/transit/random/{urlbytes}"
// "/transit/sign/{name}/{urlalgorithm}"
PathInventory []string
// EnterpriseOnly defaults to false, but should be marked true if a resource is enterprise only.
EnterpriseOnly bool
Resource *schema.Resource
return provider.NewProvider(DataSourceRegistry, ResourceRegistry, mfaResources)
}
var (
DataSourceRegistry = map[string]*Description{
DataSourceRegistry = map[string]*provider.Description{
"vault_approle_auth_backend_role_id": {
Resource: UpdateSchemaResource(approleAuthBackendRoleIDDataSource()),
PathInventory: []string{"/auth/approle/role/{role_name}/role-id"},
@ -349,7 +155,7 @@ var (
},
}
ResourceRegistry = map[string]*Description{
ResourceRegistry = map[string]*provider.Description{
"vault_alicloud_auth_backend_role": {
Resource: UpdateSchemaResource(alicloudAuthBackendRoleResource()),
PathInventory: []string{"/auth/alicloud/role/{name}"},
@ -858,86 +664,8 @@ var (
}
)
func parse(descs map[string]*Description) (map[string]*schema.Resource, error) {
var errs error
resourceMap := make(map[string]*schema.Resource)
for k, desc := range descs {
resourceMap[k] = desc.Resource
if len(desc.PathInventory) == 0 {
errs = multierror.Append(errs, fmt.Errorf("%q needs its paths inventoried", k))
}
}
return resourceMap, errs
}
func UpdateSchemaResource(r *schema.Resource) *schema.Resource {
provider.MustAddSchema(r, provider.GetNamespaceSchema())
return r
}
// ReadWrapper provides common read operations to the wrapped schema.ReadFunc.
func ReadWrapper(f schema.ReadFunc) schema.ReadFunc {
return func(d *schema.ResourceData, i interface{}) error {
if err := importNamespace(d); err != nil {
return err
}
return f(d, i)
}
}
// ReadContextWrapper provides common read operations to the wrapped schema.ReadContextFunc.
func ReadContextWrapper(f schema.ReadContextFunc) schema.ReadContextFunc {
return func(ctx context.Context, d *schema.ResourceData, i interface{}) diag.Diagnostics {
if err := importNamespace(d); err != nil {
return diag.FromErr(err)
}
return f(ctx, d, i)
}
}
// MountCreateContextWrapper performs a minimum version requirement check prior to the
// wrapped schema.CreateContextFunc.
func MountCreateContextWrapper(f schema.CreateContextFunc, minVersion *version.Version) schema.CreateContextFunc {
return func(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
currentVersion := meta.(*provider.ProviderMeta).GetVaultVersion()
if !provider.IsAPISupported(meta, minVersion) {
return diag.Errorf("feature not enabled on current Vault version. min version required=%s; "+
"current vault version=%s", minVersion, currentVersion)
}
return f(ctx, d, meta)
}
}
func importNamespace(d *schema.ResourceData) error {
if ns := os.Getenv(consts.EnvVarVaultNamespaceImport); ns != "" {
s := d.State()
var attemptNamespaceImport bool
if s.Empty() {
// state does not yet exist or is empty
// import is acceptable
attemptNamespaceImport = true
} else {
// only import if namespace
// is not already set in state
s.Lock()
defer s.Unlock()
_, ok := s.Attributes[consts.FieldNamespace]
attemptNamespaceImport = !ok
}
if attemptNamespaceImport {
log.Printf(`[INFO] Environment variable %s set, `+
`attempting TF state import "%s=%s"`,
consts.EnvVarVaultNamespaceImport, consts.FieldNamespace, ns)
if err := d.Set(consts.FieldNamespace, ns); err != nil {
return fmt.Errorf("failed to import %q, err=%w",
consts.EnvVarVaultNamespaceImport, err)
}
}
}
return nil
}

View file

@ -216,7 +216,7 @@ func adSecretBackendResource() *schema.Resource {
DeprecationMessage: `This resource is replaced by "vault_ldap_secret_backend" and will be removed in the next major release.`,
Create: createConfigResource,
Update: updateConfigResource,
Read: ReadWrapper(readConfigResource),
Read: provider.ReadWrapper(readConfigResource),
Delete: deleteConfigResource,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,

View file

@ -66,7 +66,7 @@ func adSecretBackendLibraryResource() *schema.Resource {
DeprecationMessage: `This resource is replaced by "vault_ldap_secret_backend_library_set" and will be removed in the next major release.`,
Create: createLibraryResource,
Update: updateLibraryResource,
Read: ReadWrapper(readLibraryResource),
Read: provider.ReadWrapper(readLibraryResource),
Delete: deleteLibraryResource,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,

View file

@ -62,7 +62,7 @@ func adSecretBackendRoleResource() *schema.Resource {
DeprecationMessage: `This resource is replaced by "vault_ldap_secret_backend_static_role" and will be removed in the next major release.`,
Create: createRoleResource,
Update: updateRoleResource,
Read: ReadWrapper(readRoleResource),
Read: provider.ReadWrapper(readRoleResource),
Delete: deleteRoleResource,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,

View file

@ -45,7 +45,7 @@ func alicloudAuthBackendRoleResource() *schema.Resource {
return &schema.Resource{
CreateContext: alicloudAuthBackendRoleCreate,
UpdateContext: alicloudAuthBackendRoleUpdate,
ReadContext: ReadContextWrapper(alicloudAuthBackendRoleRead),
ReadContext: provider.ReadContextWrapper(alicloudAuthBackendRoleRead),
DeleteContext: alicloudAuthBackendRoleDelete,
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,

View file

@ -20,7 +20,7 @@ import (
func approleAuthBackendLoginResource() *schema.Resource {
return &schema.Resource{
Create: approleAuthBackendLoginCreate,
Read: ReadWrapper(approleAuthBackendLoginRead),
Read: provider.ReadWrapper(approleAuthBackendLoginRead),
Delete: approleAuthBackendLoginDelete,
Exists: approleAuthBackendLoginExists,

View file

@ -77,7 +77,7 @@ func approleAuthBackendRoleResource() *schema.Resource {
return &schema.Resource{
CreateContext: approleAuthBackendRoleCreate,
ReadContext: ReadContextWrapper(approleAuthBackendRoleRead),
ReadContext: provider.ReadContextWrapper(approleAuthBackendRoleRead),
UpdateContext: approleAuthBackendRoleUpdate,
DeleteContext: approleAuthBackendRoleDelete,
Importer: &schema.ResourceImporter{

View file

@ -22,7 +22,7 @@ var approleAuthBackendRoleSecretIDIDRegex = regexp.MustCompile("^backend=(.+)::r
func approleAuthBackendRoleSecretIDResource(name string) *schema.Resource {
return &schema.Resource{
Create: approleAuthBackendRoleSecretIDCreate,
Read: ReadWrapper(approleAuthBackendRoleSecretIDRead),
Read: provider.ReadWrapper(approleAuthBackendRoleSecretIDRead),
Delete: approleAuthBackendRoleSecretIDDelete,
Exists: approleAuthBackendRoleSecretIDExists,

View file

@ -17,7 +17,7 @@ import (
func auditResource() *schema.Resource {
return &schema.Resource{
Create: auditWrite,
Read: ReadWrapper(auditRead),
Read: provider.ReadWrapper(auditRead),
Delete: auditDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,

View file

@ -21,7 +21,7 @@ func auditRequestHeaderPath(name string) string {
func auditRequestHeaderResource() *schema.Resource {
return &schema.Resource{
Create: auditRequestHeaderCreate,
Read: ReadWrapper(auditRequestHeaderRead),
Read: provider.ReadWrapper(auditRequestHeaderRead),
Update: auditRequestHeaderUpdate,
Delete: auditRequestHeaderDelete,
Exists: auditRequestHeaderExists,

View file

@ -21,7 +21,7 @@ func AuthBackendResource() *schema.Resource {
Create: authBackendWrite,
Delete: authBackendDelete,
Read: ReadWrapper(authBackendRead),
Read: provider.ReadWrapper(authBackendRead),
Update: authBackendUpdate,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,

View file

@ -24,7 +24,7 @@ var (
func awsAuthBackendCertResource() *schema.Resource {
return &schema.Resource{
Create: awsAuthBackendCertCreate,
Read: ReadWrapper(awsAuthBackendCertRead),
Read: provider.ReadWrapper(awsAuthBackendCertRead),
Delete: awsAuthBackendCertDelete,
Exists: awsAuthBackendCertExists,
Importer: &schema.ResourceImporter{

View file

@ -17,7 +17,7 @@ import (
func awsAuthBackendClientResource() *schema.Resource {
return &schema.Resource{
Create: awsAuthBackendWrite,
Read: ReadWrapper(awsAuthBackendRead),
Read: provider.ReadWrapper(awsAuthBackendRead),
Update: awsAuthBackendWrite,
Delete: awsAuthBackendDelete,
Exists: awsAuthBackendExists,

View file

@ -19,7 +19,7 @@ var awsAuthBackendIdentityWhitelistBackendFromPathRegex = regexp.MustCompile("^a
func awsAuthBackendIdentityWhitelistResource() *schema.Resource {
return &schema.Resource{
Create: awsAuthBackendIdentityWhitelistWrite,
Read: ReadWrapper(awsAuthBackendIdentityWhitelistRead),
Read: provider.ReadWrapper(awsAuthBackendIdentityWhitelistRead),
Update: awsAuthBackendIdentityWhitelistWrite,
Delete: awsAuthBackendIdentityWhitelistDelete,
Exists: awsAuthBackendIdentityWhitelistExists,

View file

@ -18,7 +18,7 @@ import (
func awsAuthBackendLoginResource() *schema.Resource {
return &schema.Resource{
Create: awsAuthBackendLoginCreate,
Read: ReadWrapper(awsAuthBackendLoginRead),
Read: provider.ReadWrapper(awsAuthBackendLoginRead),
Delete: awsAuthBackendLoginDelete,
Schema: map[string]*schema.Schema{

View file

@ -164,7 +164,7 @@ func awsAuthBackendRoleResource() *schema.Resource {
return &schema.Resource{
CustomizeDiff: resourceVaultAwsAuthBackendRoleCustomizeDiff,
CreateContext: awsAuthBackendRoleCreate,
ReadContext: ReadContextWrapper(awsAuthBackendRoleRead),
ReadContext: provider.ReadContextWrapper(awsAuthBackendRoleRead),
UpdateContext: awsAuthBackendRoleUpdate,
DeleteContext: awsAuthBackendRoleDelete,
Importer: &schema.ResourceImporter{

View file

@ -16,7 +16,7 @@ import (
func awsAuthBackendRoleTagResource() *schema.Resource {
return &schema.Resource{
Create: awsAuthBackendRoleTagResourceCreate,
Read: ReadWrapper(awsAuthBackendRoleTagResourceRead),
Read: provider.ReadWrapper(awsAuthBackendRoleTagResourceRead),
Delete: awsAuthBackendRoleTagResourceDelete,
Schema: map[string]*schema.Schema{

View file

@ -19,7 +19,7 @@ var awsAuthBackendRoleTagBlacklistBackendFromPathRegex = regexp.MustCompile("^au
func awsAuthBackendRoleTagBlacklistResource() *schema.Resource {
return &schema.Resource{
Create: awsAuthBackendRoleTagBlacklistWrite,
Read: ReadWrapper(awsAuthBackendRoleTagBlacklistRead),
Read: provider.ReadWrapper(awsAuthBackendRoleTagBlacklistRead),
Update: awsAuthBackendRoleTagBlacklistWrite,
Delete: awsAuthBackendRoleTagBlacklistDelete,
Exists: awsAuthBackendRoleTagBlacklistExists,

View file

@ -22,7 +22,7 @@ var (
func awsAuthBackendSTSRoleResource() *schema.Resource {
return &schema.Resource{
Create: awsAuthBackendSTSRoleCreate,
Read: ReadWrapper(awsAuthBackendSTSRoleRead),
Read: provider.ReadWrapper(awsAuthBackendSTSRoleRead),
Update: awsAuthBackendSTSRoleUpdate,
Delete: awsAuthBackendSTSRoleDelete,
Exists: awsAuthBackendSTSRoleExists,

View file

@ -20,7 +20,7 @@ import (
func awsSecretBackendResource() *schema.Resource {
return provider.MustAddMountMigrationSchema(&schema.Resource{
Create: awsSecretBackendCreate,
Read: ReadWrapper(awsSecretBackendRead),
Read: provider.ReadWrapper(awsSecretBackendRead),
Update: awsSecretBackendUpdate,
Delete: awsSecretBackendDelete,
Exists: awsSecretBackendExists,

View file

@ -18,7 +18,7 @@ import (
func awsSecretBackendRoleResource(name string) *schema.Resource {
return &schema.Resource{
Create: awsSecretBackendRoleWrite,
Read: ReadWrapper(awsSecretBackendRoleRead),
Read: provider.ReadWrapper(awsSecretBackendRoleRead),
Update: awsSecretBackendRoleWrite,
Delete: awsSecretBackendRoleDelete,
Exists: awsSecretBackendRoleExists,

View file

@ -19,7 +19,7 @@ var azureAuthBackendConfigFromPathRegex = regexp.MustCompile("^auth/(.+)/config$
func azureAuthBackendConfigResource() *schema.Resource {
return &schema.Resource{
Create: azureAuthBackendWrite,
Read: ReadWrapper(azureAuthBackendRead),
Read: provider.ReadWrapper(azureAuthBackendRead),
Update: azureAuthBackendWrite,
Delete: azureAuthBackendDelete,
Exists: azureAuthBackendExists,

View file

@ -94,7 +94,7 @@ func azureAuthBackendRoleResource() *schema.Resource {
return &schema.Resource{
CreateContext: azureAuthBackendRoleCreate,
ReadContext: ReadContextWrapper(azureAuthBackendRoleRead),
ReadContext: provider.ReadContextWrapper(azureAuthBackendRoleRead),
UpdateContext: azureAuthBackendRoleUpdate,
DeleteContext: azureAuthBackendRoleDelete,
Importer: &schema.ResourceImporter{

View file

@ -19,7 +19,7 @@ import (
func azureSecretBackendResource() *schema.Resource {
return provider.MustAddMountMigrationSchema(&schema.Resource{
Create: azureSecretBackendCreate,
Read: ReadWrapper(azureSecretBackendRead),
Read: provider.ReadWrapper(azureSecretBackendRead),
Update: azureSecretBackendUpdate,
Delete: azureSecretBackendDelete,
Exists: azureSecretBackendExists,

View file

@ -7,10 +7,11 @@ import (
"context"
"encoding/json"
"fmt"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"log"
"strings"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-provider-vault/internal/provider"
@ -19,7 +20,7 @@ import (
func azureSecretBackendRoleResource() *schema.Resource {
return &schema.Resource{
CreateContext: azureSecretBackendRoleCreate,
ReadContext: ReadContextWrapper(azureSecretBackendRoleRead),
ReadContext: provider.ReadContextWrapper(azureSecretBackendRoleRead),
UpdateContext: azureSecretBackendRoleCreate,
DeleteContext: azureSecretBackendRoleDelete,
Importer: &schema.ResourceImporter{

View file

@ -115,7 +115,7 @@ func certAuthBackendRoleResource() *schema.Resource {
CreateContext: certAuthResourceWrite,
UpdateContext: certAuthResourceUpdate,
ReadContext: ReadContextWrapper(certAuthResourceRead),
ReadContext: provider.ReadContextWrapper(certAuthResourceRead),
DeleteContext: certAuthResourceDelete,
Schema: fields,
}

View file

@ -23,7 +23,7 @@ import (
func consulSecretBackendResource() *schema.Resource {
return provider.MustAddMountMigrationSchema(&schema.Resource{
CreateContext: consulSecretBackendCreate,
ReadContext: ReadContextWrapper(consulSecretBackendRead),
ReadContext: provider.ReadContextWrapper(consulSecretBackendRead),
UpdateContext: consulSecretBackendUpdate,
DeleteContext: consulSecretBackendDelete,
CustomizeDiff: consulSecretsBackendCustomizeDiff,

View file

@ -25,7 +25,7 @@ var (
func consulSecretBackendRoleResource() *schema.Resource {
return &schema.Resource{
CreateContext: consulSecretBackendRoleWrite,
ReadContext: ReadContextWrapper(consulSecretBackendRoleRead),
ReadContext: provider.ReadContextWrapper(consulSecretBackendRoleRead),
UpdateContext: consulSecretBackendRoleWrite,
DeleteContext: consulSecretBackendRoleDelete,
Importer: &schema.ResourceImporter{

View file

@ -700,7 +700,7 @@ func databaseSecretBackendConnectionResource() *schema.Resource {
return &schema.Resource{
Create: databaseSecretBackendConnectionCreateOrUpdate,
Read: ReadWrapper(databaseSecretBackendConnectionRead),
Read: provider.ReadWrapper(databaseSecretBackendConnectionRead),
Update: databaseSecretBackendConnectionCreateOrUpdate,
Delete: databaseSecretBackendConnectionDelete,
Exists: databaseSecretBackendConnectionExists,

View file

@ -23,7 +23,7 @@ var (
func databaseSecretBackendRoleResource() *schema.Resource {
return &schema.Resource{
Create: databaseSecretBackendRoleWrite,
Read: ReadWrapper(databaseSecretBackendRoleRead),
Read: provider.ReadWrapper(databaseSecretBackendRoleRead),
Update: databaseSecretBackendRoleWrite,
Delete: databaseSecretBackendRoleDelete,
Exists: databaseSecretBackendRoleExists,

View file

@ -23,7 +23,7 @@ var (
func databaseSecretBackendStaticRoleResource() *schema.Resource {
return &schema.Resource{
Create: databaseSecretBackendStaticRoleWrite,
Read: ReadWrapper(databaseSecretBackendStaticRoleRead),
Read: provider.ReadWrapper(databaseSecretBackendStaticRoleRead),
Update: databaseSecretBackendStaticRoleWrite,
Delete: databaseSecretBackendStaticRoleDelete,
Exists: databaseSecretBackendStaticRoleExists,

View file

@ -108,7 +108,7 @@ func databaseSecretsMountCustomizeDiff(ctx context.Context, d *schema.ResourceDi
func databaseSecretsMountResource() *schema.Resource {
return &schema.Resource{
Create: databaseSecretsMountCreateOrUpdate,
Read: ReadWrapper(databaseSecretsMountRead),
Read: provider.ReadWrapper(databaseSecretsMountRead),
Update: databaseSecretsMountCreateOrUpdate,
Delete: databaseSecretsMountDelete,
CustomizeDiff: databaseSecretsMountCustomizeDiff,

View file

@ -5,6 +5,8 @@ package vault
import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-provider-vault/internal/provider"
)
var egpPolicyAttributes = []string{"enforcement_level", "paths", "policy"}
@ -14,7 +16,7 @@ func egpPolicyResource() *schema.Resource {
Create: egpPolicyWrite,
Update: egpPolicyWrite,
Delete: egpPolicyDelete,
Read: ReadWrapper(egpPolicyRead),
Read: provider.ReadWrapper(egpPolicyRead),
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},

View file

@ -26,7 +26,7 @@ func gcpAuthBackendResource() *schema.Resource {
return provider.MustAddMountMigrationSchema(&schema.Resource{
Create: gcpAuthBackendWrite,
Update: gcpAuthBackendUpdate,
Read: ReadWrapper(gcpAuthBackendRead),
Read: provider.ReadWrapper(gcpAuthBackendRead),
Delete: gcpAuthBackendDelete,
Exists: gcpAuthBackendExists,
Importer: &schema.ResourceImporter{

View file

@ -114,7 +114,7 @@ func gcpAuthBackendRoleResource() *schema.Resource {
CreateContext: gcpAuthResourceCreate,
UpdateContext: gcpAuthResourceUpdate,
ReadContext: ReadContextWrapper(gcpAuthResourceRead),
ReadContext: provider.ReadContextWrapper(gcpAuthResourceRead),
DeleteContext: gcpAuthResourceDelete,
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,

View file

@ -19,7 +19,7 @@ import (
func gcpSecretBackendResource(name string) *schema.Resource {
return provider.MustAddMountMigrationSchema(&schema.Resource{
Create: gcpSecretBackendCreate,
Read: ReadWrapper(gcpSecretBackendRead),
Read: provider.ReadWrapper(gcpSecretBackendRead),
Update: gcpSecretBackendUpdate,
Delete: gcpSecretBackendDelete,
Exists: gcpSecretBackendExists,

View file

@ -12,6 +12,7 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-provider-vault/internal/consts"
"github.com/hashicorp/terraform-provider-vault/internal/provider"
)
@ -24,7 +25,7 @@ var (
func gcpSecretImpersonatedAccountResource() *schema.Resource {
return &schema.Resource{
CreateContext: gcpSecretImpersonatedAccountCreate,
ReadContext: ReadContextWrapper(gcpSecretImpersonatedAccountRead),
ReadContext: provider.ReadContextWrapper(gcpSecretImpersonatedAccountRead),
UpdateContext: gcpSecretImpersonatedAccountUpdate,
DeleteContext: gcpSecretImpersonatedAccountDelete,
Importer: &schema.ResourceImporter{

View file

@ -24,7 +24,7 @@ var (
func gcpSecretRolesetResource() *schema.Resource {
return &schema.Resource{
Create: gcpSecretRolesetCreate,
Read: ReadWrapper(gcpSecretRolesetRead),
Read: provider.ReadWrapper(gcpSecretRolesetRead),
Update: gcpSecretRolesetUpdate,
Delete: gcpSecretRolesetDelete,
Exists: gcpSecretRolesetExists,

View file

@ -22,7 +22,7 @@ var (
func gcpSecretStaticAccountResource() *schema.Resource {
return &schema.Resource{
Create: gcpSecretStaticAccountCreate,
Read: ReadWrapper(gcpSecretStaticAccountRead),
Read: provider.ReadWrapper(gcpSecretStaticAccountRead),
Update: gcpSecretStaticAccountUpdate,
Delete: gcpSecretStaticAccountDelete,
Exists: gcpSecretStaticAccountExists,

View file

@ -21,7 +21,7 @@ func genericEndpointResource(name string) *schema.Resource {
Create: genericEndpointResourceWrite,
Update: genericEndpointResourceWrite,
Delete: genericEndpointResourceDelete,
Read: ReadWrapper(genericEndpointResourceRead),
Read: provider.ReadWrapper(genericEndpointResourceRead),
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},

View file

@ -27,7 +27,7 @@ func genericSecretResource(name string) *schema.Resource {
Create: genericSecretResourceWrite,
Update: genericSecretResourceWrite,
Delete: genericSecretResourceDelete,
Read: ReadWrapper(genericSecretResourceRead),
Read: provider.ReadWrapper(genericSecretResourceRead),
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},

View file

@ -62,7 +62,7 @@ func githubAuthBackendResource() *schema.Resource {
return provider.MustAddMountMigrationSchema(&schema.Resource{
Create: githubAuthBackendCreate,
Read: ReadWrapper(githubAuthBackendRead),
Read: provider.ReadWrapper(githubAuthBackendRead),
Update: githubAuthBackendUpdate,
Delete: githubAuthBackendDelete,
Importer: &schema.ResourceImporter{

View file

@ -16,7 +16,7 @@ import (
func githubTeamResource() *schema.Resource {
return &schema.Resource{
Create: githubTeamCreate,
Read: ReadWrapper(githubTeamRead),
Read: provider.ReadWrapper(githubTeamRead),
Update: githubTeamUpdate,
Delete: githubTeamDelete,
Importer: &schema.ResourceImporter{

View file

@ -16,7 +16,7 @@ import (
func githubUserResource() *schema.Resource {
return &schema.Resource{
Create: githubUserCreate,
Read: ReadWrapper(githubUserRead),
Read: provider.ReadWrapper(githubUserRead),
Update: githubUserUpdate,
Delete: githubUserDelete,
Importer: &schema.ResourceImporter{

View file

@ -21,7 +21,7 @@ func identityEntityResource() *schema.Resource {
return &schema.Resource{
Create: identityEntityCreate,
Update: identityEntityUpdate,
Read: ReadWrapper(identityEntityRead),
Read: provider.ReadWrapper(identityEntityRead),
Delete: identityEntityDelete,
Exists: identityEntityExists,
Importer: &schema.ResourceImporter{

View file

@ -23,7 +23,7 @@ func identityEntityAliasResource() *schema.Resource {
return &schema.Resource{
CreateContext: identityEntityAliasCreate,
UpdateContext: identityEntityAliasUpdate,
ReadContext: ReadContextWrapper(identityEntityAliasRead),
ReadContext: provider.ReadContextWrapper(identityEntityAliasRead),
DeleteContext: identityEntityAliasDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,

View file

@ -19,7 +19,7 @@ func identityEntityPoliciesResource() *schema.Resource {
return &schema.Resource{
Create: identityEntityPoliciesUpdate,
Update: identityEntityPoliciesUpdate,
Read: ReadWrapper(identityEntityPoliciesRead),
Read: provider.ReadWrapper(identityEntityPoliciesRead),
Delete: identityEntityPoliciesDelete,
Schema: map[string]*schema.Schema{

View file

@ -21,7 +21,7 @@ func identityGroupResource() *schema.Resource {
return &schema.Resource{
Create: identityGroupCreate,
Update: identityGroupUpdate,
Read: ReadWrapper(identityGroupRead),
Read: provider.ReadWrapper(identityGroupRead),
Delete: identityGroupDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,

View file

@ -19,7 +19,7 @@ func identityGroupAliasResource() *schema.Resource {
return &schema.Resource{
Create: identityGroupAliasCreate,
Update: identityGroupAliasUpdate,
Read: ReadWrapper(identityGroupAliasRead),
Read: provider.ReadWrapper(identityGroupAliasRead),
Delete: identityGroupAliasDelete,
Exists: identityGroupAliasExists,
Importer: &schema.ResourceImporter{

View file

@ -8,13 +8,14 @@ import (
"github.com/hashicorp/terraform-provider-vault/internal/consts"
"github.com/hashicorp/terraform-provider-vault/internal/identity/group"
"github.com/hashicorp/terraform-provider-vault/internal/provider"
)
func identityGroupMemberEntityIdsResource() *schema.Resource {
return &schema.Resource{
CreateContext: group.GetGroupMemberUpdateContextFunc(group.EntityResourceType),
UpdateContext: group.GetGroupMemberUpdateContextFunc(group.EntityResourceType),
ReadContext: ReadContextWrapper(group.GetGroupMemberReadContextFunc(group.EntityResourceType, true)),
ReadContext: provider.ReadContextWrapper(group.GetGroupMemberReadContextFunc(group.EntityResourceType, true)),
DeleteContext: group.GetGroupMemberDeleteContextFunc(group.EntityResourceType),
Schema: map[string]*schema.Schema{

View file

@ -8,13 +8,14 @@ import (
"github.com/hashicorp/terraform-provider-vault/internal/consts"
"github.com/hashicorp/terraform-provider-vault/internal/identity/group"
"github.com/hashicorp/terraform-provider-vault/internal/provider"
)
func identityGroupMemberGroupIdsResource() *schema.Resource {
return &schema.Resource{
CreateContext: group.GetGroupMemberUpdateContextFunc(group.GroupResourceType),
UpdateContext: group.GetGroupMemberUpdateContextFunc(group.GroupResourceType),
ReadContext: ReadContextWrapper(group.GetGroupMemberReadContextFunc(group.GroupResourceType, false)),
ReadContext: provider.ReadContextWrapper(group.GetGroupMemberReadContextFunc(group.GroupResourceType, false)),
DeleteContext: group.GetGroupMemberDeleteContextFunc(group.GroupResourceType),
Schema: map[string]*schema.Schema{

View file

@ -18,7 +18,7 @@ func identityGroupPoliciesResource() *schema.Resource {
return &schema.Resource{
Create: identityGroupPoliciesUpdate,
Update: identityGroupPoliciesUpdate,
Read: ReadWrapper(identityGroupPoliciesRead),
Read: provider.ReadWrapper(identityGroupPoliciesRead),
Delete: identityGroupPoliciesDelete,
Schema: map[string]*schema.Schema{

View file

@ -18,7 +18,7 @@ func identityOidc() *schema.Resource {
return &schema.Resource{
Create: identityOidcCreate,
Update: identityOidcUpdate,
Read: ReadWrapper(identityOidcRead),
Read: provider.ReadWrapper(identityOidcRead),
Delete: identityOidcDelete,
Exists: identityOidcExists,

View file

@ -18,7 +18,7 @@ func identityOIDCAssignmentResource() *schema.Resource {
return &schema.Resource{
Create: identityOIDCAssignmentCreateUpdate,
Update: identityOIDCAssignmentCreateUpdate,
Read: ReadWrapper(identityOIDCAssignmentRead),
Read: provider.ReadWrapper(identityOIDCAssignmentRead),
Delete: identityOIDCAssignmentDelete,
Schema: map[string]*schema.Schema{

View file

@ -18,7 +18,7 @@ func identityOIDCClientResource() *schema.Resource {
return &schema.Resource{
Create: identityOIDCClientCreateUpdate,
Update: identityOIDCClientCreateUpdate,
Read: ReadWrapper(identityOIDCClientRead),
Read: provider.ReadWrapper(identityOIDCClientRead),
Delete: identityOIDCClientDelete,
Schema: map[string]*schema.Schema{

View file

@ -27,7 +27,7 @@ func identityOidcKey() *schema.Resource {
return &schema.Resource{
Create: identityOidcKeyCreate,
Update: identityOidcKeyUpdate,
Read: ReadWrapper(identityOidcKeyRead),
Read: provider.ReadWrapper(identityOidcKeyRead),
Delete: identityOidcKeyDelete,
Exists: identityOidcKeyExists,
Importer: &schema.ResourceImporter{

View file

@ -16,7 +16,7 @@ import (
func identityOidcKeyAllowedClientId() *schema.Resource {
return &schema.Resource{
Create: identityOidcKeyAllowedClientIdWrite,
Read: ReadWrapper(identityOidcKeyAllowedClientIdRead),
Read: provider.ReadWrapper(identityOidcKeyAllowedClientIdRead),
Delete: identityOidcKeyAllowedClientIdDelete,
Schema: map[string]*schema.Schema{

View file

@ -18,7 +18,7 @@ func identityOIDCProviderResource() *schema.Resource {
return &schema.Resource{
Create: identityOIDCProviderCreateUpdate,
Update: identityOIDCProviderCreateUpdate,
Read: ReadWrapper(identityOIDCProviderRead),
Read: provider.ReadWrapper(identityOIDCProviderRead),
Delete: identityOIDCProviderDelete,
Schema: map[string]*schema.Schema{

View file

@ -18,7 +18,7 @@ func identityOidcRole() *schema.Resource {
return &schema.Resource{
Create: identityOidcRoleCreate,
Update: identityOidcRoleUpdate,
Read: ReadWrapper(identityOidcRoleRead),
Read: provider.ReadWrapper(identityOidcRoleRead),
Delete: identityOidcRoleDelete,
Exists: identityOidcRoleExists,
Importer: &schema.ResourceImporter{

View file

@ -19,7 +19,7 @@ func identityOIDCScopeResource() *schema.Resource {
return &schema.Resource{
Create: identityOIDCScopeCreateUpdate,
Update: identityOIDCScopeCreateUpdate,
Read: ReadWrapper(identityOIDCScopeRead),
Read: provider.ReadWrapper(identityOIDCScopeRead),
Delete: identityOIDCScopeDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,

View file

@ -26,7 +26,7 @@ func jwtAuthBackendResource() *schema.Resource {
},
Create: jwtAuthBackendWrite,
Delete: jwtAuthBackendDelete,
Read: ReadWrapper(jwtAuthBackendRead),
Read: provider.ReadWrapper(jwtAuthBackendRead),
Update: jwtAuthBackendUpdate,
CustomizeDiff: jwtCustomizeDiff,

View file

@ -150,7 +150,7 @@ func jwtAuthBackendRoleResource() *schema.Resource {
return &schema.Resource{
CreateContext: jwtAuthBackendRoleCreate,
ReadContext: ReadContextWrapper(jwtAuthBackendRoleRead),
ReadContext: provider.ReadContextWrapper(jwtAuthBackendRoleRead),
UpdateContext: jwtAuthBackendRoleUpdate,
DeleteContext: jwtAuthBackendRoleDelete,
Importer: &schema.ResourceImporter{

View file

@ -31,7 +31,7 @@ var kmipAPIFields = []string{
func kmipSecretBackendResource() *schema.Resource {
return provider.MustAddMountMigrationSchema(&schema.Resource{
Create: kmipSecretBackendCreate,
Read: ReadWrapper(kmipSecretBackendRead),
Read: provider.ReadWrapper(kmipSecretBackendRead),
Update: kmipSecretBackendUpdate,
Delete: kmipSecretBackendDelete,
CustomizeDiff: getMountCustomizeDiffFunc(consts.FieldPath),

View file

@ -53,7 +53,7 @@ var kmipRoleAPIBooleanFields = []string{
func kmipSecretRoleResource() *schema.Resource {
return &schema.Resource{
Create: kmipSecretRoleCreate,
Read: ReadWrapper(kmipSecretRoleRead),
Read: provider.ReadWrapper(kmipSecretRoleRead),
Update: kmipSecretRoleUpdate,
Delete: kmipSecretRoleDelete,
Importer: &schema.ResourceImporter{

Some files were not shown because too many files have changed in this diff Show more