224 lines
8.1 KiB
Go
224 lines
8.1 KiB
Go
package provider
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
|
|
"github.com/DevFW-CICD/terraform-provider-edge-connect/internal/client"
|
|
"github.com/hashicorp/terraform-plugin-framework/datasource"
|
|
"github.com/hashicorp/terraform-plugin-framework/path"
|
|
"github.com/hashicorp/terraform-plugin-framework/provider"
|
|
"github.com/hashicorp/terraform-plugin-framework/provider/schema"
|
|
"github.com/hashicorp/terraform-plugin-framework/resource"
|
|
"github.com/hashicorp/terraform-plugin-framework/types"
|
|
"github.com/hashicorp/terraform-plugin-log/tflog"
|
|
)
|
|
|
|
// Ensure the implementation satisfies the expected interfaces.
|
|
var (
|
|
_ provider.Provider = &edgeConnectProvider{}
|
|
)
|
|
|
|
// New is a helper function to simplify provider server and testing implementation.
|
|
func New(version string) func() provider.Provider {
|
|
return func() provider.Provider {
|
|
return &edgeConnectProvider{
|
|
version: version,
|
|
}
|
|
}
|
|
}
|
|
|
|
// edgeConnectProvider is the provider implementation.
|
|
type edgeConnectProvider struct {
|
|
version string
|
|
}
|
|
|
|
// edgeConnectProviderModel maps provider schema data to a Go type.
|
|
type edgeConnectProviderModel struct {
|
|
BaseURL types.String `tfsdk:"base_url"`
|
|
Token types.String `tfsdk:"token"`
|
|
Username types.String `tfsdk:"username"`
|
|
Password types.String `tfsdk:"password"`
|
|
}
|
|
|
|
// Metadata returns the provider type name.
|
|
func (p *edgeConnectProvider) Metadata(_ context.Context, _ provider.MetadataRequest, resp *provider.MetadataResponse) {
|
|
resp.TypeName = "edge-connect"
|
|
resp.Version = p.version
|
|
}
|
|
|
|
// Schema defines the provider-level schema for configuration data.
|
|
func (p *edgeConnectProvider) Schema(_ context.Context, _ provider.SchemaRequest, resp *provider.SchemaResponse) {
|
|
resp.Schema = schema.Schema{
|
|
Description: "Interact with Edge Connect API for managing applications and application instances.",
|
|
Attributes: map[string]schema.Attribute{
|
|
"base_url": schema.StringAttribute{
|
|
Description: "The base URL for the Edge Connect API. May also be provided via EDGE_CONNECT_BASE_URL environment variable.",
|
|
Optional: true,
|
|
},
|
|
"token": schema.StringAttribute{
|
|
Description: "Bearer token for authentication. May also be provided via EDGE_CONNECT_TOKEN environment variable.",
|
|
Optional: true,
|
|
Sensitive: true,
|
|
},
|
|
"username": schema.StringAttribute{
|
|
Description: "Username for basic authentication. May also be provided via EDGE_CONNECT_USERNAME environment variable.",
|
|
Optional: true,
|
|
},
|
|
"password": schema.StringAttribute{
|
|
Description: "Password for basic authentication. May also be provided via EDGE_CONNECT_PASSWORD environment variable.",
|
|
Optional: true,
|
|
Sensitive: true,
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
// Configure prepares a Edge Connect API client for data sources and resources.
|
|
func (p *edgeConnectProvider) Configure(ctx context.Context, req provider.ConfigureRequest, resp *provider.ConfigureResponse) {
|
|
tflog.Info(ctx, "Configuring Edge Connect client")
|
|
|
|
// Retrieve provider data from configuration
|
|
var config edgeConnectProviderModel
|
|
diags := req.Config.Get(ctx, &config)
|
|
resp.Diagnostics.Append(diags...)
|
|
if resp.Diagnostics.HasError() {
|
|
return
|
|
}
|
|
|
|
// If practitioner provided a configuration value for any of the
|
|
// attributes, it must be a known value.
|
|
if config.BaseURL.IsUnknown() {
|
|
resp.Diagnostics.AddAttributeError(
|
|
path.Root("base_url"),
|
|
"Unknown Edge Connect API Base URL",
|
|
"The provider cannot create the Edge Connect API client as there is an unknown configuration value for the base URL. "+
|
|
"Either target apply the source of the value first, set the value statically in the configuration, or use the EDGE_CONNECT_BASE_URL environment variable.",
|
|
)
|
|
}
|
|
|
|
if config.Token.IsUnknown() {
|
|
resp.Diagnostics.AddAttributeError(
|
|
path.Root("token"),
|
|
"Unknown Edge Connect API Token",
|
|
"The provider cannot create the Edge Connect API client as there is an unknown configuration value for the token. "+
|
|
"Either target apply the source of the value first, set the value statically in the configuration, or use the EDGE_CONNECT_TOKEN environment variable.",
|
|
)
|
|
}
|
|
|
|
if config.Username.IsUnknown() {
|
|
resp.Diagnostics.AddAttributeError(
|
|
path.Root("username"),
|
|
"Unknown Edge Connect API Username",
|
|
"The provider cannot create the Edge Connect API client as there is an unknown configuration value for the username. "+
|
|
"Either target apply the source of the value first, set the value statically in the configuration, or use the EDGE_CONNECT_USERNAME environment variable.",
|
|
)
|
|
}
|
|
|
|
if config.Password.IsUnknown() {
|
|
resp.Diagnostics.AddAttributeError(
|
|
path.Root("password"),
|
|
"Unknown Edge Connect API Password",
|
|
"The provider cannot create the Edge Connect API client as there is an unknown configuration value for the password. "+
|
|
"Either target apply the source of the value first, set the value statically in the configuration, or use the EDGE_CONNECT_PASSWORD environment variable.",
|
|
)
|
|
}
|
|
|
|
if resp.Diagnostics.HasError() {
|
|
return
|
|
}
|
|
|
|
// Default values to environment variables, but override
|
|
// with Terraform configuration value if set.
|
|
baseURL := os.Getenv("EDGE_CONNECT_BASE_URL")
|
|
token := os.Getenv("EDGE_CONNECT_TOKEN")
|
|
username := os.Getenv("EDGE_CONNECT_USERNAME")
|
|
password := os.Getenv("EDGE_CONNECT_PASSWORD")
|
|
|
|
if !config.BaseURL.IsNull() {
|
|
baseURL = config.BaseURL.ValueString()
|
|
}
|
|
|
|
if !config.Token.IsNull() {
|
|
token = config.Token.ValueString()
|
|
}
|
|
|
|
if !config.Username.IsNull() {
|
|
username = config.Username.ValueString()
|
|
}
|
|
|
|
if !config.Password.IsNull() {
|
|
password = config.Password.ValueString()
|
|
}
|
|
|
|
// If any of the expected configurations are missing, return
|
|
// errors with provider-specific guidance.
|
|
if baseURL == "" {
|
|
resp.Diagnostics.AddAttributeError(
|
|
path.Root("base_url"),
|
|
"Missing Edge Connect API Base URL",
|
|
"The provider requires a base URL for the Edge Connect API. "+
|
|
"Set the base_url value in the configuration or use the EDGE_CONNECT_BASE_URL environment variable. "+
|
|
"If either is already set, ensure the value is not empty.",
|
|
)
|
|
}
|
|
|
|
if token == "" && (username == "" || password == "") {
|
|
resp.Diagnostics.AddError(
|
|
"Missing Edge Connect API Authentication",
|
|
"The provider requires either a bearer token or username/password for authentication. "+
|
|
"Set the token value in the configuration or use the EDGE_CONNECT_TOKEN environment variable, "+
|
|
"or set username and password values in the configuration or use the EDGE_CONNECT_USERNAME and EDGE_CONNECT_PASSWORD environment variables.",
|
|
)
|
|
}
|
|
|
|
if resp.Diagnostics.HasError() {
|
|
return
|
|
}
|
|
|
|
ctx = tflog.SetField(ctx, "edge_connect_base_url", baseURL)
|
|
ctx = tflog.SetField(ctx, "edge_connect_token", token)
|
|
ctx = tflog.SetField(ctx, "edge_connect_username", username)
|
|
ctx = tflog.SetField(ctx, "edge_connect_password", password)
|
|
ctx = tflog.MaskFieldValuesWithFieldKeys(ctx, "edge_connect_token")
|
|
ctx = tflog.MaskFieldValuesWithFieldKeys(ctx, "edge_connect_password")
|
|
|
|
tflog.Debug(ctx, "Creating Edge Connect client")
|
|
|
|
// Create a new Edge Connect client using the configuration values
|
|
apiClient := client.NewClient(baseURL, token, username, password)
|
|
|
|
// Test the connection
|
|
if err := apiClient.HealthCheck(); err != nil {
|
|
resp.Diagnostics.AddError(
|
|
"Unable to Connect to Edge Connect API",
|
|
"An error occurred while connecting to the Edge Connect API. "+
|
|
"Please verify that your base URL and authentication credentials are correct.\n\n"+
|
|
"Edge Connect Client Error: "+err.Error(),
|
|
)
|
|
return
|
|
}
|
|
|
|
// Make the Edge Connect client available during DataSource and Resource
|
|
// type Configure methods.
|
|
resp.DataSourceData = apiClient
|
|
resp.ResourceData = apiClient
|
|
|
|
tflog.Info(ctx, "Configured Edge Connect client", map[string]any{"success": true})
|
|
}
|
|
|
|
// DataSources defines the data sources implemented in the provider.
|
|
func (p *edgeConnectProvider) DataSources(_ context.Context) []func() datasource.DataSource {
|
|
return []func() datasource.DataSource{
|
|
NewAppDataSource,
|
|
NewAppInstDataSource,
|
|
}
|
|
}
|
|
|
|
// Resources defines the resources implemented in the provider.
|
|
func (p *edgeConnectProvider) Resources(_ context.Context) []func() resource.Resource {
|
|
return []func() resource.Resource{
|
|
NewAppResource,
|
|
NewAppInstResource,
|
|
}
|
|
}
|