feat: provider audit — builder support, function tuning, source archive
Аудит провайдера vs каноничный Fission. Добавлено:
Environment:
- builder_image, builder_command для Go и языков с build step
Package:
- deploy_type (literal/source) для переключения deployment/source archive
- loadPackageSourceArchive() — zip-упаковка source_dir
- Убран пустой source:{} из literal mode
Function:
- executor_type (poolmgr/newdeploy/container)
- function_timeout, idle_timeout
- min_scale, max_scale для ExecutionStrategy
Все 21 тест пройден. Обратная совместимость проверена.
Документация: doc/AUDIT_PROVIDER_VS_FISSION_2026-06-03.md
This commit is contained in:
@@ -9,6 +9,7 @@ import (
|
||||
"github.com/hashicorp/terraform-plugin-framework/path"
|
||||
"github.com/hashicorp/terraform-plugin-framework/resource"
|
||||
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
|
||||
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault"
|
||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
|
||||
@@ -26,13 +27,18 @@ type FunctionResource struct {
|
||||
|
||||
// functionResourceModel описывает состояние terraform ресурса fission_function.
|
||||
type functionResourceModel struct {
|
||||
ID types.String `tfsdk:"id"`
|
||||
Name types.String `tfsdk:"name"`
|
||||
Environment types.String `tfsdk:"environment"`
|
||||
PackageName types.String `tfsdk:"package_name"`
|
||||
Entrypoint types.String `tfsdk:"entrypoint"`
|
||||
Namespace types.String `tfsdk:"namespace"`
|
||||
UID types.String `tfsdk:"uid"`
|
||||
ID types.String `tfsdk:"id"`
|
||||
Name types.String `tfsdk:"name"`
|
||||
Environment types.String `tfsdk:"environment"`
|
||||
PackageName types.String `tfsdk:"package_name"`
|
||||
Entrypoint types.String `tfsdk:"entrypoint"`
|
||||
ExecutorType types.String `tfsdk:"executor_type"`
|
||||
FunctionTimeout types.Int64 `tfsdk:"function_timeout"`
|
||||
IdleTimeout types.Int64 `tfsdk:"idle_timeout"`
|
||||
MinScale types.Int64 `tfsdk:"min_scale"`
|
||||
MaxScale types.Int64 `tfsdk:"max_scale"`
|
||||
Namespace types.String `tfsdk:"namespace"`
|
||||
UID types.String `tfsdk:"uid"`
|
||||
}
|
||||
|
||||
// NewFunctionResource создает инстанс ресурса функции.
|
||||
@@ -69,6 +75,28 @@ func (r *FunctionResource) Schema(_ context.Context, _ resource.SchemaRequest, r
|
||||
Required: true,
|
||||
Description: "Имя точки входа в пакете (например main.main).",
|
||||
},
|
||||
"executor_type": schema.StringAttribute{
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Default: stringdefault.StaticString("poolmgr"),
|
||||
Description: "Тип executor: poolmgr (default), newdeploy или container.",
|
||||
},
|
||||
"function_timeout": schema.Int64Attribute{
|
||||
Optional: true,
|
||||
Description: "Таймаут выполнения функции в секундах (Fission default: 60).",
|
||||
},
|
||||
"idle_timeout": schema.Int64Attribute{
|
||||
Optional: true,
|
||||
Description: "Время простоя до scale-to-zero в секундах (Fission default: 120).",
|
||||
},
|
||||
"min_scale": schema.Int64Attribute{
|
||||
Optional: true,
|
||||
Description: "Минимальное число реплик (для newdeploy/container).",
|
||||
},
|
||||
"max_scale": schema.Int64Attribute{
|
||||
Optional: true,
|
||||
Description: "Максимальное число реплик (для newdeploy/container).",
|
||||
},
|
||||
"namespace": schema.StringAttribute{
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
@@ -235,6 +263,46 @@ func (r *FunctionResource) ImportState(ctx context.Context, req resource.ImportS
|
||||
|
||||
// functionToUnstructured преобразует Terraform model в Kubernetes CRD payload.
|
||||
func functionToUnstructured(model functionResourceModel, namespace string) *unstructured.Unstructured {
|
||||
executorType := "poolmgr"
|
||||
if !model.ExecutorType.IsNull() && !model.ExecutorType.IsUnknown() && model.ExecutorType.ValueString() != "" {
|
||||
executorType = model.ExecutorType.ValueString()
|
||||
}
|
||||
|
||||
executionStrategy := map[string]interface{}{
|
||||
"ExecutorType": executorType,
|
||||
}
|
||||
if !model.MinScale.IsNull() && !model.MinScale.IsUnknown() {
|
||||
executionStrategy["MinScale"] = model.MinScale.ValueInt64()
|
||||
}
|
||||
if !model.MaxScale.IsNull() && !model.MaxScale.IsUnknown() {
|
||||
executionStrategy["MaxScale"] = model.MaxScale.ValueInt64()
|
||||
}
|
||||
|
||||
spec := map[string]interface{}{
|
||||
"environment": map[string]interface{}{
|
||||
"name": model.Environment.ValueString(),
|
||||
"namespace": namespace,
|
||||
},
|
||||
"InvokeStrategy": map[string]interface{}{
|
||||
"ExecutionStrategy": executionStrategy,
|
||||
"StrategyType": "execution",
|
||||
},
|
||||
"package": map[string]interface{}{
|
||||
"packageref": map[string]interface{}{
|
||||
"name": model.PackageName.ValueString(),
|
||||
"namespace": namespace,
|
||||
},
|
||||
"functionName": model.Entrypoint.ValueString(),
|
||||
},
|
||||
}
|
||||
|
||||
if !model.FunctionTimeout.IsNull() && !model.FunctionTimeout.IsUnknown() {
|
||||
spec["functionTimeout"] = model.FunctionTimeout.ValueInt64()
|
||||
}
|
||||
if !model.IdleTimeout.IsNull() && !model.IdleTimeout.IsUnknown() {
|
||||
spec["idletimeout"] = model.IdleTimeout.ValueInt64()
|
||||
}
|
||||
|
||||
return &unstructured.Unstructured{Object: map[string]interface{}{
|
||||
"apiVersion": "fission.io/v1",
|
||||
"kind": "Function",
|
||||
@@ -242,25 +310,7 @@ func functionToUnstructured(model functionResourceModel, namespace string) *unst
|
||||
"name": model.Name.ValueString(),
|
||||
"namespace": namespace,
|
||||
},
|
||||
"spec": map[string]interface{}{
|
||||
"environment": map[string]interface{}{
|
||||
"name": model.Environment.ValueString(),
|
||||
"namespace": namespace,
|
||||
},
|
||||
"InvokeStrategy": map[string]interface{}{
|
||||
"ExecutionStrategy": map[string]interface{}{
|
||||
"ExecutorType": "poolmgr",
|
||||
},
|
||||
"StrategyType": "execution",
|
||||
},
|
||||
"package": map[string]interface{}{
|
||||
"packageref": map[string]interface{}{
|
||||
"name": model.PackageName.ValueString(),
|
||||
"namespace": namespace,
|
||||
},
|
||||
"functionName": model.Entrypoint.ValueString(),
|
||||
},
|
||||
},
|
||||
"spec": spec,
|
||||
}}
|
||||
}
|
||||
|
||||
@@ -269,6 +319,11 @@ func unstructuredToFunctionModel(functionObject *unstructured.Unstructured, base
|
||||
environmentName, _, _ := unstructured.NestedString(functionObject.Object, "spec", "environment", "name")
|
||||
packageName, _, _ := unstructured.NestedString(functionObject.Object, "spec", "package", "packageref", "name")
|
||||
entrypoint, _, _ := unstructured.NestedString(functionObject.Object, "spec", "package", "functionName")
|
||||
executorType, _, _ := unstructured.NestedString(functionObject.Object, "spec", "InvokeStrategy", "ExecutionStrategy", "ExecutorType")
|
||||
functionTimeout, foundFT, _ := unstructured.NestedInt64(functionObject.Object, "spec", "functionTimeout")
|
||||
idleTimeout, foundIT, _ := unstructured.NestedInt64(functionObject.Object, "spec", "idletimeout")
|
||||
minScale, foundMin, _ := unstructured.NestedInt64(functionObject.Object, "spec", "InvokeStrategy", "ExecutionStrategy", "MinScale")
|
||||
maxScale, foundMax, _ := unstructured.NestedInt64(functionObject.Object, "spec", "InvokeStrategy", "ExecutionStrategy", "MaxScale")
|
||||
|
||||
state := base
|
||||
state.Name = types.StringValue(functionObject.GetName())
|
||||
@@ -285,6 +340,21 @@ func unstructuredToFunctionModel(functionObject *unstructured.Unstructured, base
|
||||
if entrypoint != "" {
|
||||
state.Entrypoint = types.StringValue(entrypoint)
|
||||
}
|
||||
if executorType != "" {
|
||||
state.ExecutorType = types.StringValue(executorType)
|
||||
}
|
||||
if foundFT {
|
||||
state.FunctionTimeout = types.Int64Value(functionTimeout)
|
||||
}
|
||||
if foundIT {
|
||||
state.IdleTimeout = types.Int64Value(idleTimeout)
|
||||
}
|
||||
if foundMin {
|
||||
state.MinScale = types.Int64Value(minScale)
|
||||
}
|
||||
if foundMax {
|
||||
state.MaxScale = types.Int64Value(maxScale)
|
||||
}
|
||||
|
||||
return state
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user