Files
terraform-provider-virtfusion/internal/provider/provider.go

149 lines
4.2 KiB
Go

// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package provider
import (
"context"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"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"
"net/http"
"net/url"
"os"
"path"
)
// Ensure VirtfusionProvider satisfies various provider interfaces.
var _ provider.Provider = &VirtfusionProvider{}
// VirtfusionProvider defines the provider implementation.
type VirtfusionProvider struct {
// version is set to the provider version on release, "dev" when the
// provider is built and ran locally, and "test" when running acceptance
// testing.
version string
}
// ScaffoldingProviderModel describes the provider data model.
type ScaffoldingProviderModel struct {
Endpoint types.String `tfsdk:"endpoint"`
ApiToken types.String `tfsdk:"api_token"`
}
func (p *VirtfusionProvider) Metadata(ctx context.Context, req provider.MetadataRequest, resp *provider.MetadataResponse) {
resp.TypeName = "virtfusion"
resp.Version = p.version
}
func (p *VirtfusionProvider) Schema(ctx context.Context, req provider.SchemaRequest, resp *provider.SchemaResponse) {
resp.Schema = schema.Schema{
Attributes: map[string]schema.Attribute{
"endpoint": schema.StringAttribute{
MarkdownDescription: "The endpoint to use for API requests.",
Required: true,
},
"api_token": schema.StringAttribute{
MarkdownDescription: "The API token to use for API requests.",
Required: true,
},
},
}
}
func (p *VirtfusionProvider) Configure(ctx context.Context, req provider.ConfigureRequest, resp *provider.ConfigureResponse) {
// Check environment variables
apiToken := os.Getenv("VIRTFUSION_API_TOKEN")
endpoint := os.Getenv("VIRTFUSION_ENDPOINT")
var data ScaffoldingProviderModel
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
if resp.Diagnostics.HasError() {
return
}
// Configuration values are now available.
// if data.Endpoint.IsNull() { /* ... */ }
if data.Endpoint.ValueString() != "" {
endpoint = data.Endpoint.ValueString()
}
if data.ApiToken.ValueString() != "" {
apiToken = data.ApiToken.ValueString()
}
if apiToken == "" {
resp.Diagnostics.AddError(
"Missing API Token Configuration",
"While configuring the provider, the API token was not found in "+
"the VIRTFUSION_API_TOKEN environment variable or provider "+
"configuration block api_token attribute.",
)
// Not returning early allows the logic to collect all errors.
}
if endpoint == "" {
resp.Diagnostics.AddError(
"Missing Endpoint Configuration",
"While configuring the provider, the endpoint was not found in "+
"the VIRTFUSION_ENDPOINT environment variable or provider "+
"configuration block endpoint attribute.",
)
// Not returning early allows the logic to collect all errors.
}
customTransport := &CustomTransport{
Transport: http.DefaultTransport,
BaseURL: &url.URL{Scheme: "https", Host: endpoint, Path: "/api/v1"},
Token: apiToken,
}
// Example client configuration for data sources and resources
client := &http.Client{
Transport: customTransport,
}
resp.DataSourceData = client
resp.ResourceData = client
}
func (p *VirtfusionProvider) Resources(ctx context.Context) []func() resource.Resource {
return []func() resource.Resource{
NewVirtfusionServerResource,
NewVirtfusionServerBuildResource,
NewVirtfusionSSHResource,
NewVirtfusionNetworkBlockResource,
}
}
func (p *VirtfusionProvider) DataSources(ctx context.Context) []func() datasource.DataSource {
return []func() datasource.DataSource{}
}
type CustomTransport struct {
Transport http.RoundTripper
BaseURL *url.URL
Token string
}
func (c *CustomTransport) RoundTrip(req *http.Request) (*http.Response, error) {
req.Header.Add("Authorization", "Bearer "+c.Token)
req.URL.Scheme = c.BaseURL.Scheme
req.URL.Host = c.BaseURL.Host
req.URL.Path = path.Join(c.BaseURL.Path, req.URL.Path)
return c.Transport.RoundTrip(req)
}
func New(version string) func() provider.Provider {
return func() provider.Provider {
return &VirtfusionProvider{
version: version,
}
}
}