diff --git a/Dockerfile b/Dockerfile index 9a9fcdd..2000308 100644 --- a/Dockerfile +++ b/Dockerfile @@ -18,9 +18,9 @@ RUN --mount=type=cache,target=/go/pkg/mod \ # Copy some necessary files to the container COPY api ./api COPY cmd/cm-beetle ./cmd/cm-beetle -COPY conf ./conf COPY pkg ./pkg COPY scripts ./scripts +# COPY conf ./conf # Build the Go app RUN --mount=type=cache,target=/go/pkg/mod \ @@ -46,17 +46,27 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ ## Copy the Pre-built binary and necessary files from the previous stage COPY --from=builder /go/src/github.com/cloud-barista/cm-beetle/scripts/ /app/scripts/ -COPY --from=builder /go/src/github.com/cloud-barista/cm-beetle/conf/ /app/conf/ COPY --from=builder /go/src/github.com/cloud-barista/cm-beetle/cmd/cm-beetle/cm-beetle /app/ COPY --from=builder /go/src/github.com/cloud-barista/cm-beetle/api/ /app/api/ +# COPY --from=builder /go/src/github.com/cloud-barista/cm-beetle/conf/ /app/conf/ ## Set environment variables # Set system endpoints -ENV BEETLE_ROOT=/app \ - BEETLE_CBSTORE_ROOT=/app \ - BEETLE_CBLOG_ROOT=/app +ENV BEETLE_ROOT=/app -ENV BEETLE_TUMBLEBUG_REST_URL=http://localhost:1323/tumblebug +## Set SELF_ENDPOINT, to access Swagger API dashboard outside (Ex: export SELF_ENDPOINT=x.x.x.x:8056) +ENV BEETLE_SELF_ENDPOINT=localhost:8056 + +## Set API access config +# API_ALLOW_ORIGINS (ex: https://cloud-barista.org,xxx.xxx.xxx.xxx or * for all) +# Set ENABLE_AUTH=true currently for basic auth for all routes (i.e., url or path) +ENV BEETLE_API_ALLOW_ORIGINS=* \ + BEETLE_API_AUTH_ENABLED=true \ + BEETLE_API_USERNAME=default \ + BEETLE_API_PASSWORD=default + +## Set internal DB config (lkvstore: local key-value store, default file path: ./db/beetle.db) +ENV BEETLE_LKVSTORE_PATH=/app/db/beetle.db ## Logger configuration # Set log file path (default logfile path: ./beetle.log) @@ -66,30 +76,19 @@ ENV BEETLE_LOGFILE_PATH=/app/log/beetle.log \ BEETLE_LOGFILE_MAXBACKUPS=3 \ BEETLE_LOGFILE_MAXAGE=30 \ BEETLE_LOGFILE_COMPRESS=false \ - BEETLE_LOGLEVEL=info + BEETLE_LOGLEVEL=info \ + BEETLE_LOGWRITER=both # Set execution environment, such as development or production ENV BEETLE_NODE_ENV=production -## Set internal DB config (SQLlite) -ENV BEETLE_SQLITE_URL=localhost:3306 \ - BEETLE_SQLITE_DATABASE=cm_beetle \ - BEETLE_SQLITE_USER=cm_beetle \ - BEETLE_SQLITE_PASSWORD=cm_beetle - -## Set API access config -# API_ALLOW_ORIGINS (ex: https://cloud-barista.org,xxx.xxx.xxx.xxx or * for all) -# Set ENABLE_AUTH=true currently for basic auth for all routes (i.e., url or path) -ENV BEETLE_API_ALLOW_ORIGINS=* \ - BEETLE_API_AUTH_ENABLED=true \ - BEETLE_API_USERNAME=default \ - BEETLE_API_PASSWORD=default - ## Set period for auto control goroutine invocation ENV BEETLE_AUTOCONTROL_DURATION_MS=10000 -## Set SELF_ENDPOINT, to access Swagger API dashboard outside (Ex: export SELF_ENDPOINT=x.x.x.x:8056) -ENV BEETLE_SELF_ENDPOINT=localhost:8056 +## Set Tumblebug access config +ENV BEETLE_TUMBLEBUG_REST_URL=http://localhost:1323 \ + BEETLE_TUMBLEBUG_API_USERNAME=default \ + BEETLE_TUMBLEBUG_API_PASSWORD=default ENTRYPOINT [ "/app/cm-beetle" ] diff --git a/Makefile b/Makefile index 27b7391..cdbff28 100644 --- a/Makefile +++ b/Makefile @@ -80,14 +80,14 @@ clean: ## Remove previous build @cd cmd/$(MODULE_NAME) && $(GO) clean @echo "Cleaned!" +compose: 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 + compose-up: ## Up services by docker compose @echo "Starting services by docker compose..." @cd deployments/docker-compose && docker compose up -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 - compose-down: ## Down services by docker compose @echo "Removing services by docker compose..." @cd deployments/docker-compose && docker compose down diff --git a/api/docs.go b/api/docs.go index 7bf9ae4..3d13218 100644 --- a/api/docs.go +++ b/api/docs.go @@ -283,13 +283,13 @@ const docTemplate = `{ "404": { "description": "Not Found", "schema": { - "$ref": "#/definitions/github_com_cloud-barista_cm-beetle_pkg_core_common.SimpleMsg" + "$ref": "#/definitions/common.SimpleMsg" } }, "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/github_com_cloud-barista_cm-beetle_pkg_core_common.SimpleMsg" + "$ref": "#/definitions/common.SimpleMsg" } } } @@ -555,6 +555,15 @@ const docTemplate = `{ } } }, + "common.SimpleMsg": { + "type": "object", + "properties": { + "message": { + "type": "string", + "example": "Any message" + } + } + }, "controller.CreateUserRequest": { "type": "object", "properties": { @@ -632,7 +641,7 @@ const docTemplate = `{ "vm": { "type": "array", "items": { - "$ref": "#/definitions/mci.TbVmDynamicReq" + "$ref": "#/definitions/model.TbVmDynamicReq" } } } @@ -675,7 +684,7 @@ const docTemplate = `{ "vm": { "type": "array", "items": { - "$ref": "#/definitions/mci.TbVmDynamicReq" + "$ref": "#/definitions/model.TbVmDynamicReq" } } } @@ -724,44 +733,15 @@ const docTemplate = `{ }, "controller.RecommendInfraResponse": { "type": "object", - "required": [ - "name", - "vm" - ], "properties": { "description": { - "type": "string", - "example": "Made in CB-TB" - }, - "installMonAgent": { - "description": "InstallMonAgent Option for CB-Dragonfly agent installation ([yes/no] default:yes)", - "type": "string", - "default": "no", - "enum": [ - "yes", - "no" - ], - "example": "no" - }, - "label": { - "description": "Label is for describing the mci in a keyword (any string can be used)", - "type": "string", - "example": "DynamicVM" - }, - "name": { - "type": "string", - "example": "mci01" + "type": "string" }, - "systemLabel": { - "description": "SystemLabel is for describing the mci in a keyword (any string can be used) for special System purpose", - "type": "string", - "example": "" + "status": { + "type": "string" }, - "vm": { - "type": "array", - "items": { - "$ref": "#/definitions/mci.TbVmDynamicReq" - } + "targetInfra": { + "$ref": "#/definitions/model.TbMciDynamicReq" } } }, @@ -793,15 +773,6 @@ const docTemplate = `{ } } }, - "github_com_cloud-barista_cm-beetle_pkg_core_common.SimpleMsg": { - "type": "object", - "properties": { - "message": { - "type": "string", - "example": "Any message" - } - } - }, "infra.CPU": { "type": "object", "required": [ @@ -1165,7 +1136,89 @@ const docTemplate = `{ } } }, - "mci.TbVmDynamicReq": { + "model.MyUser": { + "type": "object", + "properties": { + "email": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "name": { + "type": "string" + } + } + }, + "model.Response": { + "type": "object", + "properties": { + "details": { + "type": "string", + "example": "Any details" + }, + "list": { + "type": "array", + "items": {} + }, + "object": { + "type": "object", + "additionalProperties": true + }, + "success": { + "type": "boolean", + "example": true + }, + "text": { + "type": "string", + "example": "Any text" + } + } + }, + "model.TbMciDynamicReq": { + "type": "object", + "required": [ + "name", + "vm" + ], + "properties": { + "description": { + "type": "string", + "example": "Made in CB-TB" + }, + "installMonAgent": { + "description": "InstallMonAgent Option for CB-Dragonfly agent installation ([yes/no] default:yes)", + "type": "string", + "default": "no", + "enum": [ + "yes", + "no" + ], + "example": "no" + }, + "label": { + "description": "Label is for describing the mci in a keyword (any string can be used)", + "type": "string", + "example": "DynamicVM" + }, + "name": { + "type": "string", + "example": "mci01" + }, + "systemLabel": { + "description": "SystemLabel is for describing the mci in a keyword (any string can be used) for special System purpose", + "type": "string", + "example": "" + }, + "vm": { + "type": "array", + "items": { + "$ref": "#/definitions/model.TbVmDynamicReq" + } + } + } + }, + "model.TbVmDynamicReq": { "type": "object", "required": [ "commonImage", @@ -1222,45 +1275,6 @@ const docTemplate = `{ } } }, - "model.MyUser": { - "type": "object", - "properties": { - "email": { - "type": "string" - }, - "id": { - "type": "integer" - }, - "name": { - "type": "string" - } - } - }, - "model.Response": { - "type": "object", - "properties": { - "details": { - "type": "string", - "example": "Any details" - }, - "list": { - "type": "array", - "items": {} - }, - "object": { - "type": "object", - "additionalProperties": true - }, - "success": { - "type": "boolean", - "example": true - }, - "text": { - "type": "string", - "example": "Any text" - } - } - }, "network.CSP": { "type": "object", "properties": { diff --git a/api/swagger.json b/api/swagger.json index 3aa1c0f..08095c8 100644 --- a/api/swagger.json +++ b/api/swagger.json @@ -276,13 +276,13 @@ "404": { "description": "Not Found", "schema": { - "$ref": "#/definitions/github_com_cloud-barista_cm-beetle_pkg_core_common.SimpleMsg" + "$ref": "#/definitions/common.SimpleMsg" } }, "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/github_com_cloud-barista_cm-beetle_pkg_core_common.SimpleMsg" + "$ref": "#/definitions/common.SimpleMsg" } } } @@ -548,6 +548,15 @@ } } }, + "common.SimpleMsg": { + "type": "object", + "properties": { + "message": { + "type": "string", + "example": "Any message" + } + } + }, "controller.CreateUserRequest": { "type": "object", "properties": { @@ -625,7 +634,7 @@ "vm": { "type": "array", "items": { - "$ref": "#/definitions/mci.TbVmDynamicReq" + "$ref": "#/definitions/model.TbVmDynamicReq" } } } @@ -668,7 +677,7 @@ "vm": { "type": "array", "items": { - "$ref": "#/definitions/mci.TbVmDynamicReq" + "$ref": "#/definitions/model.TbVmDynamicReq" } } } @@ -717,44 +726,15 @@ }, "controller.RecommendInfraResponse": { "type": "object", - "required": [ - "name", - "vm" - ], "properties": { "description": { - "type": "string", - "example": "Made in CB-TB" - }, - "installMonAgent": { - "description": "InstallMonAgent Option for CB-Dragonfly agent installation ([yes/no] default:yes)", - "type": "string", - "default": "no", - "enum": [ - "yes", - "no" - ], - "example": "no" - }, - "label": { - "description": "Label is for describing the mci in a keyword (any string can be used)", - "type": "string", - "example": "DynamicVM" - }, - "name": { - "type": "string", - "example": "mci01" + "type": "string" }, - "systemLabel": { - "description": "SystemLabel is for describing the mci in a keyword (any string can be used) for special System purpose", - "type": "string", - "example": "" + "status": { + "type": "string" }, - "vm": { - "type": "array", - "items": { - "$ref": "#/definitions/mci.TbVmDynamicReq" - } + "targetInfra": { + "$ref": "#/definitions/model.TbMciDynamicReq" } } }, @@ -786,15 +766,6 @@ } } }, - "github_com_cloud-barista_cm-beetle_pkg_core_common.SimpleMsg": { - "type": "object", - "properties": { - "message": { - "type": "string", - "example": "Any message" - } - } - }, "infra.CPU": { "type": "object", "required": [ @@ -1158,7 +1129,89 @@ } } }, - "mci.TbVmDynamicReq": { + "model.MyUser": { + "type": "object", + "properties": { + "email": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "name": { + "type": "string" + } + } + }, + "model.Response": { + "type": "object", + "properties": { + "details": { + "type": "string", + "example": "Any details" + }, + "list": { + "type": "array", + "items": {} + }, + "object": { + "type": "object", + "additionalProperties": true + }, + "success": { + "type": "boolean", + "example": true + }, + "text": { + "type": "string", + "example": "Any text" + } + } + }, + "model.TbMciDynamicReq": { + "type": "object", + "required": [ + "name", + "vm" + ], + "properties": { + "description": { + "type": "string", + "example": "Made in CB-TB" + }, + "installMonAgent": { + "description": "InstallMonAgent Option for CB-Dragonfly agent installation ([yes/no] default:yes)", + "type": "string", + "default": "no", + "enum": [ + "yes", + "no" + ], + "example": "no" + }, + "label": { + "description": "Label is for describing the mci in a keyword (any string can be used)", + "type": "string", + "example": "DynamicVM" + }, + "name": { + "type": "string", + "example": "mci01" + }, + "systemLabel": { + "description": "SystemLabel is for describing the mci in a keyword (any string can be used) for special System purpose", + "type": "string", + "example": "" + }, + "vm": { + "type": "array", + "items": { + "$ref": "#/definitions/model.TbVmDynamicReq" + } + } + } + }, + "model.TbVmDynamicReq": { "type": "object", "required": [ "commonImage", @@ -1215,45 +1268,6 @@ } } }, - "model.MyUser": { - "type": "object", - "properties": { - "email": { - "type": "string" - }, - "id": { - "type": "integer" - }, - "name": { - "type": "string" - } - } - }, - "model.Response": { - "type": "object", - "properties": { - "details": { - "type": "string", - "example": "Any details" - }, - "list": { - "type": "array", - "items": {} - }, - "object": { - "type": "object", - "additionalProperties": true - }, - "success": { - "type": "boolean", - "example": true - }, - "text": { - "type": "string", - "example": "Any text" - } - } - }, "network.CSP": { "type": "object", "properties": { diff --git a/api/swagger.yaml b/api/swagger.yaml index 7cb392e..c9a6fe7 100644 --- a/api/swagger.yaml +++ b/api/swagger.yaml @@ -6,6 +6,12 @@ definitions: example: Any message type: string type: object + common.SimpleMsg: + properties: + message: + example: Any message + type: string + type: object controller.CreateUserRequest: properties: email: @@ -60,7 +66,7 @@ definitions: type: string vm: items: - $ref: '#/definitions/mci.TbVmDynamicReq' + $ref: '#/definitions/model.TbVmDynamicReq' type: array required: - name @@ -95,7 +101,7 @@ definitions: type: string vm: items: - $ref: '#/definitions/mci.TbVmDynamicReq' + $ref: '#/definitions/model.TbVmDynamicReq' type: array required: - name @@ -131,37 +137,11 @@ definitions: controller.RecommendInfraResponse: properties: description: - example: Made in CB-TB - type: string - installMonAgent: - default: "no" - description: InstallMonAgent Option for CB-Dragonfly agent installation ([yes/no] - default:yes) - enum: - - "yes" - - "no" - example: "no" - type: string - label: - description: Label is for describing the mci in a keyword (any string can - be used) - example: DynamicVM type: string - name: - example: mci01 - type: string - systemLabel: - description: SystemLabel is for describing the mci in a keyword (any string - can be used) for special System purpose - example: "" + status: type: string - vm: - items: - $ref: '#/definitions/mci.TbVmDynamicReq' - type: array - required: - - name - - vm + targetInfra: + $ref: '#/definitions/model.TbMciDynamicReq' type: object controller.UpdateUserRequest: properties: @@ -181,12 +161,6 @@ definitions: name: type: string type: object - github_com_cloud-barista_cm-beetle_pkg_core_common.SimpleMsg: - properties: - message: - example: Any message - type: string - type: object infra.CPU: properties: cache: @@ -429,7 +403,69 @@ definitions: required: - os type: object - mci.TbVmDynamicReq: + model.MyUser: + properties: + email: + type: string + id: + type: integer + name: + type: string + type: object + model.Response: + properties: + details: + example: Any details + type: string + list: + items: {} + type: array + object: + additionalProperties: true + type: object + success: + example: true + type: boolean + text: + example: Any text + type: string + type: object + model.TbMciDynamicReq: + properties: + description: + example: Made in CB-TB + type: string + installMonAgent: + default: "no" + description: InstallMonAgent Option for CB-Dragonfly agent installation ([yes/no] + default:yes) + enum: + - "yes" + - "no" + example: "no" + type: string + label: + description: Label is for describing the mci in a keyword (any string can + be used) + example: DynamicVM + type: string + name: + example: mci01 + type: string + systemLabel: + description: SystemLabel is for describing the mci in a keyword (any string + can be used) for special System purpose + example: "" + type: string + vm: + items: + $ref: '#/definitions/model.TbVmDynamicReq' + type: array + required: + - name + - vm + type: object + model.TbVmDynamicReq: properties: commonImage: description: CommonImage is field for id of a image in common namespace @@ -480,33 +516,6 @@ definitions: - commonImage - commonSpec type: object - model.MyUser: - properties: - email: - type: string - id: - type: integer - name: - type: string - type: object - model.Response: - properties: - details: - example: Any details - type: string - list: - items: {} - type: array - object: - additionalProperties: true - type: object - success: - example: true - type: boolean - text: - example: Any text - type: string - type: object network.CSP: properties: name: @@ -860,11 +869,11 @@ paths: "404": description: Not Found schema: - $ref: '#/definitions/github_com_cloud-barista_cm-beetle_pkg_core_common.SimpleMsg' + $ref: '#/definitions/common.SimpleMsg' "500": description: Internal Server Error schema: - $ref: '#/definitions/github_com_cloud-barista_cm-beetle_pkg_core_common.SimpleMsg' + $ref: '#/definitions/common.SimpleMsg' summary: Recommend an appropriate multi-cloud infrastructure (MCI) for cloud migration tags: diff --git a/cmd/cm-beetle/main.go b/cmd/cm-beetle/main.go index dd8661a..c25c9d7 100644 --- a/cmd/cm-beetle/main.go +++ b/cmd/cm-beetle/main.go @@ -16,12 +16,12 @@ package main import ( "flag" - "os" "strconv" "sync" "time" "github.com/cloud-barista/cm-beetle/pkg/config" + "github.com/cloud-barista/cm-beetle/pkg/lkvstore" "github.com/cloud-barista/cm-beetle/pkg/logger" "github.com/go-resty/resty/v2" "github.com/rs/zerolog/log" @@ -52,22 +52,27 @@ func init() { // Initialize the logger logger := logger.NewLogger(logger.Config{ - LogLevel: viper.GetString("beetle.loglevel"), - LogWriter: viper.GetString("beetle.logwriter"), - LogFilePath: viper.GetString("beetle.logfile.path"), - MaxSize: viper.GetInt("beetle.logfile.maxsize"), - MaxBackups: viper.GetInt("beetle.logfile.maxbackups"), - MaxAge: viper.GetInt("beetle.logfile.maxage"), - Compress: viper.GetBool("beetle.logfile.compress"), + LogLevel: config.Beetle.LogLevel, + LogWriter: config.Beetle.LogWriter, + LogFilePath: config.Beetle.LogFile.Path, + MaxSize: config.Beetle.LogFile.MaxSize, + MaxBackups: config.Beetle.LogFile.MaxBackups, + MaxAge: config.Beetle.LogFile.MaxAge, + Compress: config.Beetle.LogFile.Compress, }) // Set the global logger log.Logger = *logger + // Initialize the local key-value store with the specified file path + dbFilePath := config.Beetle.LKVStore.Path + lkvstore.Init(lkvstore.Config{ + DbFilePath: dbFilePath, + }) + // Check Tumblebug readiness - tumblebugEp := viper.GetString("beetle.tumblebug.endpoint") - url := tumblebugEp + "/tumblebug/readyz" - isReady, err := checkReadiness(url) + apiUrl := config.Tumblebug.RestUrl + "/readyz" + isReady, err := checkReadiness(apiUrl) if err != nil || !isReady { log.Fatal().Err(err).Msg("Tumblebug is not ready. Exiting...") @@ -139,7 +144,24 @@ func checkReadiness(url string) (bool, error) { func main() { - log.Info().Msg("CM-Beetle server is starting...") + log.Info().Msg("preparing to run CM-Beetle server...") + + // Load the state from the file back into the key-value store + if err := lkvstore.LoadLkvStore(); err != nil { + log.Error().Err(err).Msgf("error loading data from the lkvstore (file).") + } + + log.Info().Msg("successfully load data from the lkvstore (file).") + + defer func() { + // Save the current state of the key-value store to file + if err := lkvstore.SaveLkvStore(); err != nil { + log.Error().Err(err).Msgf("error saving data to the lkvstore (file).") + } + log.Info().Msg("successfully save data to the lkvstore (file).") + }() + + log.Info().Msg("Setting CM-Beetle REST API server...") // Set the default port number "8056" for the REST API server to listen on port := flag.String("port", "8056", "port number for the restapiserver to listen to") @@ -151,33 +173,6 @@ func main() { } log.Debug().Msgf("port number: %s", *port) - // 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_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") - common.DBPassword = common.NVL(os.Getenv("BEETLE_SQLITE_PASSWORD"), "cm_beetle") - common.AutocontrolDurationMs = common.NVL(os.Getenv("BEETLE_AUTOCONTROL_DURATION_MS"), "10000") - - // load the latest configuration from DB (if exist) - // fmt.Println("") - // fmt.Println("[Update system environment]") - // common.UpdateGlobalVariable(common.StrDragonflyRestUrl) - // common.UpdateGlobalVariable(common.StrSpiderRestUrl) - // common.UpdateGlobalVariable(common.StrAutocontrolDurationMs) - - // load config - //masterConfigInfos = confighandler.GetMasterConfigInfos() - - //Setup database (meta_db/dat/cmbeetle.s3db) - log.Info().Msg("setting SQL Database") - err := os.MkdirAll("./meta_db/dat/", os.ModePerm) - if err != nil { - log.Error().Err(err).Msg("error creating directory") - } - log.Debug().Msgf("database file path: %s", "./meta_db/dat/cmbeetle.s3db") - // Watch config file changes go func() { viper.WatchConfig() @@ -187,10 +182,13 @@ func main() { if err != nil { // Handle errors reading the config file log.Fatal().Err(err).Msg("fatal error in config file") } - err = viper.Unmarshal(&common.RuntimeConf) + err = viper.Unmarshal(&config.RuntimeConfig) if err != nil { log.Panic().Err(err).Msg("error unmarshaling runtime configuration") } + config.Beetle = config.RuntimeConfig.Beetle + config.Beetle.Tumblebug.RestUrl = config.Beetle.Tumblebug.Endpoint + "/tumblebug" + config.Tumblebug = config.Beetle.Tumblebug }) }() diff --git a/conf/config.yaml b/conf/config.yaml index 5feeb78..a818a29 100644 --- a/conf/config.yaml +++ b/conf/config.yaml @@ -2,11 +2,9 @@ beetle: root: # To be set in runtime - cbstore: - root: # To be set in runtime (based on beetle.root) - - cblog: - root: # To be set in runtime (based on beetle.root) + ## Set SELF_ENDPOINT, to access Swagger API dashboard outside (Ex: export SELF_ENDPOINT=x.x.x.x:8056) + self: + endpoint: localhost:8056 ## Set API access config api: @@ -21,22 +19,9 @@ beetle: username: default password: default - ## Set SELF_ENDPOINT, to access Swagger API dashboard outside (Ex: export SELF_ENDPOINT=x.x.x.x:8056) - self: - endpoint: localhost:8056 - - tumblebug: - endpoint: http://localhost:1323 - api: - username: default - password: default - - ## Set internal DB config (SQLlite) - db: - url: localhost:3306 - database: cm_beetle - user: cm_beetle - password: cm_beetle + ## Set internal DB config (lkvstore: local key-value store) + lkvstore: + path: ./db/beetle.db ## Logger configuration logfile: @@ -60,3 +45,10 @@ beetle: ## Set period for auto control goroutine invocation autocontrol: duration_ms: 10000 + + ## Set Tumblebug access config + tumblebug: + endpoint: http://localhost:1323 + api: + username: default + password: default diff --git a/conf/log_conf.yaml b/conf/log_conf.yaml deleted file mode 100644 index bed04b1..0000000 --- a/conf/log_conf.yaml +++ /dev/null @@ -1,18 +0,0 @@ -#### Config for CB-Log Lib. #### - -cblog: - ## true | false - loopcheck: true # This temp method for development is busy wait. cf) cblogger.go:levelSetupLoop(). - - ## debug | info | warn | error - loglevel: error # If loopcheck is true, You can set this online. - - ## true | false - logfile: true - -## Config for File Output ## -logfileinfo: - filename: $BEETLE_ROOT/log/cblogs.log - maxsize: 10 # megabytes - maxbackups: 50 - maxage: 31 # days diff --git a/conf/setup.env b/conf/setup.env index 4562b13..ef7f459 100644 --- a/conf/setup.env +++ b/conf/setup.env @@ -2,8 +2,9 @@ # Set BEETLE_ROOT based on path of setup.env relatively SCRIPT_DIR=`dirname ${BASH_SOURCE[0]-$0}` export BEETLE_ROOT=`cd $SCRIPT_DIR && cd .. && pwd` -export BEETLE_CBSTORE_ROOT=$BEETLE_ROOT -export BEETLE_CBLOG_ROOT=$BEETLE_ROOT + +## Set BEETLE_SELF_ENDPOINT, to access Swagger API dashboard outside (Ex: export SELF_ENDPOINT=x.x.x.x:8056) +export BEETLE_SELF_ENDPOINT=localhost:8056 ## Set API access config # BEETLE_API_ALLOW_ORIGINS (ex: https://cloud-barista.org,http://localhost:8080 or * for all) @@ -13,19 +14,8 @@ export BEETLE_API_AUTH_ENABLED=true export BEETLE_API_USERNAME=default export BEETLE_API_PASSWORD=default -## Set BEETLE_SELF_ENDPOINT, to access Swagger API dashboard outside (Ex: export SELF_ENDPOINT=x.x.x.x:8056) -export BEETLE_SELF_ENDPOINT=localhost:8056 - -## Set API access config -export BEETLE_TUMBLEBUG_ENDPOINT=http://localhost:1323 -export BEETLE_TUMBLEBUG_API_USERNAME=default -export BEETLE_TUMBLEBUG_API_PASSWORD=default - -## Set internal DB config (SQLlite) -export BEETLE_SQLITE_URL=localhost:3306 -export BEETLE_SQLITE_DATABASE=cm_beetle -export BEETLE_SQLITE_USER=cm_beetle -export BEETLE_SQLITE_PASSWORD=cm_beetle +## Set internal DB config (lkvstore: local key-value store, default file path: ./db/beetle.db) +export BEETLE_LKVSTORE_PATH=db/beetle.db ## Logger configuration # Set log file path (default logfile path: ./log/beetle.log) @@ -43,3 +33,8 @@ export BEETLE_NODE_ENV=development ## Set period for auto control goroutine invocation export BEETLE_AUTOCONTROL_DURATION_MS=10000 + +## Set Tumblebug access config +export BEETLE_TUMBLEBUG_ENDPOINT=http://localhost:1323 +export BEETLE_TUMBLEBUG_API_USERNAME=default +export BEETLE_TUMBLEBUG_API_PASSWORD=default \ No newline at end of file diff --git a/conf/store_conf.yaml b/conf/store_conf.yaml deleted file mode 100644 index 396b43d..0000000 --- a/conf/store_conf.yaml +++ /dev/null @@ -1,15 +0,0 @@ -#### Config for CB-Store #### - -# server type: NUTSDB | ETCD -# NUTSDB: embedded Key-Value Store on Local Filesystem -storetype: NUTSDB -#storetype: ETCD - -nutsdb: - dbpath: "$BEETLE_ROOT/meta_db/dat" - segmentsize: 1048576 # 1048576 1024*1024 (1MB) - #segmentsize: 10485760 # 10485760 10*1024*1024 (10MB) - -etcd: - # etcd server, when ETCD typpe - etcdserverport: "129.254.175.43:2379" \ No newline at end of file diff --git a/conf/template-config.yaml b/conf/template-config.yaml index f066f35..a818a29 100644 --- a/conf/template-config.yaml +++ b/conf/template-config.yaml @@ -2,11 +2,9 @@ beetle: root: # To be set in runtime - cbstore: - root: # To be set in runtime (based on beetle.root) - - cblog: - root: # To be set in runtime (based on beetle.root) + ## Set SELF_ENDPOINT, to access Swagger API dashboard outside (Ex: export SELF_ENDPOINT=x.x.x.x:8056) + self: + endpoint: localhost:8056 ## Set API access config api: @@ -21,28 +19,15 @@ beetle: username: default password: default - ## Set SELF_ENDPOINT, to access Swagger API dashboard outside (Ex: export SELF_ENDPOINT=x.x.x.x:8056) - self: - endpoint: localhost:8056 - - tumblebug: - endpoint: http://localhost:1323 - api: - username: default - password: default - - ## Set internal DB config (SQLlite) - db: - url: localhost:3306 - database: cm_beetle - user: cm_beetle - password: cm_beetle + ## Set internal DB config (lkvstore: local key-value store) + lkvstore: + path: ./db/beetle.db ## Logger configuration logfile: # Set log file path (default logfile path: ./log/beetle.log) path: ./log/beetle.log - maxsize: 100 + maxsize: 1000 maxbackups: 3 maxage: 30 compress: false @@ -60,3 +45,10 @@ beetle: ## Set period for auto control goroutine invocation autocontrol: duration_ms: 10000 + + ## Set Tumblebug access config + tumblebug: + endpoint: http://localhost:1323 + api: + username: default + password: default diff --git a/conf/template-setup.env b/conf/template-setup.env index b193600..ef7f459 100644 --- a/conf/template-setup.env +++ b/conf/template-setup.env @@ -2,8 +2,9 @@ # Set BEETLE_ROOT based on path of setup.env relatively SCRIPT_DIR=`dirname ${BASH_SOURCE[0]-$0}` export BEETLE_ROOT=`cd $SCRIPT_DIR && cd .. && pwd` -export BEETLE_CBSTORE_ROOT=$BEETLE_ROOT -export BEETLE_CBLOG_ROOT=$BEETLE_ROOT + +## Set BEETLE_SELF_ENDPOINT, to access Swagger API dashboard outside (Ex: export SELF_ENDPOINT=x.x.x.x:8056) +export BEETLE_SELF_ENDPOINT=localhost:8056 ## Set API access config # BEETLE_API_ALLOW_ORIGINS (ex: https://cloud-barista.org,http://localhost:8080 or * for all) @@ -13,24 +14,13 @@ export BEETLE_API_AUTH_ENABLED=true export BEETLE_API_USERNAME=default export BEETLE_API_PASSWORD=default -## Set BEETLE_SELF_ENDPOINT, to access Swagger API dashboard outside (Ex: export SELF_ENDPOINT=x.x.x.x:8056) -export BEETLE_SELF_ENDPOINT=localhost:8056 - -## Set API access config -export BEETLE_TUMBLEBUG_ENDPOINT=http://localhost:1323 -export BEETLE_TUMBLEBUG_API_USERNAME=default -export BEETLE_TUMBLEBUG_API_PASSWORD=default - -## Set internal DB config (SQLlite) -export BEETLE_SQLITE_URL=localhost:3306 -export BEETLE_SQLITE_DATABASE=cm_beetle -export BEETLE_SQLITE_USER=cm_beetle -export BEETLE_SQLITE_PASSWORD=cm_beetle +## Set internal DB config (lkvstore: local key-value store, default file path: ./db/beetle.db) +export BEETLE_LKVSTORE_PATH=db/beetle.db ## Logger configuration -# Set log file path (default logfile path: ./beetle.log) -export BEETLE_LOGFILE_PATH=beetle.log -export BEETLE_LOGFILE_MAXSIZE=100 +# Set log file path (default logfile path: ./log/beetle.log) +export BEETLE_LOGFILE_PATH=log/beetle.log +export BEETLE_LOGFILE_MAXSIZE=1000 export BEETLE_LOGFILE_MAXBACKUPS=3 export BEETLE_LOGFILE_MAXAGE=30 export BEETLE_LOGFILE_COMPRESS=false @@ -44,4 +34,7 @@ export BEETLE_NODE_ENV=development ## Set period for auto control goroutine invocation export BEETLE_AUTOCONTROL_DURATION_MS=10000 - +## Set Tumblebug access config +export BEETLE_TUMBLEBUG_ENDPOINT=http://localhost:1323 +export BEETLE_TUMBLEBUG_API_USERNAME=default +export BEETLE_TUMBLEBUG_API_PASSWORD=default \ No newline at end of file diff --git a/deployments/docker-compose/cb-tumblebug/conf/cloud_conf.yaml b/deployments/docker-compose/cb-tumblebug/conf/cloud_conf.yaml new file mode 100644 index 0000000..44e76c8 --- /dev/null +++ b/deployments/docker-compose/cb-tumblebug/conf/cloud_conf.yaml @@ -0,0 +1,96 @@ +cloud: + common: + enable: "y" + nlb: + enable: "y" + interval: "10" + timeout: "9" + threshold: "3" + k8scluster: + enable: "y" + aws: + enable: "y" + nlb: + enable: "y" + interval: "10" + timeout: "-1" + threshold: "3" + k8scluster: + enable: "n" + azure: + enable: "y" + nlb: + enable: "y" + interval: "10" + timeout: "9" + threshold: "3" + k8scluster: + enable: "y" + gcp: + enable: "y" + nlb: + enable: "y" + interval: "10" + timeout: "9" + threshold: "3" + k8scluster: + enable: "n" + alibaba: + enable: "y" + nlb: + enable: "y" + interval: "10" + timeout: "9" + threshold: "3" + k8scluster: + enable: "y" + tencent: + enable: "y" + nlb: + enable: "y" + interval: "10" + timeout: "9" + threshold: "3" + k8scluster: + enable: "y" + ibm: + enable: "y" + nlb: + enable: "y" + interval: "10" + timeout: "9" + threshold: "3" + k8scluster: + enable: "n" + nhncloud: + enable: "y" + k8scluster: + enable: "y" + openstack: + enable: "y" + nlb: + enable: "n" + interval: "10" + timeout: "9" + threshold: "3" + k8scluster: + enable: "n" + cloudit : + enable: "y" + nlb: + enable: "n" + interval: "10" + timeout: "9" + threshold: "3" + k8scluster: + enable: "n" +nlbsw: + sw: "HAProxy" + version: "latest" + commandNlbPrepare: "wget https://raw.githubusercontent.com/cloud-barista/cb-tumblebug/main/scripts/nlb/deployNlb.sh; wget https://raw.githubusercontent.com/cloud-barista/cb-tumblebug/main/scripts/nlb/addTargetNode.sh; wget https://raw.githubusercontent.com/cloud-barista/cb-tumblebug/main/scripts/nlb/applyConfig.sh; chmod +x ~/deployNlb.sh ~/addTargetNode.sh ~/applyConfig.sh" + commandNlbDeploy: "sudo ~/deployNlb.sh" + commandNlbAddTargetNode: "sudo ~/addTargetNode.sh" + commandNlbApplyConfig: "sudo ~/applyConfig.sh" + nlbMcisCommonSpec: "aws-ap-northeast-2-t2-small" + nlbMcisCommonImage: "ubuntu18.04" + nlbMcisSubGroupSize: "2" diff --git a/deployments/docker-compose/docker-compose.yaml b/deployments/docker-compose/docker-compose.yaml index 50022cf..870a4bb 100644 --- a/deployments/docker-compose/docker-compose.yaml +++ b/deployments/docker-compose/docker-compose.yaml @@ -1,15 +1,123 @@ +networks: + internal_network: + internal: true + external_network: + driver: bridge + services: - # etcd - etcd: + # cm-beetle + cm-beetle: + image: cloudbaristaorg/cm-beetle:0.2.0 + container_name: cm-beetle + pull_policy: missing + build: + context: ${COMPOSE_PROJECT_ROOT} + dockerfile: Dockerfile + platform: linux/amd64 + networks: + - internal_network + - external_network + ports: + - target: 8056 + published: 8056 + protocol: tcp + depends_on: + - cb-tumblebug + volumes: + - ${COMPOSE_PROJECT_ROOT}/container-volume/cm-beetle-container/log/:/app/log/ + - ${COMPOSE_PROJECT_ROOT}/container-volume/cm-beetle-container/db/:/app/db/ + environment: + # - BEETLE_ROOT=/app + - BEETLE_SELF_ENDPOINT=localhost:8056 + # - BEETLE_API_ALLOW_ORIGINS=* + # - BEETLE_API_AUTH_ENABLED=true + # - BEETLE_API_USERNAME=default + # - BEETLE_API_PASSWORD=default + # - BEETLE_LKVSTORE_PATH=/app/db/beetle.db + # - BEETLE_LOGFILE_PATH=/app/log/beetle.log + # - BEETLE_LOGFILE_MAXSIZE=1000 + # - BEETLE_LOGFILE_MAXBACKUPS=3 + # - BEETLE_LOGFILE_MAXAGE=30 + # - BEETLE_LOGFILE_COMPRESS=false + - BEETLE_LOGLEVEL=debug + # - BEETLE_LOGWRITER=both + - BEETLE_NODE_ENV=development + # - BEETLE_AUTOCONTROL_DURATION_MS=10000 + - BEETLE_TUMBLEBUG_ENDPOINT=http://cb-tumblebug:1323 + # - BEETLE_TUMBLEBUG_API_USERNAME=default + # - BEETLE_TUMBLEBUG_API_PASSWORD=default + healthcheck: # for CM-Beetle + test: [ "CMD", "curl", "-f", "http://localhost:8056/beetle/readyz" ] + interval: 1m + timeout: 5s + retries: 3 + start_period: 10s + + # CB-Tumblebug + cb-tumblebug: + image: cloudbaristaorg/cb-tumblebug:0.9.10 + container_name: cb-tumblebug + # build: + # context: . + # dockerfile: Dockerfile + platform: linux/amd64 + networks: + - internal_network + - external_network + ports: + - 1323:1323 + depends_on: + - cb-tumblebug-etcd + # - cb-tumblebug-etcd-conf + - cb-spider + volumes: + - ./cb-tumblebug/conf/:/app/conf/ + - ${COMPOSE_PROJECT_ROOT}/container-volume/cb-tumblebug-container/meta_db/:/app/meta_db/ + - ${COMPOSE_PROJECT_ROOT}/container-volume/cb-tumblebug-container/log/:/app/log/ + environment: + # - TB_ROOT_PATH=/app + - TB_SPIDER_REST_URL=http://cb-spider:1024/spider + - TB_ETCD_ENDPOINTS=http://cb-tumblebug-etcd:2379 + # - TB_ETCD_AUTH_ENABLED=true + # - TB_ETCD_USERNAME=default + # - TB_ETCD_PASSWORD=default + # - TB_SQLITE_URL=localhost:3306 + # - TB_SQLITE_DATABASE=cb_tumblebug + # - TB_SQLITE_USER=cb_tumblebug + # - TB_SQLITE_PASSWORD=cb_tumblebug + # - TB_ALLOW_ORIGINS=* + # - TB_AUTH_ENABLED=true + # - TB_API_USERNAME=default + # - TB_API_PASSWORD=default + # - TB_AUTOCONTROL_DURATION_MS=10000 + # - TB_SELF_ENDPOINT=localhost:1323 + # - TB_DRAGONFLY_REST_URL=http://cb-dragonfly:9090/dragonfly + # - TB_DEFAULT_NAMESPACE=default + # - TB_DEFAULT_CREDENTIALHOLDER=admin + # - TB_LOGFILE_PATH=/app/log/tumblebug.log + # - TB_LOGFILE_MAXSIZE=1000 + # - TB_LOGFILE_MAXBACKUPS=3 + # - TB_LOGFILE_MAXAGE=30 + # - TB_LOGFILE_COMPRESS=false + # - TB_LOGLEVEL=debug + # - TB_LOGWRITER=both + # - TB_NODE_ENV=development + healthcheck: # for CB-Tumblebug + test: [ "CMD", "curl", "-f", "http://localhost:1323/tumblebug/readyz" ] + interval: 1m + timeout: 5s + retries: 3 + start_period: 10s + + # cb-tumblebug-etcd + cb-tumblebug-etcd: image: gcr.io/etcd-development/etcd:v3.5.14 - container_name: etcd + container_name: cb-tumblebug-etcd + networks: + - internal_network ports: - - target: 2379 # Port assinged to etcd in the container - published: 2379 # Port to be exposed to the host - protocol: tcp # Protocol of the port - - target: 2380 # Port assinged to etcd in the container - published: 2380 # Port to be exposed to the host - protocol: tcp # Protocol of the port + - 2379:2379 + - 2380:2380 volumes: - ${COMPOSE_PROJECT_ROOT}/container-volume/etcd/data:/etcd-data entrypoint: /usr/local/bin/etcd @@ -47,43 +155,22 @@ services: retries: 3 start_period: 10s - # etcd-conf - etcd-conf: - image: alpine:latest - container_name: etcd-conf - depends_on: - - etcd - volumes: - - ./etcd/:/scripts/etcd/ - environment: - - ETCD_VERSION_TAG=v3.5.14 - - ETCD_ENDPOINTS=http://etcd:2379 - - ETCD_PATH=/tmp/etcd-download-test - - ETCD_AUTH_ENABLED=true - - ETCD_ROOT_PASSWORD=default - - ETCD_ADMIN_USERNAME=default - - ETCD_ADMIN_PASSWORD=default - command: sh -c "sh /scripts/etcd/etcd-conf.sh" - healthcheck: # for etcd-conf - test: ["CMD", "test", "-f", "/tmp/healthcheck"] - interval: 30s - timeout: 10s - retries: 3 - start_period: 10s - # CB-Spider cb-spider: - # image: cloudbaristaorg/cb-spider:0.9.0 - image: cloudbaristaorg/cb-spider:edge + image: cloudbaristaorg/cb-spider:0.9.3 container_name: cb-spider + # build: + # context: ../cb-spider + # dockerfile: Dockerfile platform: linux/amd64 + networks: + - internal_network + - external_network # for outbound access (not ideal for security) + # expose: + # - 1024 ports: - - target: 1024 - published: 1024 - protocol: tcp + - 1024:1024 volumes: - # - ./conf/log_conf.yaml:/root/go/src/github.com/cloud-barista/cb-spider/conf/log_conf.yaml - # - ./conf/store_conf.yaml:/root/go/src/github.com/cloud-barista/cb-spider/conf/store_conf.yaml - ${COMPOSE_PROJECT_ROOT}/container-volume/cb-spider-container/meta_db/:/root/go/src/github.com/cloud-barista/cb-spider/meta_db/ - ${COMPOSE_PROJECT_ROOT}/container-volume/cb-spider-container/log/:/root/go/src/github.com/cloud-barista/cb-spider/log/ environment: @@ -94,7 +181,7 @@ services: # - API_PASSWORD= - SPIDER_LOG_LEVEL=error - SPIDER_HISCALL_LOG_LEVEL=error - - ID_TRANSFORM_MODE=ON + - ID_TRANSFORM_MODE=OFF healthcheck: # for CB-Spider test: [ "CMD", "curl", "-f", "http://localhost:1024/spider/readyz" ] interval: 1m @@ -102,117 +189,22 @@ services: retries: 3 start_period: 10s - # CB-Tumblebug - cb-tumblebug: - image: cloudbaristaorg/cb-tumblebug:0.9.6 - container_name: cb-tumblebug - platform: linux/amd64 - ports: - - target: 1323 - published: 1323 - protocol: tcp - depends_on: - - cb-spider - - etcd-conf - volumes: - # - ./conf/:/app/conf/ - - ${COMPOSE_PROJECT_ROOT}/container-volume/cb-tumblebug-container/meta_db/:/app/meta_db/ - - ${COMPOSE_PROJECT_ROOT}/container-volume/cb-tumblebug-container/log/:/app/log/ - environment: - # - TB_ROOT_PATH=/app - - TB_SPIDER_REST_URL=http://cb-spider:1024/spider - - TB_DRAGONFLY_REST_URL=http://cb-dragonfly:9090/dragonfly - # - TB_SQLITE_URL=localhost:3306 - # - TB_SQLITE_DATABASE=cb_tumblebug - # - TB_SQLITE_USER=cb_tumblebug - # - TB_SQLITE_PASSWORD=cb_tumblebug - - TB_ETCD_ENDPOINTS=http://etcd:2379 - # - TB_ETCD_AUTH_ENABLED=true - # - TB_ETCD_USERNAME=default - # - TB_ETCD_PASSWORD=default - # - TB_ALLOW_ORIGINS=* - # - TB_AUTH_ENABLED=true - # - TB_API_USERNAME=default - # - TB_API_PASSWORD=default - # - TB_AUTOCONTROL_DURATION_MS=10000 - - TB_SELF_ENDPOINT=localhost:1323 - # - TB_DEFAULT_NAMESPACE=ns01 - # - TB_DEFAULT_CREDENTIALHOLDER=admin - # - TB_LOGFILE_PATH=/app/log/tumblebug.log - - TB_LOGFILE_MAXSIZE=1000 - # - TB_LOGFILE_MAXBACKUPS=3 - # - TB_LOGFILE_MAXAGE=30 - # - TB_LOGFILE_COMPRESS=false - # - TB_LOGLEVEL=debug - # - TB_LOGWRITER=both - # - TB_NODE_ENV=development - healthcheck: # for CB-Tumblebug - test: [ "CMD", "curl", "-f", "http://localhost:1323/tumblebug/readyz" ] - interval: 1m - timeout: 5s - retries: 3 - start_period: 10s - - # cm-beetle - cm-beetle: - image: cloudbaristaorg/cm-beetle:0.2.0 - pull_policy: missing - build: - context: ${COMPOSE_PROJECT_ROOT} - dockerfile: Dockerfile - container_name: cm-beetle - ports: - - target: 8056 - published: 8056 - protocol: tcp - depends_on: - - cb-tumblebug - volumes: - - ${COMPOSE_PROJECT_ROOT}/conf/:/app/conf/ - - ${COMPOSE_PROJECT_ROOT}/container-volume/cm-beetle-container/log/:/app/log/ - environment: - # - BEETLE_ROOT=/app - # - BEETLE_CBSTORE_ROOT=/app - # - BEETLE_CBLOG_ROOT=/app - - BEETLE_TUMBLEBUG_ENDPOINT=http://cb-tumblebug:1323 - # - BEETLE_LOGFILE_PATH=/app/log/beetle.log - # - BEETLE_LOGFILE_MAXSIZE=1000 - # - BEETLE_LOGFILE_MAXBACKUPS=3 - # - BEETLE_LOGFILE_MAXAGE=30 - # - BEETLE_LOGFILE_COMPRESS=false - - BEETLE_LOGLEVEL=debug - # - BEETLE_LOGWRITER=both - - BEETLE_NODE_ENV=development - # - BEETLE_SQLITE_URL=localhost:3306 - # - BEETLE_SQLITE_DATABASE=cm_beetle - # - BEETLE_SQLITE_USER=cm_beetle - # - BEETLE_SQLITE_PASSWORD=cm_beetle - # - BEETLE_API_ALLOW_ORIGINS=* - # - BEETLE_API_AUTH_ENABLED=true - # - BEETLE_API_USERNAME=default - # - BEETLE_API_PASSWORD=default - # - BEETLE_AUTOCONTROL_DURATION_MS=10000 - - BEETLE_SELF_ENDPOINT=localhost:8056 - healthcheck: # for CM-Beetle - test: [ "CMD", "curl", "-f", "http://localhost:8056/beetle/readyz" ] - interval: 1m - timeout: 5s - retries: 3 - start_period: 10s - - # cb-mapui (optionally use) + # cb-mapui cb-mapui: - image: cloudbaristaorg/cb-mapui:0.9.3 + image: cloudbaristaorg/cb-mapui:0.9.4 container_name: cb-mapui + # build: + # context: ../cb-mapui + # dockerfile: Dockerfile + networks: + - external_network ports: - target: 1324 published: 1324 protocol: tcp - # depends_on: - # - cb-tumblebug healthcheck: # for cb-mapui test: ["CMD", "nc", "-vz", "localhost", "1324"] interval: 1m timeout: 5s retries: 3 - start_period: 10s \ No newline at end of file + start_period: 10s diff --git a/go.mod b/go.mod index eae9094..c59f60c 100644 --- a/go.mod +++ b/go.mod @@ -3,8 +3,7 @@ module github.com/cloud-barista/cm-beetle go 1.23.0 require ( - github.com/cloud-barista/cb-store v0.8.2 - github.com/cloud-barista/cb-tumblebug v0.9.6 + github.com/cloud-barista/cb-tumblebug v0.9.10 github.com/cloud-barista/cm-honeybee/agent v0.0.0-20240704080504-526db6b80b90 github.com/fsnotify/fsnotify v1.7.0 github.com/go-playground/validator/v10 v10.22.0 @@ -13,7 +12,6 @@ require ( github.com/mattn/go-sqlite3 v1.14.22 github.com/rs/xid v1.5.0 github.com/rs/zerolog v1.33.0 - github.com/sirupsen/logrus v1.9.3 github.com/spf13/viper v1.19.0 github.com/swaggo/echo-swagger v1.4.1 github.com/swaggo/swag v1.16.3 @@ -25,8 +23,6 @@ require ( require ( filippo.io/edwards25519 v1.1.0 // indirect github.com/KyleBanks/depth v1.2.1 // indirect - github.com/coreos/go-semver v0.3.1 // indirect - github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/gabriel-vasile/mimetype v1.4.4 // indirect github.com/ghodss/yaml v1.0.0 // indirect github.com/go-openapi/jsonpointer v0.21.0 // indirect @@ -37,12 +33,9 @@ require ( github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-sql-driver/mysql v1.8.1 // indirect github.com/goccy/go-json v0.10.3 // indirect - github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-jwt/jwt v3.2.2+incompatible // indirect - github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/hashicorp/hcl v1.0.0 // indirect - github.com/jedib0t/go-pretty/v6 v6.5.9 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/labstack/gommon v0.4.2 // indirect @@ -51,12 +44,10 @@ require ( github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mattn/go-runewidth v0.0.15 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/pelletier/go-toml/v2 v2.2.2 // indirect - github.com/rivo/uniseg v0.4.7 // indirect github.com/sagikazarmark/locafero v0.6.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/sourcegraph/conc v0.3.0 // indirect @@ -66,17 +57,9 @@ require ( github.com/subosito/gotenv v1.6.0 // indirect github.com/swaggo/files/v2 v2.0.1 // indirect github.com/syndtr/goleveldb v1.0.0 // indirect - github.com/tidwall/gjson v1.17.1 // indirect - github.com/tidwall/match v1.1.1 // indirect - github.com/tidwall/pretty v1.2.1 // indirect - github.com/tidwall/sjson v1.2.5 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasttemplate v1.2.2 // indirect - go.etcd.io/etcd/api/v3 v3.5.14 // indirect - go.etcd.io/etcd/client/pkg/v3 v3.5.14 // indirect - go.etcd.io/etcd/client/v3 v3.5.14 // indirect go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.27.0 // indirect golang.org/x/crypto v0.25.0 // indirect golang.org/x/exp v0.0.0-20240716175740-e3f259677ff7 // indirect golang.org/x/net v0.27.0 // indirect @@ -84,10 +67,6 @@ require ( golang.org/x/text v0.16.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.23.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d // indirect - google.golang.org/grpc v1.65.0 // indirect - google.golang.org/protobuf v1.34.2 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect modernc.org/gc/v3 v3.0.0-20240304020402-f0dba7c97c2b // indirect diff --git a/go.sum b/go.sum index 88c9113..a5c3c15 100644 --- a/go.sum +++ b/go.sum @@ -4,15 +4,10 @@ gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGq gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU= github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc= github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= -github.com/cloud-barista/cb-store v0.8.2 h1:7excW7SX0Xw9Xxo0xO4HkndjOYonh4z6mFzNqYN3XH4= -github.com/cloud-barista/cb-store v0.8.2/go.mod h1:GBTRuOApzMWSENFSgIPtrbWUKSwP30bn90gWE0ENUD8= -github.com/cloud-barista/cb-tumblebug v0.9.6 h1:x3nufIVLwYKFiHVbRu1j/Tmtd9gd2Do0DgaOF31JLYI= -github.com/cloud-barista/cb-tumblebug v0.9.6/go.mod h1:3Uxg4eHCfrJZNgfu5MarXzALmR3JgB8fhdL7q3lJSz4= +github.com/cloud-barista/cb-tumblebug v0.9.10 h1:mnXLczjwi6FMwmrZ0n1LMdvFfDFKbz9MJp3jHDJ78Zk= +github.com/cloud-barista/cb-tumblebug v0.9.10/go.mod h1:uXi+JmmdU+cqcIqpMgfomzZNbNdrLQ+WZgK9ZlOGjY0= github.com/cloud-barista/cm-honeybee/agent v0.0.0-20240704080504-526db6b80b90 h1:qGFG4sMqwKw06Y0ZzK4L2Bm6M/WHNnLQGZ3r6qUAhR8= github.com/cloud-barista/cm-honeybee/agent v0.0.0-20240704080504-526db6b80b90/go.mod h1:+h6UB1Z2qrpfizIillcppLuh8zRlmjLSpkl63XGi1Wc= -github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4= -github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec= -github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -52,13 +47,9 @@ github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqw github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= -github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= @@ -74,14 +65,10 @@ github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/jedib0t/go-pretty/v6 v6.5.9 h1:ACteMBRrrmm1gMsXe9PSTOClQ63IXDUt03H5U+UV8OU= -github.com/jedib0t/go-pretty/v6 v6.5.9/go.mod h1:zbn98qrYlh95FIhwwsbIip0LYpwSG8SUOScs+v9/t0E= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -102,8 +89,6 @@ github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/ github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= -github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= @@ -128,9 +113,6 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= -github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= -github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc= @@ -141,8 +123,6 @@ github.com/sagikazarmark/locafero v0.6.0 h1:ON7AQg37yzcRPU69mt7gwhFEBwxI6P9T4Qu3 github.com/sagikazarmark/locafero v0.6.0/go.mod h1:77OmuIc6VTraTXKXIs/uvUxKGUXjE1GbemJYHqdNjX0= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= -github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= -github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= @@ -158,7 +138,6 @@ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSS github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= @@ -174,38 +153,14 @@ github.com/swaggo/swag v1.16.3 h1:PnCYjPCah8FK4I26l2F/KQ4yz3sILcVUN3cTlBFA9Pg= github.com/swaggo/swag v1.16.3/go.mod h1:DImHIuOFXKpMFAQjcC7FG4m3Dg4+QuUgUzJmKjI/gRk= github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= -github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= -github.com/tidwall/gjson v1.17.1 h1:wlYEnwqAHgzmhNUFfw7Xalt2JzQvsMx2Se4PcoFCT/U= -github.com/tidwall/gjson v1.17.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= -github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= -github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= -github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= -github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= -github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= -github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= -github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -go.etcd.io/etcd/api/v3 v3.5.14 h1:vHObSCxyB9zlF60w7qzAdTcGaglbJOpSj1Xj9+WGxq0= -go.etcd.io/etcd/api/v3 v3.5.14/go.mod h1:BmtWcRlQvwa1h3G2jvKYwIQy4PkHlDej5t7uLMUdJUU= -go.etcd.io/etcd/client/pkg/v3 v3.5.14 h1:SaNH6Y+rVEdxfpA2Jr5wkEvN6Zykme5+YnbCkxvuWxQ= -go.etcd.io/etcd/client/pkg/v3 v3.5.14/go.mod h1:8uMgAokyG1czCtIdsq+AGyYQMvpIKnSvPjFMunkgeZI= -go.etcd.io/etcd/client/v3 v3.5.14 h1:CWfRs4FDaDoSz81giL7zPpZH2Z35tbOrAJkkjMqOupg= -go.etcd.io/etcd/client/v3 v3.5.14/go.mod h1:k3XfdV/VIHy/97rqWjoUzrj9tk7GgJGH9J8L4dNXmAk= -go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= -go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= -go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= @@ -213,17 +168,12 @@ golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= golang.org/x/exp v0.0.0-20240716175740-e3f259677ff7 h1:wDLEX9a7YQoKdKNQt88rtydkqDxeGaBUTnIYc3iG/mA= golang.org/x/exp v0.0.0-20240716175740-e3f259677ff7/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= @@ -234,20 +184,15 @@ golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -264,8 +209,6 @@ golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= -golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= -golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= @@ -279,24 +222,11 @@ golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d h1:kHjw/5UfflP/L5EbledDrcG4C2597RtymmGRZvHiCuY= -google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d/go.mod h1:mw8MG/Qz5wfgYr6VqVCiZcHe/GJEfI+oGGDCohaVgB0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d h1:JU0iKnSg02Gmb5ZdV8nYsKEKsP6o/FGVWTrw4i1DA9A= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= -google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= -google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/go.work.sum b/go.work.sum index f254663..4048011 100644 --- a/go.work.sum +++ b/go.work.sum @@ -310,10 +310,13 @@ github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= github.com/coreos/go-iptables v0.7.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q= +github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4= +github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec= github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f h1:JOrtw2xFKzlg+cbHpyrpLDmnN1HqhBfnX7WDiW7eG2c= github.com/coreos/go-systemd/v22 v22.0.0 h1:XJIw/+VlJ+87J+doOxznsAWIdmWuViOVhkQamW5YV28= github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= github.com/coreos/go-systemd/v22 v22.3.2 h1:D9/bQk5vlXQFZ6Kwuu6zaiXJ9oTPe68++AzAJc1DzSI= +github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/digitalocean/go-libvirt v0.0.0-20221205150000-2939327a8519/go.mod h1:WyJJyfmJ0gWJvjV+ZH4DOgtOYZc1KOvYyBXWCLKxsUU= @@ -349,6 +352,8 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= github.com/go-ping/ping v1.1.0/go.mod h1:xIFjORFzTxqIV/tDVGO4eDy/bLuSyawEeojSm3GfRGk= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= @@ -357,6 +362,8 @@ github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= github.com/golang/glog v1.2.1/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/pprof v0.0.0-20211214055906-6f57359322fd/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg= github.com/google/pprof v0.0.0-20230323073829-e72429f035bd/go.mod h1:79YE0hCXdHag9sBkw2o+N/YnZtTkXi0UT9Nnixa5eYk= github.com/google/s2a-go v0.1.3/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= @@ -395,6 +402,8 @@ github.com/jackc/pgtype v1.14.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76 github.com/jackc/pgx/v4 v4.18.0/go.mod h1:FydWkUyadDmdNH/mHnGob881GawxeEm7TcMCzkb+qQE= github.com/jaypipes/ghw v0.12.0/go.mod h1:jeJGbkRB2lL3/gxYzNYzEDETV1ZJ56OKr+CSeSEym+g= github.com/jaypipes/pcidb v1.0.0/go.mod h1:TnYUvqhPBzCKnH34KrIX22kAeEbDCSRJ9cqLRCuNDfk= +github.com/jedib0t/go-pretty/v6 v6.5.6 h1:nKXVLqPfAwY7sWcYXdNZZZ2fjqDpAtj9UeWupgfUxSg= +github.com/jedib0t/go-pretty/v6 v6.5.6/go.mod h1:5LQIxa52oJ/DlDSLv0HEkWOFMDGoWkJb9ss5KqPpJBg= github.com/jollaman999/utils v1.0.10/go.mod h1:fb4x+o0k105MFIBBaNRN+tat7F3RbkolnURccQd3UEA= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/klauspost/compress v1.17.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= @@ -418,6 +427,8 @@ github.com/libvirt/libvirt-go-xml v7.4.0+incompatible/go.mod h1:oBlgD3xOA01ihiK5 github.com/lufia/plan9stats v0.0.0-20231016141302-07b5767bb0ed/go.mod h1:ilwx/Dta8jXAgpFYFvSWEMwxmbWXyiUHkd5FwyKhb5k= github.com/lufia/plan9stats v0.0.0-20240513124658-fba389f38bae/go.mod h1:ilwx/Dta8jXAgpFYFvSWEMwxmbWXyiUHkd5FwyKhb5k= github.com/m-cmp/mc-iam-manager v0.2.7/go.mod h1:ES5A3mw32SIfHMzUodo6R6D+c3p+EYzP3ga11Fi6KE8= +github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= +github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/microsoft/go-mssqldb v1.6.0/go.mod h1:00mDtPbeQCRGC1HwOOR5K/gr30P1NcEG0vx6Kbv2aJU= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= @@ -451,6 +462,8 @@ github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqr github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sagikazarmark/crypt v0.10.0/go.mod h1:gwTNHQVoOS3xp9Xvz5LLR+1AauC5M6880z5NWzdhOyQ= @@ -472,6 +485,14 @@ github.com/swaggo/files v0.0.0-20220728132757-551d4a08d97a h1:kAe4YSu0O0UFn1DowN github.com/swaggo/files v0.0.0-20220728132757-551d4a08d97a/go.mod h1:lKJPbtWzJ9JhsTN1k1gZgleJWY/cqq0psdoMmaThG3w= github.com/taigrr/systemctl v1.0.6/go.mod h1:TpeHkNuHgYT63FI5jVLBf5VNAGbxEFH3FHqg5ReXnd0= github.com/tidwall/gjson v1.17.0 h1:/Jocvlh98kcTfpN2+JzGQWQcqrPQwDrVEMApx/M5ZwM= +github.com/tidwall/gjson v1.17.1 h1:wlYEnwqAHgzmhNUFfw7Xalt2JzQvsMx2Se4PcoFCT/U= +github.com/tidwall/gjson v1.17.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= +github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= +github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= +github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/tklauser/go-sysconf v0.3.13/go.mod h1:zwleP4Q4OehZHGn4CYZDipCgg9usW5IJePewFCGVEa0= github.com/tklauser/go-sysconf v0.3.14/go.mod h1:1ym4lWMLUOhuBOPGtRcJm7tEGX4SCYNEEEtghGG/8uY= github.com/tklauser/numcpus v0.7.0/go.mod h1:bb6dMVcj8A42tSE7i32fsIUCbQNllK5iDguyOZRUzAY= @@ -491,9 +512,12 @@ github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQ github.com/zcalusic/sysinfo v1.0.2/go.mod h1:kluzTYflRWo6/tXVMJPdEjShsbPpsFRyy+p1mBQPC30= github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738 h1:VcrIfasaLFkyjk6KNlXQSzO+B0fZcnECiDrKJsfxka0= +go.etcd.io/etcd/api/v3 v3.5.12/go.mod h1:Ot+o0SWSyT6uHhA56al1oCED0JImsRiU9Dc26+C2a+4= +go.etcd.io/etcd/client/pkg/v3 v3.5.12/go.mod h1:seTzl2d9APP8R5Y2hFL3NVlD6qC/dOT+3kvrqPyTas4= go.etcd.io/etcd/client/v2 v2.305.7/go.mod h1:GQGT5Z3TBuAQGvgPfhR7VPySu/SudxmEkRq9BgzFU6s= go.etcd.io/etcd/client/v2 v2.305.10/go.mod h1:m3CKZi69HzilhVqtPDcjhSGp+kA1OmbNn0qamH80xjA= go.etcd.io/etcd/client/v2 v2.305.12/go.mod h1:aQ/yhsxMu+Oht1FOupSr60oBvcS9cKXHrzBpDsPTf9E= +go.etcd.io/etcd/client/v3 v3.5.12/go.mod h1:tSbBCakoWmmddL+BKVAJHa9km+O/E+bumDe9mSbPiqw= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0/go.mod h1:Mjt1i1INqiaoZOMGR1RIUJN+i3ChKoFRqzrRQhlkbs0= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0/go.mod h1:vy+2G/6NvVMpwGX/NyLqcC41fxepnuKHk16E6IZUcJc= @@ -506,8 +530,11 @@ go.opentelemetry.io/otel/metric v1.27.0/go.mod h1:mVFgmRlhljgBiuk/MP/oKylr4hs85G go.opentelemetry.io/otel/sdk v1.22.0/go.mod h1:iu7luyVGYovrRpe2fmj3CVKouQNdTOkxtLzPvPz1DOc= go.opentelemetry.io/otel/trace v1.26.0/go.mod h1:4iDxvGDQuUkHve82hJJ8UqrwswHYsZuWCBllGV2U2y0= go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4= +go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= +go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= +go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= @@ -515,6 +542,7 @@ golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4= golang.org/x/oauth2 v0.15.0/go.mod h1:q48ptWNTY5XWf+JNten23lcvHpLJ0ZSxF5ttTHKVCAM= +golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8= golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -529,6 +557,8 @@ golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= +golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= +golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= google.golang.org/api v0.122.0/go.mod h1:gcitW0lvnyWjSp9nKxAbdHKIZ6vF4aajGueeslZOyms= @@ -538,6 +568,11 @@ google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCID google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 h1:9+tzLLstTlPTRyJTh+ah5wIMsBW5c4tQwGTN3thOW9Y= google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9/go.mod h1:mqHbVIp48Muh7Ywss/AD6I5kNVKZMmAa/QEW58Gxp2s= +google.golang.org/genproto/googleapis/api v0.0.0-20240311132316-a219d84964c2/go.mod h1:O1cOfN1Cy6QEYr7VxtjOyP5AdAuR0aJ/MYZaaof623Y= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240314234333-6e1732d8331c/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= +google.golang.org/grpc v1.62.1/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/pkg/api/rest/controller/migration.go b/pkg/api/rest/controller/migration.go index 27feba3..6238b12 100644 --- a/pkg/api/rest/controller/migration.go +++ b/pkg/api/rest/controller/migration.go @@ -20,7 +20,7 @@ import ( model "github.com/cloud-barista/cm-beetle/pkg/api/rest/model/beetle" // cloudmodel "github.com/cloud-barista/cm-beetle/pkg/api/rest/model/cloud/infra" - "github.com/cloud-barista/cb-tumblebug/src/core/mci" + tbmodel "github.com/cloud-barista/cb-tumblebug/src/core/model" "github.com/cloud-barista/cm-beetle/pkg/core/migration" "github.com/labstack/echo/v4" @@ -32,11 +32,11 @@ type MigrateInfraRequest struct { // [NOTE] Failed to embed the struct in CB-Tumblebug as follows: // mci.TbMciDynamicReq - mci.TbMciDynamicReq + tbmodel.TbMciDynamicReq } type MigrateInfraResponse struct { - mci.TbMciDynamicReq + tbmodel.TbMciDynamicReq } // MigrateInfra godoc diff --git a/pkg/api/rest/controller/recommendation.go b/pkg/api/rest/controller/recommendation.go index 6e5df6d..2605b66 100644 --- a/pkg/api/rest/controller/recommendation.go +++ b/pkg/api/rest/controller/recommendation.go @@ -19,7 +19,7 @@ import ( // cloudmodel "github.com/cloud-barista/cm-beetle/pkg/api/rest/model/cloud/infra" // "github.com/cloud-barista/cm-beetle/pkg/api/rest/model/onprem/infra" - "github.com/cloud-barista/cb-tumblebug/src/core/mci" + "github.com/cloud-barista/cm-honeybee/agent/pkg/api/rest/model/onprem/infra" "github.com/cloud-barista/cm-beetle/pkg/core/common" @@ -42,7 +42,7 @@ type RecommendInfraRequest struct { } type RecommendInfraResponse struct { - mci.TbMciDynamicReq + recommendation.RecommendedInfraInfo } // RecommendInfra godoc @@ -70,8 +70,8 @@ func RecommendInfra(c echo.Context) error { log.Trace().Msgf("req: %v\n", req) // Process - recommendedInfra, err := recommendation.Recommend(req.Servers) - recommendedInfra.Name = "mmci01" + recommendedInfraInfo, err := recommendation.Recommend(req.Servers) + recommendedInfraInfo.TargetInfra.Name = "mmci01" // Ouput if err != nil { @@ -80,5 +80,5 @@ func RecommendInfra(c echo.Context) error { return c.JSON(http.StatusNotFound, res) } - return c.JSON(http.StatusOK, recommendedInfra) + return c.JSON(http.StatusOK, recommendedInfraInfo) } diff --git a/pkg/api/rest/server.go b/pkg/api/rest/server.go index 4c93841..074c348 100644 --- a/pkg/api/rest/server.go +++ b/pkg/api/rest/server.go @@ -27,8 +27,8 @@ import ( rest_common "github.com/cloud-barista/cm-beetle/pkg/api/rest/common" "github.com/cloud-barista/cm-beetle/pkg/api/rest/controller" "github.com/cloud-barista/cm-beetle/pkg/api/rest/middlewares" + "github.com/cloud-barista/cm-beetle/pkg/config" "github.com/cloud-barista/cm-beetle/pkg/core/common" - "github.com/spf13/viper" "crypto/subtle" "fmt" @@ -106,9 +106,9 @@ func RunServer(port string) { e.HideBanner = true //e.colorer.Printf(banner, e.colorer.Red("v"+Version), e.colorer.Blue(website)) - allowedOrigins := viper.GetString("beetle.api.allow.origins") + allowedOrigins := config.Beetle.API.Allow.Origins if allowedOrigins == "" { - log.Fatal().Msg("allow_ORIGINS env variable for CORS is " + allowedOrigins + + log.Fatal().Msg("ALLOW_ORIGINS env variable for CORS is " + allowedOrigins + ". Please provide a proper value and source setup.env again. EXITING...") } @@ -118,11 +118,10 @@ func RunServer(port string) { })) // Conditions to prevent abnormal operation due to typos (e.g., ture, falss, etc.) - enableAuth := viper.GetString("beetle.api.auth.enabled") == "true" - - apiUser := viper.GetString("beetle.api.username") - apiPass := viper.GetString("beetle.api.password") + enableAuth := config.Beetle.API.Auth.Enabled + apiUser := config.Beetle.API.Username + apiPass := config.Beetle.API.Password if enableAuth { e.Use(middleware.BasicAuthWithConfig(middleware.BasicAuthConfig{ // Skip authentication for some routes that do not require authentication @@ -130,7 +129,7 @@ func RunServer(port string) { if c.Path() == "/beetle/readyz" || c.Path() == "/beetle/httpVersion" || strings.HasPrefix(c.Path(), "/tumblebug") { - log.Debug().Msgf("Skip authentication for %s", c.Path()) + // log.Debug().Msgf("Skip authentication for %s", c.Path()) return true } return false @@ -157,7 +156,7 @@ func RunServer(port string) { gTumblebug := e.Group("/tumblebug") // Set the target server for the proxy - target := viper.GetString("beetle.tumblebug.endpoint") + target := config.Tumblebug.Endpoint url, err := url.Parse(target) if err != nil { e.Logger.Fatal(err) @@ -253,7 +252,7 @@ func RunServer(port string) { gSample.DELETE("/users/:id", controller.DeleteUser) // Start API server - selfEndpoint := viper.GetString("beetle.self.endpoint") + selfEndpoint := config.Beetle.Self.Endpoint apidashboard := " http://" + selfEndpoint + "/beetle/api" if enableAuth { diff --git a/pkg/config/README.md b/pkg/config/README.md index 2587e86..502cd3b 100644 --- a/pkg/config/README.md +++ b/pkg/config/README.md @@ -27,21 +27,30 @@ The below configurations are compatible in this project. #### How to use it -- Use a blank import in your package (e.g., main, logger, and so on) - Get a value using Viper Note - It's just my preference. `config.Init()` can be used. ```go +// Package main is the starting point of CM-Beetle +package main + import ( // other packages - // Loads configurations from setup.env and config.yaml - _ "github.com/cloud-barista/cm-beetle/pkg/config" + "github.com/cloud-barista/cm-beetle/pkg/config" ) +func init() { + + common.SystemReady = false + + // Initialize the configuration from "config.yaml" file or environment variables + config.Init() + +} + func main() { - logFilePath := viper.GetString("beetle.logfile.path") // Application logic follows } ``` diff --git a/pkg/config/config.go b/pkg/config/config.go index 68dcdcf..4b8d4e8 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -11,72 +11,143 @@ import ( "github.com/spf13/viper" ) +var ( + RuntimeConfig Config + Beetle BeetleConfig + Tumblebug TumblebugConfig +) + +type Config struct { + Beetle BeetleConfig `mapstructure:"beetle"` +} + +type BeetleConfig struct { + Root string `mapstructure:"root"` + Self SelfConfig `mapstructure:"self"` + API ApiConfig `mapstructure:"api"` + LKVStore LkvStoreConfig `mapstructure:"lkvstore"` + LogFile LogfileConfig `mapstructure:"logfile"` + LogLevel string `mapstructure:"loglevel"` + LogWriter string `mapstructure:"logwriter"` + Node NodeConfig `mapstructure:"node"` + AutoControl AutoControlConfig `mapstructure:"autocontrol"` + Tumblebug TumblebugConfig `mapstructure:"tumblebug"` +} + +type SelfConfig struct { + Endpoint string `mapstructure:"endpoint"` +} + +type ApiConfig struct { + Allow AllowConfig `mapstructure:"allow"` + Auth AuthConfig `mapstructure:"auth"` + Username string `mapstructure:"username"` + Password string `mapstructure:"password"` +} + +type AllowConfig struct { + Origins string `mapstructure:"origins"` +} +type AuthConfig struct { + Enabled bool `mapstructure:"enabled"` +} + +type LkvStoreConfig struct { + Path string `mapstructure:"path"` +} + +type LogfileConfig struct { + Path string `mapstructure:"path"` + MaxSize int `mapstructure:"maxsize"` + MaxBackups int `mapstructure:"maxbackups"` + MaxAge int `mapstructure:"maxage"` + Compress bool `mapstructure:"compress"` +} + +type NodeConfig struct { + Env string `mapstructure:"env"` +} + +type AutoControlConfig struct { + DurationMilliSec int `mapstructure:"duration_ms"` +} + +type TumblebugConfig struct { + Endpoint string `mapstructure:"endpoint"` + RestUrl string `mapstructure:"resturl"` + API TumblebugApiConfig `mapstructure:"api"` +} + +type TumblebugApiConfig struct { + Username string `mapstructure:"username"` + Password string `mapstructure:"password"` +} + func Init() { - viper.AddConfigPath("../../conf/") // config for development - viper.AddConfigPath(".") // config for production optionally looking for the configuration in the working directory - viper.AddConfigPath("./conf/") // config for production optionally looking for the configuration in the working directory/conf/ + viper.AddConfigPath("../../conf/") // for development + viper.AddConfigPath(".") // for production + viper.AddConfigPath("./conf/") // for production viper.SetConfigType("yaml") viper.SetConfigName("config") - // Load main configuration - viper.SetConfigName("config") err := viper.ReadInConfig() if err != nil { - fmt.Printf("no main config file, using default settings: %s\n", err) - log.Printf("no main config file, using default settings: %s", err) + log.Printf("No main config file, using default settings: %s", err) } - // Load secrets configuration - // viper.SetConfigName("secrets") - // err = viper.MergeInConfig() // Merge in the secrets config - // if err != nil { - // fmt.Printf("no reading secrets config file: %s\n", err) - // log.Fatalf("no reading secrets config file: %s", err) - // } + // Explicitly bind environment variables to configuration keys + bindEnvironmentVariables() - // Map environment variable names to config file key names replacer := strings.NewReplacer(".", "_") viper.SetEnvKeyReplacer(replacer) - - // NOTE - the environment variable has higher priority than the config file - // Automatically recognize environment variables viper.AutomaticEnv() - // Values set in runtime if viper.GetString("beetle.root") == "" { - fmt.Println("find project root by using project name") - log.Println("find project root by using project name") - - projectName := "cm-beetle" - // Get the executable path - execPath, err := os.Executable() - if err != nil { - fmt.Printf("Error getting executable path: %v\n", err) - log.Fatalf("Error getting executable path: %v", err) - } - execDir := filepath.Dir(execPath) - projectRoot, err := checkProjectRootInParentDirectory(projectName, execDir) - if err != nil { - fmt.Printf("set current directory as project root directory (%v)\n", err) - log.Printf("set current directory as project root directory (%v)", err) - projectRoot = execDir - } - fmt.Printf("project root directory: %s\n", projectRoot) - log.Printf("project root directory: %s\n", projectRoot) + log.Println("Finding project root by using project name") - // Set the binary path + projectRoot := findProjectRoot("cm-beetle") viper.Set("beetle.root", projectRoot) - viper.Set("beetle.cbstore.root", projectRoot) - viper.Set("beetle.cblog.root", projectRoot) } - // Recursively print all keys and values in Viper - settings := viper.AllSettings() - if viper.GetString("beetle.node.env") == "development" { + if err := viper.Unmarshal(&RuntimeConfig); err != nil { + log.Fatalf("Unable to decode into struct: %v", err) + } + Beetle = RuntimeConfig.Beetle + Beetle.Tumblebug.RestUrl = Beetle.Tumblebug.Endpoint + "/tumblebug" + Tumblebug = Beetle.Tumblebug + + // Print settings if in development mode + if Beetle.Node.Env == "development" { + settings := viper.AllSettings() recursivePrintMap(settings, "") } } +// NVL is func for null value logic +func NVL(str string, def string) string { + if len(str) == 0 { + return def + } + return str +} + +func findProjectRoot(projectName string) string { + execPath, err := os.Executable() + if err != nil { + log.Fatalf("Error getting executable path: %v", err) + } + execDir := filepath.Dir(execPath) + projectRoot, err := checkProjectRootInParentDirectory(projectName, execDir) + if err != nil { + fmt.Printf("Set current directory as project root directory (%v)\n", err) + log.Printf("Set current directory as project root directory (%v)", err) + projectRoot = execDir + } + fmt.Printf("Project root directory: %s\n", projectRoot) + log.Printf("Project root directory: %s\n", projectRoot) + return projectRoot +} + func checkProjectRootInParentDirectory(projectName string, execDir string) (string, error) { // Append a path separator to the project name for accurate matching @@ -105,3 +176,26 @@ func recursivePrintMap(m map[string]interface{}, prefix string) { } } } + +func bindEnvironmentVariables() { + // Explicitly bind environment variables to configuration keys + viper.BindEnv("beetle.root", "BEETLE_ROOT") + viper.BindEnv("beetle.self.endpoint", "BEETLE_SELF_ENDPOINT") + viper.BindEnv("beetle.api.allow.origins", "BEETLE_API_ALLOW_ORIGINS") + viper.BindEnv("beetle.api.auth.enabled", "BEETLE_API_AUTH_ENABLED") + viper.BindEnv("beetle.api.username", "BEETLE_API_USERNAME") + viper.BindEnv("beetle.api.password", "BEETLE_API_PASSWORD") + viper.BindEnv("beetle.lkvstore.path", "BEETLE_LKVSTORE_PATH") + viper.BindEnv("beetle.logfile.path", "BEETLE_LOGFILE_PATH") + viper.BindEnv("beetle.logfile.maxsize", "BEETLE_LOGFILE_MAXSIZE") + viper.BindEnv("beetle.logfile.maxbackups", "BEETLE_LOGFILE_MAXBACKUPS") + viper.BindEnv("beetle.logfile.maxage", "BEETLE_LOGFILE_MAXAGE") + viper.BindEnv("beetle.logfile.compress", "BEETLE_LOGFILE_COMPRESS") + viper.BindEnv("beetle.loglevel", "BEETLE_LOGLEVEL") + viper.BindEnv("beetle.logwriter", "BEETLE_LOGWRITER") + viper.BindEnv("beetle.node.env", "BEETLE_NODE_ENV") + viper.BindEnv("beetle.autocontrol.duration_ms", "BEETLE_AUTOCONTROL_DURATION_MS") + viper.BindEnv("beetle.tumblebug.endpoint", "BEETLE_TUMBLEBUG_ENDPOINT") + viper.BindEnv("beetle.tumblebug.api.username", "BEETLE_TUMBLEBUG_API_USERNAME") + viper.BindEnv("beetle.tumblebug.api.password", "BEETLE_TUMBLEBUG_API_PASSWORD") +} diff --git a/pkg/core/common/common.go b/pkg/core/common/common.go index 0aaf2c5..15b8441 100644 --- a/pkg/core/common/common.go +++ b/pkg/core/common/common.go @@ -18,11 +18,9 @@ import ( "database/sql" "fmt" - icbs "github.com/cloud-barista/cb-store/interfaces" + "github.com/cloud-barista/cm-beetle/pkg/config" "github.com/go-resty/resty/v2" "github.com/rs/zerolog/log" - "github.com/sirupsen/logrus" - "github.com/spf13/viper" "xorm.io/xorm" ) @@ -39,8 +37,8 @@ type IdList struct { var SystemReady bool // CB-Store -var CBLog *logrus.Logger -var CBStore icbs.Store +// var CBLog *logrus.Logger +// var CBStore icbs.Store // var SpiderRestUrl string // var DragonflyRestUrl string @@ -214,12 +212,12 @@ type RestGetAllNsResponse struct { func CreateNamespace(nsInfo NsReq) (NsInfo, error) { // Initialize resty client with basic auth client := resty.New() - apiUser := viper.GetString("beetle.tumblebug.api.username") - apiPass := viper.GetString("beetle.tumblebug.api.password") + apiUser := config.Tumblebug.API.Username + apiPass := config.Tumblebug.API.Password client.SetBasicAuth(apiUser, apiPass) - // set endpoint - epTumblebug := TumblebugRestUrl + // set API endpoint + epTumblebug := config.Tumblebug.RestUrl // create namespace method := "POST" @@ -250,12 +248,12 @@ func CreateNamespace(nsInfo NsReq) (NsInfo, error) { func GetAllNamespaces() (RestGetAllNsResponse, error) { // Initialize resty client with basic auth client := resty.New() - apiUser := viper.GetString("beetle.tumblebug.api.username") - apiPass := viper.GetString("beetle.tumblebug.api.password") + apiUser := config.Tumblebug.API.Username + apiPass := config.Tumblebug.API.Password client.SetBasicAuth(apiUser, apiPass) - // set endpoint - epTumblebug := TumblebugRestUrl + // set API endpoint + epTumblebug := config.Tumblebug.RestUrl // Get all namespaces method := "GET" @@ -286,12 +284,12 @@ func GetAllNamespaces() (RestGetAllNsResponse, error) { func GetNamespace(nsId string) (NsInfo, error) { // Initialize resty client with basic auth client := resty.New() - apiUser := viper.GetString("beetle.tumblebug.api.username") - apiPass := viper.GetString("beetle.tumblebug.api.password") + apiUser := config.Tumblebug.API.Username + apiPass := config.Tumblebug.API.Password client.SetBasicAuth(apiUser, apiPass) - // set endpoint - epTumblebug := TumblebugRestUrl + // set API endpoint + epTumblebug := config.Tumblebug.RestUrl // try to get namespace method := "GET" @@ -322,12 +320,12 @@ func GetNamespace(nsId string) (NsInfo, error) { func DeleteNamespace(nsId string) (SimpleMsg, error) { // Initialize resty client with basic auth client := resty.New() - apiUser := viper.GetString("beetle.tumblebug.api.username") - apiPass := viper.GetString("beetle.tumblebug.api.password") + apiUser := config.Tumblebug.API.Username + apiPass := config.Tumblebug.API.Password client.SetBasicAuth(apiUser, apiPass) - // set endpoint - epTumblebug := TumblebugRestUrl + // set API endpoint + epTumblebug := config.Tumblebug.RestUrl // delete namespace method := "DELETE" diff --git a/pkg/core/common/config.go b/pkg/core/common/config.go index 24253c3..ef9cf92 100644 --- a/pkg/core/common/config.go +++ b/pkg/core/common/config.go @@ -14,329 +14,232 @@ limitations under the License. // Package common is to include common methods for managing multi-cloud infra package common -import ( - "encoding/json" - "fmt" - "os" - "strings" - - cbstore_utils "github.com/cloud-barista/cb-store/utils" -) - -// CloudInfo is structure for cloud information -type CloudInfo struct { - CSPs map[string]CSPDetail `mapstructure:"cloud" json:"csps"` -} - -// CSPDetail is structure for CSP information -type CSPDetail struct { - Description string `mapstructure:"description" json:"description"` - Driver string `mapstructure:"driver" json:"driver"` - Links []string `mapstructure:"link" json:"links"` - Regions map[string]RegionDetail `mapstructure:"region" json:"regions"` -} - -// RegionDetail is structure for region information -type RegionDetail struct { - RegionId string `mapstructure:"id" json:"regionId"` - RegionName string `mapstructure:"regionName" json:"regionName"` - Description string `mapstructure:"description" json:"description"` - Location Location `mapstructure:"location" json:"location"` - Zones []string `mapstructure:"zone" json:"zones"` -} - -// Location is structure for location information -type Location struct { - Display string `mapstructure:"display" json:"display"` - Latitude float64 `mapstructure:"latitude" json:"latitude"` - Longitude float64 `mapstructure:"longitude" json:"longitude"` -} - -// RuntimeCloudInfo is global variable for CloudInfo -var RuntimeCloudInfo = CloudInfo{} - -type Credential struct { - Credentialholder map[string]map[string]map[string]string `yaml:"credentialholder"` -} - -var RuntimeCredential = Credential{} - -// RuntimeLatancyMap is global variable for LatancyMap -var RuntimeLatancyMap = [][]string{} - -// RuntimeLatancyMapIndex is global variable for LatancyMap (index) -var RuntimeLatancyMapIndex = make(map[string]int) - -// RuntimeConf is global variable for cloud config -var RuntimeConf = RuntimeConfig{} - -// RuntimeConfig is structure for global variable for cloud config -type RuntimeConfig struct { - Cloud Cloud `yaml:"cloud"` - Nlbsw Nlbsw `yaml:"nlbsw"` -} - -// Cloud is structure for cloud settings per CSP -type Cloud struct { - Common CloudSetting `yaml:"common"` - Aws CloudSetting `yaml:"aws"` - Azure CloudSetting `yaml:"azure"` - Gcp CloudSetting `yaml:"gcp"` - Alibaba CloudSetting `yaml:"alibaba"` - Tencent CloudSetting `yaml:"tencent"` - Ibm CloudSetting `yaml:"ibm"` - Openstack CloudSetting `yaml:"openstack"` - Cloudit CloudSetting `yaml:"cloudit"` -} - -// CloudSetting is structure for cloud settings per CSP in details -type CloudSetting struct { - Enable string `yaml:"enable"` - Nlb NlbSetting `yaml:"nlb"` -} - -// NlbSetting is structure for NLB setting -type NlbSetting struct { - Enable string `yaml:"enable"` - Interval string `yaml:"interval"` - Timeout string `yaml:"timeout"` - Threshold string `yaml:"threshold"` -} - -// Nlbsw is structure for NLB setting -type Nlbsw struct { - Sw string `yaml:"sw"` - Version string `yaml:"version"` - CommandNlbPrepare string `yaml:"commandNlbPrepare"` - CommandNlbDeploy string `yaml:"commandNlbDeploy"` - CommandNlbAddTargetNode string `yaml:"commandNlbAddTargetNode"` - CommandNlbApplyConfig string `yaml:"commandNlbApplyConfig"` - NlbMciCommonSpec string `yaml:"nlbMciCommonSpec"` - NlbMciCommonImage string `yaml:"nlbMciCommonImage"` - NlbMciSubGroupSize string `yaml:"nlbMciSubGroupSize"` -} - -// type DataDiskCmd string -const ( - AttachDataDisk string = "attach" - DetachDataDisk string = "detach" - AvailableDataDisk string = "available" -) - -// swagger:request ConfigReq -type ConfigReq struct { - Name string `json:"name" example:"SPIDER_REST_URL"` - Value string `json:"value" example:"http://localhost:1024/spider"` -} - -// swagger:response ConfigInfo -type ConfigInfo struct { - Id string `json:"id" example:"SPIDER_REST_URL"` - Name string `json:"name" example:"SPIDER_REST_URL"` - Value string `json:"value" example:"http://localhost:1024/spider"` -} - -func UpdateConfig(u *ConfigReq) (ConfigInfo, error) { - - if u.Name == "" { - return ConfigInfo{}, fmt.Errorf("The provided name is empty.") - } - - content := ConfigInfo{} - content.Id = u.Name - content.Name = u.Name - content.Value = u.Value - - key := "/config/" + content.Id - //mapA := map[string]string{"name": content.Name, "description": content.Description} - val, _ := json.Marshal(content) - err := CBStore.Put(key, string(val)) - if err != nil { - CBLog.Error(err) - return content, err - } - keyValue, _ := CBStore.Get(key) - fmt.Println("UpdateConfig(); ===========================") - fmt.Println("UpdateConfig(); Key: " + keyValue.Key + "\nValue: " + keyValue.Value) - fmt.Println("UpdateConfig(); ===========================") - - UpdateGlobalVariable(content.Id) - - return content, nil -} - -func UpdateGlobalVariable(id string) error { - - configInfo, err := GetConfig(id) - if err != nil { - //CBLog.Error(err) - return err - } - - switch id { - // case StrSpiderRestUrl: - // SpiderRestUrl = configInfo.Value - // fmt.Println(" " + SpiderRestUrl) - // case StrDragonflyRestUrl: - // DragonflyRestUrl = configInfo.Value - // fmt.Println(" " + DragonflyRestUrl) - case StrTumblebugRestUrl: - TumblebugRestUrl = configInfo.Value - fmt.Println(" " + TumblebugRestUrl) - case StrDBUrl: - DBUrl = configInfo.Value - fmt.Println(" " + DBUrl) - case StrDBDatabase: - DBDatabase = configInfo.Value - fmt.Println(" " + DBDatabase) - case StrDBUser: - DBUser = configInfo.Value - fmt.Println(" " + DBUser) - case StrDBPassword: - DBPassword = configInfo.Value - fmt.Println(" " + DBPassword) - case StrAutocontrolDurationMs: - AutocontrolDurationMs = configInfo.Value - fmt.Println(" " + AutocontrolDurationMs) - default: - - } - - return nil -} - -func InitConfig(id string) error { - - switch id { - // case StrSpiderRestUrl: - // SpiderRestUrl = NVL(os.Getenv("BEETLE_SPIDER_REST_URL"), "http://localhost:1024/spider") - // fmt.Println(" " + SpiderRestUrl) - // case StrDragonflyRestUrl: - // DragonflyRestUrl = NVL(os.Getenv("BEETLE_DRAGONFLY_REST_URL"), "http://localhost:9090/dragonfly") - // fmt.Println(" " + DragonflyRestUrl) - case StrTumblebugRestUrl: - TumblebugRestUrl = NVL(os.Getenv("BEETLE_TUMBLEBUG_REST_URL"), "http://localhost:1323/tumblebug") - fmt.Println(" " + TumblebugRestUrl) - case StrDBUrl: - DBUrl = NVL(os.Getenv("BEETLE_SQLITE_URL"), "localhost:3306") - fmt.Println(" " + DBUrl) - case StrDBDatabase: - DBDatabase = NVL(os.Getenv("BEETLE_SQLITE_DATABASE"), "cm_beetle") - fmt.Println(" " + DBDatabase) - case StrDBUser: - DBUser = NVL(os.Getenv("BEETLE_SQLITE_USER"), "cm_beetle") - fmt.Println(" " + DBUser) - case StrDBPassword: - DBPassword = NVL(os.Getenv("BEETLE_SQLITE_PASSWORD"), "cm_beetle") - fmt.Println(" " + DBPassword) - case StrAutocontrolDurationMs: - AutocontrolDurationMs = NVL(os.Getenv("BEETLE_AUTOCONTROL_DURATION_MS"), "10000") - fmt.Println(" " + AutocontrolDurationMs) - default: - - } - - check, err := CheckConfig(id) - - if check && err == nil { - fmt.Println("[Init config] " + id) - key := "/config/" + id - - CBStore.Delete(key) - // if err != nil { - // CBLog.Error(err) - // return err - // } - } - - return nil -} - -func GetConfig(id string) (ConfigInfo, error) { - - res := ConfigInfo{} - - check, err := CheckConfig(id) - - if !check { - errString := "The config " + id + " does not exist." - err := fmt.Errorf(errString) - return res, err - } - - if err != nil { - temp := ConfigInfo{} - CBLog.Error(err) - return temp, err - } - - fmt.Println("[Get config] " + id) - key := "/config/" + id - - keyValue, err := CBStore.Get(key) - if err != nil { - //CBLog.Error(err) - return res, err - } - - fmt.Println("<" + keyValue.Key + "> " + keyValue.Value) - - err = json.Unmarshal([]byte(keyValue.Value), &res) - if err != nil { - CBLog.Error(err) - return res, err - } - return res, nil -} - -func ListConfig() ([]ConfigInfo, error) { - fmt.Println("[List config]") - key := "/config" - fmt.Println(key) - - keyValue, err := CBStore.GetList(key, true) - keyValue = cbstore_utils.GetChildList(keyValue, key) - - if err != nil { - CBLog.Error(err) - return nil, err - } - if keyValue != nil { - res := []ConfigInfo{} - for _, v := range keyValue { - tempObj := ConfigInfo{} - err = json.Unmarshal([]byte(v.Value), &tempObj) - if err != nil { - CBLog.Error(err) - return nil, err - } - res = append(res, tempObj) - } - return res, nil - //return true, nil - } - return nil, nil // When err == nil && keyValue == nil -} - -func ListConfigId() []string { - - fmt.Println("[List config]") - key := "/config" - fmt.Println(key) - - keyValue, _ := CBStore.GetList(key, true) - - var configList []string - for _, v := range keyValue { - configList = append(configList, strings.TrimPrefix(v.Key, "/config/")) - } - for _, v := range configList { - fmt.Println("<" + v + "> \n") - } - fmt.Println("===============================================") - return configList - -} +// import ( +// "encoding/json" +// "fmt" + +// "github.com/cloud-barista/cm-beetle/pkg/lkvstore" +// "github.com/rs/zerolog/log" +// ) + +// // swagger:request ConfigReq +// type ConfigReq struct { +// Name string `json:"name" example:"SPIDER_REST_URL"` +// Value string `json:"value" example:"http://localhost:1024/spider"` +// } + +// // swagger:response ConfigInfo +// type ConfigInfo struct { +// Id string `json:"id" example:"SPIDER_REST_URL"` +// Name string `json:"name" example:"SPIDER_REST_URL"` +// Value string `json:"value" example:"http://localhost:1024/spider"` +// } + +// func UpdateConfig(u *ConfigReq) (ConfigInfo, error) { + +// if u.Name == "" { +// return ConfigInfo{}, fmt.Errorf("The provided name is empty.") +// } + +// content := ConfigInfo{} +// content.Id = u.Name +// content.Name = u.Name +// content.Value = u.Value + +// key := "/config/" + content.Id +// //mapA := map[string]string{"name": content.Name, "description": content.Description} +// val, _ := json.Marshal(content) +// lkvstore.Put(key, string(val)) +// if err != nil { +// log.Error().Err(err).Msg("") +// return content, err +// } +// keyValue, exists := lkvstore.GetKv(key) +// if !exists { +// err := fmt.Errorf("Failed to put the config with key: " + key) +// log.Error().Err(err).Msg("") +// return content, err +// } + +// log.Info().Msgf("UpdateConfig(); Key: " + keyValue.Key + "\nValue: " + keyValue.Value) + +// UpdateGlobalVariable(content.Id) + +// return content, nil +// } + +// func UpdateGlobalVariable(id string) error { + +// configInfo, err := GetConfig(id) +// if err != nil { +// //CBLog.Error(err) +// return err +// } + +// switch id { +// // case StrSpiderRestUrl: +// // SpiderRestUrl = configInfo.Value +// // fmt.Println(" " + SpiderRestUrl) +// // case StrDragonflyRestUrl: +// // DragonflyRestUrl = configInfo.Value +// // fmt.Println(" " + DragonflyRestUrl) +// case StrTumblebugRestUrl: +// TumblebugRestUrl = configInfo.Value +// fmt.Println(" " + TumblebugRestUrl) +// case StrDBUrl: +// DBUrl = configInfo.Value +// fmt.Println(" " + DBUrl) +// case StrDBDatabase: +// DBDatabase = configInfo.Value +// fmt.Println(" " + DBDatabase) +// case StrDBUser: +// DBUser = configInfo.Value +// fmt.Println(" " + DBUser) +// case StrDBPassword: +// DBPassword = configInfo.Value +// fmt.Println(" " + DBPassword) +// case StrAutocontrolDurationMs: +// AutocontrolDurationMs = configInfo.Value +// fmt.Println(" " + AutocontrolDurationMs) +// default: + +// } + +// return nil +// } + +// func InitConfig(id string) error { + +// switch id { +// // case StrSpiderRestUrl: +// // SpiderRestUrl = NVL(os.Getenv("BEETLE_SPIDER_REST_URL"), "http://localhost:1024/spider") +// // fmt.Println(" " + SpiderRestUrl) +// // case StrDragonflyRestUrl: +// // DragonflyRestUrl = NVL(os.Getenv("BEETLE_DRAGONFLY_REST_URL"), "http://localhost:9090/dragonfly") +// // fmt.Println(" " + DragonflyRestUrl) +// case StrTumblebugRestUrl: +// TumblebugRestUrl = NVL(os.Getenv("BEETLE_TUMBLEBUG_REST_URL"), "http://localhost:1323/tumblebug") +// fmt.Println(" " + TumblebugRestUrl) +// case StrDBUrl: +// DBUrl = NVL(os.Getenv("BEETLE_SQLITE_URL"), "localhost:3306") +// fmt.Println(" " + DBUrl) +// case StrDBDatabase: +// DBDatabase = NVL(os.Getenv("BEETLE_SQLITE_DATABASE"), "cm_beetle") +// fmt.Println(" " + DBDatabase) +// case StrDBUser: +// DBUser = NVL(os.Getenv("BEETLE_SQLITE_USER"), "cm_beetle") +// fmt.Println(" " + DBUser) +// case StrDBPassword: +// DBPassword = NVL(os.Getenv("BEETLE_SQLITE_PASSWORD"), "cm_beetle") +// fmt.Println(" " + DBPassword) +// case StrAutocontrolDurationMs: +// AutocontrolDurationMs = NVL(os.Getenv("BEETLE_AUTOCONTROL_DURATION_MS"), "10000") +// fmt.Println(" " + AutocontrolDurationMs) +// default: + +// } + +// check, err := CheckConfig(id) + +// if check && err == nil { +// fmt.Println("[Init config] " + id) +// key := "/config/" + id + +// lkvstore.Delete(key) +// // if err != nil { +// // CBLog.Error(err) +// // return err +// // } +// } + +// return nil +// } + +// func GetConfig(id string) (ConfigInfo, error) { + +// res := ConfigInfo{} + +// check, err := CheckConfig(id) + +// if !check { +// errMsg := fmt.Errorf("dose not exist, the config ID: %s", id) +// log.Error().Err(errMsg).Msg("") +// return res, err +// } + +// if err != nil { +// temp := ConfigInfo{} +// log.Error().Err(err) +// return temp, err +// } + +// fmt.Println("[Get config] " + id) +// key := "/config/" + id + +// keyValue, exist := lkvstore.GetKv(key) +// if !exist { +// errMsg := fmt.Errorf("dose not exist, the config ID: %s", id) +// log.Error().Err(errMsg).Msg("") +// return res, errMsg +// } + +// log.Debug().Msgf("GetConfig(); Key: " + keyValue.Key + "\nValue: " + keyValue.Value) + +// err = json.Unmarshal([]byte(keyValue.Value), &res) +// if err != nil { +// log.Error().Err(err).Msg("") +// return res, err +// } +// return res, nil +// } + +// func ListConfig() ([]ConfigInfo, error) { +// fmt.Println("[List config]") +// key := "/config" +// fmt.Println(key) + +// keyValue, err := CBStore.GetList(key, true) +// keyValue = cbstore_utils.GetChildList(keyValue, key) + +// if err != nil { +// CBLog.Error(err) +// return nil, err +// } +// if keyValue != nil { +// res := []ConfigInfo{} +// for _, v := range keyValue { +// tempObj := ConfigInfo{} +// err = json.Unmarshal([]byte(v.Value), &tempObj) +// if err != nil { +// CBLog.Error(err) +// return nil, err +// } +// res = append(res, tempObj) +// } +// return res, nil +// //return true, nil +// } +// return nil, nil // When err == nil && keyValue == nil +// } + +// func ListConfigId() []string { + +// fmt.Println("[List config]") +// key := "/config" +// fmt.Println(key) + +// keyValue, _ := CBStore.GetList(key, true) + +// var configList []string +// for _, v := range keyValue { +// configList = append(configList, strings.TrimPrefix(v.Key, "/config/")) +// } +// for _, v := range configList { +// fmt.Println("<" + v + "> \n") +// } +// fmt.Println("===============================================") +// return configList +// } /* func DelAllConfig() error { @@ -360,29 +263,28 @@ func DelAllConfig() error { } */ -func InitAllConfig() error { - fmt.Printf("InitAllConfig() called;") +// func InitAllConfig() error { +// fmt.Printf("InitAllConfig() called;") - configIdList := ListConfigId() +// configIdList := ListConfigId() - for _, v := range configIdList { - InitConfig(v) - } - return nil -} +// for _, v := range configIdList { +// InitConfig(v) +// } +// return nil +// } -func CheckConfig(id string) (bool, error) { +// func CheckConfig(id string) (bool, error) { - if id == "" { - err := fmt.Errorf("CheckConfig failed; configId given is null.") - return false, err - } +// if id == "" { +// err := fmt.Errorf("invalid config ID: %s.", id) +// log.Error().Err(err).Msg("") +// return false, err +// } - key := "/config/" + id +// key := "/config/" + id - keyValue, _ := CBStore.Get(key) - if keyValue != nil { - return true, nil - } - return false, nil -} +// _, exist := lkvstore.GetKv(key) + +// return exist, nil +// } diff --git a/pkg/core/common/utility.go b/pkg/core/common/utility.go index d024657..ff459ef 100644 --- a/pkg/core/common/utility.go +++ b/pkg/core/common/utility.go @@ -21,7 +21,6 @@ import ( "strings" "time" - cbstore_utils "github.com/cloud-barista/cb-store/utils" uid "github.com/rs/xid" "gopkg.in/yaml.v2" @@ -235,134 +234,134 @@ type mcirIds struct { // Tumblebug ConnectionName string } -// GetCspResourceId is func to retrieve CSP native resource ID -func GetCspResourceId(nsId string, resourceType string, resourceId string) (string, error) { - key := GenResourceKey(nsId, resourceType, resourceId) - if key == "/invalidKey" { - return "", fmt.Errorf("invalid nsId or resourceType or resourceId") - } - keyValue, err := CBStore.Get(key) - if err != nil { - CBLog.Error(err) - return "", err - } - if keyValue == nil { - //CBLog.Error(err) - // if there is no matched value for the key, return empty string. Error will be handled in a parent function - return "", fmt.Errorf("cannot find the key " + key) - } +// // GetCspResourceId is func to retrieve CSP native resource ID +// func GetCspResourceId(nsId string, resourceType string, resourceId string) (string, error) { +// key := GenResourceKey(nsId, resourceType, resourceId) +// if key == "/invalidKey" { +// return "", fmt.Errorf("invalid nsId or resourceType or resourceId") +// } +// keyValue, err := CBStore.Get(key) +// if err != nil { +// CBLog.Error(err) +// return "", err +// } +// if keyValue == nil { +// //CBLog.Error(err) +// // if there is no matched value for the key, return empty string. Error will be handled in a parent function +// return "", fmt.Errorf("cannot find the key " + key) +// } - switch resourceType { - case StrImage: - content := mcirIds{} - json.Unmarshal([]byte(keyValue.Value), &content) - return content.CspImageId, nil - case StrCustomImage: - content := mcirIds{} - json.Unmarshal([]byte(keyValue.Value), &content) - return content.CspCustomImageName, nil - case StrSSHKey: - content := mcirIds{} - json.Unmarshal([]byte(keyValue.Value), &content) - return content.CspSshKeyName, nil - case StrSpec: - content := mcirIds{} - json.Unmarshal([]byte(keyValue.Value), &content) - return content.CspSpecName, nil - case StrVNet: - content := mcirIds{} - json.Unmarshal([]byte(keyValue.Value), &content) - return content.CspVNetName, nil // contains CspSubnetId - // case "subnet": - // content := subnetInfo{} - // json.Unmarshal([]byte(keyValue.Value), &content) - // return content.CspSubnetId - case StrSecurityGroup: - content := mcirIds{} - json.Unmarshal([]byte(keyValue.Value), &content) - return content.CspSecurityGroupName, nil - case StrDataDisk: - content := mcirIds{} - json.Unmarshal([]byte(keyValue.Value), &content) - return content.CspDataDiskName, nil - /* - case "publicIp": - content := mcirIds{} - json.Unmarshal([]byte(keyValue.Value), &content) - return content.CspPublicIpName - case "vNic": - content := mcirIds{} - err = json.Unmarshal([]byte(keyValue.Value), &content) - if err != nil { - CBLog.Error(err) - // if there is no matched value for the key, return empty string. Error will be handled in a parent function - return "" - } - return content.CspVNicName - */ - default: - return "", fmt.Errorf("invalid resourceType") - } -} +// switch resourceType { +// case StrImage: +// content := mcirIds{} +// json.Unmarshal([]byte(keyValue.Value), &content) +// return content.CspImageId, nil +// case StrCustomImage: +// content := mcirIds{} +// json.Unmarshal([]byte(keyValue.Value), &content) +// return content.CspCustomImageName, nil +// case StrSSHKey: +// content := mcirIds{} +// json.Unmarshal([]byte(keyValue.Value), &content) +// return content.CspSshKeyName, nil +// case StrSpec: +// content := mcirIds{} +// json.Unmarshal([]byte(keyValue.Value), &content) +// return content.CspSpecName, nil +// case StrVNet: +// content := mcirIds{} +// json.Unmarshal([]byte(keyValue.Value), &content) +// return content.CspVNetName, nil // contains CspSubnetId +// // case "subnet": +// // content := subnetInfo{} +// // json.Unmarshal([]byte(keyValue.Value), &content) +// // return content.CspSubnetId +// case StrSecurityGroup: +// content := mcirIds{} +// json.Unmarshal([]byte(keyValue.Value), &content) +// return content.CspSecurityGroupName, nil +// case StrDataDisk: +// content := mcirIds{} +// json.Unmarshal([]byte(keyValue.Value), &content) +// return content.CspDataDiskName, nil +// /* +// case "publicIp": +// content := mcirIds{} +// json.Unmarshal([]byte(keyValue.Value), &content) +// return content.CspPublicIpName +// case "vNic": +// content := mcirIds{} +// err = json.Unmarshal([]byte(keyValue.Value), &content) +// if err != nil { +// CBLog.Error(err) +// // if there is no matched value for the key, return empty string. Error will be handled in a parent function +// return "" +// } +// return content.CspVNicName +// */ +// default: +// return "", fmt.Errorf("invalid resourceType") +// } +// } -// ConnConfig is struct for containing modified CB-Spider struct for connection config -type ConnConfig struct { - ConfigName string `json:"configName"` - ProviderName string `json:"providerName"` - DriverName string `json:"driverName"` - CredentialName string `json:"credentialName"` - CredentialHolder string `json:"credentialHolder"` - RegionZoneInfoName string `json:"regionZoneInfoName"` - RegionZoneInfo RegionZoneInfo `json:"regionZoneInfo"` - RegionDetail RegionDetail `json:"regionDetail"` - RegionRepresentative bool `json:"regionRepresentative"` - Verified bool `json:"verified"` -} +// // ConnConfig is struct for containing modified CB-Spider struct for connection config +// type ConnConfig struct { +// ConfigName string `json:"configName"` +// ProviderName string `json:"providerName"` +// DriverName string `json:"driverName"` +// CredentialName string `json:"credentialName"` +// CredentialHolder string `json:"credentialHolder"` +// RegionZoneInfoName string `json:"regionZoneInfoName"` +// RegionZoneInfo RegionZoneInfo `json:"regionZoneInfo"` +// RegionDetail RegionDetail `json:"regionDetail"` +// RegionRepresentative bool `json:"regionRepresentative"` +// Verified bool `json:"verified"` +// } -// SpiderConnConfig is struct for containing a CB-Spider struct for connection config -type SpiderConnConfig struct { - ConfigName string - ProviderName string - DriverName string - CredentialName string - RegionName string -} +// // SpiderConnConfig is struct for containing a CB-Spider struct for connection config +// type SpiderConnConfig struct { +// ConfigName string +// ProviderName string +// DriverName string +// CredentialName string +// RegionName string +// } -// CloudDriverInfo is struct for containing a CB-Spider struct for cloud driver info -type CloudDriverInfo struct { - DriverName string - ProviderName string - DriverLibFileName string -} +// // CloudDriverInfo is struct for containing a CB-Spider struct for cloud driver info +// type CloudDriverInfo struct { +// DriverName string +// ProviderName string +// DriverLibFileName string +// } -// CredentialReq is struct for containing a struct for credential request -type CredentialReq struct { - CredentialHolder string `json:"credentialHolder"` - ProviderName string `json:"providerName"` - KeyValueInfoList []KeyValue `json:"keyValueInfoList"` -} +// // CredentialReq is struct for containing a struct for credential request +// type CredentialReq struct { +// CredentialHolder string `json:"credentialHolder"` +// ProviderName string `json:"providerName"` +// KeyValueInfoList []KeyValue `json:"keyValueInfoList"` +// } -// CredentialInfo is struct for containing a struct for credential info -type CredentialInfo struct { - CredentialName string `json:"credentialName"` - CredentialHolder string `json:"credentialHolder"` - ProviderName string `json:"providerName"` - KeyValueInfoList []KeyValue `json:"keyValueInfoList"` -} +// // CredentialInfo is struct for containing a struct for credential info +// type CredentialInfo struct { +// CredentialName string `json:"credentialName"` +// CredentialHolder string `json:"credentialHolder"` +// ProviderName string `json:"providerName"` +// KeyValueInfoList []KeyValue `json:"keyValueInfoList"` +// } -// SpiderRegionZoneInfo is struct for containing region struct of CB-Spider -type SpiderRegionZoneInfo struct { - RegionName string // ex) "region01" - ProviderName string // ex) "GCP" - KeyValueInfoList []KeyValue // ex) { {region, us-east1}, {zone, us-east1-c} } - AvailableZoneList []string -} +// // SpiderRegionZoneInfo is struct for containing region struct of CB-Spider +// type SpiderRegionZoneInfo struct { +// RegionName string // ex) "region01" +// ProviderName string // ex) "GCP" +// KeyValueInfoList []KeyValue // ex) { {region, us-east1}, {zone, us-east1-c} } +// AvailableZoneList []string +// } -// RegionZoneInfo is struct for containing region struct -type RegionZoneInfo struct { - AssignedRegion string `json:"assignedRegion"` - AssignedZone string `json:"assignedZone"` -} +// // RegionZoneInfo is struct for containing region struct +// type RegionZoneInfo struct { +// AssignedRegion string `json:"assignedRegion"` +// AssignedZone string `json:"assignedZone"` +// } // // GetCloudLocation is to get location of clouds (need error handling) // func GetCloudLocation(cloudType string, nativeRegion string) GeoLocation { @@ -749,77 +748,77 @@ func NVL(str string, def string) string { return str } -// GetChildIdList is func to get child id list from given key -func GetChildIdList(key string) []string { +// // GetChildIdList is func to get child id list from given key +// func GetChildIdList(key string) []string { - keyValue, _ := CBStore.GetList(key, true) - keyValue = cbstore_utils.GetChildList(keyValue, key) +// keyValue, _ := CBStore.GetList(key, true) +// keyValue = cbstore_utils.GetChildList(keyValue, key) - var childIdList []string - for _, v := range keyValue { - childIdList = append(childIdList, strings.TrimPrefix(v.Key, key+"/")) +// var childIdList []string +// for _, v := range keyValue { +// childIdList = append(childIdList, strings.TrimPrefix(v.Key, key+"/")) - } - for _, v := range childIdList { - fmt.Println("<" + v + "> \n") - } - fmt.Println("===============================================") - return childIdList +// } +// for _, v := range childIdList { +// fmt.Println("<" + v + "> \n") +// } +// fmt.Println("===============================================") +// return childIdList -} +// } -// GetObjectList is func to return IDs of each child objects that has the same key -func GetObjectList(key string) []string { +// // GetObjectList is func to return IDs of each child objects that has the same key +// func GetObjectList(key string) []string { - keyValue, _ := CBStore.GetList(key, true) +// keyValue, _ := CBStore.GetList(key, true) - var childIdList []string - for _, v := range keyValue { - childIdList = append(childIdList, v.Key) - } +// var childIdList []string +// for _, v := range keyValue { +// childIdList = append(childIdList, v.Key) +// } - fmt.Println("===============================================") - return childIdList +// fmt.Println("===============================================") +// return childIdList -} +// } -// GetObjectValue is func to return the object value -func GetObjectValue(key string) (string, error) { +// // GetObjectValue is func to return the object value +// func GetObjectValue(key string) (string, error) { - keyValue, err := CBStore.Get(key) - if err != nil { - CBLog.Error(err) - return "", err - } - if keyValue == nil { - return "", nil - } - return keyValue.Value, nil -} +// keyValue, err := CBStore.Get(key) +// if err != nil { +// CBLog.Error(err) +// return "", err +// } +// if keyValue == nil { +// return "", nil +// } +// return keyValue.Value, nil +// } -// DeleteObject is func to delete the object -func DeleteObject(key string) error { +// // DeleteObject is func to delete the object +// func DeleteObject(key string) error { - err := CBStore.Delete(key) - if err != nil { - CBLog.Error(err) - return err - } - return nil -} +// err := CBStore.Delete(key) +// if err != nil { +// CBLog.Error(err) +// return err +// } +// return nil +// } -// DeleteObjects is func to delete objects -func DeleteObjects(key string) error { - keyValue, _ := CBStore.GetList(key, true) - for _, v := range keyValue { - err := CBStore.Delete(v.Key) - if err != nil { - CBLog.Error(err) - return err - } - } - return nil -} +// // DeleteObjects is func to delete objects +// func DeleteObjects(key string) error { +// keyValue, _ := CBStore.GetList(key, true) +// for _, v := range keyValue { +// err := CBStore.Delete(v.Key) +// if err != nil { +// CBLog.Error(err) +// return err +// } +// } +// return nil +// } func CheckElement(a string, list []string) bool { for _, b := range list { diff --git a/pkg/core/migration/migration.go b/pkg/core/migration/migration.go index a060894..8f815a1 100644 --- a/pkg/core/migration/migration.go +++ b/pkg/core/migration/migration.go @@ -16,15 +16,14 @@ package migration import ( "fmt" - "os" "time" - "github.com/cloud-barista/cb-tumblebug/src/core/mci" + tbmodel "github.com/cloud-barista/cb-tumblebug/src/core/model" // cloudmodel "github.com/cloud-barista/cm-beetle/pkg/api/rest/model/cloud/infra" + "github.com/cloud-barista/cm-beetle/pkg/config" "github.com/cloud-barista/cm-beetle/pkg/core/common" "github.com/go-resty/resty/v2" "github.com/rs/zerolog/log" - "github.com/spf13/viper" ) //"log" @@ -97,26 +96,25 @@ const ( // DefaultSystemLabel is const for string to specify the Default System Label const DefaultSystemLabel string = "Managed by CM-Beetle" -func CreateVMInfra(nsId string, infraModel *mci.TbMciDynamicReq) (mci.TbMciInfo, error) { +func CreateVMInfra(nsId string, infraModel *tbmodel.TbMciDynamicReq) (tbmodel.TbMciInfo, error) { client := resty.New() - apiUser := viper.GetString("beetle.tumblebug.api.username") - apiPass := viper.GetString("beetle.tumblebug.api.password") + apiUser := config.Tumblebug.API.Username + apiPass := config.Tumblebug.API.Password client.SetBasicAuth(apiUser, apiPass) - method := "POST" + // set Tumblebug rest url + epTumblebug := config.Tumblebug.RestUrl - // CB-Tumblebug API endpoint - //cbTumblebugApiEndpoint := "http://localhost:1323/tumblebug" - cbTumblebugApiEndpoint := common.TumblebugRestUrl - url := cbTumblebugApiEndpoint + fmt.Sprintf("/ns/%s/mciDynamic", nsId) + method := "POST" + url := epTumblebug + fmt.Sprintf("/ns/%s/mciDynamic", nsId) // url := fmt.Sprintf("%s/ns/{nsId}/mciDynamic%s", cbTumblebugApiEndpoint, idDetails.IdInSp) // Set request body requestBody := *infraModel // Set response body - responseBody := mci.TbMciInfo{} + responseBody := tbmodel.TbMciInfo{} client.SetTimeout(5 * time.Minute) @@ -133,22 +131,22 @@ func CreateVMInfra(nsId string, infraModel *mci.TbMciDynamicReq) (mci.TbMciInfo, if err != nil { // common.CBLog.Error(err) - return mci.TbMciInfo{}, err + return tbmodel.TbMciInfo{}, err } return responseBody, nil } -func GetVMInfra(nsId, infraId string) (mci.TbMciInfo, error) { +func GetVMInfra(nsId, infraId string) (tbmodel.TbMciInfo, error) { // Initialize resty client with basic auth client := resty.New() - apiUser := os.Getenv("BEETLE_API_USERNAME") - apiPass := os.Getenv("BEETLE_API_PASSWORD") + apiUser := config.Tumblebug.API.Username + apiPass := config.Tumblebug.API.Password client.SetBasicAuth(apiUser, apiPass) - // set endpoint - epTumblebug := common.TumblebugRestUrl + // set Tumblebug rest url + epTumblebug := config.Tumblebug.RestUrl // check readyz method := "GET" @@ -158,7 +156,7 @@ func GetVMInfra(nsId, infraId string) (mci.TbMciInfo, error) { requestBody := common.NoBody // Set response body - responseBody := new(mci.TbMciInfo) + responseBody := new(tbmodel.TbMciInfo) client.SetTimeout(5 * time.Minute) @@ -175,7 +173,7 @@ func GetVMInfra(nsId, infraId string) (mci.TbMciInfo, error) { if err != nil { log.Error().Err(err).Msgf("failed to get the infrastructure info (nsId: %s, infraId: %s)", nsId, infraId) - return mci.TbMciInfo{}, err + return tbmodel.TbMciInfo{}, err } return *responseBody, nil @@ -185,12 +183,12 @@ func DeleteVMInfra(nsId, infraId string) (common.SimpleMsg, error) { // Initialize resty client with basic auth client := resty.New() - apiUser := os.Getenv("BEETLE_API_USERNAME") - apiPass := os.Getenv("BEETLE_PI_PASSWORD") + apiUser := config.Tumblebug.API.Username + apiPass := config.Tumblebug.API.Password client.SetBasicAuth(apiUser, apiPass) - // set endpoint - epTumblebug := common.TumblebugRestUrl + // set Tumblebug rest url + epTumblebug := config.Tumblebug.RestUrl // delete the infrastructure with terminate option method := "DELETE" diff --git a/pkg/core/recommendation/model.go b/pkg/core/recommendation/model.go new file mode 100644 index 0000000..d6739b3 --- /dev/null +++ b/pkg/core/recommendation/model.go @@ -0,0 +1,18 @@ +package recommendation + +import tbmodel "github.com/cloud-barista/cb-tumblebug/src/core/model" + +// RecommendationStatus represents the status of a recommendation. +type RecommendationStatus string + +const ( + NothingRecommended RecommendationStatus = "none" + PartiallyRecommended RecommendationStatus = "partial" + FullyRecommended RecommendationStatus = "ok" +) + +type RecommendedInfraInfo struct { + Status string `json:"status"` + Description string `json:"description"` + TargetInfra tbmodel.TbMciDynamicReq `json:"targetInfra"` +} diff --git a/pkg/core/recommendation/recommendation.go b/pkg/core/recommendation/recommendation.go index 6703065..1c01370 100644 --- a/pkg/core/recommendation/recommendation.go +++ b/pkg/core/recommendation/recommendation.go @@ -5,32 +5,43 @@ import ( "fmt" "strings" - "github.com/cloud-barista/cb-tumblebug/src/core/mci" - "github.com/cloud-barista/cb-tumblebug/src/core/mcir" + tbmodel "github.com/cloud-barista/cb-tumblebug/src/core/model" // cloudmodel "github.com/cloud-barista/cm-beetle/pkg/api/rest/model/cloud/infra" "github.com/cloud-barista/cm-honeybee/agent/pkg/api/rest/model/onprem/infra" // "github.com/cloud-barista/cm-beetle/pkg/api/rest/model/onprem/infra" + "github.com/cloud-barista/cm-beetle/pkg/config" "github.com/cloud-barista/cm-beetle/pkg/core/common" "github.com/cloud-barista/cm-beetle/pkg/similarity" "github.com/go-resty/resty/v2" "github.com/rs/zerolog/log" - "github.com/spf13/viper" ) -// func Recommend(srcInfra []infra.Infra) (cloudmodel.InfraMigrationReq, error) { -func Recommend(srcInfra []infra.Infra) (mci.TbMciDynamicReq, error) { +func Recommend(srcInfra []infra.Infra) (RecommendedInfraInfo, error) { + + var emptyResp RecommendedInfraInfo + var recommendedInfraInfo RecommendedInfraInfo + + // Set target infra + recommendedInfraInfo.TargetInfra = tbmodel.TbMciDynamicReq{ + Description: "A cloud infra recommended by CM-Beetle", + InstallMonAgent: "no", + Label: "rehosted-mci", + Name: "", + SystemLabel: "", + Vm: []tbmodel.TbVmDynamicReq{}, + } // Initialize resty client with basic auth client := resty.New() - apiUser := viper.GetString("beetle.api.username") - apiPass := viper.GetString("beetle.api.password") + apiUser := config.Tumblebug.API.Username + apiPass := config.Tumblebug.API.Password client.SetBasicAuth(apiUser, apiPass) - // set endpoint - epTumblebug := common.TumblebugRestUrl + // set tumblebug rest url + epTumblebug := config.Tumblebug.RestUrl // Set a deployment plan to recommand virtual machines // Ref: https://github.com/cloud-barista/cb-tumblebug/discussions/1234 @@ -91,37 +102,45 @@ func Recommend(srcInfra []infra.Infra) (mci.TbMciDynamicReq, error) { } }` - // A target infrastructure by recommendation - targetInfra := mci.TbMciDynamicReq{ - Description: "A cloud infra recommended by CM-Beetle", - InstallMonAgent: "no", - Label: "rehosted-mci", - Name: "", - SystemLabel: "", - Vm: []mci.TbVmDynamicReq{}, - } - // Recommand VMs for _, server := range srcInfra { + // Set VM info + recommendedVm := tbmodel.TbVmDynamicReq{ + ConnectionName: "", + CommonImage: "", // Search and set an appropriate VM OS image + CommonSpec: "", // Search and set an appropriate VM spec + Description: "a recommended virtual machine", + Label: "rehosted-vm", + Name: fmt.Sprintf("rehosted-%s", server.Compute.OS.Node.Hostname), + RootDiskSize: "", // TBD + RootDiskType: "", // TBD + SubGroupSize: "", + VmUserPassword: "", + } + + /* + Search an appropriate VM spec for the server by /mciRecommendVm API + */ + // Extract server info from source computing infra info cores := server.Compute.ComputeResource.CPU.Cores memory := MBtoGiB(float64(server.Compute.ComputeResource.Memory.Size)) - coreUpperLimit := cores << 1 - var coreLowerLimit uint + coresMax := cores << 1 + var coresMin uint if cores > 1 { - coreLowerLimit = cores >> 1 + coresMin = cores >> 1 } else { - coreLowerLimit = 1 + coresMin = 1 } - memoryUpperLimit := memory << 1 - var memoryLowerLimit uint32 + memoryMax := memory << 1 + var memoryMin uint32 if memory > 1 { - memoryLowerLimit = memory >> 1 + memoryMin = memory >> 1 } else { - memoryLowerLimit = 1 + memoryMin = 1 } providerName := "aws" @@ -132,41 +151,41 @@ func Recommend(srcInfra []infra.Infra) (mci.TbMciDynamicReq, error) { osNameWithVersion := strings.ToLower(osVendor + osVersion) log.Debug(). - Uint("coreUpperLimit", coreUpperLimit). - Uint("coreLowerLimit", coreLowerLimit). - Uint32("memoryUpperLimit (GiB)", memoryUpperLimit). - Uint32("memoryLowerLimit (GiB)", memoryLowerLimit). + Uint("coreLowerLimit", coresMin). + Uint("coreUpperLimit", coresMax). + Uint32("memoryLowerLimit (GiB)", memoryMin). + Uint32("memoryUpperLimit (GiB)", memoryMax). Str("providerName", providerName). Str("regionName", regionName). Str("osNameWithVersion", osNameWithVersion). Msg("Source computing infrastructure info") - // To search proper VMs with the server info, set a deployment plan + // Set a deployment plan to search VMs having appropriate specs planToSearchProperVm := fmt.Sprintf(planDocstring, - coreLowerLimit, - coreUpperLimit, - memoryLowerLimit, - memoryUpperLimit, + coresMin, + coresMax, + memoryMin, + memoryMax, providerName, regionName, ) + log.Debug().Msgf("deployment plan to search proper VMs: %s", planToSearchProperVm) - //////////////////////////////////////// // Search and set a target VM spec method := "POST" url := fmt.Sprintf("%s/mciRecommendVm", epTumblebug) // Request body - reqRecommVm := new(mci.DeploymentPlan) + reqRecommVm := new(tbmodel.DeploymentPlan) err := json.Unmarshal([]byte(planToSearchProperVm), reqRecommVm) if err != nil { log.Err(err).Msg("") - return mci.TbMciDynamicReq{}, err + return emptyResp, err } log.Trace().Msgf("deployment plan for the VM recommendation: %+v", reqRecommVm) // Response body - resRecommVmList := []mcir.TbSpecInfo{} + resRecommVmList := []tbmodel.TbSpecInfo{} err = common.ExecuteHttpRequest( client, @@ -181,7 +200,7 @@ func Recommend(srcInfra []infra.Infra) (mci.TbMciDynamicReq, error) { if err != nil { log.Err(err).Msg("") - return mci.TbMciDynamicReq{}, err + return emptyResp, err } numRecommenedVm := len(resRecommVmList) @@ -191,25 +210,29 @@ func Recommend(srcInfra []infra.Infra) (mci.TbMciDynamicReq, error) { if numRecommenedVm == 0 { log.Warn().Msgf("no VM spec recommended for the inserted PM/VM with spec (cores: %d, memory (GiB): %d)", cores, memory) + recommendedInfraInfo.TargetInfra.Vm = append(recommendedInfraInfo.TargetInfra.Vm, recommendedVm) continue } log.Debug().Msgf("select the 1st recommended virtual machine: %+v", resRecommVmList[0]) recommendedSpec := resRecommVmList[0].Id - // name := fmt.Sprintf("rehosted-%s-%s", server.Compute.OS.Node.Hostname, server.Compute.OS.Node.Machineid) - name := fmt.Sprintf("rehosted-%s", server.Compute.OS.Node.Hostname) + // Assign the recommended spec + recommendedVm.CommonSpec = recommendedSpec + + /* + Search an appropriate VM OS image for the server by /mciDynamicCheckRequest API + */ - //////////////////////////////////////// // Search and set target VM image (e.g. ubuntu22.04) method = "POST" url = fmt.Sprintf("%s/mciDynamicCheckRequest", epTumblebug) // Request body - reqMciDynamicCheck := new(mci.MciConnectionConfigCandidatesReq) + reqMciDynamicCheck := new(tbmodel.MciConnectionConfigCandidatesReq) reqMciDynamicCheck.CommonSpecs = []string{recommendedSpec} // Response body - resMciDynamicCheck := new(mci.CheckMciDynamicReqInfo) + resMciDynamicCheck := new(tbmodel.CheckMciDynamicReqInfo) err = common.ExecuteHttpRequest( client, @@ -224,13 +247,20 @@ func Recommend(srcInfra []infra.Infra) (mci.TbMciDynamicReq, error) { if err != nil { log.Err(err).Msg("") - return mci.TbMciDynamicReq{}, err + return emptyResp, err } - log.Trace().Msgf("resMciDynamicCheck: %+v", resMciDynamicCheck) + // for pretty logging + prettyImages, err := json.MarshalIndent(resMciDynamicCheck.ReqCheck[0].Image, "", " ") + if err != nil { + log.Err(err).Msg("failed to marshal response") + return emptyResp, err + } + log.Debug().Msgf("resMciDynamicCheck.ReqCheck[0].Image: %s", prettyImages) if len(resMciDynamicCheck.ReqCheck) == 0 { log.Warn().Msg("no VM OS image recommended for the inserted PM/VM") + recommendedInfraInfo.TargetInfra.Vm = append(recommendedInfraInfo.TargetInfra.Vm, recommendedVm) continue } @@ -246,27 +276,48 @@ func Recommend(srcInfra []infra.Infra) (mci.TbMciDynamicReq, error) { delimiters2 := delimiters1 vmOsImageId := FindBestVmOsImage(keywords, delimiters1, resMciDynamicCheck.ReqCheck[0].Image, delimiters2) - // vmOsImage := fmt.Sprintf("%s+%s+%s", providerName, regionName, osNameWithVersion) - - vm := mci.TbVmDynamicReq{ - ConnectionName: "", - CommonImage: vmOsImageId, - CommonSpec: recommendedSpec, - Description: "a recommended virtual machine", - Label: "rehosted-vm", - Name: name, - RootDiskSize: "", - RootDiskType: "", - SubGroupSize: "", - VmUserPassword: "", - } + // Assign the recommended VM OS image + recommendedVm.CommonImage = vmOsImageId - targetInfra.Vm = append(targetInfra.Vm, vm) + recommendedInfraInfo.TargetInfra.Vm = append(recommendedInfraInfo.TargetInfra.Vm, recommendedVm) + } + log.Debug().Msgf("the recommended infra info: %+v", recommendedInfraInfo) + + status := checkOverallVmStatus(recommendedInfraInfo.TargetInfra.Vm) + recommendedInfraInfo.Status = status + if status == string(NothingRecommended) { + recommendedInfraInfo.Description = "Could not find approprate VMs." + } else if status == string(FullyRecommended) { + recommendedInfraInfo.Description = "Target infra is recommended." + } else { + recommendedInfraInfo.Description = "Some VMs are recommended. Please check and fill the required information." } - log.Trace().Msgf("targetInfra: %+v", targetInfra) + return recommendedInfraInfo, nil +} + +// Function to check overall status for the entire list of VMs +func checkOverallVmStatus(vms []tbmodel.TbVmDynamicReq) string { + allOk := true + allNone := true - return targetInfra, nil + for _, vm := range vms { + if vm.CommonImage == "" || vm.CommonSpec == "" { + allOk = false // At least one VM is not fully populated + } + if vm.CommonImage != "" || vm.CommonSpec != "" { + allNone = false // At least one VM has a value + } + } + + // Determine overall status + if allNone { + return string(NothingRecommended) + } else if allOk { + return string(FullyRecommended) + } else { + return string(PartiallyRecommended) + } } func MBtoGiB(mb float64) uint32 { @@ -277,18 +328,18 @@ func MBtoGiB(mb float64) uint32 { } // FindBestVmOsImage finds the best matching image based on the similarity scores -func FindBestVmOsImage(keywords string, kwDelimiters []string, vmImages []mcir.TbImageInfo, imgDelimiters []string) string { +func FindBestVmOsImage(keywords string, kwDelimiters []string, vmImages []tbmodel.TbImageInfo, imgDelimiters []string) string { var bestVmOsImageID string - var highestScore float64 + var highestScore float64 = 0.0 for _, image := range vmImages { - score := similarity.CalcResourceSimilarity(keywords, kwDelimiters, image.CspImageName, imgDelimiters) + score := similarity.CalcResourceSimilarity(keywords, kwDelimiters, image.Description, imgDelimiters) if score > highestScore { highestScore = score bestVmOsImageID = image.Id } - log.Trace().Msgf("VmImageName: %s, score: %f", image.CspImageName, score) + log.Debug().Msgf("VmImageName: %s, score: %f", image.Description, score) } log.Debug().Msgf("bestVmOsImageID: %s, highestScore: %f", bestVmOsImageID, highestScore) diff --git a/pkg/example/lkvstore/main.go b/pkg/example/lkvstore/main.go new file mode 100644 index 0000000..fc4f2ac --- /dev/null +++ b/pkg/example/lkvstore/main.go @@ -0,0 +1,72 @@ +package main + +import ( + "encoding/json" + "fmt" + + "github.com/cloud-barista/cm-beetle/pkg/lkvstore" +) + +type ExampleStruct struct { + Name string + Age int +} + +func main() { + // Initialize the key-value store with the specified file path + config := lkvstore.Config{ + DbFilePath: "./lkvstore.db", + } + lkvstore.Init(config) + + // Example usage with various keys + lkvstore.Put("prefix1_key1", string(123)) + lkvstore.Put("prefix1_key2", "Hello, world!") + example := ExampleStruct{Name: "John Doe", Age: 30} + bytes, err := json.Marshal(example) + if err != nil { + fmt.Printf("Error marshalling: %v\n", err) + } + + lkvstore.Put("prefix2_key1", string(bytes)) + lkvstore.Put("prefix1_key3", "Another string") + + // Save the current state of the key-value store to file + if err := lkvstore.SaveLkvStore(); err != nil { + fmt.Printf("Error saving: %v\n", err) + } else { + fmt.Println("Successfully saved the lkvstore to file.") + } + + // Clear the in-memory store + lkvstore.Delete("prefix1_key1") + lkvstore.Delete("prefix1_key2") + lkvstore.Delete("prefix1_key3") + lkvstore.Delete("prefix2_key1") + + // Load the state from the file back into the key-value store + if err := lkvstore.LoadLkvStore(); err != nil { + fmt.Printf("Error loading: %v\n", err) + } else { + fmt.Println("Successfully loaded the lkvstore from file.") + } + + // Verify loaded data with prefix + values, exists := lkvstore.GetWithPrefix("prefix1_") + if exists { + fmt.Println("Values with prefix 'prefix1_':") + for _, value := range values { + fmt.Printf("%v\n", value) + } + } else { + fmt.Println("No values found with prefix 'prefix1_'") + } + + // Verify loaded data without prefix + value, exists := lkvstore.Get("prefix2_key1") + if exists { + fmt.Printf("Loaded value for 'prefix2_key1': %v\n", value) + } else { + fmt.Println("No value found for 'prefix2_key1'") + } +} diff --git a/pkg/lkvstore/lkvstore.go b/pkg/lkvstore/lkvstore.go new file mode 100644 index 0000000..80798af --- /dev/null +++ b/pkg/lkvstore/lkvstore.go @@ -0,0 +1,146 @@ +// Local Key-Value Store based on sync.Map and file I/O +package lkvstore + +import ( + "encoding/json" + "fmt" + "os" + "strings" + "sync" +) + +var ( + lkvstore sync.Map + dbFilePath string +) + +type Config struct { + DbFilePath string +} + +type KeyValue struct { + Key string + Value string +} + +func Init(config Config) { + if config.DbFilePath != "" { + dbFilePath = config.DbFilePath + } else { + dbFilePath = ".lkvstore/lkvstore.db" + } +} + +// Save lkvstore to file +func SaveLkvStore() error { + if dbFilePath == "" { + return fmt.Errorf("db file path is not set") + } + + file, err := os.Create(dbFilePath) + if err != nil { + return fmt.Errorf("failed to create db file: %w", err) + } + defer file.Close() + + tempMap := make(map[string]interface{}) + lkvstore.Range(func(key, value interface{}) bool { + tempMap[key.(string)] = value + return true + }) + + encoder := json.NewEncoder(file) + if err := encoder.Encode(tempMap); err != nil { + return fmt.Errorf("failed to encode map: %w", err) + } + + return nil +} + +// Load the info from file +func LoadLkvStore() error { + if dbFilePath == "" { + return fmt.Errorf("db file path is not set") + } + + if _, err := os.Stat(dbFilePath); os.IsNotExist(err) { + return fmt.Errorf("db file does not exist: %w", err) + } + + file, err := os.Open(dbFilePath) + if err != nil { + return fmt.Errorf("failed to open db file: %w", err) + } + defer file.Close() + + var tempMap map[string]interface{} + decoder := json.NewDecoder(file) + if err := decoder.Decode(&tempMap); err != nil { + return fmt.Errorf("failed to decode map: %w", err) + } + + for key, value := range tempMap { + lkvstore.Store(key, value) + } + + return nil +} + +// Get returns the value for a given key. +func Get(key string) (string, bool) { + if value, ok := lkvstore.Load(key); ok { + return value.(string), true + } + return "", false +} + +// GetWithPrefix returns the values for a given key prefix. +func GetWithPrefix(keyPrefix string) ([]string, bool) { + var results []string + var exists bool + lkvstore.Range(func(key, value interface{}) bool { + if strings.HasPrefix(key.(string), keyPrefix) { + results = append(results, value.(string)) + exists = true + } + return true + }) + return results, exists +} + +// GetKv returns the key-value pair for a given key. +func GetKv(key string) (KeyValue, bool) { + var kv KeyValue + var exists bool + if value, ok := lkvstore.Load(key); ok { + kv.Key = key + kv.Value = value.(string) + exists = true + } + return kv, exists +} + +// GetKvWIthPrefix returns the key-value pairs for a given key prefix. +func GetKvWIthPrefix(keyPrefix string) ([]KeyValue, bool) { + var results []KeyValue + var exists bool + lkvstore.Range(func(key, value interface{}) bool { + if strings.HasPrefix(key.(string), keyPrefix) { + kv := KeyValue{Key: key.(string), Value: value.(string)} + results = append(results, kv) + exists = true + } + return true + }) + return results, exists +} + +// Put the key-value pair. +func Put(key string, value string) { + lkvstore.Store(key, value) +} + +// Delete the key-value pair for a given key. +func Delete(key string) { + lkvstore.Delete(key) +} diff --git a/scripts/system-info/system_info.py b/scripts/system-info/system_info.py index f40f025..c0230c1 100755 --- a/scripts/system-info/system_info.py +++ b/scripts/system-info/system_info.py @@ -101,7 +101,7 @@ def get_disk_info(): ("Free (GB)", bytes_to_gb(disk_info.free)), ("Used (GB)", bytes_to_gb(disk_info.used)), ("Read Count", disk_io.read_count), - ("Write Count", disk_io.write_count) + ("Write Count", disk_io.write_count), # ("Partitions", partition_info), # ("File System Types", ', '.join([p.fstype for p in partitions])) ] @@ -286,9 +286,9 @@ def main(): print("\nAdvanced Network Information:") print(advanced_network_table) - system_info[ - "Advanced Network" - ] = advanced_network_data # Add to system info dictionary + system_info["Advanced Network"] = ( + advanced_network_data # Add to system info dictionary + ) # Fetch process information process_table = PrettyTable()