internal/schema/connection.go (482 lines of code) (raw):
package schema
import (
"fmt"
"github.com/hashicorp/terraform-plugin-framework-validators/listvalidator"
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
"github.com/hashicorp/terraform-plugin-framework/path"
fwschema "github.com/hashicorp/terraform-plugin-framework/provider/schema"
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)
func GetEsFWConnectionBlock(keyName string, isProviderConfiguration bool) fwschema.Block {
usernamePath := path.MatchRelative().AtParent().AtName("username")
passwordPath := path.MatchRelative().AtParent().AtName("password")
apiKeyPath := path.MatchRelative().AtParent().AtName("api_key")
bearerTokenPath := path.MatchRelative().AtParent().AtName("bearer_token")
caFilePath := path.MatchRelative().AtParent().AtName("ca_file")
caDataPath := path.MatchRelative().AtParent().AtName("ca_data")
certFilePath := path.MatchRelative().AtParent().AtName("cert_file")
certDataPath := path.MatchRelative().AtParent().AtName("cert_data")
keyFilePath := path.MatchRelative().AtParent().AtName("key_file")
keyDataPath := path.MatchRelative().AtParent().AtName("key_data")
return fwschema.ListNestedBlock{
MarkdownDescription: "Elasticsearch connection configuration block. ",
Description: "Elasticsearch connection configuration block. ",
DeprecationMessage: getDeprecationMessage(isProviderConfiguration),
NestedObject: fwschema.NestedBlockObject{
Attributes: map[string]fwschema.Attribute{
"username": fwschema.StringAttribute{
MarkdownDescription: "Username to use for API authentication to Elasticsearch.",
Optional: true,
Validators: []validator.String{stringvalidator.AlsoRequires(passwordPath)},
},
"password": fwschema.StringAttribute{
MarkdownDescription: "Password to use for API authentication to Elasticsearch.",
Optional: true,
Sensitive: true,
Validators: []validator.String{stringvalidator.AlsoRequires(usernamePath)},
},
"api_key": fwschema.StringAttribute{
MarkdownDescription: "API Key to use for authentication to Elasticsearch",
Optional: true,
Sensitive: true,
Validators: []validator.String{
stringvalidator.ConflictsWith(usernamePath, passwordPath, bearerTokenPath),
},
},
"bearer_token": fwschema.StringAttribute{
MarkdownDescription: "Bearer Token to use for authentication to Elasticsearch",
Optional: true,
Sensitive: true,
Validators: []validator.String{
stringvalidator.ConflictsWith(usernamePath, passwordPath, apiKeyPath),
},
},
"es_client_authentication": fwschema.StringAttribute{
MarkdownDescription: "ES Client Authentication field to be used with the JWT token",
Optional: true,
Sensitive: true,
Validators: []validator.String{
stringvalidator.ConflictsWith(usernamePath, passwordPath, apiKeyPath),
stringvalidator.AlsoRequires(bearerTokenPath),
},
},
"endpoints": fwschema.ListAttribute{
MarkdownDescription: "A list of endpoints where the terraform provider will point to, this must include the http(s) schema and port number.",
Optional: true,
Sensitive: true,
ElementType: types.StringType,
},
"headers": fwschema.MapAttribute{
MarkdownDescription: "A list of headers to be sent with each request to Elasticsearch.",
Optional: true,
Sensitive: true,
ElementType: types.StringType,
},
"insecure": fwschema.BoolAttribute{
MarkdownDescription: "Disable TLS certificate validation",
Optional: true,
},
"ca_file": fwschema.StringAttribute{
MarkdownDescription: "Path to a custom Certificate Authority certificate",
Optional: true,
Validators: []validator.String{
stringvalidator.ConflictsWith(caDataPath),
},
},
"ca_data": fwschema.StringAttribute{
MarkdownDescription: "PEM-encoded custom Certificate Authority certificate",
Optional: true,
Validators: []validator.String{
stringvalidator.ConflictsWith(caFilePath),
},
},
"cert_file": fwschema.StringAttribute{
MarkdownDescription: "Path to a file containing the PEM encoded certificate for client auth",
Optional: true,
Validators: []validator.String{
stringvalidator.AlsoRequires(keyFilePath),
stringvalidator.ConflictsWith(caDataPath, keyDataPath),
},
},
"key_file": fwschema.StringAttribute{
MarkdownDescription: "Path to a file containing the PEM encoded private key for client auth",
Optional: true,
Validators: []validator.String{
stringvalidator.AlsoRequires(certFilePath),
stringvalidator.ConflictsWith(certDataPath, keyDataPath),
},
},
"cert_data": fwschema.StringAttribute{
MarkdownDescription: "PEM encoded certificate for client auth",
Optional: true,
Validators: []validator.String{
stringvalidator.AlsoRequires(keyDataPath),
stringvalidator.ConflictsWith(certFilePath, keyFilePath),
},
},
"key_data": fwschema.StringAttribute{
MarkdownDescription: "PEM encoded private key for client auth",
Optional: true,
Sensitive: true,
Validators: []validator.String{
stringvalidator.AlsoRequires(certDataPath),
stringvalidator.ConflictsWith(certFilePath, keyFilePath),
},
},
},
},
Validators: []validator.List{
listvalidator.SizeAtMost(1),
},
}
}
func GetKbFWConnectionBlock() fwschema.Block {
usernamePath := path.MatchRelative().AtParent().AtName("username")
passwordPath := path.MatchRelative().AtParent().AtName("password")
return fwschema.ListNestedBlock{
MarkdownDescription: "Kibana connection configuration block.",
NestedObject: fwschema.NestedBlockObject{
Attributes: map[string]fwschema.Attribute{
"api_key": fwschema.StringAttribute{
MarkdownDescription: "API Key to use for authentication to Kibana",
Optional: true,
Sensitive: true,
Validators: []validator.String{
stringvalidator.ConflictsWith(usernamePath, passwordPath),
},
},
"username": fwschema.StringAttribute{
MarkdownDescription: "Username to use for API authentication to Kibana.",
Optional: true,
Validators: []validator.String{stringvalidator.AlsoRequires(passwordPath)},
},
"password": fwschema.StringAttribute{
MarkdownDescription: "Password to use for API authentication to Kibana.",
Optional: true,
Sensitive: true,
Validators: []validator.String{stringvalidator.AlsoRequires(usernamePath)},
},
"endpoints": fwschema.ListAttribute{
MarkdownDescription: "A comma-separated list of endpoints where the terraform provider will point to, this must include the http(s) schema and port number.",
Optional: true,
Sensitive: true,
ElementType: types.StringType,
},
"ca_certs": fwschema.ListAttribute{
MarkdownDescription: "A list of paths to CA certificates to validate the certificate presented by the Kibana server.",
Optional: true,
ElementType: types.StringType,
},
"insecure": fwschema.BoolAttribute{
MarkdownDescription: "Disable TLS certificate validation",
Optional: true,
},
},
},
Validators: []validator.List{
listvalidator.SizeAtMost(1),
},
}
}
func GetFleetFWConnectionBlock() fwschema.Block {
usernamePath := path.MatchRelative().AtParent().AtName("username")
passwordPath := path.MatchRelative().AtParent().AtName("password")
return fwschema.ListNestedBlock{
MarkdownDescription: "Fleet connection configuration block.",
NestedObject: fwschema.NestedBlockObject{
Attributes: map[string]fwschema.Attribute{
"username": fwschema.StringAttribute{
MarkdownDescription: "Username to use for API authentication to Fleet.",
Optional: true,
Validators: []validator.String{stringvalidator.AlsoRequires(passwordPath)},
},
"password": fwschema.StringAttribute{
MarkdownDescription: "Password to use for API authentication to Fleet.",
Optional: true,
Sensitive: true,
Validators: []validator.String{stringvalidator.AlsoRequires(usernamePath)},
},
"api_key": fwschema.StringAttribute{
MarkdownDescription: "API Key to use for authentication to Fleet.",
Optional: true,
Sensitive: true,
Validators: []validator.String{
stringvalidator.ConflictsWith(usernamePath),
stringvalidator.ConflictsWith(passwordPath),
},
},
"endpoint": fwschema.StringAttribute{
MarkdownDescription: "The Fleet server where the terraform provider will point to, this must include the http(s) schema and port number.",
Optional: true,
Sensitive: true,
},
"ca_certs": fwschema.ListAttribute{
MarkdownDescription: "A list of paths to CA certificates to validate the certificate presented by the Fleet server.",
Optional: true,
ElementType: types.StringType,
},
"insecure": fwschema.BoolAttribute{
MarkdownDescription: "Disable TLS certificate validation",
Optional: true,
},
},
},
Validators: []validator.List{
listvalidator.SizeAtMost(1),
},
}
}
func GetEsConnectionSchema(keyName string, isProviderConfiguration bool) *schema.Schema {
usernamePath := makePathRef(keyName, "username")
passwordPath := makePathRef(keyName, "password")
apiKeyPath := makePathRef(keyName, "api_key")
bearerTokenPath := makePathRef(keyName, "bearer_token")
caFilePath := makePathRef(keyName, "ca_file")
caDataPath := makePathRef(keyName, "ca_data")
certFilePath := makePathRef(keyName, "cert_file")
certDataPath := makePathRef(keyName, "cert_data")
keyFilePath := makePathRef(keyName, "key_file")
keyDataPath := makePathRef(keyName, "key_data")
usernameRequiredWithValidation := []string{passwordPath}
passwordRequiredWithValidation := []string{usernamePath}
withEnvDefault := func(key string, dv interface{}) schema.SchemaDefaultFunc { return nil }
if isProviderConfiguration {
withEnvDefault = func(key string, dv interface{}) schema.SchemaDefaultFunc { return schema.EnvDefaultFunc(key, dv) }
// RequireWith validation isn't compatible when used in conjunction with DefaultFunc
usernameRequiredWithValidation = nil
passwordRequiredWithValidation = nil
}
return &schema.Schema{
Description: fmt.Sprintf("Elasticsearch connection configuration block. %s", getDeprecationMessage(isProviderConfiguration)),
Deprecated: getDeprecationMessage(isProviderConfiguration),
Type: schema.TypeList,
MaxItems: 1,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"username": {
Description: "Username to use for API authentication to Elasticsearch.",
Type: schema.TypeString,
Optional: true,
DefaultFunc: withEnvDefault("ELASTICSEARCH_USERNAME", nil),
RequiredWith: usernameRequiredWithValidation,
},
"password": {
Description: "Password to use for API authentication to Elasticsearch.",
Type: schema.TypeString,
Optional: true,
Sensitive: true,
DefaultFunc: withEnvDefault("ELASTICSEARCH_PASSWORD", nil),
RequiredWith: passwordRequiredWithValidation,
},
"api_key": {
Description: "API Key to use for authentication to Elasticsearch",
Type: schema.TypeString,
Optional: true,
Sensitive: true,
DefaultFunc: withEnvDefault("ELASTICSEARCH_API_KEY", nil),
ConflictsWith: []string{usernamePath, passwordPath, bearerTokenPath},
},
"bearer_token": {
Description: "Bearer Token to use for authentication to Elasticsearch",
Type: schema.TypeString,
Optional: true,
Sensitive: true,
DefaultFunc: withEnvDefault("ELASTICSEARCH_BEARER_TOKEN", nil),
ConflictsWith: []string{usernamePath, passwordPath, apiKeyPath},
},
"es_client_authentication": {
Description: "ES Client Authentication field to be used with the JWT token",
Type: schema.TypeString,
Optional: true,
Sensitive: true,
DefaultFunc: withEnvDefault("ELASTICSEARCH_ES_CLIENT_AUTHENTICATION", nil),
},
"endpoints": {
Description: "A list of endpoints where the terraform provider will point to, this must include the http(s) schema and port number.",
Type: schema.TypeList,
Optional: true,
Sensitive: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"headers": {
Description: "A list of headers to be sent with each request to Elasticsearch.",
Type: schema.TypeMap,
Optional: true,
Sensitive: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"insecure": {
Description: "Disable TLS certificate validation",
Type: schema.TypeBool,
Optional: true,
DefaultFunc: withEnvDefault("ELASTICSEARCH_INSECURE", false),
},
"ca_file": {
Description: "Path to a custom Certificate Authority certificate",
Type: schema.TypeString,
Optional: true,
ConflictsWith: []string{caDataPath},
},
"ca_data": {
Description: "PEM-encoded custom Certificate Authority certificate",
Type: schema.TypeString,
Optional: true,
ConflictsWith: []string{caFilePath},
},
"cert_file": {
Description: "Path to a file containing the PEM encoded certificate for client auth",
Type: schema.TypeString,
Optional: true,
RequiredWith: []string{keyFilePath},
ConflictsWith: []string{certDataPath, keyDataPath},
},
"key_file": {
Description: "Path to a file containing the PEM encoded private key for client auth",
Type: schema.TypeString,
Optional: true,
RequiredWith: []string{certFilePath},
ConflictsWith: []string{certDataPath, keyDataPath},
},
"cert_data": {
Description: "PEM encoded certificate for client auth",
Type: schema.TypeString,
Optional: true,
RequiredWith: []string{keyDataPath},
ConflictsWith: []string{certFilePath, keyFilePath},
},
"key_data": {
Description: "PEM encoded private key for client auth",
Type: schema.TypeString,
Optional: true,
Sensitive: true,
RequiredWith: []string{certDataPath},
ConflictsWith: []string{certFilePath, keyFilePath},
},
},
},
}
}
func GetKibanaConnectionSchema() *schema.Schema {
withEnvDefault := func(key string, dv interface{}) schema.SchemaDefaultFunc { return nil }
return &schema.Schema{
Description: "Kibana connection configuration block.",
Type: schema.TypeList,
MaxItems: 1,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"api_key": {
Description: "API Key to use for authentication to Kibana",
Type: schema.TypeString,
Optional: true,
Sensitive: true,
DefaultFunc: withEnvDefault("KIBANA_API_KEY", nil),
ConflictsWith: []string{"kibana.0.password", "kibana.0.username"},
},
"username": {
Description: "Username to use for API authentication to Kibana.",
Type: schema.TypeString,
Optional: true,
RequiredWith: []string{"kibana.0.password"},
},
"password": {
Description: "Password to use for API authentication to Kibana.",
Type: schema.TypeString,
Optional: true,
Sensitive: true,
RequiredWith: []string{"kibana.0.username"},
},
"endpoints": {
Description: "A comma-separated list of endpoints where the terraform provider will point to, this must include the http(s) schema and port number.",
Type: schema.TypeList,
Optional: true,
Sensitive: true,
MaxItems: 1, // Current API restriction
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"ca_certs": {
Description: "A list of paths to CA certificates to validate the certificate presented by the Kibana server.",
Type: schema.TypeList,
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"insecure": {
Description: "Disable TLS certificate validation",
Type: schema.TypeBool,
Optional: true,
Default: false,
},
},
},
}
}
func GetFleetConnectionSchema() *schema.Schema {
return &schema.Schema{
Description: "Fleet connection configuration block.",
Type: schema.TypeList,
MaxItems: 1,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"username": {
Description: "Username to use for API authentication to Fleet.",
Type: schema.TypeString,
Optional: true,
RequiredWith: []string{"fleet.0.password"},
},
"password": {
Description: "Password to use for API authentication to Fleet.",
Type: schema.TypeString,
Optional: true,
Sensitive: true,
RequiredWith: []string{"fleet.0.username"},
},
"api_key": {
Description: "API Key to use for authentication to Fleet.",
Type: schema.TypeString,
Optional: true,
Sensitive: true,
},
"endpoint": {
Description: "The Fleet server where the terraform provider will point to, this must include the http(s) schema and port number.",
Type: schema.TypeString,
Optional: true,
Sensitive: true,
},
"ca_certs": {
Description: "A list of paths to CA certificates to validate the certificate presented by the Fleet server.",
Type: schema.TypeList,
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"insecure": {
Description: "Disable TLS certificate validation",
Type: schema.TypeBool,
Optional: true,
Default: false,
},
},
},
}
}
func makePathRef(keyName string, keyValue string) string {
return fmt.Sprintf("%s.0.%s", keyName, keyValue)
}
func getDeprecationMessage(isProviderConfiguration bool) string {
if isProviderConfiguration {
return ""
}
return "This property will be removed in a future provider version. Configure the Elasticsearch connection via the provider configuration instead."
}