Files
fission-console/admin-console/DEEPSEEK_HANDOFF.md
T

6.4 KiB
Raw Blame History

Handoff: admin-console — задание для DeepSeek

Контекст

Репозиторий fission-console, ветка restructure/repo-layout.

Это Fission Serverless Platform — кастомная установка. Клиентская консоль (client-console/) уже готова и работает в проде. Нужно реализовать admin-console (admin-console/) — панель для оператора платформы (просмотр всех клиентов, использование ресурсов, данные для бухгалтерии).


Что уже сделано (скелет)

admin-console/
  cmd/server/main.go          — точка входа, порт 8091, требует ADMIN_TOKEN
  internal/api/server.go      — роуты: /admin/api/namespaces, /usage, /users
  internal/metrics/k8s.go     — k8s-клиент (in-cluster), заглушки для реальных данных
  internal/model/types.go     — типы NamespaceInfo, UsageEntry, UserInfo
  deploy/admin.yaml           — K8s Deployment + ClusterRole (read-only всё)
  ui/index.html               — базовый UI (тёмная тема, 3 вкладки)
  go.mod                      — module admin-console, зависит от k8s.io/client-go v0.31.0

Что нужно реализовать

1. internal/metrics/k8s.go — подсчёт Fission CRD

Метод ListClientNamespaces должен для каждого namespace считать объекты через Dynamic client:

import (
    "k8s.io/client-go/dynamic"
    "k8s.io/apimachinery/pkg/runtime/schema"
)

dynamicClient, _ := dynamic.NewForConfig(cfg)

gvr := schema.GroupVersionResource{Group: "fission.io", Version: "v1", Resource: "functions"}
list, err := dynamicClient.Resource(gvr).Namespace(ns).List(ctx, metav1.ListOptions{})
info.Functions = len(list.Items)

Аналогично для: packages, environments, httptriggers, timetriggers.

Сохрани dynamicClient в структуру K8sClient и используй его в обоих методах.

2. internal/metrics/k8s.go — S3-хранилище в CollectUsage

Поле StorageGB — читать из S3. Конфигурация через env:

  • S3_ENDPOINT = https://s3.msk-1.ngcloud.ru
  • S3_BUCKET = sless-functions
  • S3_ACCESS_KEY, S3_SECRET_KEY

Использовать github.com/aws/aws-sdk-go-v2. Для каждого namespace prefix = {namespace}/, суммировать размер всех объектов.

import (
    "github.com/aws/aws-sdk-go-v2/aws"
    "github.com/aws/aws-sdk-go-v2/credentials"
    "github.com/aws/aws-sdk-go-v2/service/s3"
    awscfg "github.com/aws/aws-sdk-go-v2/config"
)

cfg, _ := awscfg.LoadDefaultConfig(ctx,
    awscfg.WithRegion("ru-msk-1"),
    awscfg.WithCredentialsProvider(credentials.NewStaticCredentialsProvider(accessKey, secretKey, "")),
    awscfg.WithEndpointResolverWithOptions(...), // custom endpoint
)
client := s3.NewFromConfig(cfg, func(o *s3.Options) { o.UsePathStyle = true })

paginator := s3.NewListObjectsV2Paginator(client, &s3.ListObjectsV2Input{
    Bucket: aws.String(bucket),
    Prefix: aws.String(namespace + "/"),
})
var totalBytes int64
for paginator.HasMorePages() {
    page, _ := paginator.NextPage(ctx)
    for _, obj := range page.Contents {
        totalBytes += aws.ToInt64(obj.Size)
    }
}
entry.StorageGB = float64(totalBytes) / (1024 * 1024 * 1024)

Поля Invocations, CPUMilliCores, MemoryMB — оставить 0 (TODO).

3. go.mod — добавить зависимости

github.com/aws/aws-sdk-go-v2 v1.30.0
github.com/aws/aws-sdk-go-v2/config v1.27.0
github.com/aws/aws-sdk-go-v2/service/s3 v1.58.0
github.com/aws/aws-sdk-go-v2/credentials v1.17.0

Запустить go mod tidy после добавления.

4. deploy/admin.yaml — добавить env в контейнер

env:
  - name: ADMIN_TOKEN
    valueFrom:
      secretKeyRef:
        name: fission-admin-token
        key: token
  - name: S3_ENDPOINT
    value: "https://s3.msk-1.ngcloud.ru"
  - name: S3_BUCKET
    value: "sless-functions"
  - name: S3_ACCESS_KEY
    valueFrom:
      secretKeyRef:
        name: fission-s3-credentials
        key: access_key
  - name: S3_SECRET_KEY
    valueFrom:
      secretKeyRef:
        name: fission-s3-credentials
        key: secret_key

5. ui/index.html — доработать UI

  • В таблице "Использование" показывать реальное поле storage_gb (уже есть в шаблоне).
  • Добавить кнопку "Экспорт CSV" над таблицей Usage — генерировать CSV из текущих данных и скачивать через Blob:
function exportCSV(rows) {
    const header = 'Namespace,Email,Функции,Вызовы,Хранилище GB,Период\n';
    const body = rows.map(u =>
        [u.namespace, u.user_email, u.functions, u.invocations_total,
         u.storage_gb.toFixed(3), `${u.period_start}${u.period_end}`].join(',')
    ).join('\n');
    const blob = new Blob([header + body], { type: 'text/csv;charset=utf-8;' });
    const a = document.createElement('a');
    a.href = URL.createObjectURL(blob);
    a.download = `usage-${new Date().toISOString().slice(0,10)}.csv`;
    a.click();
}

Правила среды

  • Go version: 1.25.0 (не менять в go.mod)
  • Образ: naeel/fission-admin-console:v0.1.0
  • Build + push: только через SSH на ВМ naeel@5.172.178.213 (ключ у оператора)
  • Namespace деплоя: fission
  • S3-секрет fission-s3-credentials уже существует в namespace fission
  • Admin-токен создать вручную перед деплоем:
    kubectl create secret generic fission-admin-token -n fission --from-literal=token=<случайная_строка>
    
  • Деплой: kubectl apply -f ~/terra/fission/admin-console/deploy/admin.yaml

Что НЕ трогать

  • client-console/ — рабочий код в проде, не трогать вообще
  • helm/, terraform/, scripts/ — не трогать
  • Любой файл вне admin-console/ — без явного разрешения не трогать