Независимый Go-модуль terraform/provider/ для управления функциями через REST API. Ресурсы: - sless_function: CRUD + upload zip + WaitReady (kaniko build 5 мин) - sless_trigger: CRUD (http/cron) Компоненты: - internal/client/client.go — HTTP-клиент, готов к переносу в nubes - internal/provider/provider.go — паттерн идентичен nubes NubesProvider - internal/resources/ — function_resource.go, trigger_resource.go - hack/build-and-publish.sh — GPG-подпись + mc upload в S3 Опубликовано: terra.k8c.ru/naeel/sless v0.1.0 Проверено: terraform init успешен
105 lines
3.3 KiB
Go
105 lines
3.3 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"`
|
|
}
|
|
|
|
// 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,
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
// 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)
|
|
}
|
|
}
|
|
|
|
c := client.New(endpoint, token)
|
|
resp.ResourceData = c
|
|
resp.DataSourceData = c
|
|
}
|
|
|
|
func (p *SlessProvider) Resources(_ context.Context) []func() resource.Resource {
|
|
return []func() resource.Resource{
|
|
resources.NewFunctionResource,
|
|
resources.NewTriggerResource,
|
|
}
|
|
}
|
|
|
|
func (p *SlessProvider) DataSources(_ context.Context) []func() datasource.DataSource {
|
|
return nil
|
|
}
|