115 lines
3.9 KiB
Go
115 lines
3.9 KiB
Go
// 2026-03-07
|
||
// provider.go — описание провайдера sless для Terraform.
|
||
// Паттерн идентичен nubes провайдеру (NubesProvider) — для облегчения переноса.
|
||
// Атрибуты: endpoint (URL оператора) + token (Bearer).
|
||
// Env-переменные: SLESS_ENDPOINT, SLESS_API_TOKEN.
|
||
package provider
|
||
|
||
import (
|
||
"context"
|
||
"os"
|
||
"strings"
|
||
|
||
"terraform-provider-sless/internal/client"
|
||
"terraform-provider-sless/internal/resources"
|
||
|
||
"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"
|
||
)
|
||
|
||
var _ provider.Provider = &SlessProvider{}
|
||
|
||
type SlessProvider struct {
|
||
version string
|
||
}
|
||
|
||
// SlessProviderModel — конфигурация блока provider {} в .tf файле.
|
||
type SlessProviderModel struct {
|
||
Endpoint types.String `tfsdk:"endpoint"`
|
||
Token types.String `tfsdk:"token"`
|
||
Namespace types.String `tfsdk:"namespace"`
|
||
}
|
||
|
||
// New возвращает фабрику провайдера — точная копия паттерна nubes.
|
||
func New(version string) func() provider.Provider {
|
||
return func() provider.Provider {
|
||
return &SlessProvider{version: version}
|
||
}
|
||
}
|
||
|
||
func (p *SlessProvider) Metadata(_ context.Context, _ provider.MetadataRequest, resp *provider.MetadataResponse) {
|
||
resp.TypeName = "sless"
|
||
resp.Version = p.version
|
||
}
|
||
|
||
func (p *SlessProvider) Schema(_ context.Context, _ provider.SchemaRequest, resp *provider.SchemaResponse) {
|
||
resp.Schema = schema.Schema{
|
||
Attributes: map[string]schema.Attribute{
|
||
"endpoint": schema.StringAttribute{
|
||
MarkdownDescription: "sless operator API endpoint, например http://sless-operator.sless.svc:9090",
|
||
Optional: true,
|
||
},
|
||
"token": schema.StringAttribute{
|
||
MarkdownDescription: "Bearer-токен аутентификации (env: SLESS_API_TOKEN)",
|
||
Optional: true,
|
||
Sensitive: true,
|
||
},
|
||
// namespace — окружение/проект в кластере. Задаётся один раз здесь.
|
||
// В ресурсах (sless_function, sless_trigger, sless_job) namespace НЕ указывается.
|
||
"namespace": schema.StringAttribute{
|
||
MarkdownDescription: "Пространство имён (окружение). Задаётся один раз для всех ресурсов.",
|
||
Required: true,
|
||
},
|
||
},
|
||
}
|
||
}
|
||
|
||
// Configure инициализирует HTTP-клиент и кладёт его в ResourceData/DataSourceData.
|
||
// Ресурсы получают клиент через Configure(req.ProviderData).
|
||
func (p *SlessProvider) Configure(ctx context.Context, req provider.ConfigureRequest, resp *provider.ConfigureResponse) {
|
||
var config SlessProviderModel
|
||
resp.Diagnostics.Append(req.Config.Get(ctx, &config)...)
|
||
if resp.Diagnostics.HasError() {
|
||
return
|
||
}
|
||
|
||
endpoint := "http://localhost:9090"
|
||
token := ""
|
||
|
||
if !config.Endpoint.IsNull() && config.Endpoint.ValueString() != "" {
|
||
endpoint = config.Endpoint.ValueString()
|
||
} else if v := os.Getenv("SLESS_ENDPOINT"); v != "" {
|
||
endpoint = v
|
||
}
|
||
|
||
if !config.Token.IsNull() {
|
||
token = strings.TrimSpace(config.Token.ValueString())
|
||
}
|
||
if token == "" {
|
||
if v := os.Getenv("SLESS_API_TOKEN"); v != "" {
|
||
token = strings.TrimSpace(v)
|
||
}
|
||
}
|
||
|
||
namespace := config.Namespace.ValueString()
|
||
|
||
c := client.New(endpoint, token, namespace)
|
||
resp.ResourceData = c
|
||
resp.DataSourceData = c
|
||
}
|
||
|
||
func (p *SlessProvider) Resources(_ context.Context) []func() resource.Resource {
|
||
return []func() resource.Resource{
|
||
resources.NewFunctionResource,
|
||
resources.NewTriggerResource,
|
||
resources.NewJobResource,
|
||
}
|
||
}
|
||
|
||
func (p *SlessProvider) DataSources(_ context.Context) []func() datasource.DataSource {
|
||
return nil
|
||
}
|