From ec0dc0a76bebefc5a5debdf5c887019d1c10d233 Mon Sep 17 00:00:00 2001 From: Yunkon Kim Date: Thu, 22 Aug 2024 17:46:33 +0900 Subject: [PATCH] Tidy up Beetle APIs * Expose the concept of namespace (ns) and multi-cloud infrastructure (mci) * Update handlers and functions for Beetle APIs * Add externalDocs to show Tumblebug API docs --- Dockerfile | 2 +- Makefile | 2 +- api/docs.go | 76 ++++++--- api/swagger.json | 76 ++++++--- api/swagger.yaml | 78 +++++---- cmd/cm-beetle/main.go | 21 ++- .../docker-compose/docker-compose.yaml | 6 +- pkg/api/rest/controller/migration.go | 153 ++++++++---------- pkg/api/rest/controller/recommendation.go | 16 +- pkg/api/rest/server.go | 28 ++-- pkg/core/common/common.go | 116 ++----------- pkg/core/recommendation/recommendation.go | 25 +-- 12 files changed, 284 insertions(+), 315 deletions(-) diff --git a/Dockerfile b/Dockerfile index 0749cd3..9a9fcdd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -62,7 +62,7 @@ ENV BEETLE_TUMBLEBUG_REST_URL=http://localhost:1323/tumblebug # Set log file path (default logfile path: ./beetle.log) # Set log level, such as trace, debug info, warn, error, fatal, and panic ENV BEETLE_LOGFILE_PATH=/app/log/beetle.log \ - BEETLE_LOGFILE_MAXSIZE=10 \ + BEETLE_LOGFILE_MAXSIZE=1000 \ BEETLE_LOGFILE_MAXBACKUPS=3 \ BEETLE_LOGFILE_MAXAGE=30 \ BEETLE_LOGFILE_COMPRESS=false \ diff --git a/Makefile b/Makefile index 1f671f7..27b7391 100644 --- a/Makefile +++ b/Makefile @@ -84,7 +84,7 @@ compose-up: ## Up services by docker compose @echo "Starting services by docker compose..." @cd deployments/docker-compose && docker compose up -compose-build-up: ## Build and up services by docker compose +compose-build-up: swag ## Build and up services by docker compose @echo "Building and starting services by docker compose..." @cd deployments/docker-compose && DOCKER_BUILDKIT=1 docker compose up --build diff --git a/api/docs.go b/api/docs.go index 683d727..e687596 100644 --- a/api/docs.go +++ b/api/docs.go @@ -58,9 +58,9 @@ const docTemplate = `{ } } }, - "/migration/infra": { + "/migration/ns/{nsId}/mci": { "post": { - "description": "It migrates an infrastructure on a cloud platform.", + "description": "Migrate an infrastructure to the multi-cloud infrastructure (MCI)", "consumes": [ "application/json" ], @@ -70,11 +70,19 @@ const docTemplate = `{ "tags": [ "[Migration] Infrastructure" ], - "summary": "Migrate an infrastructure on a cloud platform", + "summary": "Migrate an infrastructure to the multi-cloud infrastructure (MCI)", "parameters": [ { - "description": "Specify network, disk, compute, security group, virtual machine, etc.", - "name": "InfrastructureInfo", + "type": "string", + "default": "mig01", + "description": "Namespace ID", + "name": "nsId", + "in": "path", + "required": true + }, + { + "description": "Specify the information for the targeted mulci-cloud infrastructure (MCI)", + "name": "mciInfo", "in": "body", "required": true, "schema": { @@ -84,7 +92,7 @@ const docTemplate = `{ ], "responses": { "200": { - "description": "Successfully migrated infrastructure on a cloud platform", + "description": "Successfully migrated to the multi-cloud infrastructure", "schema": { "$ref": "#/definitions/controller.MigrateInfraResponse" } @@ -104,9 +112,9 @@ const docTemplate = `{ } } }, - "/migration/infra/{infraId}": { + "/migration/ns/{nsId}/mci/{mciId}": { "get": { - "description": "It gets the migrated infrastructure on a cloud platform.", + "description": "Get the migrated multi-cloud infrastructure (MCI)", "consumes": [ "application/json" ], @@ -116,19 +124,28 @@ const docTemplate = `{ "tags": [ "[Migration] Infrastructure" ], - "summary": "Get the migrated infrastructure on a cloud platform", + "summary": "Get the migrated multi-cloud infrastructure (MCI)", "parameters": [ { "type": "string", - "description": "a infrastructure ID created for migration", - "name": "infraId", + "default": "mig01", + "description": "Namespace ID", + "name": "nsId", + "in": "path", + "required": true + }, + { + "type": "string", + "default": "mmci01", + "description": "Migrated Multi-Cloud Infrastructure (MCI) ID", + "name": "mciId", "in": "path", "required": true } ], "responses": { "200": { - "description": "Successfully got the migrated infrastructure on a cloud platform", + "description": "The migrated multi-cloud infrastructure (MCI) information", "schema": { "$ref": "#/definitions/controller.MigrateInfraResponse" } @@ -148,7 +165,7 @@ const docTemplate = `{ } }, "delete": { - "description": "It deletes the migrated infrastructure on a cloud platform.", + "description": "Delete the migrated mult-cloud infrastructure (MCI)", "consumes": [ "application/json" ], @@ -158,19 +175,28 @@ const docTemplate = `{ "tags": [ "[Migration] Infrastructure" ], - "summary": "Delete the migrated infrastructure on a cloud platform", + "summary": "Delete the migrated mult-cloud infrastructure (MCI)", "parameters": [ { "type": "string", - "description": "a infrastructure ID created for migration", - "name": "infraId", + "default": "mig01", + "description": "Namespace ID", + "name": "nsId", + "in": "path", + "required": true + }, + { + "type": "string", + "default": "mmci01", + "description": "Migrated Multi-Cloud Infrastructure (MCI) ID", + "name": "mciId", "in": "path", "required": true } ], "responses": { "200": { - "description": "Successfully deleted the migrated infrastructure on a cloud platform", + "description": "The result of deleting the migrated multi-cloud infrastructure (MCI)", "schema": { "$ref": "#/definitions/model.Response" } @@ -219,9 +245,9 @@ const docTemplate = `{ } } }, - "/recommendation/infra": { + "/recommendation/mci": { "post": { - "description": "It recommends a cloud infrastructure most similar to the input. Infrastructure includes network, storage, compute, and so on.", + "description": "Recommend an appropriate multi-cloud infrastructure (MCI) for cloud migration", "consumes": [ "application/json" ], @@ -231,11 +257,11 @@ const docTemplate = `{ "tags": [ "[Recommendation] Infrastructure" ], - "summary": "Recommend an appropriate infrastructure for cloud migration", + "summary": "Recommend an appropriate multi-cloud infrastructure (MCI) for cloud migration", "parameters": [ { - "description": "Specify network, disk, compute, security group, virtual machine, etc.", - "name": "UserInfrastructure", + "description": "Specify the your infrastructure to be migrated", + "name": "UserInfra", "in": "body", "required": true, "schema": { @@ -245,7 +271,7 @@ const docTemplate = `{ ], "responses": { "200": { - "description": "Successfully recommended an appropriate infrastructure for cloud migration", + "description": "The result of recommended infrastructure", "schema": { "$ref": "#/definitions/controller.RecommendInfraResponse" } @@ -1470,6 +1496,10 @@ const docTemplate = `{ "BasicAuth": { "type": "basic" } + }, + "externalDocs": { + "description": "▶▶▶ CB-Tumblebug REST API", + "url": "http://localhost:8056/tumblebug/api/index.html" } }` diff --git a/api/swagger.json b/api/swagger.json index 7efaaa7..633cc71 100644 --- a/api/swagger.json +++ b/api/swagger.json @@ -51,9 +51,9 @@ } } }, - "/migration/infra": { + "/migration/ns/{nsId}/mci": { "post": { - "description": "It migrates an infrastructure on a cloud platform.", + "description": "Migrate an infrastructure to the multi-cloud infrastructure (MCI)", "consumes": [ "application/json" ], @@ -63,11 +63,19 @@ "tags": [ "[Migration] Infrastructure" ], - "summary": "Migrate an infrastructure on a cloud platform", + "summary": "Migrate an infrastructure to the multi-cloud infrastructure (MCI)", "parameters": [ { - "description": "Specify network, disk, compute, security group, virtual machine, etc.", - "name": "InfrastructureInfo", + "type": "string", + "default": "mig01", + "description": "Namespace ID", + "name": "nsId", + "in": "path", + "required": true + }, + { + "description": "Specify the information for the targeted mulci-cloud infrastructure (MCI)", + "name": "mciInfo", "in": "body", "required": true, "schema": { @@ -77,7 +85,7 @@ ], "responses": { "200": { - "description": "Successfully migrated infrastructure on a cloud platform", + "description": "Successfully migrated to the multi-cloud infrastructure", "schema": { "$ref": "#/definitions/controller.MigrateInfraResponse" } @@ -97,9 +105,9 @@ } } }, - "/migration/infra/{infraId}": { + "/migration/ns/{nsId}/mci/{mciId}": { "get": { - "description": "It gets the migrated infrastructure on a cloud platform.", + "description": "Get the migrated multi-cloud infrastructure (MCI)", "consumes": [ "application/json" ], @@ -109,19 +117,28 @@ "tags": [ "[Migration] Infrastructure" ], - "summary": "Get the migrated infrastructure on a cloud platform", + "summary": "Get the migrated multi-cloud infrastructure (MCI)", "parameters": [ { "type": "string", - "description": "a infrastructure ID created for migration", - "name": "infraId", + "default": "mig01", + "description": "Namespace ID", + "name": "nsId", + "in": "path", + "required": true + }, + { + "type": "string", + "default": "mmci01", + "description": "Migrated Multi-Cloud Infrastructure (MCI) ID", + "name": "mciId", "in": "path", "required": true } ], "responses": { "200": { - "description": "Successfully got the migrated infrastructure on a cloud platform", + "description": "The migrated multi-cloud infrastructure (MCI) information", "schema": { "$ref": "#/definitions/controller.MigrateInfraResponse" } @@ -141,7 +158,7 @@ } }, "delete": { - "description": "It deletes the migrated infrastructure on a cloud platform.", + "description": "Delete the migrated mult-cloud infrastructure (MCI)", "consumes": [ "application/json" ], @@ -151,19 +168,28 @@ "tags": [ "[Migration] Infrastructure" ], - "summary": "Delete the migrated infrastructure on a cloud platform", + "summary": "Delete the migrated mult-cloud infrastructure (MCI)", "parameters": [ { "type": "string", - "description": "a infrastructure ID created for migration", - "name": "infraId", + "default": "mig01", + "description": "Namespace ID", + "name": "nsId", + "in": "path", + "required": true + }, + { + "type": "string", + "default": "mmci01", + "description": "Migrated Multi-Cloud Infrastructure (MCI) ID", + "name": "mciId", "in": "path", "required": true } ], "responses": { "200": { - "description": "Successfully deleted the migrated infrastructure on a cloud platform", + "description": "The result of deleting the migrated multi-cloud infrastructure (MCI)", "schema": { "$ref": "#/definitions/model.Response" } @@ -212,9 +238,9 @@ } } }, - "/recommendation/infra": { + "/recommendation/mci": { "post": { - "description": "It recommends a cloud infrastructure most similar to the input. Infrastructure includes network, storage, compute, and so on.", + "description": "Recommend an appropriate multi-cloud infrastructure (MCI) for cloud migration", "consumes": [ "application/json" ], @@ -224,11 +250,11 @@ "tags": [ "[Recommendation] Infrastructure" ], - "summary": "Recommend an appropriate infrastructure for cloud migration", + "summary": "Recommend an appropriate multi-cloud infrastructure (MCI) for cloud migration", "parameters": [ { - "description": "Specify network, disk, compute, security group, virtual machine, etc.", - "name": "UserInfrastructure", + "description": "Specify the your infrastructure to be migrated", + "name": "UserInfra", "in": "body", "required": true, "schema": { @@ -238,7 +264,7 @@ ], "responses": { "200": { - "description": "Successfully recommended an appropriate infrastructure for cloud migration", + "description": "The result of recommended infrastructure", "schema": { "$ref": "#/definitions/controller.RecommendInfraResponse" } @@ -1463,5 +1489,9 @@ "BasicAuth": { "type": "basic" } + }, + "externalDocs": { + "description": "▶▶▶ CB-Tumblebug REST API", + "url": "http://localhost:8056/tumblebug/api/index.html" } } \ No newline at end of file diff --git a/api/swagger.yaml b/api/swagger.yaml index 9bfdb00..dd41af4 100644 --- a/api/swagger.yaml +++ b/api/swagger.yaml @@ -666,6 +666,9 @@ definitions: $ref: '#/definitions/network.Subnet' type: array type: object +externalDocs: + description: ▶▶▶ CB-Tumblebug REST API + url: http://localhost:8056/tumblebug/api/index.html info: contact: email: contact-to-cloud-barista@googlegroups.com @@ -702,16 +705,22 @@ paths: summary: Check HTTP version of incoming request tags: - '[Admin] System management' - /migration/infra: + /migration/ns/{nsId}/mci: post: consumes: - application/json - description: It migrates an infrastructure on a cloud platform. + description: Migrate an infrastructure to the multi-cloud infrastructure (MCI) parameters: - - description: Specify network, disk, compute, security group, virtual machine, - etc. + - default: mig01 + description: Namespace ID + in: path + name: nsId + required: true + type: string + - description: Specify the information for the targeted mulci-cloud infrastructure + (MCI) in: body - name: InfrastructureInfo + name: mciInfo required: true schema: $ref: '#/definitions/controller.MigrateInfraRequest' @@ -719,7 +728,7 @@ paths: - application/json responses: "200": - description: Successfully migrated infrastructure on a cloud platform + description: Successfully migrated to the multi-cloud infrastructure schema: $ref: '#/definitions/controller.MigrateInfraResponse' "404": @@ -730,26 +739,33 @@ paths: description: Internal Server Error schema: $ref: '#/definitions/model.Response' - summary: Migrate an infrastructure on a cloud platform + summary: Migrate an infrastructure to the multi-cloud infrastructure (MCI) tags: - '[Migration] Infrastructure' - /migration/infra/{infraId}: + /migration/ns/{nsId}/mci/{mciId}: delete: consumes: - application/json - description: It deletes the migrated infrastructure on a cloud platform. + description: Delete the migrated mult-cloud infrastructure (MCI) parameters: - - description: a infrastructure ID created for migration + - default: mig01 + description: Namespace ID in: path - name: infraId + name: nsId + required: true + type: string + - default: mmci01 + description: Migrated Multi-Cloud Infrastructure (MCI) ID + in: path + name: mciId required: true type: string produces: - application/json responses: "200": - description: Successfully deleted the migrated infrastructure on a cloud - platform + description: The result of deleting the migrated multi-cloud infrastructure + (MCI) schema: $ref: '#/definitions/model.Response' "404": @@ -760,24 +776,31 @@ paths: description: Internal Server Error schema: $ref: '#/definitions/model.Response' - summary: Delete the migrated infrastructure on a cloud platform + summary: Delete the migrated mult-cloud infrastructure (MCI) tags: - '[Migration] Infrastructure' get: consumes: - application/json - description: It gets the migrated infrastructure on a cloud platform. + description: Get the migrated multi-cloud infrastructure (MCI) parameters: - - description: a infrastructure ID created for migration + - default: mig01 + description: Namespace ID + in: path + name: nsId + required: true + type: string + - default: mmci01 + description: Migrated Multi-Cloud Infrastructure (MCI) ID in: path - name: infraId + name: mciId required: true type: string produces: - application/json responses: "200": - description: Successfully got the migrated infrastructure on a cloud platform + description: The migrated multi-cloud infrastructure (MCI) information schema: $ref: '#/definitions/controller.MigrateInfraResponse' "404": @@ -788,7 +811,7 @@ paths: description: Internal Server Error schema: $ref: '#/definitions/model.Response' - summary: Get the migrated infrastructure on a cloud platform + summary: Get the migrated multi-cloud infrastructure (MCI) tags: - '[Migration] Infrastructure' /readyz: @@ -810,17 +833,16 @@ paths: summary: Check Beetle is ready tags: - '[Admin] System management' - /recommendation/infra: + /recommendation/mci: post: consumes: - application/json - description: It recommends a cloud infrastructure most similar to the input. - Infrastructure includes network, storage, compute, and so on. + description: Recommend an appropriate multi-cloud infrastructure (MCI) for cloud + migration parameters: - - description: Specify network, disk, compute, security group, virtual machine, - etc. + - description: Specify the your infrastructure to be migrated in: body - name: UserInfrastructure + name: UserInfra required: true schema: $ref: '#/definitions/controller.RecommendInfraRequest' @@ -828,8 +850,7 @@ paths: - application/json responses: "200": - description: Successfully recommended an appropriate infrastructure for - cloud migration + description: The result of recommended infrastructure schema: $ref: '#/definitions/controller.RecommendInfraResponse' "404": @@ -840,7 +861,8 @@ paths: description: Internal Server Error schema: $ref: '#/definitions/github_com_cloud-barista_cm-beetle_pkg_core_common.SimpleMsg' - summary: Recommend an appropriate infrastructure for cloud migration + summary: Recommend an appropriate multi-cloud infrastructure (MCI) for cloud + migration tags: - '[Recommendation] Infrastructure' /sample/users: diff --git a/cmd/cm-beetle/main.go b/cmd/cm-beetle/main.go index 8a9526c..dd8661a 100644 --- a/cmd/cm-beetle/main.go +++ b/cmd/cm-beetle/main.go @@ -74,7 +74,6 @@ func init() { } log.Info().Msg("Tumblebug is ready. Initializing Beetle...") - } func checkReadiness(url string) (bool, error) { @@ -135,6 +134,9 @@ func checkReadiness(url string) (bool, error) { // @securityDefinitions.basic BasicAuth +// @externalDocs.description ▶▶▶ CB-Tumblebug REST API +// @externalDocs.url http://localhost:8056/tumblebug/api/index.html + func main() { log.Info().Msg("CM-Beetle server is starting...") @@ -151,7 +153,7 @@ func main() { // common.SpiderRestUrl = common.NVL(os.Getenv("BEETLE_SPIDER_REST_URL"), "http://localhost:1024/spider") // common.DragonflyRestUrl = common.NVL(os.Getenv("BEETLE_DRAGONFLY_REST_URL"), "http://localhost:9090/dragonfly") - common.TumblebugRestUrl = common.NVL(os.Getenv("BEETLE_TUMBLEBUG_REST_URL"), "http://localhost:1323/tumblebug") + common.TumblebugRestUrl = common.NVL(os.Getenv("BEETLE_TUMBLEBUG_ENDPOINT"), "http://localhost:1323") + "/tumblebug" common.DBUrl = common.NVL(os.Getenv("BEETLE_SQLITE_URL"), "localhost:3306") common.DBDatabase = common.NVL(os.Getenv("BEETLE_SQLITE_DATABASE"), "cm_beetle") common.DBUser = common.NVL(os.Getenv("BEETLE_SQLITE_USER"), "cm_beetle") @@ -192,6 +194,21 @@ func main() { }) }() + // Create the default namespace + log.Debug().Msgf("creating the default namespace (%s)", common.DefaulNamespaceId) + nsInfo, err := common.GetNamespace(common.DefaulNamespaceId) + if err != nil { + log.Debug().Msgf("not found, the default namespace (nsId: %s)", common.DefaulNamespaceId) + nsReq := common.NsReq{ + Name: common.DefaulNamespaceId, + } + nsInfo, err = common.CreateNamespace(nsReq) + if err != nil { + log.Error().Err(err).Msg("failed to create a namespace") + } + } + log.Info().Msgf("the default namespace (nsId: %s)", nsInfo.Id) + // Launch API servers (REST) wg := new(sync.WaitGroup) wg.Add(1) diff --git a/deployments/docker-compose/docker-compose.yaml b/deployments/docker-compose/docker-compose.yaml index 7622664..50022cf 100644 --- a/deployments/docker-compose/docker-compose.yaml +++ b/deployments/docker-compose/docker-compose.yaml @@ -176,13 +176,13 @@ services: # - BEETLE_CBLOG_ROOT=/app - BEETLE_TUMBLEBUG_ENDPOINT=http://cb-tumblebug:1323 # - BEETLE_LOGFILE_PATH=/app/log/beetle.log - # - BEETLE_LOGFILE_MAXSIZE=10 + # - BEETLE_LOGFILE_MAXSIZE=1000 # - BEETLE_LOGFILE_MAXBACKUPS=3 # - BEETLE_LOGFILE_MAXAGE=30 # - BEETLE_LOGFILE_COMPRESS=false - # - BEETLE_LOGLEVEL=debug + - BEETLE_LOGLEVEL=debug # - BEETLE_LOGWRITER=both - # - BEETLE_NODE_ENV=development + - BEETLE_NODE_ENV=development # - BEETLE_SQLITE_URL=localhost:3306 # - BEETLE_SQLITE_DATABASE=cm_beetle # - BEETLE_SQLITE_USER=cm_beetle diff --git a/pkg/api/rest/controller/migration.go b/pkg/api/rest/controller/migration.go index e86a262..3128c50 100644 --- a/pkg/api/rest/controller/migration.go +++ b/pkg/api/rest/controller/migration.go @@ -22,7 +22,6 @@ import ( // cloudmodel "github.com/cloud-barista/cm-beetle/pkg/api/rest/model/cloud/infra" "github.com/cloud-barista/cb-tumblebug/src/core/mci" - "github.com/cloud-barista/cm-beetle/pkg/core/common" "github.com/cloud-barista/cm-beetle/pkg/core/migration" "github.com/labstack/echo/v4" @@ -41,30 +40,31 @@ type MigrateInfraResponse struct { } // MigrateInfra godoc -// @Summary Migrate an infrastructure on a cloud platform -// @Description It migrates an infrastructure on a cloud platform. +// @Summary Migrate an infrastructure to the multi-cloud infrastructure (MCI) +// @Description Migrate an infrastructure to the multi-cloud infrastructure (MCI) // @Tags [Migration] Infrastructure // @Accept json // @Produce json -// @Param InfrastructureInfo body MigrateInfraRequest true "Specify network, disk, compute, security group, virtual machine, etc." -// @Success 200 {object} MigrateInfraResponse "Successfully migrated infrastructure on a cloud platform" +// @Param nsId path string true "Namespace ID" default(mig01) +// @Param mciInfo body MigrateInfraRequest true "Specify the information for the targeted mulci-cloud infrastructure (MCI)" +// @Success 200 {object} MigrateInfraResponse "Successfully migrated to the multi-cloud infrastructure" // @Failure 404 {object} model.Response // @Failure 500 {object} model.Response -// @Router /migration/infra [post] +// @Router /migration/ns/{nsId}/mci [post] func MigrateInfra(c echo.Context) error { // [Note] Input section - // nsId := c.Param("nsId") - // if nsId == "" { - // err := fmt.Errorf("invalid request, namespace ID (nsId: %s) is required", nsId) - // log.Warn().Msg(err.Error()) - // res := model.Response{ - // Success: false, - // Text: err.Error(), - // } - // return c.JSON(http.StatusBadRequest, res) - // } - nsId := common.DefaulNamespaceId + nsId := c.Param("nsId") + if nsId == "" { + err := fmt.Errorf("invalid request, namespace ID (nsId: %s) is required", nsId) + log.Warn().Msg(err.Error()) + res := model.Response{ + Success: false, + Text: err.Error(), + } + return c.JSON(http.StatusBadRequest, res) + } + // nsId := common.DefaulNamespaceId req := &MigrateInfraRequest{} if err := c.Bind(req); err != nil { @@ -74,32 +74,11 @@ func MigrateInfra(c echo.Context) error { log.Trace().Msgf("req: %v\n", req) log.Trace().Msgf("req.TbMciDynamicReq: %v\n", req.TbMciDynamicReq) - nsInfo, err := common.GetNamespace(nsId) - if err != nil { - // [temporary code block] Create a namespace as a default - log.Warn().Msgf("failed to get the namespace (nsId: %s)", nsId) - log.Info().Msgf("create a namespace as a default (nsId: %s)", common.DefaulNamespaceId) - nsReq := common.NsReq{ - Name: common.DefaulNamespaceId, - } - nsInfo, err = common.CreateNamespace(nsReq) - - } - - if nsInfo.Id == "" { - err := fmt.Errorf("not found the namespace (nsId: %s), create a namespace first", nsId) - log.Error().Err(err).Msg("") - res := model.Response{ - Success: false, - Text: err.Error(), - } - return c.JSON(http.StatusBadRequest, res) - } - + // [Note] Process section // Create the VM infrastructure for migration - infraInfo, err := migration.CreateVMInfra(nsId, &req.TbMciDynamicReq) + mciInfo, err := migration.CreateVMInfra(nsId, &req.TbMciDynamicReq) - log.Trace().Msgf("infraInfo: %v\n", infraInfo) + log.Trace().Msgf("mciInfo: %v\n", mciInfo) // [Note] Ouput section if err != nil { @@ -112,40 +91,41 @@ func MigrateInfra(c echo.Context) error { return c.JSON(http.StatusInternalServerError, res) } - res := infraInfo + res := mciInfo return c.JSON(http.StatusOK, res) } // GetInfra godoc -// @Summary Get the migrated infrastructure on a cloud platform -// @Description It gets the migrated infrastructure on a cloud platform. +// @Summary Get the migrated multi-cloud infrastructure (MCI) +// @Description Get the migrated multi-cloud infrastructure (MCI) // @Tags [Migration] Infrastructure // @Accept json // @Produce json -// @Param infraId path string true "a infrastructure ID created for migration" -// @Success 200 {object} MigrateInfraResponse "Successfully got the migrated infrastructure on a cloud platform" +// @Param nsId path string true "Namespace ID" default(mig01) +// @Param mciId path string true "Migrated Multi-Cloud Infrastructure (MCI) ID" default(mmci01) +// @Success 200 {object} MigrateInfraResponse "The migrated multi-cloud infrastructure (MCI) information" // @Failure 404 {object} model.Response // @Failure 500 {object} model.Response -// @Router /migration/infra/{infraId} [get] +// @Router /migration/ns/{nsId}/mci/{mciId} [get] func GetInfra(c echo.Context) error { // [Note] Input section - // nsId := c.Param("nsId") - // if nsId == "" { - // err := fmt.Errorf("invalid request, the nanespace ID (nsId: %s) is required", nsId) - // log.Warn().Msg(err.Error()) - // res := model.Response{ - // Success: false, - // Text: err.Error(), - // } - // return c.JSON(http.StatusBadRequest, res) - // } - nsId := common.DefaulNamespaceId - - infraId := c.Param("infraId") - if infraId == "" { - err := fmt.Errorf("invalid request, the infrastructure ID (infraId: %s) is required", infraId) + nsId := c.Param("nsId") + if nsId == "" { + err := fmt.Errorf("invalid request, the nanespace ID (nsId: %s) is required", nsId) + log.Warn().Msg(err.Error()) + res := model.Response{ + Success: false, + Text: err.Error(), + } + return c.JSON(http.StatusBadRequest, res) + } + // nsId := common.DefaulNamespaceId + + mciId := c.Param("mciId") + if mciId == "" { + err := fmt.Errorf("invalid request, the multi-cloud infrastructure ID (mciId: %s) is required", mciId) log.Warn().Msg(err.Error()) res := model.Response{ Success: false, @@ -155,9 +135,9 @@ func GetInfra(c echo.Context) error { } // [Note] Process section - vmInfraInfo, err := migration.GetVMInfra(nsId, infraId) + vmInfraInfo, err := migration.GetVMInfra(nsId, mciId) if err != nil { - log.Error().Err(err).Msg("failed to get the migrated infrastructure") + log.Error().Err(err).Msg("failed to get the migrated multi-cloud infrastructure") res := model.Response{ Success: false, Text: err.Error(), @@ -170,34 +150,35 @@ func GetInfra(c echo.Context) error { } // DeleteInfra godoc -// @Summary Delete the migrated infrastructure on a cloud platform -// @Description It deletes the migrated infrastructure on a cloud platform. +// @Summary Delete the migrated mult-cloud infrastructure (MCI) +// @Description Delete the migrated mult-cloud infrastructure (MCI) // @Tags [Migration] Infrastructure // @Accept json // @Produce json -// @Param infraId path string true "a infrastructure ID created for migration" -// @Success 200 {object} model.Response "Successfully deleted the migrated infrastructure on a cloud platform" +// @Param nsId path string true "Namespace ID" default(mig01) +// @Param mciId path string true "Migrated Multi-Cloud Infrastructure (MCI) ID" default(mmci01) +// @Success 200 {object} model.Response "The result of deleting the migrated multi-cloud infrastructure (MCI)" // @Failure 404 {object} model.Response // @Failure 500 {object} model.Response -// @Router /migration/infra/{infraId} [delete] +// @Router /migration/ns/{nsId}/mci/{mciId} [delete] func DeleteInfra(c echo.Context) error { // [Note] Input section - // nsId := c.Param("nsId") - // if nsId == "" { - // err := fmt.Errorf("invalid request, the nanespace ID (nsId: %s) is required", nsId) - // log.Warn().Msg(err.Error()) - // res := model.Response{ - // Success: false, - // Text: err.Error(), - // } - // return c.JSON(http.StatusBadRequest, res) - // } - nsId := common.DefaulNamespaceId - - infraId := c.Param("infraId") - if infraId == "" { - err := fmt.Errorf("invalid request, the infrastructure ID (infraId: %s) is required", infraId) + nsId := c.Param("nsId") + if nsId == "" { + err := fmt.Errorf("invalid request, the namespace ID (nsId: %s) is required", nsId) + log.Warn().Msg(err.Error()) + res := model.Response{ + Success: false, + Text: err.Error(), + } + return c.JSON(http.StatusBadRequest, res) + } + // nsId := common.DefaulNamespaceId + + mciId := c.Param("mciId") + if mciId == "" { + err := fmt.Errorf("invalid request, the multi-cloud infrastructure ID (mciId: %s) is required", mciId) log.Warn().Msg(err.Error()) res := model.Response{ Success: false, @@ -207,10 +188,10 @@ func DeleteInfra(c echo.Context) error { } // [Note] Process section - retMsg, err := migration.DeleteVMInfra(nsId, infraId) + retMsg, err := migration.DeleteVMInfra(nsId, mciId) if err != nil { - log.Error().Err(err).Msg("failed to delete the migrated infrastructure") + log.Error().Err(err).Msg("failed to delete the migrated multi-cloud infrastructure") res := model.Response{ Success: false, Text: err.Error(), diff --git a/pkg/api/rest/controller/recommendation.go b/pkg/api/rest/controller/recommendation.go index dea9c6a..f8c3914 100644 --- a/pkg/api/rest/controller/recommendation.go +++ b/pkg/api/rest/controller/recommendation.go @@ -46,22 +46,22 @@ type RecommendInfraResponse struct { } // RecommendInfra godoc -// @Summary Recommend an appropriate infrastructure for cloud migration -// @Description It recommends a cloud infrastructure most similar to the input. Infrastructure includes network, storage, compute, and so on. +// @Summary Recommend an appropriate multi-cloud infrastructure (MCI) for cloud migration +// @Description Recommend an appropriate multi-cloud infrastructure (MCI) for cloud migration // @Tags [Recommendation] Infrastructure // @Accept json // @Produce json -// @Param UserInfrastructure body RecommendInfraRequest true "Specify network, disk, compute, security group, virtual machine, etc." -// @Success 200 {object} RecommendInfraResponse "Successfully recommended an appropriate infrastructure for cloud migration" +// @Param UserInfra body RecommendInfraRequest true "Specify the your infrastructure to be migrated" +// @Success 200 {object} RecommendInfraResponse "The result of recommended infrastructure" // @Failure 404 {object} common.SimpleMsg // @Failure 500 {object} common.SimpleMsg -// @Router /recommendation/infra [post] +// @Router /recommendation/mci [post] func RecommendInfra(c echo.Context) error { // Input req := &RecommendInfraRequest{} if err := c.Bind(req); err != nil { - log.Error().Err(err).Msg("Failed to bind a request body") + log.Error().Err(err).Msg("failed to bind a request body") res := common.SimpleMsg{Message: err.Error()} return c.JSON(http.StatusBadRequest, res) } @@ -70,11 +70,11 @@ func RecommendInfra(c echo.Context) error { // Process recommendedInfra, err := recommendation.Recommend(req.Servers) - recommendedInfra.Name = "cloud-infra01" + recommendedInfra.Name = "mmci01" // Ouput if err != nil { - log.Error().Err(err).Msg("Failed to recommend an appropriate infrastructure for cloud migration") + log.Error().Err(err).Msg("failed to recommend an appropriate multi-cloud infrastructure (MCI) for cloud migration") res := common.SimpleMsg{Message: err.Error()} return c.JSON(http.StatusNotFound, res) } diff --git a/pkg/api/rest/server.go b/pkg/api/rest/server.go index 3838066..4c93841 100644 --- a/pkg/api/rest/server.go +++ b/pkg/api/rest/server.go @@ -92,6 +92,7 @@ func RunServer(port string) { APILogSkipPatterns := [][]string{ {"/beetle/api"}, + {"/tumblebug/api"}, // {"/mci", "option=status"}, } @@ -175,24 +176,27 @@ func RunServer(port string) { } resBody := strings.TrimSuffix(string(resBytes), "\n") - log.Debug().Msgf("[Proxy] response from %s: %s", res.Request.URL, resBody) + log.Debug().Msgf("[Proxy] response from %s", res.Request.URL) + log.Trace().Msgf("[Proxy] response body: %s", resBody) res.Body = io.NopCloser(bytes.NewReader(resBytes)) return nil }, })) - // Route for system management + // Beetle API group which has /beetle as prefix + gBeetle := e.Group("/beetle") + + // Swagger API docs swaggerRedirect := func(c echo.Context) error { return c.Redirect(http.StatusMovedPermanently, "/beetle/api/index.html") } - - // Beetle API group which has /beetle as prefix - gBeetle := e.Group("/beetle") gBeetle.GET("/api", swaggerRedirect) gBeetle.GET("/api/", swaggerRedirect) + gBeetle.GET("/api/*", echoSwagger.WrapHandler) + // System management APIs gBeetle.GET("/readyz", rest_common.RestGetReadyz) gBeetle.GET("/httpVersion", rest_common.RestCheckHTTPVersion) @@ -205,16 +209,16 @@ func RunServer(port string) { // Recommendation API group gRecommendation := gBeetle.Group("/recommendation") - gRecommendation.POST("/infra", controller.RecommendInfra) + gRecommendation.POST("/mci", controller.RecommendInfra) // Migration API group gMigration := gBeetle.Group("/migration") - gMigration.POST("/infra", controller.MigrateInfra) - gMigration.GET("/infra/:infraId", controller.GetInfra) - gMigration.DELETE("/infra/:infraId", controller.DeleteInfra) - // gMigration.POST("/infra/network", controller.MigrateInfra) - // gMigration.POST("/infra/storage", controller.MigrateInfra) - // gMigration.POST("/infra/instance", controller.MigrateInfra) + gMigration.POST("/ns/:nsId/mci", controller.MigrateInfra) + gMigration.GET("/ns/:nsId/mci/:mciId", controller.GetInfra) + gMigration.DELETE("/ns/:nsId/mci/:mciId", controller.DeleteInfra) + // gMigration.POST("/ns/:nsId/mci/network", controller.MigrateInfra) + // gMigration.POST("/ns/:nsId/mci/storage", controller.MigrateInfra) + // gMigration.POST("/ns/:nsId/mci/instance", controller.MigrateInfra) // Route // e.GET("/beetle/connConfig", rest_common.RestGetConnConfigList) diff --git a/pkg/core/common/common.go b/pkg/core/common/common.go index b04449d..0aaf2c5 100644 --- a/pkg/core/common/common.go +++ b/pkg/core/common/common.go @@ -76,7 +76,7 @@ const ( StrDataDisk string = "dataDisk" StrNLB string = "nlb" StrVM string = "vm" - StrMCI string = "mci" + StrMCI string = "mci" StrDefaultResourceName string = "-systemdefault-" // StrFirewallRule string = "firewallRule" @@ -190,7 +190,7 @@ func CreateImageTable() error { } */ -var DefaulNamespaceId = "ns-mig01" +var DefaulNamespaceId = "mig01" // NsReq is struct for namespace creation type NsReq struct { @@ -221,32 +221,9 @@ func CreateNamespace(nsInfo NsReq) (NsInfo, error) { // set endpoint epTumblebug := TumblebugRestUrl - // check readyz - method := "GET" - url := fmt.Sprintf("%s/readyz", epTumblebug) - reqReadyz := NoBody - resReadyz := new(SimpleMsg) - - err := ExecuteHttpRequest( - client, - method, - url, - nil, - SetUseBody(reqReadyz), - &reqReadyz, - resReadyz, - VeryShortDuration, - ) - - if err != nil { - log.Err(err).Msg("") - return NsInfo{}, err - } - log.Debug().Msgf("resReadyz: %+v", resReadyz.Message) - - // check readyz - method = "POST" - url = fmt.Sprintf("%s/ns", epTumblebug) + // create namespace + method := "POST" + url := fmt.Sprintf("%s/ns", epTumblebug) reqNs := nsInfo resNs := new(NsInfo) @@ -280,32 +257,9 @@ func GetAllNamespaces() (RestGetAllNsResponse, error) { // set endpoint epTumblebug := TumblebugRestUrl - // check readyz + // Get all namespaces method := "GET" - url := fmt.Sprintf("%s/readyz", epTumblebug) - reqReadyz := NoBody - resReadyz := new(SimpleMsg) - - err := ExecuteHttpRequest( - client, - method, - url, - nil, - SetUseBody(reqReadyz), - &reqReadyz, - resReadyz, - VeryShortDuration, - ) - - if err != nil { - log.Err(err).Msg("") - return RestGetAllNsResponse{}, err - } - log.Debug().Msgf("resReadyz: %+v", resReadyz.Message) - - // check readyz - method = "GET" - url = fmt.Sprintf("%s/ns", epTumblebug) + url := fmt.Sprintf("%s/ns", epTumblebug) reqNs := NoBody resAllNs := new(RestGetAllNsResponse) @@ -339,32 +293,9 @@ func GetNamespace(nsId string) (NsInfo, error) { // set endpoint epTumblebug := TumblebugRestUrl - // check readyz + // try to get namespace method := "GET" - url := fmt.Sprintf("%s/readyz", epTumblebug) - reqReadyz := NoBody - resReadyz := new(SimpleMsg) - - err := ExecuteHttpRequest( - client, - method, - url, - nil, - SetUseBody(reqReadyz), - &reqReadyz, - resReadyz, - VeryShortDuration, - ) - - if err != nil { - log.Err(err).Msg("") - return NsInfo{}, err - } - log.Debug().Msgf("resReadyz: %+v", resReadyz.Message) - - // check readyz - method = "GET" - url = fmt.Sprintf("%s/ns/%s", epTumblebug, nsId) + url := fmt.Sprintf("%s/ns/%s", epTumblebug, nsId) reqNs := NoBody resNsInfo := new(NsInfo) @@ -398,32 +329,9 @@ func DeleteNamespace(nsId string) (SimpleMsg, error) { // set endpoint epTumblebug := TumblebugRestUrl - // check readyz - method := "GET" - url := fmt.Sprintf("%s/readyz", epTumblebug) - reqReadyz := NoBody - resReadyz := new(SimpleMsg) - - err := ExecuteHttpRequest( - client, - method, - url, - nil, - SetUseBody(reqReadyz), - &reqReadyz, - resReadyz, - VeryShortDuration, - ) - - if err != nil { - log.Err(err).Msg("") - return SimpleMsg{}, err - } - log.Debug().Msgf("resReadyz: %+v", resReadyz.Message) - - // check readyz - method = "DELETE" - url = fmt.Sprintf("%s/ns/%s", epTumblebug, nsId) + // delete namespace + method := "DELETE" + url := fmt.Sprintf("%s/ns/%s", epTumblebug, nsId) reqNs := NoBody resMsg := new(SimpleMsg) diff --git a/pkg/core/recommendation/recommendation.go b/pkg/core/recommendation/recommendation.go index ef399c1..6703065 100644 --- a/pkg/core/recommendation/recommendation.go +++ b/pkg/core/recommendation/recommendation.go @@ -32,29 +32,6 @@ func Recommend(srcInfra []infra.Infra) (mci.TbMciDynamicReq, error) { // set endpoint epTumblebug := common.TumblebugRestUrl - // check readyz - method := "GET" - url := fmt.Sprintf("%s/readyz", epTumblebug) - reqReadyz := common.NoBody - resReadyz := new(common.SimpleMsg) - - err := common.ExecuteHttpRequest( - client, - method, - url, - nil, - common.SetUseBody(reqReadyz), - &reqReadyz, - resReadyz, - common.VeryShortDuration, - ) - - if err != nil { - log.Err(err).Msg("") - return mci.TbMciDynamicReq{}, err - } - log.Debug().Msgf("resReadyz: %+v", resReadyz.Message) - // Set a deployment plan to recommand virtual machines // Ref: https://github.com/cloud-barista/cb-tumblebug/discussions/1234 planDocstring := `{ @@ -118,7 +95,7 @@ func Recommend(srcInfra []infra.Infra) (mci.TbMciDynamicReq, error) { targetInfra := mci.TbMciDynamicReq{ Description: "A cloud infra recommended by CM-Beetle", InstallMonAgent: "no", - Label: "rehosted-infra", + Label: "rehosted-mci", Name: "", SystemLabel: "", Vm: []mci.TbVmDynamicReq{},