feat: scaffold terraform provider for fission via kubernetes CRD
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/client-go/dynamic"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
)
|
||||
|
||||
// Client хранит клиентов Kubernetes API для работы с CRD Fission.
|
||||
type Client struct {
|
||||
DynClient dynamic.Interface
|
||||
K8sClient kubernetes.Interface
|
||||
Namespace string
|
||||
}
|
||||
|
||||
// New создает Kubernetes clients из kubeconfig/context.
|
||||
func New(kubeconfigPath, kubeContext, namespace string) (*Client, error) {
|
||||
cfg, err := buildConfig(kubeconfigPath, kubeContext)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
dynClient, err := dynamic.NewForConfig(cfg)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("create dynamic client: %w", err)
|
||||
}
|
||||
|
||||
k8sClient, err := kubernetes.NewForConfig(cfg)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("create kubernetes client: %w", err)
|
||||
}
|
||||
|
||||
return &Client{
|
||||
DynClient: dynClient,
|
||||
K8sClient: k8sClient,
|
||||
Namespace: namespace,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func buildConfig(kubeconfigPath, kubeContext string) (*rest.Config, error) {
|
||||
loadingRules := &clientcmd.ClientConfigLoadingRules{}
|
||||
if kubeconfigPath != "" {
|
||||
loadingRules.ExplicitPath = kubeconfigPath
|
||||
}
|
||||
|
||||
overrides := &clientcmd.ConfigOverrides{}
|
||||
if kubeContext != "" {
|
||||
overrides.CurrentContext = kubeContext
|
||||
}
|
||||
|
||||
clientCfg := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, overrides)
|
||||
cfg, err := clientCfg.ClientConfig()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("build kube config: %w", err)
|
||||
}
|
||||
|
||||
return cfg, nil
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
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"
|
||||
|
||||
"terraform-provider-fission/internal/client"
|
||||
"terraform-provider-fission/internal/resources"
|
||||
)
|
||||
|
||||
var _ provider.Provider = &FissionProvider{}
|
||||
|
||||
type FissionProvider struct {
|
||||
version string
|
||||
}
|
||||
|
||||
type FissionProviderModel struct {
|
||||
KubeconfigPath types.String `tfsdk:"kubeconfig_path"`
|
||||
KubeContext types.String `tfsdk:"kube_context"`
|
||||
Namespace types.String `tfsdk:"namespace"`
|
||||
}
|
||||
|
||||
func New(version string) func() provider.Provider {
|
||||
return func() provider.Provider {
|
||||
return &FissionProvider{version: version}
|
||||
}
|
||||
}
|
||||
|
||||
func (p *FissionProvider) Metadata(_ context.Context, _ provider.MetadataRequest, resp *provider.MetadataResponse) {
|
||||
resp.TypeName = "fission"
|
||||
resp.Version = p.version
|
||||
}
|
||||
|
||||
func (p *FissionProvider) Schema(_ context.Context, _ provider.SchemaRequest, resp *provider.SchemaResponse) {
|
||||
resp.Schema = schema.Schema{
|
||||
Attributes: map[string]schema.Attribute{
|
||||
"kubeconfig_path": schema.StringAttribute{
|
||||
Optional: true,
|
||||
Description: "Путь к kubeconfig файлу.",
|
||||
},
|
||||
"kube_context": schema.StringAttribute{
|
||||
Optional: true,
|
||||
Description: "Имя kubernetes context.",
|
||||
},
|
||||
"namespace": schema.StringAttribute{
|
||||
Optional: true,
|
||||
Description: "Namespace для ресурсов Fission.",
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (p *FissionProvider) Configure(ctx context.Context, req provider.ConfigureRequest, resp *provider.ConfigureResponse) {
|
||||
var data FissionProviderModel
|
||||
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
kubeconfigPath := data.KubeconfigPath.ValueString()
|
||||
if kubeconfigPath == "" {
|
||||
kubeconfigPath = os.Getenv("KUBECONFIG")
|
||||
}
|
||||
|
||||
kubeContext := data.KubeContext.ValueString()
|
||||
if kubeContext == "" {
|
||||
kubeContext = os.Getenv("KUBE_CONTEXT")
|
||||
}
|
||||
|
||||
namespace := data.Namespace.ValueString()
|
||||
if namespace == "" {
|
||||
namespace = os.Getenv("FISSION_NAMESPACE")
|
||||
}
|
||||
if namespace == "" {
|
||||
namespace = "default"
|
||||
}
|
||||
|
||||
fissionClient, err := client.New(kubeconfigPath, kubeContext, namespace)
|
||||
if err != nil {
|
||||
resp.Diagnostics.AddError("Ошибка инициализации Kubernetes клиента", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
resp.DataSourceData = fissionClient
|
||||
resp.ResourceData = fissionClient
|
||||
}
|
||||
|
||||
func (p *FissionProvider) Resources(_ context.Context) []func() resource.Resource {
|
||||
return []func() resource.Resource{
|
||||
resources.NewEnvironmentResource,
|
||||
resources.NewPackageResource,
|
||||
resources.NewFunctionResource,
|
||||
resources.NewHTTPTriggerResource,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *FissionProvider) DataSources(_ context.Context) []func() datasource.DataSource {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *FissionProvider) ValidateConfig(ctx context.Context, req provider.ValidateConfigRequest, resp *provider.ValidateConfigResponse) {
|
||||
var data FissionProviderModel
|
||||
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
if data.Namespace.IsNull() || data.Namespace.IsUnknown() {
|
||||
return
|
||||
}
|
||||
|
||||
if data.Namespace.ValueString() == "" {
|
||||
resp.Diagnostics.AddAttributeError(
|
||||
path.Root("namespace"),
|
||||
"Некорректный namespace",
|
||||
"Значение namespace не может быть пустой строкой.",
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package resources
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/resource"
|
||||
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
|
||||
)
|
||||
|
||||
var _ resource.Resource = &EnvironmentResource{}
|
||||
|
||||
type EnvironmentResource struct{}
|
||||
|
||||
func NewEnvironmentResource() resource.Resource {
|
||||
return &EnvironmentResource{}
|
||||
}
|
||||
|
||||
func (r *EnvironmentResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
|
||||
resp.TypeName = req.ProviderTypeName + "_environment"
|
||||
}
|
||||
|
||||
func (r *EnvironmentResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {
|
||||
resp.Schema = schema.Schema{}
|
||||
}
|
||||
|
||||
func (r *EnvironmentResource) Configure(_ context.Context, _ resource.ConfigureRequest, _ *resource.ConfigureResponse) {}
|
||||
func (r *EnvironmentResource) Create(_ context.Context, _ resource.CreateRequest, _ *resource.CreateResponse) {}
|
||||
func (r *EnvironmentResource) Read(_ context.Context, _ resource.ReadRequest, _ *resource.ReadResponse) {}
|
||||
func (r *EnvironmentResource) Update(_ context.Context, _ resource.UpdateRequest, _ *resource.UpdateResponse) {}
|
||||
func (r *EnvironmentResource) Delete(_ context.Context, _ resource.DeleteRequest, _ *resource.DeleteResponse) {}
|
||||
@@ -0,0 +1,30 @@
|
||||
package resources
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/resource"
|
||||
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
|
||||
)
|
||||
|
||||
var _ resource.Resource = &FunctionResource{}
|
||||
|
||||
type FunctionResource struct{}
|
||||
|
||||
func NewFunctionResource() resource.Resource {
|
||||
return &FunctionResource{}
|
||||
}
|
||||
|
||||
func (r *FunctionResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
|
||||
resp.TypeName = req.ProviderTypeName + "_function"
|
||||
}
|
||||
|
||||
func (r *FunctionResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {
|
||||
resp.Schema = schema.Schema{}
|
||||
}
|
||||
|
||||
func (r *FunctionResource) Configure(_ context.Context, _ resource.ConfigureRequest, _ *resource.ConfigureResponse) {}
|
||||
func (r *FunctionResource) Create(_ context.Context, _ resource.CreateRequest, _ *resource.CreateResponse) {}
|
||||
func (r *FunctionResource) Read(_ context.Context, _ resource.ReadRequest, _ *resource.ReadResponse) {}
|
||||
func (r *FunctionResource) Update(_ context.Context, _ resource.UpdateRequest, _ *resource.UpdateResponse) {}
|
||||
func (r *FunctionResource) Delete(_ context.Context, _ resource.DeleteRequest, _ *resource.DeleteResponse) {}
|
||||
@@ -0,0 +1,30 @@
|
||||
package resources
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/resource"
|
||||
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
|
||||
)
|
||||
|
||||
var _ resource.Resource = &HTTPTriggerResource{}
|
||||
|
||||
type HTTPTriggerResource struct{}
|
||||
|
||||
func NewHTTPTriggerResource() resource.Resource {
|
||||
return &HTTPTriggerResource{}
|
||||
}
|
||||
|
||||
func (r *HTTPTriggerResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
|
||||
resp.TypeName = req.ProviderTypeName + "_http_trigger"
|
||||
}
|
||||
|
||||
func (r *HTTPTriggerResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {
|
||||
resp.Schema = schema.Schema{}
|
||||
}
|
||||
|
||||
func (r *HTTPTriggerResource) Configure(_ context.Context, _ resource.ConfigureRequest, _ *resource.ConfigureResponse) {}
|
||||
func (r *HTTPTriggerResource) Create(_ context.Context, _ resource.CreateRequest, _ *resource.CreateResponse) {}
|
||||
func (r *HTTPTriggerResource) Read(_ context.Context, _ resource.ReadRequest, _ *resource.ReadResponse) {}
|
||||
func (r *HTTPTriggerResource) Update(_ context.Context, _ resource.UpdateRequest, _ *resource.UpdateResponse) {}
|
||||
func (r *HTTPTriggerResource) Delete(_ context.Context, _ resource.DeleteRequest, _ *resource.DeleteResponse) {}
|
||||
@@ -0,0 +1,30 @@
|
||||
package resources
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/resource"
|
||||
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
|
||||
)
|
||||
|
||||
var _ resource.Resource = &PackageResource{}
|
||||
|
||||
type PackageResource struct{}
|
||||
|
||||
func NewPackageResource() resource.Resource {
|
||||
return &PackageResource{}
|
||||
}
|
||||
|
||||
func (r *PackageResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
|
||||
resp.TypeName = req.ProviderTypeName + "_package"
|
||||
}
|
||||
|
||||
func (r *PackageResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {
|
||||
resp.Schema = schema.Schema{}
|
||||
}
|
||||
|
||||
func (r *PackageResource) Configure(_ context.Context, _ resource.ConfigureRequest, _ *resource.ConfigureResponse) {}
|
||||
func (r *PackageResource) Create(_ context.Context, _ resource.CreateRequest, _ *resource.CreateResponse) {}
|
||||
func (r *PackageResource) Read(_ context.Context, _ resource.ReadRequest, _ *resource.ReadResponse) {}
|
||||
func (r *PackageResource) Update(_ context.Context, _ resource.UpdateRequest, _ *resource.UpdateResponse) {}
|
||||
func (r *PackageResource) Delete(_ context.Context, _ resource.DeleteRequest, _ *resource.DeleteResponse) {}
|
||||
Reference in New Issue
Block a user