93 lines
3.4 KiB
Go
93 lines
3.4 KiB
Go
// Package provider is the Terraform provider for Hammerhead.
|
|
package provider
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
|
|
"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"
|
|
|
|
"git.veillax.com/Veillax/hhctl/client"
|
|
)
|
|
|
|
type hammerheadProvider struct{ version string }
|
|
|
|
// New returns a provider factory.
|
|
func New(version string) func() provider.Provider {
|
|
return func() provider.Provider { return &hammerheadProvider{version} }
|
|
}
|
|
|
|
type providerModel struct {
|
|
URL types.String `tfsdk:"url"`
|
|
Token types.String `tfsdk:"token"`
|
|
Org types.String `tfsdk:"org"`
|
|
}
|
|
|
|
func (p *hammerheadProvider) Metadata(_ context.Context, _ provider.MetadataRequest, resp *provider.MetadataResponse) {
|
|
resp.TypeName = "hammerhead"
|
|
resp.Version = p.version
|
|
}
|
|
|
|
func (p *hammerheadProvider) Schema(_ context.Context, _ provider.SchemaRequest, resp *provider.SchemaResponse) {
|
|
resp.Schema = schema.Schema{
|
|
Description: "Manage a Hammerhead control plane: sites, ports, domains, edges and alert channels.",
|
|
Attributes: map[string]schema.Attribute{
|
|
"url": schema.StringAttribute{Optional: true, Description: "Hammerhead address, e.g. https://hammerhead.example.com. Defaults to $HAMMERHEAD_URL."},
|
|
"token": schema.StringAttribute{Optional: true, Sensitive: true, Description: "API key (hhk_...). An organization key manages that organization; edges and server alert channels need a server key. Defaults to $HAMMERHEAD_TOKEN."},
|
|
"org": schema.StringAttribute{Optional: true, Description: "Organization ID. Optional with an organization key. Defaults to $HAMMERHEAD_ORG."},
|
|
},
|
|
}
|
|
}
|
|
|
|
func orDefault(v types.String, env string) string {
|
|
if !v.IsNull() && !v.IsUnknown() {
|
|
return v.ValueString()
|
|
}
|
|
return os.Getenv(env)
|
|
}
|
|
|
|
func (p *hammerheadProvider) Configure(ctx context.Context, req provider.ConfigureRequest, resp *provider.ConfigureResponse) {
|
|
var cfg providerModel
|
|
resp.Diagnostics.Append(req.Config.Get(ctx, &cfg)...)
|
|
if resp.Diagnostics.HasError() {
|
|
return
|
|
}
|
|
for _, v := range []struct {
|
|
name string
|
|
val types.String
|
|
}{{"url", cfg.URL}, {"token", cfg.Token}, {"org", cfg.Org}} {
|
|
if v.val.IsUnknown() {
|
|
resp.Diagnostics.AddAttributeError(path.Root(v.name), "Unknown "+v.name, "The value must be known when the provider is configured.")
|
|
}
|
|
}
|
|
if resp.Diagnostics.HasError() {
|
|
return
|
|
}
|
|
url, token := orDefault(cfg.URL, "HAMMERHEAD_URL"), orDefault(cfg.Token, "HAMMERHEAD_TOKEN")
|
|
if url == "" || token == "" {
|
|
resp.Diagnostics.AddError("Missing configuration", "Set url and token in the provider block, or HAMMERHEAD_URL and HAMMERHEAD_TOKEN.")
|
|
return
|
|
}
|
|
c := client.New(url, token, orDefault(cfg.Org, "HAMMERHEAD_ORG"))
|
|
resp.ResourceData, resp.DataSourceData = c, c
|
|
}
|
|
|
|
func (p *hammerheadProvider) Resources(context.Context) []func() resource.Resource {
|
|
return []func() resource.Resource{NewSite, NewPort, NewDomain, NewEdge, NewAlertChannel}
|
|
}
|
|
|
|
func (p *hammerheadProvider) DataSources(context.Context) []func() datasource.DataSource {
|
|
return []func() datasource.DataSource{NewEdgeData}
|
|
}
|
|
|
|
// clientFrom pulls the configured client out of ProviderData (nil before Configure ran).
|
|
func clientFrom(data any) *client.Client {
|
|
c, _ := data.(*client.Client)
|
|
return c
|
|
}
|