146 lines
4.5 KiB
Go
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})
|
|
}
|