Skip to content

Commit

Permalink
Add remote file transfer feature
Browse files Browse the repository at this point in the history
  • Loading branch information
cb-github-robot authored Sep 20, 2024
2 parents ebfcd88 + 80139ba commit ef758c6
Show file tree
Hide file tree
Showing 6 changed files with 577 additions and 0 deletions.
89 changes: 89 additions & 0 deletions src/api/rest/docs/docs.go
Original file line number Diff line number Diff line change
Expand Up @@ -8535,6 +8535,95 @@ const docTemplate = `{
}
}
},
"/ns/{nsId}/transferFile/mci/{mciId}": {
"post": {
"description": "Transfer a file to specified MCI to the specified path.\nThe file size should be less than 10MB.\nNot for gerneral file transfer but for specific purpose (small configuration files).",
"consumes": [
"multipart/form-data"
],
"produces": [
"application/json"
],
"tags": [
"[MC-Infra] MCI Remote Command"
],
"summary": "Transfer a file to specified MCI",
"operationId": "PostFileToMci",
"parameters": [
{
"type": "string",
"default": "default",
"description": "Namespace ID",
"name": "nsId",
"in": "path",
"required": true
},
{
"type": "string",
"default": "mci01",
"description": "MCI ID",
"name": "mciId",
"in": "path",
"required": true
},
{
"type": "string",
"default": "g1",
"description": "subGroupId to apply the file transfer only for VMs in subGroup of MCI",
"name": "subGroupId",
"in": "query"
},
{
"type": "string",
"default": "g1-1",
"description": "vmId to apply the file transfer only for a VM in MCI",
"name": "vmId",
"in": "query"
},
{
"type": "string",
"default": "/home/cb-user/",
"description": "Target path where the file will be stored",
"name": "path",
"in": "formData",
"required": true
},
{
"type": "file",
"description": "The file to be uploaded (Max 10MB)",
"name": "file",
"in": "formData",
"required": true
},
{
"type": "string",
"description": "Custom request ID",
"name": "x-request-id",
"in": "header"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/model.MciSshCmdResult"
}
},
"400": {
"description": "Invalid request",
"schema": {
"$ref": "#/definitions/model.SimpleMsg"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/model.SimpleMsg"
}
}
}
}
},
"/object": {
"get": {
"description": "Get value of an object",
Expand Down
89 changes: 89 additions & 0 deletions src/api/rest/docs/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -8529,6 +8529,95 @@
}
}
},
"/ns/{nsId}/transferFile/mci/{mciId}": {
"post": {
"description": "Transfer a file to specified MCI to the specified path.\nThe file size should be less than 10MB.\nNot for gerneral file transfer but for specific purpose (small configuration files).",
"consumes": [
"multipart/form-data"
],
"produces": [
"application/json"
],
"tags": [
"[MC-Infra] MCI Remote Command"
],
"summary": "Transfer a file to specified MCI",
"operationId": "PostFileToMci",
"parameters": [
{
"type": "string",
"default": "default",
"description": "Namespace ID",
"name": "nsId",
"in": "path",
"required": true
},
{
"type": "string",
"default": "mci01",
"description": "MCI ID",
"name": "mciId",
"in": "path",
"required": true
},
{
"type": "string",
"default": "g1",
"description": "subGroupId to apply the file transfer only for VMs in subGroup of MCI",
"name": "subGroupId",
"in": "query"
},
{
"type": "string",
"default": "g1-1",
"description": "vmId to apply the file transfer only for a VM in MCI",
"name": "vmId",
"in": "query"
},
{
"type": "string",
"default": "/home/cb-user/",
"description": "Target path where the file will be stored",
"name": "path",
"in": "formData",
"required": true
},
{
"type": "file",
"description": "The file to be uploaded (Max 10MB)",
"name": "file",
"in": "formData",
"required": true
},
{
"type": "string",
"description": "Custom request ID",
"name": "x-request-id",
"in": "header"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/model.MciSshCmdResult"
}
},
"400": {
"description": "Invalid request",
"schema": {
"$ref": "#/definitions/model.SimpleMsg"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/model.SimpleMsg"
}
}
}
}
},
"/object": {
"get": {
"description": "Get value of an object",
Expand Down
80 changes: 80 additions & 0 deletions src/api/rest/docs/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6448,6 +6448,86 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/model.SimpleMsg'
/ns/{nsId}/transferFile/mci/{mciId}:
post:
tags:
- "[MC-Infra] MCI Remote Command"
summary: Transfer a file to specified MCI
description: |-
Transfer a file to specified MCI to the specified path.
The file size should be less than 10MB.
Not for gerneral file transfer but for specific purpose (small configuration files).
operationId: PostFileToMci
parameters:
- name: nsId
in: path
description: Namespace ID
required: true
schema:
type: string
default: default
- name: mciId
in: path
description: MCI ID
required: true
schema:
type: string
default: mci01
- name: subGroupId
in: query
description: subGroupId to apply the file transfer only for VMs in subGroup
of MCI
schema:
type: string
default: g1
- name: vmId
in: query
description: vmId to apply the file transfer only for a VM in MCI
schema:
type: string
default: g1-1
- name: x-request-id
in: header
description: Custom request ID
schema:
type: string
requestBody:
content:
multipart/form-data:
schema:
required:
- file
- path
type: object
properties:
path:
type: string
description: Target path where the file will be stored
default: /home/cb-user/
file:
type: string
description: The file to be uploaded (Max 10MB)
format: binary
required: true
responses:
"200":
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/model.MciSshCmdResult'
"400":
description: Invalid request
content:
application/json:
schema:
$ref: '#/components/schemas/model.SimpleMsg'
"500":
description: Internal Server Error
content:
application/json:
schema:
$ref: '#/components/schemas/model.SimpleMsg'
/object:
get:
tags:
Expand Down
78 changes: 78 additions & 0 deletions src/api/rest/server/infra/remoteCommand.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ limitations under the License.
package infra

import (
"fmt"
"io"
"net/http"

"github.com/cloud-barista/cb-tumblebug/src/core/common"
Expand Down Expand Up @@ -76,6 +78,82 @@ func RestPostCmdMci(c echo.Context) error {

}

// RestPostFileToMci godoc
// @ID PostFileToMci
// @Summary Transfer a file to specified MCI
// @Description Transfer a file to specified MCI to the specified path.
// @Description The file size should be less than 10MB.
// @Description Not for gerneral file transfer but for specific purpose (small configuration files).
// @Tags [MC-Infra] MCI Remote Command
// @Accept multipart/form-data
// @Produce json
// @Param nsId path string true "Namespace ID" default(default)
// @Param mciId path string true "MCI ID" default(mci01)
// @Param subGroupId query string false "subGroupId to apply the file transfer only for VMs in subGroup of MCI" default(g1)
// @Param vmId query string false "vmId to apply the file transfer only for a VM in MCI" default(g1-1)
// @Param path formData string true "Target path where the file will be stored" default(/home/cb-user/)
// @Param file formData file true "The file to be uploaded (Max 10MB)"
// @Param x-request-id header string false "Custom request ID"
// @Success 200 {object} model.MciSshCmdResult
// @Failure 400 {object} model.SimpleMsg "Invalid request"
// @Failure 500 {object} model.SimpleMsg "Internal Server Error"
// @Router /ns/{nsId}/transferFile/mci/{mciId} [post]
func RestPostFileToMci(c echo.Context) error {
reqID, idErr := common.StartRequestWithLog(c)
if idErr != nil {
return c.JSON(http.StatusBadRequest, map[string]string{"message": idErr.Error()})
}
nsId := c.Param("nsId")
mciId := c.Param("mciId")
subGroupId := c.QueryParam("subGroupId")
vmId := c.QueryParam("vmId")
targetPath := c.FormValue("path")

if targetPath == "" {
err := fmt.Errorf("target path is required")
return common.EndRequestWithLog(c, reqID, err, nil)
}

// Validate the file
file, err := c.FormFile("file")
if err != nil {
err = fmt.Errorf("failed to read the file %v", err)
return common.EndRequestWithLog(c, reqID, err, nil)
}

// File size validation
fileSizeLimit := int64(10 * 1024 * 1024) // (10MB limit)
if file.Size > fileSizeLimit {
err := fmt.Errorf("file too large, max size is %v", fileSizeLimit)
return common.EndRequestWithLog(c, reqID, err, nil)
}

// Open the file and read it into memory
src, err := file.Open()
if err != nil {
err = fmt.Errorf("failed to open the file %v", err)
return common.EndRequestWithLog(c, reqID, err, nil)
}
defer src.Close()

// Read the file into memory
fileBytes, err := io.ReadAll(src)
if err != nil {
err = fmt.Errorf("failed to read the file %v", err)
return common.EndRequestWithLog(c, reqID, err, nil)
}

// Call the TransferFileToMci function
result, err := infra.TransferFileToMci(nsId, mciId, subGroupId, vmId, fileBytes, file.Filename, targetPath)
if err != nil {
err = fmt.Errorf("failed to transfer file to mci %v", err)
return common.EndRequestWithLog(c, reqID, err, nil)
}

// Return the result
return common.EndRequestWithLog(c, reqID, err, result)
}

// RestSetBastionNodes godoc
// @ID SetBastionNodes
// @Summary Set bastion nodes for a VM
Expand Down
1 change: 1 addition & 0 deletions src/api/rest/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,7 @@ func RunServer(port string) {
g.GET("/:nsId/control/mci/:mciId/vm/:vmId", rest_infra.RestGetControlMciVm)

g.POST("/:nsId/cmd/mci/:mciId", rest_infra.RestPostCmdMci)
g.POST("/:nsId/transferFile/mci/:mciId", rest_infra.RestPostFileToMci)
g.PUT("/:nsId/mci/:mciId/vm/:targetVmId/bastion/:bastionVmId", rest_infra.RestSetBastionNodes)
g.DELETE("/:nsId/mci/:mciId/bastion/:bastionVmId", rest_infra.RestRemoveBastionNodes)
g.GET("/:nsId/mci/:mciId/vm/:targetVmId/bastion", rest_infra.RestGetBastionNodes)
Expand Down
Loading

0 comments on commit ef758c6

Please sign in to comment.