Files
kandev/apps/backend/internal/gitlab/controller_config.go
T
2026-07-21 23:24:22 +01:00

146 lines
4.5 KiB
Go

package gitlab
import (
"errors"
"net/http"
"strings"
"github.com/gin-gonic/gin"
)
func (c *Controller) registerConfigRoutes(api *gin.RouterGroup) {
api.GET("/config", c.httpGetConfig)
api.PUT("/config", c.httpSetConfig)
api.DELETE("/config", c.httpDeleteConfig)
api.POST("/config/test", c.httpTestConfig)
api.POST("/config/copy", c.httpCopyConfig)
}
func (c *Controller) httpCopyConfig(ctx *gin.Context) {
var req struct {
TargetWorkspaceID string `json:"targetWorkspaceId"`
}
if err := ctx.ShouldBindJSON(&req); err != nil || strings.TrimSpace(req.TargetWorkspaceID) == "" {
ctx.JSON(http.StatusBadRequest, gin.H{responseErrorKey: "targetWorkspaceId required"})
return
}
cfg, err := c.service.CopyConfigToWorkspace(ctx.Request.Context(), c.workspaceID(ctx), req.TargetWorkspaceID)
if err != nil {
writeConfigMutationError(ctx, err)
return
}
ctx.JSON(http.StatusOK, cfg)
}
func (c *Controller) workspaceID(ctx *gin.Context) string {
return strings.TrimSpace(ctx.Query("workspace_id"))
}
func (c *Controller) workspaceClient(ctx *gin.Context) (Client, bool) {
workspaceID := c.workspaceID(ctx)
if workspaceID == "" {
ctx.JSON(http.StatusBadRequest, gin.H{responseErrorKey: "workspace_id query parameter required"})
return nil, false
}
client, err := c.service.ClientForWorkspaceHost(
ctx.Request.Context(), workspaceID, ctx.Query("expected_host"),
)
if err != nil {
status := http.StatusInternalServerError
if errors.Is(err, ErrWorkspaceHostMismatch) {
status = http.StatusNotFound
} else if errors.Is(err, ErrNotConfigured) {
status = http.StatusServiceUnavailable
}
message := providerActionFailedMessage + ": connection resolution"
if status == http.StatusNotFound {
message = "GitLab resource not found"
}
ctx.JSON(status, gin.H{responseErrorKey: message})
return nil, false
}
return client, true
}
func (c *Controller) runWorkspaceClientAction(ctx *gin.Context, action func(Client) error) error {
return c.service.RunWithWorkspaceClient(
ctx.Request.Context(), c.workspaceID(ctx), ctx.Query("expected_host"), action,
)
}
func writeWorkspaceClientActionError(ctx *gin.Context, err error, action string) {
switch {
case errors.Is(err, ErrWorkspaceRequired):
ctx.JSON(http.StatusBadRequest, gin.H{responseErrorKey: "workspace_id query parameter required"})
case errors.Is(err, ErrNotConfigured):
ctx.JSON(http.StatusServiceUnavailable, gin.H{responseErrorKey: providerActionFailedMessage + ": connection resolution"})
default:
writeProviderActionError(ctx, err, action)
}
}
func (c *Controller) httpSetConfig(ctx *gin.Context) {
var req SetConfigRequest
if err := ctx.ShouldBindJSON(&req); err != nil {
ctx.JSON(http.StatusBadRequest, gin.H{responseErrorKey: "invalid payload"})
return
}
cfg, err := c.service.SetConfigForWorkspace(ctx.Request.Context(), c.workspaceID(ctx), &req)
if err != nil {
writeConfigMutationError(ctx, err)
return
}
ctx.JSON(http.StatusOK, cfg)
}
func (c *Controller) httpDeleteConfig(ctx *gin.Context) {
if err := c.service.DeleteConfigForWorkspace(ctx.Request.Context(), c.workspaceID(ctx)); err != nil {
writeConfigMutationError(ctx, err)
return
}
ctx.JSON(http.StatusOK, gin.H{"deleted": true})
}
func (c *Controller) httpTestConfig(ctx *gin.Context) {
var req SetConfigRequest
if err := ctx.ShouldBindJSON(&req); err != nil {
ctx.JSON(http.StatusBadRequest, gin.H{responseErrorKey: "invalid payload"})
return
}
result := c.service.TestConfigForWorkspace(ctx.Request.Context(), c.workspaceID(ctx), &req)
ctx.JSON(http.StatusOK, result)
}
func (c *Controller) httpGetConfig(ctx *gin.Context) {
cfg, err := c.service.GetConfigForWorkspace(ctx.Request.Context(), c.workspaceID(ctx))
if err != nil {
writeConfigMutationError(ctx, err)
return
}
if cfg == nil {
ctx.Status(http.StatusNoContent)
return
}
ctx.JSON(http.StatusOK, cfg)
}
func writeConfigMutationError(ctx *gin.Context, err error) {
status := http.StatusInternalServerError
message := "GitLab connection operation failed"
switch {
case errors.Is(err, ErrWorkspaceRequired):
status = http.StatusBadRequest
message = "workspace_id query parameter required"
case errors.Is(err, ErrInvalidConfig):
status = http.StatusBadRequest
message = "invalid GitLab connection configuration"
case errors.Is(err, ErrSameWorkspace):
status = http.StatusBadRequest
message = "source and target workspace must differ"
case errors.Is(err, ErrNothingToCopy):
status = http.StatusBadRequest
message = "source workspace has no GitLab connection"
}
ctx.JSON(status, gin.H{responseErrorKey: message})
}