chore: add handlers for rename dir ans scripts
ci-agent / build (push) Failing after 2m50s

This commit is contained in:
d3m0k1d
2026-04-05 03:29:36 +03:00
parent 534d6aa738
commit 1f6908900b
5 changed files with 316 additions and 0 deletions
+3
View File
@@ -265,6 +265,9 @@ func main() {
scriptsGroup.POST("/folder", scriptManageHandlers.CreateFolder)
scriptsGroup.DELETE("/folder", scriptManageHandlers.DeleteFolder)
// Rename script or folder
scriptsGroup.POST("/rename", scriptManageHandlers.Rename)
// Get script by path
scriptsGroup.GET("/by-path", scriptManageHandlers.GetScriptByPath)
}
+84
View File
@@ -2018,6 +2018,73 @@ const docTemplate = `{
}
}
},
"/scripts/rename": {
"post": {
"security": [
{
"Bearer": []
}
],
"description": "Renames a single script or all scripts under a folder prefix",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"scripts"
],
"summary": "Rename script or folder",
"parameters": [
{
"description": "Rename request",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_handlers.RenameRequest"
}
}
],
"responses": {
"200": {
"description": "Rename result with count of renamed scripts",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"400": {
"description": "Bad Request",
"schema": {
"type": "object",
"additionalProperties": {
"type": "string"
}
}
},
"404": {
"description": "Not Found",
"schema": {
"type": "object",
"additionalProperties": {
"type": "string"
}
}
},
"409": {
"description": "Conflict",
"schema": {
"type": "object",
"additionalProperties": {
"type": "string"
}
}
}
}
}
},
"/scripts/run": {
"post": {
"security": [
@@ -2798,6 +2865,23 @@ const docTemplate = `{
}
}
},
"internal_handlers.RenameRequest": {
"type": "object",
"required": [
"new_path",
"old_path"
],
"properties": {
"new_path": {
"type": "string",
"example": "deploy/nginx-v2"
},
"old_path": {
"type": "string",
"example": "deploy/nginx"
}
}
},
"internal_handlers.RunScriptIn": {
"type": "object",
"required": [
+84
View File
@@ -2007,6 +2007,73 @@
}
}
},
"/scripts/rename": {
"post": {
"security": [
{
"Bearer": []
}
],
"description": "Renames a single script or all scripts under a folder prefix",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"scripts"
],
"summary": "Rename script or folder",
"parameters": [
{
"description": "Rename request",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_handlers.RenameRequest"
}
}
],
"responses": {
"200": {
"description": "Rename result with count of renamed scripts",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"400": {
"description": "Bad Request",
"schema": {
"type": "object",
"additionalProperties": {
"type": "string"
}
}
},
"404": {
"description": "Not Found",
"schema": {
"type": "object",
"additionalProperties": {
"type": "string"
}
}
},
"409": {
"description": "Conflict",
"schema": {
"type": "object",
"additionalProperties": {
"type": "string"
}
}
}
}
}
},
"/scripts/run": {
"post": {
"security": [
@@ -2787,6 +2854,23 @@
}
}
},
"internal_handlers.RenameRequest": {
"type": "object",
"required": [
"new_path",
"old_path"
],
"properties": {
"new_path": {
"type": "string",
"example": "deploy/nginx-v2"
},
"old_path": {
"type": "string",
"example": "deploy/nginx"
}
}
},
"internal_handlers.RunScriptIn": {
"type": "object",
"required": [
+55
View File
@@ -477,6 +477,18 @@ definitions:
client_cert:
type: string
type: object
internal_handlers.RenameRequest:
properties:
new_path:
example: deploy/nginx-v2
type: string
old_path:
example: deploy/nginx
type: string
required:
- new_path
- old_path
type: object
internal_handlers.RunScriptIn:
properties:
agent_id:
@@ -1809,6 +1821,49 @@ paths:
summary: Update interpreter
tags:
- scripts
/scripts/rename:
post:
consumes:
- application/json
description: Renames a single script or all scripts under a folder prefix
parameters:
- description: Rename request
in: body
name: body
required: true
schema:
$ref: '#/definitions/internal_handlers.RenameRequest'
produces:
- application/json
responses:
"200":
description: Rename result with count of renamed scripts
schema:
additionalProperties: true
type: object
"400":
description: Bad Request
schema:
additionalProperties:
type: string
type: object
"404":
description: Not Found
schema:
additionalProperties:
type: string
type: object
"409":
description: Conflict
schema:
additionalProperties:
type: string
type: object
security:
- Bearer: []
summary: Rename script or folder
tags:
- scripts
/scripts/run:
post:
consumes:
@@ -280,6 +280,96 @@ type DeleteFolderRequest struct {
Path string `json:"path" binding:"required" example:"deploy/nginx" description:"Folder path to delete"`
}
// RenameRequest is the request body for renaming a script or folder.
type RenameRequest struct {
OldPath string `json:"old_path" binding:"required" example:"deploy/nginx" description:"Current path"`
NewPath string `json:"new_path" binding:"required" example:"deploy/nginx-v2" description:"New path"`
}
// Rename renames a script or all scripts under a folder path.
// @Summary Rename script or folder
// @Description Renames a single script or all scripts under a folder prefix
// @Tags scripts
// @Accept json
// @Produce json
// @Param body body RenameRequest true "Rename request"
// @Success 200 {object} map[string]interface{} "Rename result with count of renamed scripts"
// @Failure 400 {object} map[string]string
// @Failure 404 {object} map[string]string
// @Failure 409 {object} map[string]string
// @Security Bearer
// @Router /scripts/rename [post]
func (sh *ScriptHandlersGroup) Rename(c *gin.Context) {
var req RenameRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid request body"})
return
}
// Validate new path
if err := validateScriptPath(req.NewPath); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Sprintf("invalid new path: %v", err)})
return
}
// Validate old path
if err := validateScriptPath(req.OldPath); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Sprintf("invalid old path: %v", err)})
return
}
// Get all scripts
allScripts, err := sh.svc.Repo.ListScripts()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to list scripts"})
return
}
// Find scripts to rename: exact match or folder prefix
prefix := req.OldPath + "/"
var toRename []repository.Script
for _, script := range allScripts {
if script.Path == req.OldPath || strings.HasPrefix(script.Path, prefix) {
toRename = append(toRename, script)
}
}
if len(toRename) == 0 {
c.JSON(http.StatusNotFound, gin.H{"error": "no scripts found with this path"})
return
}
// Rename each script
renamedCount := 0
for _, script := range toRename {
newPath := req.NewPath + strings.TrimPrefix(script.Path, req.OldPath)
// Check if new path already exists (excluding the scripts we're renaming)
for _, existing := range allScripts {
if existing.ID != script.ID && existing.Path == newPath {
c.JSON(http.StatusConflict, gin.H{"error": fmt.Sprintf("path '%s' already exists", newPath)})
return
}
}
_, err := sh.svc.Repo.UpdateScript(script.ID, repository.ScriptUpdate{
Path: &newPath,
})
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": fmt.Sprintf("failed to rename %s: %v", script.Path, err)})
return
}
renamedCount++
}
c.JSON(http.StatusOK, gin.H{
"message": "renamed",
"old_path": req.OldPath,
"new_path": req.NewPath,
"renamed_count": renamedCount,
})
}
// CreateFolder creates a virtual folder in the script tree.
// @Summary Create folder
// @Description Creates a virtual folder by creating a placeholder script with the folder path