feat(funcs-console): показывать sless_service вместе с функциями — единый листинг
This commit is contained in:
+51
-4
@@ -1,4 +1,4 @@
|
||||
// Изменено: 2026-04-25 (добавлена HTML web-консоль, proxy endpoints для source/triggers)
|
||||
// Изменено: 2026-03-21 (добавлен вывод sless_service вместе с функциями — пользователь видит оба типа как «функции»)
|
||||
// main.go — глобальный HTTP сервис листинга функций пользователя.
|
||||
// Развёрнут ОДИН РАЗ в namespace sless; работает для ВСЕХ пользователей.
|
||||
// Не связан с terraform — деплоится манифестом deployments/k8s/funcs-service.yaml.
|
||||
@@ -39,7 +39,9 @@ import (
|
||||
//go:embed index.html
|
||||
var htmlPageTemplate string
|
||||
|
||||
// fnResponse — ответ /v1/namespaces/{ns}/functions (подмножество полей оператора)
|
||||
// fnResponse — унифицированная запись функции для листинга.
|
||||
// Kind="function" — job-style (запускается per-request).
|
||||
// Kind="service" — always-on Deployment (всегда готов к запросам, имеет прямой URL).
|
||||
type fnResponse struct {
|
||||
Name string `json:"name"`
|
||||
Runtime string `json:"runtime"`
|
||||
@@ -47,6 +49,19 @@ type fnResponse struct {
|
||||
Message string `json:"message"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
LastBuiltAt string `json:"last_built_at"`
|
||||
Kind string `json:"kind"` // "function" | "service"
|
||||
URL string `json:"url,omitempty"` // прямой URL для sless_service
|
||||
}
|
||||
|
||||
// svcResponse — ответ /v1/namespaces/{ns}/services (подмножество полей оператора).
|
||||
type svcResponse struct {
|
||||
Name string `json:"name"`
|
||||
Runtime string `json:"runtime"`
|
||||
Phase string `json:"phase"`
|
||||
Message string `json:"message"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
LastBuiltAt string `json:"last_built_at"`
|
||||
URL string `json:"url"`
|
||||
}
|
||||
|
||||
// trResponse — ответ /v1/namespaces/{ns}/triggers
|
||||
@@ -182,13 +197,35 @@ func handleFuncsNS(operatorURL, externalURL, serviceToken string, exclude map[st
|
||||
}
|
||||
}
|
||||
|
||||
// fetchAndRender загружает данные из оператора и отдаёт ответ: HTML (браузер) или plain text (curl).
|
||||
// fetchAndRender загружает functions + services из оператора и отдаёт ответ.
|
||||
// Оба типа объединяются в единый список — пользователь видит их как «функции».
|
||||
func fetchAndRender(w http.ResponseWriter, r *http.Request, operatorURL, externalURL, authHeader, ns string, exclude map[string]bool) {
|
||||
fns, err := apiGet[[]fnResponse](operatorURL+"/v1/namespaces/"+ns+"/functions", authHeader)
|
||||
if err != nil {
|
||||
http.Error(w, fmt.Sprintf("operator error (functions): %s\n", err), http.StatusBadGateway)
|
||||
return
|
||||
}
|
||||
for i := range fns {
|
||||
fns[i].Kind = "function"
|
||||
}
|
||||
|
||||
// sless_service — always-on Deployment + URL. Объединяем с функциями.
|
||||
svcs, svcErr := apiGet[[]svcResponse](operatorURL+"/v1/namespaces/"+ns+"/services", authHeader)
|
||||
if svcErr == nil {
|
||||
for _, svc := range svcs {
|
||||
fns = append(fns, fnResponse{
|
||||
Name: svc.Name,
|
||||
Runtime: svc.Runtime,
|
||||
Phase: svc.Phase,
|
||||
Message: svc.Message,
|
||||
CreatedAt: svc.CreatedAt,
|
||||
LastBuiltAt: svc.LastBuiltAt,
|
||||
Kind: "service",
|
||||
URL: svc.URL,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
trs, err := apiGet[[]trResponse](operatorURL+"/v1/namespaces/"+ns+"/triggers", authHeader)
|
||||
if err != nil {
|
||||
http.Error(w, fmt.Sprintf("operator error (triggers): %s\n", err), http.StatusBadGateway)
|
||||
@@ -279,7 +316,10 @@ func servePlainText(w http.ResponseWriter, ns, externalURL string, fns []fnRespo
|
||||
} else {
|
||||
sb.WriteString(" active: нет\n")
|
||||
}
|
||||
if len(it.httpT) > 0 {
|
||||
// Для sless_service — прямой URL из статуса деплоя
|
||||
if fn.URL != "" {
|
||||
sb.WriteString(fmt.Sprintf(" url: %s\n", fn.URL))
|
||||
} else if len(it.httpT) > 0 {
|
||||
url := it.httpT[0].URL
|
||||
if externalURL != "" {
|
||||
url = externalURL + "/fn/" + ns + "/" + fn.Name
|
||||
@@ -415,6 +455,13 @@ func isValidK8sName(s string) bool {
|
||||
}
|
||||
|
||||
func buildComment(fn fnResponse, httpT, cronT []trResponse) string {
|
||||
if fn.Kind == "service" {
|
||||
active := "неактивна"
|
||||
if fn.Phase == "Ready" {
|
||||
active = "активна"
|
||||
}
|
||||
return fmt.Sprintf("always-on сервис (%s) — %s, %s", fn.Runtime, fn.Phase, active)
|
||||
}
|
||||
if len(httpT) > 0 {
|
||||
active := "активна"
|
||||
if !httpT[0].Active {
|
||||
|
||||
Reference in New Issue
Block a user