diff --git a/api/docs.go b/api/docs.go index c2b8584..5ae8352 100644 --- a/api/docs.go +++ b/api/docs.go @@ -40,7 +40,7 @@ const docTemplate = `{ { "type": "string", "description": "Custom request ID (NOTE: It will be used as a trace ID.)", - "name": "x-request-id", + "name": "X-Request-Id", "in": "header" } ], @@ -101,7 +101,7 @@ const docTemplate = `{ { "type": "string", "description": "Custom request ID (NOTE: It will be used as a trace ID.)", - "name": "x-request-id", + "name": "X-Request-Id", "in": "header" } ], @@ -161,7 +161,7 @@ const docTemplate = `{ { "type": "string", "description": "Custom request ID (NOTE: It will be used as a trace ID.)", - "name": "x-request-id", + "name": "X-Request-Id", "in": "header" } ], @@ -216,10 +216,21 @@ const docTemplate = `{ "in": "path", "required": true }, + { + "enum": [ + "terminate", + "force" + ], + "type": "string", + "default": "terminate", + "description": "Action for deletion", + "name": "action", + "in": "query" + }, { "type": "string", "description": "Custom request ID (NOTE: It will be used as a trace ID.)", - "name": "x-request-id", + "name": "X-Request-Id", "in": "header" } ], @@ -263,7 +274,7 @@ const docTemplate = `{ { "type": "string", "description": "Custom request ID (NOTE: It will be used as a trace ID.)", - "name": "x-request-id", + "name": "X-Request-Id", "in": "header" } ], @@ -310,7 +321,7 @@ const docTemplate = `{ { "type": "string", "description": "Custom request ID (NOTE: It will be used as a trace ID.)", - "name": "x-request-id", + "name": "X-Request-Id", "in": "header" } ], @@ -354,7 +365,7 @@ const docTemplate = `{ { "type": "string", "description": "Custom request ID (NOTE: It will be used as a trace ID.)", - "name": "x-request-id", + "name": "X-Request-Id", "in": "header" } ], @@ -399,7 +410,7 @@ const docTemplate = `{ { "type": "string", "description": "Custom request ID (NOTE: It will be used as a trace ID.)", - "name": "x-request-id", + "name": "X-Request-Id", "in": "header" } ], @@ -444,7 +455,7 @@ const docTemplate = `{ { "type": "string", "description": "Custom request ID (NOTE: It will be used as a trace ID.)", - "name": "x-request-id", + "name": "X-Request-Id", "in": "header" } ], @@ -496,7 +507,7 @@ const docTemplate = `{ { "type": "string", "description": "Custom request ID (NOTE: It will be used as a trace ID.)", - "name": "x-request-id", + "name": "X-Request-Id", "in": "header" } ], @@ -539,7 +550,7 @@ const docTemplate = `{ { "type": "string", "description": "Custom request ID (NOTE: It will be used as a trace ID.)", - "name": "x-request-id", + "name": "X-Request-Id", "in": "header" } ], @@ -597,7 +608,7 @@ const docTemplate = `{ { "type": "string", "description": "Custom request ID (NOTE: It will be used as a trace ID.)", - "name": "x-request-id", + "name": "X-Request-Id", "in": "header" } ], @@ -641,7 +652,7 @@ const docTemplate = `{ { "type": "string", "description": "Custom request ID (NOTE: It will be used as a trace ID.)", - "name": "x-request-id", + "name": "X-Request-Id", "in": "header" } ], @@ -742,9 +753,11 @@ const docTemplate = `{ "example": "no" }, "label": { - "description": "Label is for describing the mci in a keyword (any string can be used)", - "type": "string", - "example": "DynamicVM" + "description": "Label is for describing the object by keywords", + "type": "object", + "additionalProperties": { + "type": "string" + } }, "name": { "type": "string", @@ -785,9 +798,11 @@ const docTemplate = `{ "example": "no" }, "label": { - "description": "Label is for describing the mci in a keyword (any string can be used)", - "type": "string", - "example": "DynamicVM" + "description": "Label is for describing the object by keywords", + "type": "object", + "additionalProperties": { + "type": "string" + } }, "name": { "type": "string", @@ -837,17 +852,21 @@ const docTemplate = `{ "controller.RecommendInfraRequest": { "type": "object", "required": [ - "servers" + "desiredProvider", + "desiredRegion", + "onpremiseInfraModel" ], "properties": { - "network": { - "$ref": "#/definitions/onprem.NetworkProperty" + "desiredProvider": { + "type": "string", + "example": "aws" }, - "servers": { - "type": "array", - "items": { - "$ref": "#/definitions/onprem.ServerProperty" - } + "desiredRegion": { + "type": "string", + "example": "ap-northeast-2" + }, + "onpremiseInfraModel": { + "$ref": "#/definitions/onprem.OnPremInfra" } } }, @@ -954,9 +973,11 @@ const docTemplate = `{ "example": "no" }, "label": { - "description": "Label is for describing the mci in a keyword (any string can be used)", - "type": "string", - "example": "DynamicVM" + "description": "Label is for describing the object by keywords", + "type": "object", + "additionalProperties": { + "type": "string" + } }, "name": { "type": "string", @@ -1001,8 +1022,11 @@ const docTemplate = `{ "example": "Description" }, "label": { - "type": "string", - "example": "DynamicVM" + "description": "Label is for describing the object by keywords", + "type": "object", + "additionalProperties": { + "type": "string" + } }, "name": { "description": "VM name or subGroup name if is (not empty) \u0026\u0026 (\u003e 0). If it is a group, actual VM name will be generated with -N postfix.", @@ -1134,28 +1158,76 @@ const docTemplate = `{ "onprem.NetworkInterfaceProperty": { "type": "object", "required": [ - "ipAddress" + "name" ], "properties": { - "ipAddress": { - "type": "string" + "ipv4CidrBlocks": { + "description": "IPv4 address with prefix length (e.g., 192.168.0.21/24), instead of inet addr, Bcast, and Mask", + "type": "array", + "items": { + "type": "string" + } + }, + "ipv6CidrBlocks": { + "description": "IPv6 address with prefix length (e.g., \"2001:db8::1/64\")", + "type": "array", + "items": { + "type": "string" + } }, "macAddress": { + "description": "MAC address", "type": "string" }, "mtu": { "description": "Maximum Transmission Unit (MTU) in bytes", "type": "integer" + }, + "name": { + "description": "Interface name (e.g., eth0, ens01, enp0s3)", + "type": "string" + }, + "state": { + "description": "Interface state (e.g., UP, DOWN)", + "type": "string" } } }, "onprem.NetworkProperty": { "type": "object", "properties": { - "gateway": { - "description": "Gateway IP address", - "type": "string", - "example": "172.26.240.0/20" + "ipv4Networks": { + "type": "array", + "items": { + "type": "string" + }, + "example": [ + "172.26.240.0/20" + ] + }, + "ipv6Networks": { + "description": "TBD", + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "onprem.OnPremInfra": { + "type": "object", + "required": [ + "servers" + ], + "properties": { + "network": { + "$ref": "#/definitions/onprem.NetworkProperty" + }, + "servers": { + "type": "array", + "items": { + "$ref": "#/definitions/onprem.ServerProperty" + } } } }, @@ -1197,6 +1269,43 @@ const docTemplate = `{ } } }, + "onprem.RouteProperty": { + "type": "object", + "properties": { + "destination": { + "description": "Destination network, expressed in CIDR format", + "type": "string" + }, + "gateway": { + "description": "Gateway address to which packets are forwarded", + "type": "string" + }, + "interface": { + "description": "Network interface associated with the route", + "type": "string" + }, + "linkState": { + "description": "Link state of the route (e.g., UP, DOWN)", + "type": "string" + }, + "metric": { + "description": "Metric value indicating the priority of the route", + "type": "integer" + }, + "protocol": { + "description": "Protocol used to set the route (e.g., kernel, static)", + "type": "string" + }, + "scope": { + "description": "Scope of the route (e.g., global, link, host)", + "type": "string" + }, + "source": { + "description": "Optionally stores the source address (used for policy-based routing)", + "type": "string" + } + } + }, "onprem.ServerProperty": { "type": "object", "properties": { @@ -1226,6 +1335,12 @@ const docTemplate = `{ }, "rootDisk": { "$ref": "#/definitions/onprem.DiskProperty" + }, + "routingTable": { + "type": "array", + "items": { + "$ref": "#/definitions/onprem.RouteProperty" + } } } } diff --git a/api/swagger.json b/api/swagger.json index 81f0c44..0e5b203 100644 --- a/api/swagger.json +++ b/api/swagger.json @@ -34,7 +34,7 @@ { "type": "string", "description": "Custom request ID (NOTE: It will be used as a trace ID.)", - "name": "x-request-id", + "name": "X-Request-Id", "in": "header" } ], @@ -95,7 +95,7 @@ { "type": "string", "description": "Custom request ID (NOTE: It will be used as a trace ID.)", - "name": "x-request-id", + "name": "X-Request-Id", "in": "header" } ], @@ -155,7 +155,7 @@ { "type": "string", "description": "Custom request ID (NOTE: It will be used as a trace ID.)", - "name": "x-request-id", + "name": "X-Request-Id", "in": "header" } ], @@ -210,10 +210,21 @@ "in": "path", "required": true }, + { + "enum": [ + "terminate", + "force" + ], + "type": "string", + "default": "terminate", + "description": "Action for deletion", + "name": "action", + "in": "query" + }, { "type": "string", "description": "Custom request ID (NOTE: It will be used as a trace ID.)", - "name": "x-request-id", + "name": "X-Request-Id", "in": "header" } ], @@ -257,7 +268,7 @@ { "type": "string", "description": "Custom request ID (NOTE: It will be used as a trace ID.)", - "name": "x-request-id", + "name": "X-Request-Id", "in": "header" } ], @@ -304,7 +315,7 @@ { "type": "string", "description": "Custom request ID (NOTE: It will be used as a trace ID.)", - "name": "x-request-id", + "name": "X-Request-Id", "in": "header" } ], @@ -348,7 +359,7 @@ { "type": "string", "description": "Custom request ID (NOTE: It will be used as a trace ID.)", - "name": "x-request-id", + "name": "X-Request-Id", "in": "header" } ], @@ -393,7 +404,7 @@ { "type": "string", "description": "Custom request ID (NOTE: It will be used as a trace ID.)", - "name": "x-request-id", + "name": "X-Request-Id", "in": "header" } ], @@ -438,7 +449,7 @@ { "type": "string", "description": "Custom request ID (NOTE: It will be used as a trace ID.)", - "name": "x-request-id", + "name": "X-Request-Id", "in": "header" } ], @@ -490,7 +501,7 @@ { "type": "string", "description": "Custom request ID (NOTE: It will be used as a trace ID.)", - "name": "x-request-id", + "name": "X-Request-Id", "in": "header" } ], @@ -533,7 +544,7 @@ { "type": "string", "description": "Custom request ID (NOTE: It will be used as a trace ID.)", - "name": "x-request-id", + "name": "X-Request-Id", "in": "header" } ], @@ -591,7 +602,7 @@ { "type": "string", "description": "Custom request ID (NOTE: It will be used as a trace ID.)", - "name": "x-request-id", + "name": "X-Request-Id", "in": "header" } ], @@ -635,7 +646,7 @@ { "type": "string", "description": "Custom request ID (NOTE: It will be used as a trace ID.)", - "name": "x-request-id", + "name": "X-Request-Id", "in": "header" } ], @@ -736,9 +747,11 @@ "example": "no" }, "label": { - "description": "Label is for describing the mci in a keyword (any string can be used)", - "type": "string", - "example": "DynamicVM" + "description": "Label is for describing the object by keywords", + "type": "object", + "additionalProperties": { + "type": "string" + } }, "name": { "type": "string", @@ -779,9 +792,11 @@ "example": "no" }, "label": { - "description": "Label is for describing the mci in a keyword (any string can be used)", - "type": "string", - "example": "DynamicVM" + "description": "Label is for describing the object by keywords", + "type": "object", + "additionalProperties": { + "type": "string" + } }, "name": { "type": "string", @@ -831,17 +846,21 @@ "controller.RecommendInfraRequest": { "type": "object", "required": [ - "servers" + "desiredProvider", + "desiredRegion", + "onpremiseInfraModel" ], "properties": { - "network": { - "$ref": "#/definitions/onprem.NetworkProperty" + "desiredProvider": { + "type": "string", + "example": "aws" }, - "servers": { - "type": "array", - "items": { - "$ref": "#/definitions/onprem.ServerProperty" - } + "desiredRegion": { + "type": "string", + "example": "ap-northeast-2" + }, + "onpremiseInfraModel": { + "$ref": "#/definitions/onprem.OnPremInfra" } } }, @@ -948,9 +967,11 @@ "example": "no" }, "label": { - "description": "Label is for describing the mci in a keyword (any string can be used)", - "type": "string", - "example": "DynamicVM" + "description": "Label is for describing the object by keywords", + "type": "object", + "additionalProperties": { + "type": "string" + } }, "name": { "type": "string", @@ -995,8 +1016,11 @@ "example": "Description" }, "label": { - "type": "string", - "example": "DynamicVM" + "description": "Label is for describing the object by keywords", + "type": "object", + "additionalProperties": { + "type": "string" + } }, "name": { "description": "VM name or subGroup name if is (not empty) \u0026\u0026 (\u003e 0). If it is a group, actual VM name will be generated with -N postfix.", @@ -1128,28 +1152,76 @@ "onprem.NetworkInterfaceProperty": { "type": "object", "required": [ - "ipAddress" + "name" ], "properties": { - "ipAddress": { - "type": "string" + "ipv4CidrBlocks": { + "description": "IPv4 address with prefix length (e.g., 192.168.0.21/24), instead of inet addr, Bcast, and Mask", + "type": "array", + "items": { + "type": "string" + } + }, + "ipv6CidrBlocks": { + "description": "IPv6 address with prefix length (e.g., \"2001:db8::1/64\")", + "type": "array", + "items": { + "type": "string" + } }, "macAddress": { + "description": "MAC address", "type": "string" }, "mtu": { "description": "Maximum Transmission Unit (MTU) in bytes", "type": "integer" + }, + "name": { + "description": "Interface name (e.g., eth0, ens01, enp0s3)", + "type": "string" + }, + "state": { + "description": "Interface state (e.g., UP, DOWN)", + "type": "string" } } }, "onprem.NetworkProperty": { "type": "object", "properties": { - "gateway": { - "description": "Gateway IP address", - "type": "string", - "example": "172.26.240.0/20" + "ipv4Networks": { + "type": "array", + "items": { + "type": "string" + }, + "example": [ + "172.26.240.0/20" + ] + }, + "ipv6Networks": { + "description": "TBD", + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "onprem.OnPremInfra": { + "type": "object", + "required": [ + "servers" + ], + "properties": { + "network": { + "$ref": "#/definitions/onprem.NetworkProperty" + }, + "servers": { + "type": "array", + "items": { + "$ref": "#/definitions/onprem.ServerProperty" + } } } }, @@ -1191,6 +1263,43 @@ } } }, + "onprem.RouteProperty": { + "type": "object", + "properties": { + "destination": { + "description": "Destination network, expressed in CIDR format", + "type": "string" + }, + "gateway": { + "description": "Gateway address to which packets are forwarded", + "type": "string" + }, + "interface": { + "description": "Network interface associated with the route", + "type": "string" + }, + "linkState": { + "description": "Link state of the route (e.g., UP, DOWN)", + "type": "string" + }, + "metric": { + "description": "Metric value indicating the priority of the route", + "type": "integer" + }, + "protocol": { + "description": "Protocol used to set the route (e.g., kernel, static)", + "type": "string" + }, + "scope": { + "description": "Scope of the route (e.g., global, link, host)", + "type": "string" + }, + "source": { + "description": "Optionally stores the source address (used for policy-based routing)", + "type": "string" + } + } + }, "onprem.ServerProperty": { "type": "object", "properties": { @@ -1220,6 +1329,12 @@ }, "rootDisk": { "$ref": "#/definitions/onprem.DiskProperty" + }, + "routingTable": { + "type": "array", + "items": { + "$ref": "#/definitions/onprem.RouteProperty" + } } } } diff --git a/api/swagger.yaml b/api/swagger.yaml index 05ca093..56baacb 100644 --- a/api/swagger.yaml +++ b/api/swagger.yaml @@ -52,10 +52,10 @@ definitions: example: "no" type: string label: - description: Label is for describing the mci in a keyword (any string can - be used) - example: DynamicVM - type: string + additionalProperties: + type: string + description: Label is for describing the object by keywords + type: object name: example: mci01 type: string @@ -87,10 +87,10 @@ definitions: example: "no" type: string label: - description: Label is for describing the mci in a keyword (any string can - be used) - example: DynamicVM - type: string + additionalProperties: + type: string + description: Label is for describing the object by keywords + type: object name: example: mci01 type: string @@ -127,14 +127,18 @@ definitions: type: object controller.RecommendInfraRequest: properties: - network: - $ref: '#/definitions/onprem.NetworkProperty' - servers: - items: - $ref: '#/definitions/onprem.ServerProperty' - type: array + desiredProvider: + example: aws + type: string + desiredRegion: + example: ap-northeast-2 + type: string + onpremiseInfraModel: + $ref: '#/definitions/onprem.OnPremInfra' required: - - servers + - desiredProvider + - desiredRegion + - onpremiseInfraModel type: object controller.RecommendInfraResponse: properties: @@ -205,10 +209,10 @@ definitions: example: "no" type: string label: - description: Label is for describing the mci in a keyword (any string can - be used) - example: DynamicVM - type: string + additionalProperties: + type: string + description: Label is for describing the object by keywords + type: object name: example: mci01 type: string @@ -244,8 +248,10 @@ definitions: example: Description type: string label: - example: DynamicVM - type: string + additionalProperties: + type: string + description: Label is for describing the object by keywords + type: object name: description: VM name or subGroup name if is (not empty) && (> 0). If it is a group, actual VM name will be generated with -N postfix. @@ -353,22 +359,56 @@ definitions: type: object onprem.NetworkInterfaceProperty: properties: - ipAddress: - type: string + ipv4CidrBlocks: + description: IPv4 address with prefix length (e.g., 192.168.0.21/24), instead + of inet addr, Bcast, and Mask + items: + type: string + type: array + ipv6CidrBlocks: + description: IPv6 address with prefix length (e.g., "2001:db8::1/64") + items: + type: string + type: array macAddress: + description: MAC address type: string mtu: description: Maximum Transmission Unit (MTU) in bytes type: integer + name: + description: Interface name (e.g., eth0, ens01, enp0s3) + type: string + state: + description: Interface state (e.g., UP, DOWN) + type: string required: - - ipAddress + - name type: object onprem.NetworkProperty: properties: - gateway: - description: Gateway IP address - example: 172.26.240.0/20 - type: string + ipv4Networks: + example: + - 172.26.240.0/20 + items: + type: string + type: array + ipv6Networks: + description: TBD + items: + type: string + type: array + type: object + onprem.OnPremInfra: + properties: + network: + $ref: '#/definitions/onprem.NetworkProperty' + servers: + items: + $ref: '#/definitions/onprem.ServerProperty' + type: array + required: + - servers type: object onprem.OsProperty: properties: @@ -398,6 +438,33 @@ definitions: required: - prettyName type: object + onprem.RouteProperty: + properties: + destination: + description: Destination network, expressed in CIDR format + type: string + gateway: + description: Gateway address to which packets are forwarded + type: string + interface: + description: Network interface associated with the route + type: string + linkState: + description: Link state of the route (e.g., UP, DOWN) + type: string + metric: + description: Metric value indicating the priority of the route + type: integer + protocol: + description: Protocol used to set the route (e.g., kernel, static) + type: string + scope: + description: Scope of the route (e.g., global, link, host) + type: string + source: + description: Optionally stores the source address (used for policy-based routing) + type: string + type: object onprem.ServerProperty: properties: cpu: @@ -418,6 +485,10 @@ definitions: $ref: '#/definitions/onprem.OsProperty' rootDisk: $ref: '#/definitions/onprem.DiskProperty' + routingTable: + items: + $ref: '#/definitions/onprem.RouteProperty' + type: array type: object externalDocs: description: ▶▶▶ CB-Tumblebug REST API (access via Beetle's reverse proxy) @@ -444,7 +515,7 @@ paths: parameters: - description: 'Custom request ID (NOTE: It will be used as a trace ID.)' in: header - name: x-request-id + name: X-Request-Id type: string produces: - application/json @@ -486,7 +557,7 @@ paths: $ref: '#/definitions/controller.MigrateInfraRequest' - description: 'Custom request ID (NOTE: It will be used as a trace ID.)' in: header - name: x-request-id + name: X-Request-Id type: string produces: - application/json @@ -525,9 +596,17 @@ paths: name: mciId required: true type: string + - default: terminate + description: Action for deletion + enum: + - terminate + - force + in: query + name: action + type: string - description: 'Custom request ID (NOTE: It will be used as a trace ID.)' in: header - name: x-request-id + name: X-Request-Id type: string produces: - application/json @@ -568,7 +647,7 @@ paths: type: string - description: 'Custom request ID (NOTE: It will be used as a trace ID.)' in: header - name: x-request-id + name: X-Request-Id type: string produces: - application/json @@ -597,7 +676,7 @@ paths: parameters: - description: 'Custom request ID (NOTE: It will be used as a trace ID.)' in: header - name: x-request-id + name: X-Request-Id type: string produces: - application/json @@ -629,7 +708,7 @@ paths: $ref: '#/definitions/controller.RecommendInfraRequest' - description: 'Custom request ID (NOTE: It will be used as a trace ID.)' in: header - name: x-request-id + name: X-Request-Id type: string produces: - application/json @@ -659,7 +738,7 @@ paths: parameters: - description: 'Custom request ID (NOTE: It will be used as a trace ID.)' in: header - name: x-request-id + name: X-Request-Id type: string produces: - application/json @@ -690,7 +769,7 @@ paths: $ref: '#/definitions/controller.CreateUserRequest' - description: 'Custom request ID (NOTE: It will be used as a trace ID.)' in: header - name: x-request-id + name: X-Request-Id type: string produces: - application/json @@ -721,7 +800,7 @@ paths: type: integer - description: 'Custom request ID (NOTE: It will be used as a trace ID.)' in: header - name: x-request-id + name: X-Request-Id type: string produces: - application/json @@ -754,7 +833,7 @@ paths: type: integer - description: 'Custom request ID (NOTE: It will be used as a trace ID.)' in: header - name: x-request-id + name: X-Request-Id type: string produces: - application/json @@ -790,7 +869,7 @@ paths: $ref: '#/definitions/controller.PatchUserRequest' - description: 'Custom request ID (NOTE: It will be used as a trace ID.)' in: header - name: x-request-id + name: X-Request-Id type: string produces: - application/json @@ -830,7 +909,7 @@ paths: $ref: '#/definitions/controller.UpdateUserRequest' - description: 'Custom request ID (NOTE: It will be used as a trace ID.)' in: header - name: x-request-id + name: X-Request-Id type: string produces: - application/json @@ -856,7 +935,7 @@ paths: parameters: - description: 'Custom request ID (NOTE: It will be used as a trace ID.)' in: header - name: x-request-id + name: X-Request-Id type: string produces: - application/json diff --git a/deployments/docker-compose/cb-tumblebug/conf/cloud_conf.yaml b/deployments/docker-compose/cb-tumblebug/conf/cloud_conf.yaml index 44e76c8..301d91b 100644 --- a/deployments/docker-compose/cb-tumblebug/conf/cloud_conf.yaml +++ b/deployments/docker-compose/cb-tumblebug/conf/cloud_conf.yaml @@ -75,7 +75,7 @@ cloud: threshold: "3" k8scluster: enable: "n" - cloudit : + cloudit: enable: "y" nlb: enable: "n" diff --git a/deployments/docker-compose/docker-compose.yaml b/deployments/docker-compose/docker-compose.yaml index 7d58e78..8dc4370 100644 --- a/deployments/docker-compose/docker-compose.yaml +++ b/deployments/docker-compose/docker-compose.yaml @@ -55,7 +55,7 @@ services: # CB-Tumblebug cb-tumblebug: - image: cloudbaristaorg/cb-tumblebug:0.9.11 + image: cloudbaristaorg/cb-tumblebug:0.9.12 container_name: cb-tumblebug # build: # context: . @@ -191,7 +191,7 @@ services: # cb-mapui cb-mapui: - image: cloudbaristaorg/cb-mapui:0.9.4 + image: cloudbaristaorg/cb-mapui:0.9.6 container_name: cb-mapui # build: # context: ../cb-mapui diff --git a/go.mod b/go.mod index 16fc000..e4728a2 100644 --- a/go.mod +++ b/go.mod @@ -6,8 +6,8 @@ go 1.23.0 // replace github.com/cloud-barista/cm-model => ../cm-model require ( - github.com/cloud-barista/cb-tumblebug v0.9.11 - github.com/cloud-barista/cm-model v0.0.1 + github.com/cloud-barista/cb-tumblebug v0.9.12 + github.com/cloud-barista/cm-model v0.0.2 github.com/fsnotify/fsnotify v1.7.0 github.com/go-playground/validator/v10 v10.22.0 github.com/go-resty/resty/v2 v2.13.1 diff --git a/go.sum b/go.sum index 4f99c80..12580dd 100644 --- a/go.sum +++ b/go.sum @@ -6,8 +6,12 @@ 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-tumblebug v0.9.11 h1:PLqQ+OD4+Nec1xTHJ3Qde7C74t2XiY5D43UemMg838A= github.com/cloud-barista/cb-tumblebug v0.9.11/go.mod h1:uXi+JmmdU+cqcIqpMgfomzZNbNdrLQ+WZgK9ZlOGjY0= +github.com/cloud-barista/cb-tumblebug v0.9.12 h1:FjjALvPzql3RtloYN+fNkrFhIdZ5RSUryfh8r06hWW8= +github.com/cloud-barista/cb-tumblebug v0.9.12/go.mod h1:uXi+JmmdU+cqcIqpMgfomzZNbNdrLQ+WZgK9ZlOGjY0= github.com/cloud-barista/cm-model v0.0.1 h1:tcj5KHacQYuoLgvcuFoA+Cp23pbQg1xoAYNGtVRJXiU= github.com/cloud-barista/cm-model v0.0.1/go.mod h1:gSuMhQxD813KIdSvkp8uGptYOeyDik749sYcICZjhj8= +github.com/cloud-barista/cm-model v0.0.2 h1:6qxrkENlGurVs20rywKoT7L8OlvK4KWegIpJHaPJN3M= +github.com/cloud-barista/cm-model v0.0.2/go.mod h1:gSuMhQxD813KIdSvkp8uGptYOeyDik749sYcICZjhj8= 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= diff --git a/go.work.sum b/go.work.sum index 8d5138d..9efc08e 100644 --- a/go.work.sum +++ b/go.work.sum @@ -299,6 +299,8 @@ github.com/cloud-barista/cb-log v0.8.2 h1:hPCbLj6TW6m9UWlq002sDuGgxKFVp68w4V3k49 github.com/cloud-barista/cb-log v0.8.2/go.mod h1:nGgfTFMPwl1MpCO3FBjexUkNdOYA0BNJoyM9Pd0lMms= github.com/cloud-barista/cb-tumblebug v0.0.0-20230724172618-8f225d0127e8 h1:3aao7cE0ntlhJwl4p9RBaFz6ulM2xXq/SGR/xPxfxYc= github.com/cloud-barista/cb-tumblebug v0.0.0-20230724172618-8f225d0127e8/go.mod h1:RdSc2Ji06owVW3gwkBlZCSPrmxAyzstCWu9fa0emyco= +github.com/cloud-barista/cb-tumblebug v0.9.12 h1:FjjALvPzql3RtloYN+fNkrFhIdZ5RSUryfh8r06hWW8= +github.com/cloud-barista/cb-tumblebug v0.9.12/go.mod h1:uXi+JmmdU+cqcIqpMgfomzZNbNdrLQ+WZgK9ZlOGjY0= github.com/cloud-barista/cm-beetle/src v0.0.0-20230724172618-8f225d0127e8/go.mod h1:XQuz7L64MNUu04FmG5gB0z41VcrfaLuQP80EGyQTDgo= github.com/cloud-barista/cm-honeybee v0.1.3 h1:G9Gb2NiiDtw9nRn7v56bpUM5FEfyBYJ8kgIKxZJZSkI= github.com/cloud-barista/cm-honeybee v0.1.3/go.mod h1:A0Qm1CY4O1hAMxDRnEWjXACztP2D2y/U9GNNJvYzyzM= diff --git a/pkg/api/rest/controller/migration.go b/pkg/api/rest/controller/migration.go index 8b05218..34bbb69 100644 --- a/pkg/api/rest/controller/migration.go +++ b/pkg/api/rest/controller/migration.go @@ -48,14 +48,14 @@ type MigrateInfraResponse struct { // @Produce json // @Param nsId path string true "Namespace ID" default(mig01) // @Param mciInfo body MigrateInfraRequest true "Specify the information for the targeted mulci-cloud infrastructure (MCI)" -// @Param x-request-id header string false "Custom request ID (NOTE: It will be used as a trace ID.)" +// @Param X-Request-Id header string false "Custom request ID (NOTE: It will be used as a trace ID.)" // @Success 200 {object} MigrateInfraResponse "Successfully migrated to the multi-cloud infrastructure" // @Failure 404 {object} model.Response // @Failure 500 {object} model.Response // @Router /migration/ns/{nsId}/mci [post] func MigrateInfra(c echo.Context) error { - // [Note] Input section + // [Input] nsId := c.Param("nsId") if nsId == "" { err := fmt.Errorf("invalid request, namespace ID (nsId: %s) is required", nsId) @@ -76,13 +76,13 @@ func MigrateInfra(c echo.Context) error { log.Trace().Msgf("req: %v\n", req) log.Trace().Msgf("req.TbMciDynamicReq: %v\n", req.TbMciDynamicReq) - // [Note] Process section + // [Process] // Create the VM infrastructure for migration mciInfo, err := migration.CreateVMInfra(nsId, &req.TbMciDynamicReq) log.Trace().Msgf("mciInfo: %v\n", mciInfo) - // [Note] Ouput section + // [Output] if err != nil { log.Error().Err(err).Msg("failed to create VM infrastructure") @@ -107,14 +107,14 @@ func MigrateInfra(c echo.Context) error { // @Produce json // @Param nsId path string true "Namespace ID" default(mig01) // @Param mciId path string true "Migrated Multi-Cloud Infrastructure (MCI) ID" default(mmci01) -// @Param x-request-id header string false "Custom request ID (NOTE: It will be used as a trace ID.)" +// @Param X-Request-Id header string false "Custom request ID (NOTE: It will be used as a trace ID.)" // @Success 200 {object} MigrateInfraResponse "The migrated multi-cloud infrastructure (MCI) information" // @Failure 404 {object} model.Response // @Failure 500 {object} model.Response // @Router /migration/ns/{nsId}/mci/{mciId} [get] func GetInfra(c echo.Context) error { - // [Note] Input section + // [Input] nsId := c.Param("nsId") if nsId == "" { err := fmt.Errorf("invalid request, the nanespace ID (nsId: %s) is required", nsId) @@ -138,7 +138,7 @@ func GetInfra(c echo.Context) error { return c.JSON(http.StatusBadRequest, res) } - // [Note] Process section + // [Process] vmInfraInfo, err := migration.GetVMInfra(nsId, mciId) if err != nil { log.Error().Err(err).Msg("failed to get the migrated multi-cloud infrastructure") @@ -149,7 +149,7 @@ func GetInfra(c echo.Context) error { return c.JSON(http.StatusInternalServerError, res) } - // [Note] Ouput section + // [Ouput] return c.JSON(http.StatusOK, vmInfraInfo) } @@ -162,14 +162,15 @@ func GetInfra(c echo.Context) error { // @Produce json // @Param nsId path string true "Namespace ID" default(mig01) // @Param mciId path string true "Migrated Multi-Cloud Infrastructure (MCI) ID" default(mmci01) -// @Param x-request-id header string false "Custom request ID (NOTE: It will be used as a trace ID.)" +// @Param action query string false "Action for deletion" Enums(terminate,force) default(terminate) +// @Param X-Request-Id header string false "Custom request ID (NOTE: It will be used as a trace ID.)" // @Success 200 {object} model.Response "The result of deleting the migrated multi-cloud infrastructure (MCI)" // @Failure 404 {object} model.Response // @Failure 500 {object} model.Response // @Router /migration/ns/{nsId}/mci/{mciId} [delete] func DeleteInfra(c echo.Context) error { - // [Note] Input section + // [Input] nsId := c.Param("nsId") if nsId == "" { err := fmt.Errorf("invalid request, the namespace ID (nsId: %s) is required", nsId) @@ -193,8 +194,19 @@ func DeleteInfra(c echo.Context) error { return c.JSON(http.StatusBadRequest, res) } - // [Note] Process section - retMsg, err := migration.DeleteVMInfra(nsId, mciId) + action := c.QueryParam("action") + if action != "" && action != "terminate" && action != "force" { + err := fmt.Errorf("invalid request, the action (action: %s) is invalid", action) + log.Warn().Msg(err.Error()) + res := model.Response{ + Success: false, + Text: err.Error(), + } + return c.JSON(http.StatusBadRequest, res) + } + + // [Process] + retMsg, err := migration.DeleteVMInfra(nsId, mciId, action) if err != nil { log.Error().Err(err).Msg("failed to delete the migrated multi-cloud infrastructure") @@ -205,7 +217,7 @@ func DeleteInfra(c echo.Context) error { return c.JSON(http.StatusInternalServerError, res) } - // [Note] Ouput section + // [Ouput] res := model.Response{ Success: true, Text: retMsg.Message, @@ -237,7 +249,7 @@ func DeleteInfra(c echo.Context) error { // // @Router /migration/infra/network [post] // func MigrateNetwork(c echo.Context) error { -// // [Note] Input section +// // [Input] // req := &MigrateNetworkRequest{} // if err := c.Bind(req); err != nil { // return err @@ -246,7 +258,7 @@ func DeleteInfra(c echo.Context) error { // log.Trace().Msgf("req: %v\n", req) // log.Trace().Msgf("req.DummyNetwork: %v\n", req.DummyNetwork) -// // [Note] Process section +// // [Process] // // Something to process here like, // // Perform some functions, // // Calls external APIs and so on @@ -259,7 +271,7 @@ func DeleteInfra(c echo.Context) error { // // You will have to delete this later. // var err error = nil -// // [Note] Ouput section +// // [Ouput] // if err != nil { // log.Error().Err(err).Msg("Failed to migrate network on a cloud platform") // mapA := map[string]string{"message": err.Error()} @@ -295,7 +307,7 @@ func DeleteInfra(c echo.Context) error { // // @Router /migration/infra/storage [post] // func MigrateStorage(c echo.Context) error { -// // [Note] Input section +// // [Input] // req := &MigrateStorageRequest{} // if err := c.Bind(req); err != nil { // return err @@ -304,7 +316,7 @@ func DeleteInfra(c echo.Context) error { // log.Trace().Msgf("req: %v\n", req) // log.Trace().Msgf("req.DummyStorage: %v\n", req.DummyStorage) -// // [Note] Process section +// // [Process] // // Something to process here like, // // Perform some functions, // // Calls external APIs and so on @@ -317,7 +329,7 @@ func DeleteInfra(c echo.Context) error { // // You will have to delete this later. // var err error = nil -// // [Note] Ouput section +// // [Ouput] // if err != nil { // log.Error().Err(err).Msg("Failed to migrate storage on a cloud platform") // mapA := map[string]string{"message": err.Error()} @@ -353,7 +365,7 @@ func DeleteInfra(c echo.Context) error { // // @Router /migration/infra/instance [post] // func MigrateInstance(c echo.Context) error { -// // [Note] Input section +// // [Input] // req := &MigrateInstanceRequest{} // if err := c.Bind(req); err != nil { // return err @@ -362,7 +374,7 @@ func DeleteInfra(c echo.Context) error { // log.Trace().Msgf("req: %v\n", req) // log.Trace().Msgf("req.DummyInstance: %v\n", req.DummyInstance) -// // [Note] Process section +// // [Process] // // Something to process here like, // // Perform some functions, // // Calls external APIs and so on @@ -375,7 +387,7 @@ func DeleteInfra(c echo.Context) error { // // You will have to delete this later. // var err error = nil -// // [Note] Ouput section +// // [Ouput] // if err != nil { // log.Error().Err(err).Msg("Failed to migrate instance on a cloud platform") // mapA := map[string]string{"message": err.Error()} diff --git a/pkg/api/rest/controller/recommendation.go b/pkg/api/rest/controller/recommendation.go index b0c655d..0403766 100644 --- a/pkg/api/rest/controller/recommendation.go +++ b/pkg/api/rest/controller/recommendation.go @@ -39,8 +39,9 @@ import ( // } type RecommendInfraRequest struct { - // Servers []infra.Infra `json:"servers" validate:"required"` - onprem.OnPremInfra + DesiredProvider string `json:"desiredProvider" validate:"required" example:"aws"` + DesiredRegion string `json:"desiredRegion" validate:"required" example:"ap-northeast-2"` + OnpremiseInfraModel onprem.OnPremInfra `json:"onpremiseInfraModel" validate:"required"` } type RecommendInfraResponse struct { @@ -55,28 +56,39 @@ type RecommendInfraResponse struct { // @Accept json // @Produce json // @Param UserInfra body RecommendInfraRequest true "Specify the your infrastructure to be migrated" -// @Param x-request-id header string false "Custom request ID (NOTE: It will be used as a trace ID.)" +// @Param X-Request-Id header string false "Custom request ID (NOTE: It will be used as a trace ID.)" // @Success 200 {object} RecommendInfraResponse "The result of recommended infrastructure" // @Failure 404 {object} common.SimpleMsg // @Failure 500 {object} common.SimpleMsg // @Router /recommendation/mci [post] func RecommendInfra(c echo.Context) error { - // Input - req := &RecommendInfraRequest{} - if err := c.Bind(req); err != nil { + // [Input] + reqt := &RecommendInfraRequest{} + if err := c.Bind(reqt); err != nil { log.Error().Err(err).Msg("failed to bind a request body") res := common.SimpleMsg{Message: err.Error()} return c.JSON(http.StatusBadRequest, res) } - log.Trace().Msgf("req: %v\n", req) + log.Trace().Msgf("reqt: %v\n", reqt) - // Process - recommendedInfraInfo, err := recommendation.Recommend(req.OnPremInfra) + provider := reqt.DesiredProvider + region := reqt.DesiredRegion + sourceInfra := reqt.OnpremiseInfraModel + + ok, err := recommendation.IsValidProviderAndRegion(provider, region) + if !ok { + log.Error().Err(err).Msg("failed to validate provider and region") + res := common.SimpleMsg{Message: err.Error()} + return c.JSON(http.StatusBadRequest, res) + } + + // [Process] + recommendedInfraInfo, err := recommendation.Recommend(provider, region, sourceInfra) recommendedInfraInfo.TargetInfra.Name = "mmci01" - // Ouput + // [Ouput] if err != nil { log.Error().Err(err).Msg("failed to recommend an appropriate multi-cloud infrastructure (MCI) for cloud migration") res := common.SimpleMsg{Message: err.Error()} diff --git a/pkg/api/rest/controller/sample.go b/pkg/api/rest/controller/sample.go index 08d3f61..60300a6 100644 --- a/pkg/api/rest/controller/sample.go +++ b/pkg/api/rest/controller/sample.go @@ -35,7 +35,7 @@ type GetUsersResponse struct { // @Tags [Sample API] Users // @Accept json // @Produce json -// @Param x-request-id header string false "Custom request ID (NOTE: It will be used as a trace ID.)" +// @Param X-Request-Id header string false "Custom request ID (NOTE: It will be used as a trace ID.)" // @Success 200 {object} GetUsersResponse "(sample) This is a sample description for success response in Swagger UI" // @Failure 404 {object} object "User Not Found" // @Router /sample/users [get] @@ -67,7 +67,7 @@ type GetUserResponse struct { // @Accept json // @Produce json // @Param id path int true "User ID" -// @Param x-request-id header string false "Custom request ID (NOTE: It will be used as a trace ID.)" +// @Param X-Request-Id header string false "Custom request ID (NOTE: It will be used as a trace ID.)" // @Success 200 {object} GetUserResponse "(Sample) This is a sample description for success response in Swagger UI" // @Failure 404 {object} object "User Not Found" // @Router /sample/users/{id} [get] @@ -107,7 +107,7 @@ type CreateUserResponse struct { // @Accept json // @Produce json // @Param User body CreateUserRequest true "User information" -// @Param x-request-id header string false "Custom request ID (NOTE: It will be used as a trace ID.)" +// @Param X-Request-Id header string false "Custom request ID (NOTE: It will be used as a trace ID.)" // @Success 201 {object} GetUserResponse "(Sample) This is a sample description for success response in Swagger UI" // @Failure 400 {object} object "Invalid Request" // @Router /sample/users [post] @@ -144,7 +144,7 @@ type UpdateUserResponse struct { // @Produce json // @Param id path int true "User ID" // @Param User body UpdateUserRequest true "User information to update" -// @Param x-request-id header string false "Custom request ID (NOTE: It will be used as a trace ID.)" +// @Param X-Request-Id header string false "Custom request ID (NOTE: It will be used as a trace ID.)" // @Success 201 {object} UpdateUserResponse "(Sample) This is a sample description for success response in Swagger UI" // @Failure 400 {object} object "Invalid Request" // @Router /sample/users/{id} [put] @@ -186,7 +186,7 @@ type PatchUserResponse struct { // @Produce json // @Param id path int true "User ID" // @Param User body PatchUserRequest true "User information to update" -// @Param x-request-id header string false "Custom request ID (NOTE: It will be used as a trace ID.)" +// @Param X-Request-Id header string false "Custom request ID (NOTE: It will be used as a trace ID.)" // @Success 200 {object} PatchUserResponse "(Sample) This is a sample description for success response in Swagger UI" // @Failure 400 {object} object "Invalid Request" // @Failure 404 {object} object "User Not Found" @@ -222,7 +222,7 @@ func PatchUser(c echo.Context) error { // @Accept json // @Produce json // @Param id path int true "User ID" -// @Param x-request-id header string false "Custom request ID (NOTE: It will be used as a trace ID.)" +// @Param X-Request-Id header string false "Custom request ID (NOTE: It will be used as a trace ID.)" // @Success 200 {string} string "User deletion successful" // @Failure 400 {object} object "Invalid Request" // @Failure 404 {object} object "User Not Found" diff --git a/pkg/core/migration/migration.go b/pkg/core/migration/migration.go index 1ad6621..e2e3ef9 100644 --- a/pkg/core/migration/migration.go +++ b/pkg/core/migration/migration.go @@ -96,6 +96,7 @@ const ( // DefaultSystemLabel is const for string to specify the Default System Label const DefaultSystemLabel string = "Managed by CM-Beetle" +// Create a VM infrastructure for migration func CreateVMInfra(nsId string, infraModel *tbmodel.TbMciDynamicReq) (tbmodel.TbMciInfo, error) { client := resty.New() @@ -130,13 +131,14 @@ func CreateVMInfra(nsId string, infraModel *tbmodel.TbMciDynamicReq) (tbmodel.Tb ) if err != nil { - // common.CBLog.Error(err) + log.Error().Err(err).Msgf("failed to create/migrate the infrastructure (nsId: %s)", nsId) return tbmodel.TbMciInfo{}, err } return responseBody, nil } +// Get the migrated VM infrastructure func GetVMInfra(nsId, infraId string) (tbmodel.TbMciInfo, error) { // Initialize resty client with basic auth @@ -179,7 +181,8 @@ func GetVMInfra(nsId, infraId string) (tbmodel.TbMciInfo, error) { return *responseBody, nil } -func DeleteVMInfra(nsId, infraId string) (common.SimpleMsg, error) { +// Delete the migrated VM infrastructure +func DeleteVMInfra(nsId, infraId, action string) (common.SimpleMsg, error) { // Initialize resty client with basic auth client := resty.New() @@ -193,9 +196,8 @@ func DeleteVMInfra(nsId, infraId string) (common.SimpleMsg, error) { // delete the infrastructure with terminate option method := "DELETE" url := fmt.Sprintf("%s/ns/%s/mci/%s", epTumblebug, nsId, infraId) - options := "option=terminate" - if options != "" { - url += "?" + options + if action != "" { + url += "?option=" + action } // Set request body @@ -222,13 +224,11 @@ func DeleteVMInfra(nsId, infraId string) (common.SimpleMsg, error) { return common.SimpleMsg{}, err } + time.Sleep(5 * time.Second) + // delete the infrastructure with terminate option method = "DELETE" url = fmt.Sprintf("%s/ns/%s/sharedResources", epTumblebug, nsId) - // options = "" - // if options != "" { - // url += "?" + options - // } // Set request body requestBody = common.NoBody diff --git a/pkg/core/recommendation/recommendation.go b/pkg/core/recommendation/recommendation.go index 9233de0..e7f1903 100644 --- a/pkg/core/recommendation/recommendation.go +++ b/pkg/core/recommendation/recommendation.go @@ -21,7 +21,78 @@ import ( "github.com/rs/zerolog/log" ) -func Recommend(srcInfra onprem.OnPremInfra) (RecommendedInfraInfo, error) { +func isSupportedCSP(csp string) bool { + supportedCSPs := map[string]bool{ + "aws": true, + "azure": true, + "gcp": true, + // "alibaba": true, + // "tencent": true, + // "ibm": true, + "ncp": true, + // "nhn": true, + // "kt": true, + // "openstack": true, + } + + return supportedCSPs[csp] +} + +func IsValidProviderAndRegion(provider string, region string) (bool, error) { + + isValid := false + + providerName := strings.ToLower(provider) + regionName := strings.ToLower(region) + + supportedCsp := isSupportedCSP(providerName) + + if !supportedCsp { + err := fmt.Errorf("not supported yet (provider: %s)", providerName) + log.Warn().Msgf(err.Error()) + return isValid, err + } + + // Initialize resty client with basic auth + client := resty.New() + apiUser := config.Tumblebug.API.Username + apiPass := config.Tumblebug.API.Password + client.SetBasicAuth(apiUser, apiPass) + + // set tumblebug rest url + epTumblebug := config.Tumblebug.RestUrl + + // [via Tumblebug] Check if the provider and region are valid + method := "GET" + url := fmt.Sprintf("%s/provider/%s/region/%s", epTumblebug, providerName, regionName) + + // Request body + tbReqt := common.NoBody + tbResp := tbmodel.RegionDetail{} + + err := common.ExecuteHttpRequest( + client, + method, + url, + nil, + common.SetUseBody(tbReqt), + &tbReqt, + &tbResp, + common.VeryShortDuration, + ) + + if err != nil { + log.Error().Err(err).Msg("") + return isValid, err + } + + isValid = true + + return isValid, nil +} + +// Recommend an appropriate multi-cloud infrastructure (MCI) for cloud migration +func Recommend(desiredProvider string, desiredRegion string, srcInfra onprem.OnPremInfra) (RecommendedInfraInfo, error) { var emptyResp RecommendedInfraInfo var recommendedInfraInfo RecommendedInfraInfo @@ -30,7 +101,6 @@ func Recommend(srcInfra onprem.OnPremInfra) (RecommendedInfraInfo, error) { recommendedInfraInfo.TargetInfra = tbmodel.TbMciDynamicReq{ Description: "A cloud infra recommended by CM-Beetle", InstallMonAgent: "no", - Label: "rehosted-mci", Name: "", SystemLabel: "", Vm: []tbmodel.TbVmDynamicReq{}, @@ -113,7 +183,6 @@ func Recommend(srcInfra onprem.OnPremInfra) (RecommendedInfraInfo, error) { 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.Hostname), RootDiskSize: "", // TBD RootDiskType: "", // TBD @@ -145,8 +214,8 @@ func Recommend(srcInfra onprem.OnPremInfra) (RecommendedInfraInfo, error) { memoryMin = 1 } - providerName := "aws" - regionName := "ap-northeast-2" + providerName := desiredProvider + regionName := desiredRegion osNameAndVersion := server.OS.Name + " " + server.OS.Version osNameWithVersion := strings.ToLower(osNameAndVersion) @@ -180,7 +249,7 @@ func Recommend(srcInfra onprem.OnPremInfra) (RecommendedInfraInfo, error) { reqRecommVm := new(tbmodel.DeploymentPlan) err := json.Unmarshal([]byte(planToSearchProperVm), reqRecommVm) if err != nil { - log.Err(err).Msg("") + log.Error().Err(err).Msg("") return emptyResp, err } log.Trace().Msgf("deployment plan for the VM recommendation: %+v", reqRecommVm) @@ -200,7 +269,7 @@ func Recommend(srcInfra onprem.OnPremInfra) (RecommendedInfraInfo, error) { ) if err != nil { - log.Err(err).Msg("") + log.Error().Err(err).Msg("") return emptyResp, err } @@ -247,14 +316,14 @@ func Recommend(srcInfra onprem.OnPremInfra) (RecommendedInfraInfo, error) { ) if err != nil { - log.Err(err).Msg("") + log.Error().Err(err).Msg("") return emptyResp, err } // for pretty logging prettyImages, err := json.MarshalIndent(resMciDynamicCheck.ReqCheck[0].Image, "", " ") if err != nil { - log.Err(err).Msg("failed to marshal response") + log.Error().Err(err).Msg("failed to marshal response") return emptyResp, err } log.Debug().Msgf("resMciDynamicCheck.ReqCheck[0].Image: %s", prettyImages) @@ -335,12 +404,12 @@ func FindBestVmOsImage(keywords string, kwDelimiters []string, vmImages []tbmode var highestScore float64 = 0.0 for _, image := range vmImages { - score := similarity.CalcResourceSimilarity(keywords, kwDelimiters, image.Description, imgDelimiters) + score := similarity.CalcResourceSimilarity(keywords, kwDelimiters, image.GuestOS, imgDelimiters) if score > highestScore { highestScore = score bestVmOsImageID = image.Id } - log.Debug().Msgf("VmImageName: %s, score: %f", image.Description, score) + log.Debug().Msgf("VmImageName: %s, score: %f, description: %s", image.GuestOS, score, image.Description) } log.Debug().Msgf("bestVmOsImageID: %s, highestScore: %f", bestVmOsImageID, highestScore)