Files
sless/internal/storage/s3/client.go
T
“Naeel” 43e7d0ea48 feat: REST API (gorilla/mux + slog) + trigger controller + main.go wiring
- controllers/trigger_controller.go: полная реализация, HTTP->Ingress+Service, Cron->CronJob
- internal/config: добавлены IngressHost, APIToken
- internal/api/router.go: gorilla/mux роутер /v1/namespaces/{ns}/...
- internal/api/handler/: functions, triggers, invocations, base handler с slog
- internal/api/middleware/: auth (Bearer token) + logging (slog)
- main.go: запуск operator + HTTP сервера параллельно
- go.sum: добавлен gorilla/mux v1.8.1
2026-03-07 08:46:10 +04:00

83 lines
2.9 KiB
Go

// Изменено: 2026-03-07
// S3 storage — загрузка и скачивание zip архивов с кодом функций.
// Используем Ceph S3 compatible API (minio-go клиент умеет работать с любым S3).
// Код загружается пользователем через REST API, хранится в S3,
// builder скачивает его для сборки Docker образа.
package s3
import (
"context"
"fmt"
"io"
"github.com/minio/minio-go/v7"
"github.com/minio/minio-go/v7/pkg/credentials"
)
// Client — клиент для работы с S3.
type Client struct {
mc *minio.Client
bucket string
}
// New создаёт клиент S3 и проверяет/создаёт бакет.
func New(endpoint, accessKey, secretKey, bucket string, useSSL bool) (*Client, error) {
mc, err := minio.New(endpoint, &minio.Options{
Creds: credentials.NewStaticV4(accessKey, secretKey, ""),
Secure: useSSL,
})
if err != nil {
return nil, fmt.Errorf("create minio client: %w", err)
}
return &Client{mc: mc, bucket: bucket}, nil
}
// EnsureBucket создаёт бакет если он не существует.
// Вызывается при старте сервиса.
func (c *Client) EnsureBucket(ctx context.Context) error {
exists, err := c.mc.BucketExists(ctx, c.bucket)
if err != nil {
return fmt.Errorf("check bucket: %w", err)
}
if !exists {
if err := c.mc.MakeBucket(ctx, c.bucket, minio.MakeBucketOptions{}); err != nil {
return fmt.Errorf("create bucket: %w", err)
}
}
return nil
}
// Upload загружает zip архив с кодом функции в S3.
// Ключ: functions/{namespace}/{name}/{version}.zip
// Возвращает ключ объекта для сохранения в CRD.
func (c *Client) Upload(ctx context.Context, namespace, funcName, version string, r io.Reader, size int64) (string, error) {
key := fmt.Sprintf("functions/%s/%s/%s.zip", namespace, funcName, version)
_, err := c.mc.PutObject(ctx, c.bucket, key, r, size, minio.PutObjectOptions{
ContentType: "application/zip",
})
if err != nil {
return "", fmt.Errorf("upload function code: %w", err)
}
return key, nil
}
// Download скачивает zip архив с кодом функции из S3.
// Используется builder'ом для сборки образа.
func (c *Client) Download(ctx context.Context, key string) (io.ReadCloser, error) {
obj, err := c.mc.GetObject(ctx, c.bucket, key, minio.GetObjectOptions{})
if err != nil {
return nil, fmt.Errorf("download function code: %w", err)
}
return obj, nil
}
// Delete удаляет архив с кодом функции из S3.
// Вызывается при удалении Function CRD.
func (c *Client) Delete(ctx context.Context, key string) error {
if err := c.mc.RemoveObject(ctx, c.bucket, key, minio.RemoveObjectOptions{}); err != nil {
return fmt.Errorf("delete function code: %w", err)
}
return nil
}