mirror of
https://github.com/DeBrosOfficial/orama.git
synced 2026-03-17 20:46:58 +00:00
- Introduced `secrets` command for managing function secrets, including set, list, and delete operations. - Added `triggers` command for managing PubSub triggers associated with functions, allowing addition, listing, and deletion of triggers. - Implemented API handlers for secrets management, including setting, listing, and deleting secrets. - Updated serverless handlers to support new secrets and triggers functionalities. - Enhanced tests for the new features, ensuring proper functionality and error handling.
147 lines
3.8 KiB
Go
147 lines
3.8 KiB
Go
package serverless
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/DeBrosOfficial/network/pkg/serverless"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
// setSecretRequest is the request body for setting a secret.
|
|
type setSecretRequest struct {
|
|
Name string `json:"name"`
|
|
Value string `json:"value"`
|
|
}
|
|
|
|
// HandleSetSecret handles PUT /v1/functions/secrets
|
|
// Stores an encrypted secret scoped to the caller's namespace.
|
|
func (h *ServerlessHandlers) HandleSetSecret(w http.ResponseWriter, r *http.Request) {
|
|
if h.secretsManager == nil {
|
|
writeError(w, http.StatusNotImplemented, "Secrets management not available")
|
|
return
|
|
}
|
|
|
|
namespace := h.getNamespaceFromRequest(r)
|
|
if namespace == "" {
|
|
writeError(w, http.StatusBadRequest, "namespace required")
|
|
return
|
|
}
|
|
|
|
var req setSecretRequest
|
|
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
|
writeError(w, http.StatusBadRequest, "Invalid JSON: "+err.Error())
|
|
return
|
|
}
|
|
|
|
if req.Name == "" {
|
|
writeError(w, http.StatusBadRequest, "secret name required")
|
|
return
|
|
}
|
|
if req.Value == "" {
|
|
writeError(w, http.StatusBadRequest, "secret value required")
|
|
return
|
|
}
|
|
|
|
ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second)
|
|
defer cancel()
|
|
|
|
if err := h.secretsManager.Set(ctx, namespace, req.Name, req.Value); err != nil {
|
|
h.logger.Error("Failed to set secret",
|
|
zap.String("namespace", namespace),
|
|
zap.String("name", req.Name),
|
|
zap.Error(err),
|
|
)
|
|
writeError(w, http.StatusInternalServerError, "Failed to set secret: "+err.Error())
|
|
return
|
|
}
|
|
|
|
h.logger.Info("Secret set via API",
|
|
zap.String("namespace", namespace),
|
|
zap.String("name", req.Name),
|
|
)
|
|
|
|
writeJSON(w, http.StatusOK, map[string]any{
|
|
"message": "Secret set",
|
|
"name": req.Name,
|
|
"namespace": namespace,
|
|
})
|
|
}
|
|
|
|
// HandleListSecrets handles GET /v1/functions/secrets
|
|
// Lists all secret names in the caller's namespace (values are never returned).
|
|
func (h *ServerlessHandlers) HandleListSecrets(w http.ResponseWriter, r *http.Request) {
|
|
if h.secretsManager == nil {
|
|
writeError(w, http.StatusNotImplemented, "Secrets management not available")
|
|
return
|
|
}
|
|
|
|
namespace := h.getNamespaceFromRequest(r)
|
|
if namespace == "" {
|
|
writeError(w, http.StatusBadRequest, "namespace required")
|
|
return
|
|
}
|
|
|
|
ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second)
|
|
defer cancel()
|
|
|
|
names, err := h.secretsManager.List(ctx, namespace)
|
|
if err != nil {
|
|
h.logger.Error("Failed to list secrets",
|
|
zap.String("namespace", namespace),
|
|
zap.Error(err),
|
|
)
|
|
writeError(w, http.StatusInternalServerError, "Failed to list secrets")
|
|
return
|
|
}
|
|
|
|
writeJSON(w, http.StatusOK, map[string]any{
|
|
"secrets": names,
|
|
"count": len(names),
|
|
})
|
|
}
|
|
|
|
// HandleDeleteSecret handles DELETE /v1/functions/secrets/{name}
|
|
// Deletes a secret from the caller's namespace.
|
|
func (h *ServerlessHandlers) HandleDeleteSecret(w http.ResponseWriter, r *http.Request, secretName string) {
|
|
if h.secretsManager == nil {
|
|
writeError(w, http.StatusNotImplemented, "Secrets management not available")
|
|
return
|
|
}
|
|
|
|
namespace := h.getNamespaceFromRequest(r)
|
|
if namespace == "" {
|
|
writeError(w, http.StatusBadRequest, "namespace required")
|
|
return
|
|
}
|
|
|
|
ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second)
|
|
defer cancel()
|
|
|
|
if err := h.secretsManager.Delete(ctx, namespace, secretName); err != nil {
|
|
if errors.Is(err, serverless.ErrSecretNotFound) {
|
|
writeError(w, http.StatusNotFound, "Secret not found")
|
|
return
|
|
}
|
|
h.logger.Error("Failed to delete secret",
|
|
zap.String("namespace", namespace),
|
|
zap.String("name", secretName),
|
|
zap.Error(err),
|
|
)
|
|
writeError(w, http.StatusInternalServerError, "Failed to delete secret: "+err.Error())
|
|
return
|
|
}
|
|
|
|
h.logger.Info("Secret deleted via API",
|
|
zap.String("namespace", namespace),
|
|
zap.String("name", secretName),
|
|
)
|
|
|
|
writeJSON(w, http.StatusOK, map[string]any{
|
|
"message": "Secret deleted",
|
|
})
|
|
}
|