From 01946277bcba0188a9ca898eb5b8ddb63a75e639 Mon Sep 17 00:00:00 2001 From: Yunkon Kim Date: Wed, 15 Nov 2023 19:17:43 +0900 Subject: [PATCH 1/6] Update README and related things - Describe how to run CB-Beetle - Change the CD workflow to only run on tags due to GitHub Packages billing - Skip BasicAuth when the host is localhost, health-check, etc. --- .github/workflows/continuous-delivery.yaml | 10 +- README.md | 113 +++++++++++++++++++++ pkg/api/rest/server/migration/model.go | 2 +- pkg/api/rest/server/server.go | 26 +++-- 4 files changed, 139 insertions(+), 12 deletions(-) diff --git a/.github/workflows/continuous-delivery.yaml b/.github/workflows/continuous-delivery.yaml index 3280b53..99894fc 100644 --- a/.github/workflows/continuous-delivery.yaml +++ b/.github/workflows/continuous-delivery.yaml @@ -12,8 +12,8 @@ on: # A "push" event is occurred after the pull request "close" event with "merged" true condition. # The "push" event could replace "merged" event. push: - branches: - - main + # branches: + # - main # # workflow trigger button # workflow_dispatch: tags: @@ -52,6 +52,8 @@ jobs: - name: Checkout source code uses: actions/checkout@v4 + # About billing for GitHub Packages + # https://docs.github.com/en/billing/managing-billing-for-github-packages/about-billing-for-github-packages - name: Extract metadata from Git reference and GitHub events id: meta uses: docker/metadata-action@v5 @@ -67,8 +69,8 @@ jobs: type=semver,enable=true,pattern={{version}} # type=semver,pattern={{major}}.{{minor}} ## Tags for a push branch event - # minimal (short sha) - type=sha,enable=true,format=short + # minimal (short sha) + # type=sha,enable=true,format=short ## Other types (currently the followings may be out of scope) ## Tags for a push or pull_request event # type=ref,event=branch diff --git a/README.md b/README.md index 9ef7300..6a4dbf2 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,121 @@ This is a sub-system on [Cloud-Barista platform](https://github.com/cloud-barist and utilizes [CB-Tumblebug](https://github.com/cloud-barista/cb-tumblebug) to depoly a multi-cloud infra as a target computing infrastructure. + ## Overview Computing Infrastructure Migration framework (codename: cm-beetle) is going to support: - migration execution and control from source to target computing infrastructure, and - recommendation of optimal configuration of target cloud infrastructure. + + +## Execution and development environment + +- Operating system (OS): + - Ubuntu 20.04 +- Languages: + - Go: 1.19 + - Python: 3.8.10 +- Container runtime: + - Docker: 20.10.12 + + +## How to run CM-Beetle + +### Source code based installation and execution + +#### Configure build environment + +1. Install dependencies + +```bash +# Ensure that your system is up to date +sudo apt update -y + +# Ensure that you have installed the dependencies, +# such as `ca-certificates`, `curl`, and `gnupg` packages. +sudo apt install make gcc git +``` +2. Install Go + +To install Go v1.19+, see [Go all releases](https://golang.org/dl/) and [Download and install](https://go.dev/doc/install) + +Example - Go 1.19 installtion + +```bash +# Get Go archive +wget https://go.dev/dl/go1.19.linux-amd64.tar.gz + +# Remove any previous Go installation and +# Extract the archive into /usr/local/ +sudo rm -rf /usr/local/go && sudo tar -C /usr/local -xzf go1.19.linux-amd64.tar.gz + +# Append /usr/local/go/bin to .bashrc +echo 'export PATH=$PATH:/usr/local/go/bin:$HOME/go/bin' >> ~/.bashrc +echo 'export GOPATH=$HOME/go' >> ~/.bashrc + +# Apply the .bashrc changes +source ~/.bashrc + +# Verify the installation +echo $GOPATH +go version +``` + +#### Download source code + +1. Clone CM-Beetle repository + +```bash +git clone https://github.com/cloud-barista/cm-beetle.git ${HOME}/cm-beetle +``` + +#### Build CM-Beetle + +```bash +cd ${HOME}/cm-beetle/pkg +make +``` + +(Optional) Update Swagger API document +```bash +cd ${HOME}/cm-beetle/pkg +make swag +``` + +#### Run CM-Beetle binary + +```bash +cd ${HOME}/cm-beetle/pkg +make run +``` + +#### Health-check CM-Beetle + +```bash +curl http://localhost:8056/beetle/health + +# Output if it's running successfully +# {"message":"CM-Beetle API server is running"} +``` + + +### Container based execution + +Check a tag of CM-Beetle container image in [cloudbaristaorg/cm-beetle](https://hub.docker.com/r/cloudbaristaorg/cm-beetle/tags) + +#### Run CM-Beetle container + +```bash +docker run -p 8056:8056 \ +--name cm-beetle \ +cloudbaristaorg/cm-beetle:latest +``` + +#### Health-check CM-Beetle +```bash +curl http://localhost:8056/beetle/health + +# Output if it's running successfully +# {"message":"CM-Beetle API server is running"} +``` \ No newline at end of file diff --git a/pkg/api/rest/server/migration/model.go b/pkg/api/rest/server/migration/model.go index 7f8ae35..b0af5e5 100644 --- a/pkg/api/rest/server/migration/model.go +++ b/pkg/api/rest/server/migration/model.go @@ -67,7 +67,7 @@ type TbVmDynamicReq struct { RootDiskType string `json:"rootDiskType,omitempty" example:"default, TYPE1, ..."` // "", "default", "TYPE1", AWS: ["standard", "gp2", "gp3"], Azure: ["PremiumSSD", "StandardSSD", "StandardHDD"], GCP: ["pd-standard", "pd-balanced", "pd-ssd", "pd-extreme"], ALIBABA: ["cloud_efficiency", "cloud", "cloud_essd"], TENCENT: ["CLOUD_PREMIUM", "CLOUD_SSD"] RootDiskSize string `json:"rootDiskSize,omitempty" example:"default, 30, 42, ..."` // "default", Integer (GB): ["50", ..., "1000"] - VmUserPassword string `json:"vmUserPassword default:""` + VmUserPassword string `json:"vmUserPassword" default:""` // if ConnectionName is given, the VM tries to use associtated credential. // if not, it will use predefined ConnectionName in Spec objects ConnectionName string `json:"connectionName,omitempty" default:""` diff --git a/pkg/api/rest/server/server.go b/pkg/api/rest/server/server.go index 39d7897..5cc72af 100644 --- a/pkg/api/rest/server/server.go +++ b/pkg/api/rest/server/server.go @@ -18,6 +18,7 @@ import ( "context" "log" "os/signal" + "strings" "sync" "syscall" "time" @@ -100,13 +101,24 @@ func RunServer(port string) { apiUser := os.Getenv("API_USERNAME") apiPass := os.Getenv("API_PASSWORD") - e.Use(middleware.BasicAuth(func(username, password string, c echo.Context) (bool, error) { - // Be careful to use constant time comparison to prevent timing attacks - if subtle.ConstantTimeCompare([]byte(username), []byte(apiUser)) == 1 && - subtle.ConstantTimeCompare([]byte(password), []byte(apiPass)) == 1 { - return true, nil - } - return false, nil + e.Use(middleware.BasicAuthWithConfig(middleware.BasicAuthConfig{ + Skipper: func(c echo.Context) bool { + if strings.HasPrefix(c.Request().Host, "localhost") || + c.Path() == "/beetle/health" || + c.Path() == "/beetle/httpVersion" { + // c.Path() == "/beetle/swagger/*" { + return true + } + return false + }, + Validator: func(username, password string, c echo.Context) (bool, error) { + // Be careful to use constant time comparison to prevent timing attacks + if subtle.ConstantTimeCompare([]byte(username), []byte(apiUser)) == 1 && + subtle.ConstantTimeCompare([]byte(password), []byte(apiPass)) == 1 { + return true, nil + } + return false, nil + }, })) fmt.Println("\n \n ") From 727be8289b0210651750913cd8a4b3543ae63322 Mon Sep 17 00:00:00 2001 From: Yunkon Kim Date: Wed, 15 Nov 2023 22:28:47 +0900 Subject: [PATCH 2/6] Add skip BasicAuth option --- Dockerfile | 1 + conf/setup.env | 2 ++ pkg/api/rest/server/server.go | 5 +++-- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 0a06b28..a726212 100644 --- a/Dockerfile +++ b/Dockerfile @@ -52,6 +52,7 @@ ENV DB_PASSWORD cm_beetle # API Setting # ALLOW_ORIGINS (ex: https://cloud-barista.org,xxx.xxx.xxx.xxx or * for all) ENV ALLOW_ORIGINS * +ENV SKIP_BASIC_AUTH false ENV API_USERNAME default ENV API_PASSWORD default diff --git a/conf/setup.env b/conf/setup.env index adb31eb..25fcb02 100644 --- a/conf/setup.env +++ b/conf/setup.env @@ -19,6 +19,8 @@ export DB_PASSWORD=cm_beetle # Set API access config ## ALLOW_ORIGINS (ex: https://cloud-barista.org,http://localhost:8080 or * for all) export ALLOW_ORIGINS=* +## Set SKIP_BASIC_AUTH=true to skip basic auth for all routes (i.e., url or path) +export SKIP_BASIC_AUTH=false export API_USERNAME=default export API_PASSWORD=default diff --git a/pkg/api/rest/server/server.go b/pkg/api/rest/server/server.go index 5cc72af..cf3f0a9 100644 --- a/pkg/api/rest/server/server.go +++ b/pkg/api/rest/server/server.go @@ -18,7 +18,6 @@ import ( "context" "log" "os/signal" - "strings" "sync" "syscall" "time" @@ -98,12 +97,14 @@ func RunServer(port string) { AllowMethods: []string{http.MethodGet, http.MethodPut, http.MethodPost, http.MethodDelete}, })) + skipBasicAuthOption := os.Getenv("SKIP_BASIC_AUTH") == "true" + apiUser := os.Getenv("API_USERNAME") apiPass := os.Getenv("API_PASSWORD") e.Use(middleware.BasicAuthWithConfig(middleware.BasicAuthConfig{ Skipper: func(c echo.Context) bool { - if strings.HasPrefix(c.Request().Host, "localhost") || + if skipBasicAuthOption || c.Path() == "/beetle/health" || c.Path() == "/beetle/httpVersion" { // c.Path() == "/beetle/swagger/*" { From f4c8cc221e42eadecf5bebaf1e2cbde1846755d1 Mon Sep 17 00:00:00 2001 From: Yunkon Kim Date: Thu, 16 Nov 2023 14:39:50 +0900 Subject: [PATCH 3/6] Update to optionally enable/disable authentication - Perform skipping BasicAuth separated from AUTH enablement --- Dockerfile | 3 ++- conf/setup.env | 4 +-- pkg/api/rest/server/server.go | 46 +++++++++++++++++++---------------- 3 files changed, 29 insertions(+), 24 deletions(-) diff --git a/Dockerfile b/Dockerfile index a726212..c1c3c26 100644 --- a/Dockerfile +++ b/Dockerfile @@ -52,7 +52,8 @@ ENV DB_PASSWORD cm_beetle # API Setting # ALLOW_ORIGINS (ex: https://cloud-barista.org,xxx.xxx.xxx.xxx or * for all) ENV ALLOW_ORIGINS * -ENV SKIP_BASIC_AUTH false +## Set ENABLE_AUTH=true currently for basic auth for all routes (i.e., url or path) +ENV ENABLE_AUTH true ENV API_USERNAME default ENV API_PASSWORD default diff --git a/conf/setup.env b/conf/setup.env index 25fcb02..5e56167 100644 --- a/conf/setup.env +++ b/conf/setup.env @@ -19,8 +19,8 @@ export DB_PASSWORD=cm_beetle # Set API access config ## ALLOW_ORIGINS (ex: https://cloud-barista.org,http://localhost:8080 or * for all) export ALLOW_ORIGINS=* -## Set SKIP_BASIC_AUTH=true to skip basic auth for all routes (i.e., url or path) -export SKIP_BASIC_AUTH=false +## Set ENABLE_AUTH=true currently for basic auth for all routes (i.e., url or path) +export ENABLE_AUTH=true export API_USERNAME=default export API_PASSWORD=default diff --git a/pkg/api/rest/server/server.go b/pkg/api/rest/server/server.go index cf3f0a9..9d87a9f 100644 --- a/pkg/api/rest/server/server.go +++ b/pkg/api/rest/server/server.go @@ -97,30 +97,32 @@ func RunServer(port string) { AllowMethods: []string{http.MethodGet, http.MethodPut, http.MethodPost, http.MethodDelete}, })) - skipBasicAuthOption := os.Getenv("SKIP_BASIC_AUTH") == "true" + // Conditions to prevent abnormal operation due to typos (e.g., ture, falss, etc.) + enableAuth := os.Getenv("ENABLE_AUTH") == "true" apiUser := os.Getenv("API_USERNAME") apiPass := os.Getenv("API_PASSWORD") - e.Use(middleware.BasicAuthWithConfig(middleware.BasicAuthConfig{ - Skipper: func(c echo.Context) bool { - if skipBasicAuthOption || - c.Path() == "/beetle/health" || - c.Path() == "/beetle/httpVersion" { - // c.Path() == "/beetle/swagger/*" { - return true - } - return false - }, - Validator: func(username, password string, c echo.Context) (bool, error) { - // Be careful to use constant time comparison to prevent timing attacks - if subtle.ConstantTimeCompare([]byte(username), []byte(apiUser)) == 1 && - subtle.ConstantTimeCompare([]byte(password), []byte(apiPass)) == 1 { - return true, nil - } - return false, nil - }, - })) + if enableAuth { + e.Use(middleware.BasicAuthWithConfig(middleware.BasicAuthConfig{ + // Skip authentication for some routes that do not require authentication + Skipper: func(c echo.Context) bool { + if c.Path() == "/beetle/health" || + c.Path() == "/beetle/httpVersion" { + return true + } + return false + }, + Validator: func(username, password string, c echo.Context) (bool, error) { + // Be careful to use constant time comparison to prevent timing attacks + if subtle.ConstantTimeCompare([]byte(username), []byte(apiUser)) == 1 && + subtle.ConstantTimeCompare([]byte(password), []byte(apiPass)) == 1 { + return true, nil + } + return false, nil + }, + })) + } fmt.Println("\n \n ") fmt.Print(banner) @@ -173,7 +175,9 @@ func RunServer(port string) { selfEndpoint := os.Getenv("SELF_ENDPOINT") apidashboard := " http://" + selfEndpoint + "/beetle/swagger/index.html" - fmt.Println(" Access to API dashboard" + " (username: " + apiUser + " / password: " + apiPass + ")") + if enableAuth { + fmt.Println(" Access to API dashboard" + " (username: " + apiUser + " / password: " + apiPass + ")") + } fmt.Printf(noticeColor, apidashboard) fmt.Println("\n ") From ae3b177371655b62159654607c1d50b32af668cd Mon Sep 17 00:00:00 2001 From: Yunkon Kim Date: Thu, 16 Nov 2023 14:40:44 +0900 Subject: [PATCH 4/6] Add skeleton code for infra migration APIs --- pkg/api/rest/server/migration/migration.go | 218 +++++++++++++++++++++ pkg/api/rest/server/server.go | 4 + 2 files changed, 222 insertions(+) diff --git a/pkg/api/rest/server/migration/migration.go b/pkg/api/rest/server/migration/migration.go index a3bbc5b..105a34b 100644 --- a/pkg/api/rest/server/migration/migration.go +++ b/pkg/api/rest/server/migration/migration.go @@ -119,3 +119,221 @@ func createVMInfra(nsId string, infraModel *TbMcisDynamicReq) (TbMcisInfo, error return responseBody, nil } + +//////////////////////// + +type Network struct { + Name string `json:"name"` + Id string `json:"id"` + IPv4CIDRBlock string `json:"ipv4CidrBlock"` + IPv6CIDRBlock string `json:"ipv6CidrBlock"` +} + +type Subnet struct { + Network + ParentNetworkId string `json:"parentNetworkId"` +} + +type DummyNetwork struct { + Network + Subnets []Subnet `json:"subnets"` +} + +type MigrateNetworkRequest struct { + DummyNetwork +} + +type MigrateNetworkResponse struct { + DummyNetwork +} + +// MigrateNetwork godoc +// @Summary (Skeleton) Migrate network on a cloud platform +// @Description It migrates network on a cloud platform. Network includes name, ID, IPv4 CIDR block, IPv6 CIDR block, and so on. +// @Tags [Migration] Network +// @Accept json +// @Produce json +// @Param Network information body MigrateNetworkRequest true "Specify name, IPv4 CIDR block, etc." +// @Success 200 {object} MigrateNetworkResponse "Successfully migrated network on a cloud platform" +// @Failure 404 {object} common.SimpleMsg +// @Failure 500 {object} common.SimpleMsg +// @Router /migration/infra/network [post] +func (rh *Handlers) MigrateNetwork(c echo.Context) error { + + // [Note] Input section + req := &MigrateNetworkRequest{} + if err := c.Bind(req); err != nil { + return err + } + + fmt.Printf("RequestBody: %v\n", req) + fmt.Print(req) + fmt.Print(req.DummyNetwork) + + // [Note] Process section + // Something to process here like, + // Perform some functions, + // Calls external APIs and so on + + res := &MigrateNetworkResponse{} + fmt.Print(res) + fmt.Print(res.DummyNetwork) + + // This is an intentionally created variable. + // You will have to delete this later. + var err error = nil + + // [Note] Ouput section + if err != nil { + common.CBLog.Error(err) + mapA := map[string]string{"message": err.Error()} + return c.JSON(http.StatusInternalServerError, &mapA) + } + + return c.JSON(http.StatusOK, res) + +} + +//////////////////////// + +//////////////////////// + +type Storage struct { + Name string `json:"name"` + Id string `json:"id"` + Type string `json:"type"` + Size string `json:"size"` +} + +type DummyStorage struct { + Storage + NetworkID string `json:"NetworkId"` +} + +type MigrateStorageRequest struct { + DummyStorage +} + +type MigrateStorageResponse struct { + DummyStorage +} + +// MigrateStorage godoc +// @Summary (Skeleton) Migrate storage on a cloud platform +// @Description It migrates storage on a cloud platform. Storage includes name, ID, type, size, and so on. +// @Tags [Migration] Storage +// @Accept json +// @Produce json +// @Param Storage information body MigrateStorageRequest true "Specify name, type, size, affiliated Network ID, and so on." +// @Success 200 {object} MigrateStorageResponse "Successfully migrated storage on a cloud platform" +// @Failure 404 {object} common.SimpleMsg +// @Failure 500 {object} common.SimpleMsg +// @Router /migration/infra/storage [post] +func (rh *Handlers) MigrateStorage(c echo.Context) error { + + // [Note] Input section + req := &MigrateStorageRequest{} + if err := c.Bind(req); err != nil { + return err + } + + fmt.Printf("RequestBody: %v\n", req) + fmt.Print(req) + fmt.Print(req.DummyStorage) + + // [Note] Process section + // Something to process here like, + // Perform some functions, + // Calls external APIs and so on + + res := &MigrateStorageResponse{} + fmt.Print(res) + fmt.Print(res.DummyStorage) + + // This is an intentionally created variable. + // You will have to delete this later. + var err error = nil + + // [Note] Ouput section + if err != nil { + common.CBLog.Error(err) + mapA := map[string]string{"message": err.Error()} + return c.JSON(http.StatusInternalServerError, &mapA) + } + + return c.JSON(http.StatusOK, res) + +} + +//////////////////////// + +//////////////////////// + +type Instance struct { + Name string `json:"name"` + Id string `json:"id"` + Spec string `json:"type"` + OS string `json:"os"` +} + +type DummyInstance struct { + Instance + NetworkID string `json:"NetworkId"` +} + +type MigrateInstanceRequest struct { + DummyInstance +} + +type MigrateInstanceResponse struct { + DummyInstance +} + +// MigrateInstance godoc +// @Summary (Skeleton) Migrate instance on a cloud platform +// @Description It migrates instance on a cloud platform. Storage includes name, spec, OS, and so on. +// @Tags [Migration] Instance +// @Accept json +// @Produce json +// @Param Instance information body MigrateInstanceRequest true "Specify name, spec, OS, and so on." +// @Success 200 {object} MigrateInstanceResponse "Successfully migrated storage on a cloud platform" +// @Failure 404 {object} common.SimpleMsg +// @Failure 500 {object} common.SimpleMsg +// @Router /migration/infra/instance [post] +func (rh *Handlers) MigrateInstance(c echo.Context) error { + + // [Note] Input section + req := &MigrateInstanceRequest{} + if err := c.Bind(req); err != nil { + return err + } + + fmt.Printf("RequestBody: %v\n", req) + fmt.Print(req) + fmt.Print(req.DummyInstance) + + // [Note] Process section + // Something to process here like, + // Perform some functions, + // Calls external APIs and so on + + res := &MigrateInstanceResponse{} + fmt.Print(res) + fmt.Print(res.DummyInstance) + + // This is an intentionally created variable. + // You will have to delete this later. + var err error = nil + + // [Note] Ouput section + if err != nil { + common.CBLog.Error(err) + mapA := map[string]string{"message": err.Error()} + return c.JSON(http.StatusInternalServerError, &mapA) + } + + return c.JSON(http.StatusOK, res) + +} + +//////////////////////// diff --git a/pkg/api/rest/server/server.go b/pkg/api/rest/server/server.go index 9d87a9f..4e921db 100644 --- a/pkg/api/rest/server/server.go +++ b/pkg/api/rest/server/server.go @@ -146,6 +146,10 @@ func RunServer(port string) { mig.POST("/infra", migHandlers.MigrateInfra) + mig.POST("/infra/network", migHandlers.MigrateInfra) + mig.POST("/infra/storage", migHandlers.MigrateInfra) + mig.POST("/infra/instance", migHandlers.MigrateInfra) + } // Route From 072409ee19d7806533ffcf39ba71fa7b5224c9bd Mon Sep 17 00:00:00 2001 From: Yunkon Kim Date: Thu, 16 Nov 2023 14:43:23 +0900 Subject: [PATCH 5/6] Fix wrong param description of Swagger --- pkg/api/rest/server/migration/migration.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/api/rest/server/migration/migration.go b/pkg/api/rest/server/migration/migration.go index 105a34b..5e92e3c 100644 --- a/pkg/api/rest/server/migration/migration.go +++ b/pkg/api/rest/server/migration/migration.go @@ -153,7 +153,7 @@ type MigrateNetworkResponse struct { // @Tags [Migration] Network // @Accept json // @Produce json -// @Param Network information body MigrateNetworkRequest true "Specify name, IPv4 CIDR block, etc." +// @Param NetworkInfo body MigrateNetworkRequest true "Specify name, IPv4 CIDR block, etc." // @Success 200 {object} MigrateNetworkResponse "Successfully migrated network on a cloud platform" // @Failure 404 {object} common.SimpleMsg // @Failure 500 {object} common.SimpleMsg @@ -224,7 +224,7 @@ type MigrateStorageResponse struct { // @Tags [Migration] Storage // @Accept json // @Produce json -// @Param Storage information body MigrateStorageRequest true "Specify name, type, size, affiliated Network ID, and so on." +// @Param StorageInfo body MigrateStorageRequest true "Specify name, type, size, affiliated Network ID, and so on." // @Success 200 {object} MigrateStorageResponse "Successfully migrated storage on a cloud platform" // @Failure 404 {object} common.SimpleMsg // @Failure 500 {object} common.SimpleMsg @@ -295,7 +295,7 @@ type MigrateInstanceResponse struct { // @Tags [Migration] Instance // @Accept json // @Produce json -// @Param Instance information body MigrateInstanceRequest true "Specify name, spec, OS, and so on." +// @Param InstanceInfo body MigrateInstanceRequest true "Specify name, spec, OS, and so on." // @Success 200 {object} MigrateInstanceResponse "Successfully migrated storage on a cloud platform" // @Failure 404 {object} common.SimpleMsg // @Failure 500 {object} common.SimpleMsg From 9047379870761a58ceeb18b9d606393769b735f9 Mon Sep 17 00:00:00 2001 From: Yunkon Kim Date: Thu, 16 Nov 2023 14:46:48 +0900 Subject: [PATCH 6/6] Update tag description for grouping APIs in swagger-ui --- pkg/api/rest/server/migration/migration.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/api/rest/server/migration/migration.go b/pkg/api/rest/server/migration/migration.go index 5e92e3c..c7fe0e0 100644 --- a/pkg/api/rest/server/migration/migration.go +++ b/pkg/api/rest/server/migration/migration.go @@ -150,7 +150,7 @@ type MigrateNetworkResponse struct { // MigrateNetwork godoc // @Summary (Skeleton) Migrate network on a cloud platform // @Description It migrates network on a cloud platform. Network includes name, ID, IPv4 CIDR block, IPv6 CIDR block, and so on. -// @Tags [Migration] Network +// @Tags [Migration] Infrastructure // @Accept json // @Produce json // @Param NetworkInfo body MigrateNetworkRequest true "Specify name, IPv4 CIDR block, etc." @@ -221,7 +221,7 @@ type MigrateStorageResponse struct { // MigrateStorage godoc // @Summary (Skeleton) Migrate storage on a cloud platform // @Description It migrates storage on a cloud platform. Storage includes name, ID, type, size, and so on. -// @Tags [Migration] Storage +// @Tags [Migration] Infrastructure // @Accept json // @Produce json // @Param StorageInfo body MigrateStorageRequest true "Specify name, type, size, affiliated Network ID, and so on." @@ -292,7 +292,7 @@ type MigrateInstanceResponse struct { // MigrateInstance godoc // @Summary (Skeleton) Migrate instance on a cloud platform // @Description It migrates instance on a cloud platform. Storage includes name, spec, OS, and so on. -// @Tags [Migration] Instance +// @Tags [Migration] Infrastructure // @Accept json // @Produce json // @Param InstanceInfo body MigrateInstanceRequest true "Specify name, spec, OS, and so on."