feat: define Function and Trigger CRD types

Function:
  - runtime (go1.21/python3.11/nodejs20)
  - entrypoint, s3Bucket, s3Key
  - memoryMB (default 128), timeoutSec (default 30)
  - env map
  - status: phase (Pending/Building/Ready/Failed), imageRef, conditions

Trigger:
  - type (http/cron), functionRef
  - schedule (cron only)
  - preWarmSeconds (default 300) - pre-warm before cron run
  - status: active, url, lastScheduleTime

printcolumns for kubectl get output
This commit is contained in:
“Naeel”
2026-03-07 08:24:33 +04:00
parent 3e10ac1d63
commit d9f5ab56bb
5 changed files with 332 additions and 70 deletions
+63 -27
View File
@@ -1,18 +1,6 @@
/*
Copyright 2026.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Изменено: 2026-03-07
// Описание CRD Function — основной ресурс serverless функции.
// Пользователь создаёт Function, контроллер строит образ и деплоит в k8s.
package v1alpha1
@@ -20,28 +8,76 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
// FunctionSpec defines the desired state of Function
// FunctionSpec — желаемое состояние функции.
// Описывает всё необходимое для сборки и запуска пользовательского кода.
type FunctionSpec struct {
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
// Important: Run "make" to regenerate code after modifying this file
// Runtime — язык и версия выполнения (go1.21, python3.11, nodejs20)
// +kubebuilder:validation:Enum=go1.21;python3.11;nodejs20
// +kubebuilder:validation:Required
Runtime string `json:"runtime"`
// Foo is an example field of Function. Edit function_types.go to remove/update
Foo string `json:"foo,omitempty"`
// Entrypoint — точка входа в код функции (например: handler.handle)
// +kubebuilder:validation:Required
Entrypoint string `json:"entrypoint"`
// S3Bucket — бакет S3 где хранится zip архив с кодом
S3Bucket string `json:"s3Bucket"`
// S3Key — ключ объекта в S3 (путь до zip архива)
S3Key string `json:"s3Key"`
// MemoryMB — лимит памяти в мегабайтах (default: 128)
// +kubebuilder:default=128
MemoryMB int32 `json:"memoryMB,omitempty"`
// TimeoutSec — максимальное время выполнения в секундах (default: 30)
// +kubebuilder:default=30
TimeoutSec int32 `json:"timeoutSec,omitempty"`
// Env — переменные окружения, передаются в контейнер функции
Env map[string]string `json:"env,omitempty"`
}
// FunctionStatus defines the observed state of Function
// FunctionPhase — текущая фаза жизненного цикла функции.
// Используем строковый тип чтобы было читаемо в kubectl get functions.
type FunctionPhase string
const (
// FunctionPhasePending — функция создана, ожидает сборки образа
FunctionPhasePending FunctionPhase = "Pending"
// FunctionPhaseBuilding — идёт сборка Docker образа
FunctionPhaseBuilding FunctionPhase = "Building"
// FunctionPhaseReady — образ собран, функция готова к вызову
FunctionPhaseReady FunctionPhase = "Ready"
// FunctionPhaseFailed — ошибка при сборке или деплое
FunctionPhaseFailed FunctionPhase = "Failed"
)
// FunctionStatus — наблюдаемое состояние функции (заполняет контроллер).
type FunctionStatus struct {
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
// Important: Run "make" to regenerate code after modifying this file
// Phase — текущая фаза: Pending, Building, Ready, Failed
Phase FunctionPhase `json:"phase,omitempty"`
// ImageRef — полный путь к собранному Docker образу в registry
ImageRef string `json:"imageRef,omitempty"`
// Message — человекочитаемое сообщение об ошибке или статусе
Message string `json:"message,omitempty"`
// Conditions — стандартные k8s conditions для интеграции с инструментами
Conditions []metav1.Condition `json:"conditions,omitempty"`
// LastBuiltAt — время последней успешной сборки образа
LastBuiltAt *metav1.Time `json:"lastBuiltAt,omitempty"`
}
//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
//+kubebuilder:printcolumn:name="Runtime",type=string,JSONPath=`.spec.runtime`
//+kubebuilder:printcolumn:name="Phase",type=string,JSONPath=`.status.phase`
//+kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
// Function is the Schema for the functions API
// Function — основной ресурс для управления serverless функцией.
type Function struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
+46 -26
View File
@@ -1,18 +1,6 @@
/*
Copyright 2026.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Изменено: 2026-03-07
// Описание CRD Trigger — триггер для функции (HTTP или Cron).
// Один Trigger ссылается на одну Function и определяет способ вызова.
package v1alpha1
@@ -20,28 +8,60 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
// TriggerType — тип триггера.
type TriggerType string
// TriggerSpec defines the desired state of Trigger
const (
// TriggerTypeHTTP — функция вызывается по HTTP запросу через Ingress
TriggerTypeHTTP TriggerType = "http"
// TriggerTypeCron — функция вызывается по расписанию (k8s CronJob)
TriggerTypeCron TriggerType = "cron"
)
// TriggerSpec — желаемое состояние триггера.
type TriggerSpec struct {
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
// Important: Run "make" to regenerate code after modifying this file
// FunctionRef — имя Function ресурса в том же namespace
// +kubebuilder:validation:Required
FunctionRef string `json:"functionRef"`
// Foo is an example field of Trigger. Edit trigger_types.go to remove/update
Foo string `json:"foo,omitempty"`
// Type — тип триггера: http или cron
// +kubebuilder:validation:Enum=http;cron
// +kubebuilder:validation:Required
Type TriggerType `json:"type"`
// Schedule — расписание в формате cron (только для type=cron, например: "0 2 * * *")
Schedule string `json:"schedule,omitempty"`
// PreWarmSeconds — за сколько секунд до запуска прогреть контейнер.
// Актуально для cron: запускаем pod заранее чтобы избежать cold start.
// +kubebuilder:default=300
PreWarmSeconds int32 `json:"preWarmSeconds,omitempty"`
}
// TriggerStatus defines the observed state of Trigger
// TriggerStatus — наблюдаемое состояние триггера (заполняет контроллер).
type TriggerStatus struct {
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
// Important: Run "make" to regenerate code after modifying this file
// Active — активен ли триггер в данный момент
Active bool `json:"active,omitempty"`
// URL — публичный URL для вызова функции (только для type=http)
URL string `json:"url,omitempty"`
// LastScheduleTime — время последнего запуска по расписанию (только для type=cron)
LastScheduleTime *metav1.Time `json:"lastScheduleTime,omitempty"`
// Message — человекочитаемое сообщение об ошибке или статусе
Message string `json:"message,omitempty"`
}
//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
//+kubebuilder:printcolumn:name="Type",type=string,JSONPath=`.spec.type`
//+kubebuilder:printcolumn:name="Function",type=string,JSONPath=`.spec.functionRef`
//+kubebuilder:printcolumn:name="Active",type=boolean,JSONPath=`.status.active`
//+kubebuilder:printcolumn:name="URL",type=string,JSONPath=`.status.url`
//+kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
// Trigger is the Schema for the triggers API
// Trigger — ресурс для управления способом вызова Function.
type Trigger struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
+26 -3
View File
@@ -21,6 +21,7 @@ limitations under the License.
package v1alpha1
import (
"k8s.io/apimachinery/pkg/apis/meta/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
)
@@ -29,8 +30,8 @@ func (in *Function) DeepCopyInto(out *Function) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
out.Spec = in.Spec
out.Status = in.Status
in.Spec.DeepCopyInto(&out.Spec)
in.Status.DeepCopyInto(&out.Status)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Function.
@@ -86,6 +87,13 @@ func (in *FunctionList) DeepCopyObject() runtime.Object {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *FunctionSpec) DeepCopyInto(out *FunctionSpec) {
*out = *in
if in.Env != nil {
in, out := &in.Env, &out.Env
*out = make(map[string]string, len(*in))
for key, val := range *in {
(*out)[key] = val
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FunctionSpec.
@@ -101,6 +109,17 @@ func (in *FunctionSpec) DeepCopy() *FunctionSpec {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *FunctionStatus) DeepCopyInto(out *FunctionStatus) {
*out = *in
if in.Conditions != nil {
in, out := &in.Conditions, &out.Conditions
*out = make([]v1.Condition, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.LastBuiltAt != nil {
in, out := &in.LastBuiltAt, &out.LastBuiltAt
*out = (*in).DeepCopy()
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FunctionStatus.
@@ -119,7 +138,7 @@ func (in *Trigger) DeepCopyInto(out *Trigger) {
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
out.Spec = in.Spec
out.Status = in.Status
in.Status.DeepCopyInto(&out.Status)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Trigger.
@@ -190,6 +209,10 @@ func (in *TriggerSpec) DeepCopy() *TriggerSpec {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *TriggerStatus) DeepCopyInto(out *TriggerStatus) {
*out = *in
if in.LastScheduleTime != nil {
in, out := &in.LastScheduleTime, &out.LastScheduleTime
*out = (*in).DeepCopy()
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TriggerStatus.