From a9a8a233411ff56f072ed69383497f6191b7182c Mon Sep 17 00:00:00 2001 From: Ronald Date: Sat, 9 Nov 2024 17:11:17 +0000 Subject: [PATCH] Major changes, adding new routes and moved them This commit moves where the functions for the routes are defined and adds some new ones for the hosts group and adds a new group for CPUs. --- docs/docs.go | 266 +++++++++++++++++++++++++++++++++++++++++++--- docs/swagger.json | 266 +++++++++++++++++++++++++++++++++++++++++++--- docs/swagger.yaml | 179 +++++++++++++++++++++++++++++-- main.go | 72 ++----------- models/models.go | 15 ++- routes.go | 246 ++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 944 insertions(+), 100 deletions(-) create mode 100644 routes.go diff --git a/docs/docs.go b/docs/docs.go index 5e9e3e5..f85a98b 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -15,7 +15,85 @@ const docTemplate = `{ "host": "{{.Host}}", "basePath": "{{.BasePath}}", "paths": { - "/hosts/create": { + "/cpus/add_cpu_to_host": { + "post": { + "description": "Create a CPU", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "CPUs" + ], + "summary": "Create a CPU", + "parameters": [ + { + "description": "The host to create", + "name": "host", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/models.CPU" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/models.CPU" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/models.Error" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/models.Error" + } + }, + "409": { + "description": "Conflict", + "schema": { + "$ref": "#/definitions/models.Error" + } + } + } + } + }, + "/cpus/cpus": { + "get": { + "description": "Lists all the CPUs in LSM for every host", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "CPUs" + ], + "summary": "Get all CPUs in LSM", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/models.CPU" + } + } + } + } + } + }, + "/hosts/add_host": { "post": { "description": "Create a host", "consumes": [ @@ -35,15 +113,109 @@ const docTemplate = `{ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/models.CreateHostInput" + "$ref": "#/definitions/models.AddHost" } } ], "responses": { - "200": { - "description": "OK", + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/models.AddHost" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/models.Error" + } + }, + "409": { + "description": "Conflict", + "schema": { + "$ref": "#/definitions/models.Error" + } + } + } + } + }, + "/hosts/delete_host/{host_id}": { + "delete": { + "description": "Delete a host", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Hosts" + ], + "summary": "Delete a host", + "parameters": [ + { + "type": "string", + "description": "The ID of the host to be deleted", + "name": "host_id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad Request", "schema": { - "$ref": "#/definitions/models.CreateHostInput" + "$ref": "#/definitions/models.Error" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/models.Error" + } + } + } + } + }, + "/hosts/delete_host_by_hostname/{hostname}": { + "delete": { + "description": "Delete a host using it hostname", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Hosts" + ], + "summary": "Delete a host using its hostname", + "parameters": [ + { + "type": "string", + "description": "The hostname of the host to be deleted", + "name": "hostname", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/models.Error" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/models.Error" } } } @@ -77,6 +249,62 @@ const docTemplate = `{ "schema": { "$ref": "#/definitions/models.Host" } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/models.Error" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/models.Error" + } + } + } + } + }, + "/hosts/get_host_id_for_hostname/{hostname}": { + "get": { + "description": "Get a host ID for hostname", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Hosts" + ], + "summary": "Get a host ID for hostname", + "parameters": [ + { + "type": "string", + "description": "The hostname to get the host ID by", + "name": "hostname", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "integer" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/models.Error" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/models.Error" + } } } } @@ -109,12 +337,23 @@ const docTemplate = `{ } }, "definitions": { + "models.AddHost": { + "type": "object", + "properties": { + "hostname": { + "type": "string" + } + } + }, "models.CPU": { "type": "object", "properties": { "cores": { "type": "integer" }, + "host_id": { + "type": "integer" + }, "id": { "type": "integer" }, @@ -129,10 +368,13 @@ const docTemplate = `{ } } }, - "models.CreateHostInput": { + "models.Error": { "type": "object", "properties": { - "hostname": { + "error": { + "type": "string" + }, + "status": { "type": "string" } } @@ -149,9 +391,6 @@ const docTemplate = `{ "hostname": { "type": "string" }, - "id": { - "type": "integer" - }, "memory": { "type": "array", "items": { @@ -163,8 +402,8 @@ const docTemplate = `{ "models.Memory": { "type": "object", "properties": { - "Usage": { - "type": "number" + "host_id": { + "type": "integer" }, "id": { "type": "integer" @@ -178,6 +417,9 @@ const docTemplate = `{ "type": { "type": "string" }, + "usage": { + "type": "number" + }, "used": { "type": "integer" } diff --git a/docs/swagger.json b/docs/swagger.json index 0968bcb..835b0c7 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -5,7 +5,85 @@ }, "basePath": "/api/v1", "paths": { - "/hosts/create": { + "/cpus/add_cpu_to_host": { + "post": { + "description": "Create a CPU", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "CPUs" + ], + "summary": "Create a CPU", + "parameters": [ + { + "description": "The host to create", + "name": "host", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/models.CPU" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/models.CPU" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/models.Error" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/models.Error" + } + }, + "409": { + "description": "Conflict", + "schema": { + "$ref": "#/definitions/models.Error" + } + } + } + } + }, + "/cpus/cpus": { + "get": { + "description": "Lists all the CPUs in LSM for every host", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "CPUs" + ], + "summary": "Get all CPUs in LSM", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/models.CPU" + } + } + } + } + } + }, + "/hosts/add_host": { "post": { "description": "Create a host", "consumes": [ @@ -25,15 +103,109 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/models.CreateHostInput" + "$ref": "#/definitions/models.AddHost" } } ], "responses": { - "200": { - "description": "OK", + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/models.AddHost" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/models.Error" + } + }, + "409": { + "description": "Conflict", + "schema": { + "$ref": "#/definitions/models.Error" + } + } + } + } + }, + "/hosts/delete_host/{host_id}": { + "delete": { + "description": "Delete a host", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Hosts" + ], + "summary": "Delete a host", + "parameters": [ + { + "type": "string", + "description": "The ID of the host to be deleted", + "name": "host_id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad Request", "schema": { - "$ref": "#/definitions/models.CreateHostInput" + "$ref": "#/definitions/models.Error" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/models.Error" + } + } + } + } + }, + "/hosts/delete_host_by_hostname/{hostname}": { + "delete": { + "description": "Delete a host using it hostname", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Hosts" + ], + "summary": "Delete a host using its hostname", + "parameters": [ + { + "type": "string", + "description": "The hostname of the host to be deleted", + "name": "hostname", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/models.Error" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/models.Error" } } } @@ -67,6 +239,62 @@ "schema": { "$ref": "#/definitions/models.Host" } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/models.Error" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/models.Error" + } + } + } + } + }, + "/hosts/get_host_id_for_hostname/{hostname}": { + "get": { + "description": "Get a host ID for hostname", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Hosts" + ], + "summary": "Get a host ID for hostname", + "parameters": [ + { + "type": "string", + "description": "The hostname to get the host ID by", + "name": "hostname", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "integer" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/models.Error" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/models.Error" + } } } } @@ -99,12 +327,23 @@ } }, "definitions": { + "models.AddHost": { + "type": "object", + "properties": { + "hostname": { + "type": "string" + } + } + }, "models.CPU": { "type": "object", "properties": { "cores": { "type": "integer" }, + "host_id": { + "type": "integer" + }, "id": { "type": "integer" }, @@ -119,10 +358,13 @@ } } }, - "models.CreateHostInput": { + "models.Error": { "type": "object", "properties": { - "hostname": { + "error": { + "type": "string" + }, + "status": { "type": "string" } } @@ -139,9 +381,6 @@ "hostname": { "type": "string" }, - "id": { - "type": "integer" - }, "memory": { "type": "array", "items": { @@ -153,8 +392,8 @@ "models.Memory": { "type": "object", "properties": { - "Usage": { - "type": "number" + "host_id": { + "type": "integer" }, "id": { "type": "integer" @@ -168,6 +407,9 @@ "type": { "type": "string" }, + "usage": { + "type": "number" + }, "used": { "type": "integer" } diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 6950a98..9bf2421 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -1,9 +1,16 @@ basePath: /api/v1 definitions: + models.AddHost: + properties: + hostname: + type: string + type: object models.CPU: properties: cores: type: integer + host_id: + type: integer id: type: integer name: @@ -13,9 +20,11 @@ definitions: time: type: string type: object - models.CreateHostInput: + models.Error: properties: - hostname: + error: + type: string + status: type: string type: object models.Host: @@ -26,8 +35,6 @@ definitions: type: array hostname: type: string - id: - type: integer memory: items: $ref: '#/definitions/models.Memory' @@ -35,8 +42,8 @@ definitions: type: object models.Memory: properties: - Usage: - type: number + host_id: + type: integer id: type: integer time: @@ -45,34 +52,149 @@ definitions: type: integer type: type: string + usage: + type: number used: type: integer type: object info: contact: {} paths: - /hosts/create: + /cpus/add_cpu_to_host: post: consumes: - application/json - description: Create a host + description: Create a CPU parameters: - description: The host to create in: body name: host required: true schema: - $ref: '#/definitions/models.CreateHostInput' + $ref: '#/definitions/models.CPU' + produces: + - application/json + responses: + "201": + description: Created + schema: + $ref: '#/definitions/models.CPU' + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.Error' + "404": + description: Not Found + schema: + $ref: '#/definitions/models.Error' + "409": + description: Conflict + schema: + $ref: '#/definitions/models.Error' + summary: Create a CPU + tags: + - CPUs + /cpus/cpus: + get: + consumes: + - application/json + description: Lists all the CPUs in LSM for every host produces: - application/json responses: "200": description: OK schema: - $ref: '#/definitions/models.CreateHostInput' + items: + $ref: '#/definitions/models.CPU' + type: array + summary: Get all CPUs in LSM + tags: + - CPUs + /hosts/add_host: + post: + consumes: + - application/json + description: Create a host + parameters: + - description: The host to create + in: body + name: host + required: true + schema: + $ref: '#/definitions/models.AddHost' + produces: + - application/json + responses: + "201": + description: Created + schema: + $ref: '#/definitions/models.AddHost' + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.Error' + "409": + description: Conflict + schema: + $ref: '#/definitions/models.Error' summary: Create a host tags: - Hosts + /hosts/delete_host/{host_id}: + delete: + consumes: + - application/json + description: Delete a host + parameters: + - description: The ID of the host to be deleted + in: path + name: host_id + required: true + type: string + produces: + - application/json + responses: + "204": + description: No Content + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.Error' + "404": + description: Not Found + schema: + $ref: '#/definitions/models.Error' + summary: Delete a host + tags: + - Hosts + /hosts/delete_host_by_hostname/{hostname}: + delete: + consumes: + - application/json + description: Delete a host using it hostname + parameters: + - description: The hostname of the host to be deleted + in: path + name: hostname + required: true + type: string + produces: + - application/json + responses: + "204": + description: No Content + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.Error' + "404": + description: Not Found + schema: + $ref: '#/definitions/models.Error' + summary: Delete a host using its hostname + tags: + - Hosts /hosts/get_host_by_hostname/{hostname}: get: consumes: @@ -91,9 +213,46 @@ paths: description: OK schema: $ref: '#/definitions/models.Host' + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.Error' + "404": + description: Not Found + schema: + $ref: '#/definitions/models.Error' summary: Get a host by hostname tags: - Hosts + /hosts/get_host_id_for_hostname/{hostname}: + get: + consumes: + - application/json + description: Get a host ID for hostname + parameters: + - description: The hostname to get the host ID by + in: path + name: hostname + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + type: integer + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.Error' + "404": + description: Not Found + schema: + $ref: '#/definitions/models.Error' + summary: Get a host ID for hostname + tags: + - Hosts /hosts/hosts: get: consumes: diff --git a/main.go b/main.go index ce1d7da..c468d1e 100644 --- a/main.go +++ b/main.go @@ -1,11 +1,9 @@ package main import ( - "errors" "fmt" "log" docs "lsm-api/docs" - "net/http" "strings" "github.com/gin-gonic/gin" @@ -24,66 +22,6 @@ var DB *gorm.DB // @BasePath /api/v1 -// @Summary Get all hosts in LSM -// @Description Lists all the hosts in LSM -// @Tags Hosts -// @Accept json -// @Produce json -// @Success 200 {object} []models.Host -// @Router /hosts/hosts [get] -func GetHosts(c *gin.Context) { - var hosts []models.Host - DB.Find(&hosts) - c.JSON(http.StatusOK, hosts) -} - -// @Summary Get a host by hostname -// @Description Get a host by hostname -// @Tags Hosts -// @Accept json -// @Produce json -// @Param hostname path string true "The hostname to get the host by" -// @Success 200 {object} models.Host -// @Router /hosts/get_host_by_hostname/{hostname} [get] -func GetHostByHostname(c *gin.Context) { - var host models.Host - hostname := c.Param("hostname") - - log.Println("TEST", hostname) - - if err := DB.Where("hostname = ?", hostname).First(&host).Error; err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": "Record not found"}) - } - - c.JSON(http.StatusOK, host) -} - -// CreateHost godoc -// @Summary Create a host -// @Description Create a host -// @Tags Hosts -// @Accept json -// @Produce json -// @Param host body models.CreateHostInput true "The host to create" -// @Success 200 {object} models.CreateHostInput -// @Router /hosts/create [post] -func CreateHost(c *gin.Context) { - var input models.CreateHostInput - if err := c.ShouldBindJSON(&input); err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) - return - } - - host := models.Host{Hostname: input.Hostname} - result := DB.Create(&host) - if errors.Is(result.Error, gorm.ErrDuplicatedKey) { - c.JSON(http.StatusBadRequest, gin.H{"error": "Hostname already exists"}) - return - } - - c.JSON(http.StatusOK, input) -} - func main() { cfg, err := ini.Load("config.ini") if err != nil { @@ -147,7 +85,15 @@ func main() { { hosts.GET("/hosts", GetHosts) hosts.GET("/get_host_by_hostname/:hostname", GetHostByHostname) - hosts.POST("/create", CreateHost) + hosts.GET("/get_host_id_for_hostname/:hostname", GetHostIDForHostname) + hosts.POST("/add_host", AddHost) + hosts.DELETE("/delete_host/:host_id", DeleteHost) + hosts.DELETE("/delete_host_by_hostname/:hostname", DeleteHostByHostname) + } + cpus := v1.Group("/cpus") + { + cpus.GET("/cpus", GetCPUs) + cpus.POST("/add_cpu_to_host", AddCPUToHost) } } diff --git a/models/models.go b/models/models.go index e251b82..5cf2dcb 100644 --- a/models/models.go +++ b/models/models.go @@ -13,6 +13,8 @@ type CPU struct { Name string `json:"name"` Socket int `json:"socket"` Cores int `json:"cores"` + HostID int `json:"host_id"` + Host Host `json:"-" gorm:"foreignKey:ID;references:HostID"` } type Memory struct { @@ -22,17 +24,24 @@ type Memory struct { Type string `json:"type"` Total int `json:"total"` Used int `json:"used"` - Usage float64 `json:"Usage"` + Usage float64 `json:"usage"` + HostID int `json:"host_id"` + Host Host `json:"-" gorm:"foreignKey:ID;references:HostID"` } type Host struct { gorm.Model `json:"-"` - ID uint `json:"id" gorm:"primary_key"` + ID string `json:"-" gorm:"primary_key;autoIncrement"` Hostname string `json:"hostname" gorm:"unique"` Cpus []CPU `json:"cpus" gorm:"foreignKey:ID"` Memory []Memory `json:"memory" gorm:"foreignKey:ID"` } -type CreateHostInput struct { +type AddHost struct { Hostname string `json:"hostname"` } + +type Error struct { + Status string `json:"status"` + Error string `json:"error"` +} diff --git a/routes.go b/routes.go new file mode 100644 index 0000000..716eac7 --- /dev/null +++ b/routes.go @@ -0,0 +1,246 @@ +package main + +import ( + "errors" + "lsm-api/models" + "net/http" + + "github.com/gin-gonic/gin" + "gorm.io/gorm" +) + +// @Summary Get all hosts in LSM +// @Description Lists all the hosts in LSM +// @Tags Hosts +// @Accept json +// @Produce json +// @Success 200 {object} []models.Host +// @Router /hosts/hosts [get] +func GetHosts(c *gin.Context) { + var hosts []models.Host + DB.Find(&hosts) + c.JSON(http.StatusOK, hosts) +} + +// @Summary Get a host by hostname +// @Description Get a host by hostname +// @Tags Hosts +// @Accept json +// @Produce json +// @Param hostname path string true "The hostname to get the host by" +// @Success 200 {object} models.Host +// @Failure 400 {object} models.Error +// @Failure 404 {object} models.Error +// @Router /hosts/get_host_by_hostname/{hostname} [get] +func GetHostByHostname(c *gin.Context) { + var host models.Host + hostname := c.Param("hostname") + + if err := DB.Where("hostname = ?", hostname).First(&host).Error; err == gorm.ErrRecordNotFound { + c.JSON(http.StatusBadRequest, gin.H{ + "status": "error", + "error": "record not found", + }) + return + } else if err != nil { + c.JSON(http.StatusBadRequest, gin.H{ + "status": "error", + "error": err.Error, + }) + } + + c.JSON(http.StatusOK, host) +} + +// @Summary Get a host ID for hostname +// @Description Get a host ID for hostname +// @Tags Hosts +// @Accept json +// @Produce json +// @Param hostname path string true "The hostname to get the host ID by" +// @Success 200 {object} int +// @Failure 400 {object} models.Error +// @Failure 404 {object} models.Error +// @Router /hosts/get_host_id_for_hostname/{hostname} [get] +func GetHostIDForHostname(c *gin.Context) { + var host models.Host + hostname := c.Param("hostname") + + if err := DB.Where("hostname = ?", hostname).First(&host).Error; err == gorm.ErrRecordNotFound { + c.JSON(http.StatusNotFound, gin.H{ + "Status": "failed", + "error": "record not found", + }) + return + } else if err != nil { + c.JSON(http.StatusNotFound, gin.H{ + "Status": "failed", + "Error": err.Error, + }) + return + } + + c.JSON(http.StatusOK, host.ID) +} + +// AddHost godoc +// @Summary Create a host +// @Description Create a host +// @Tags Hosts +// @Accept json +// @Produce json +// @Param host body models.AddHost true "The host to create" +// @Success 201 {object} models.AddHost +// @Failure 400 {object} models.Error +// @Failure 409 {object} models.Error +// @Router /hosts/add_host [post] +func AddHost(c *gin.Context) { + var input models.AddHost + if err := c.ShouldBindJSON(&input); err != nil { + c.JSON(http.StatusBadRequest, gin.H{ + "status": "error", + "error": err.Error(), + }) + return + } + + host := models.Host{Hostname: input.Hostname} + result := DB.Create(&host) + if errors.Is(result.Error, gorm.ErrDuplicatedKey) { + c.JSON(http.StatusConflict, gin.H{ + "status": "failure", + "error": "host already exists in lsm", + }) + return + } else if result.Error != nil { + c.JSON(http.StatusBadRequest, gin.H{ + "status": "failure", + "error": result.Error, + }) + return + } + + c.JSON(http.StatusCreated, input) +} + +// DeleteHost godoc +// @Summary Delete a host +// @Description Delete a host +// @Tags Hosts +// @Accept json +// @Produce json +// @Param host_id path string true "The ID of the host to be deleted" +// @Success 204 +// @Failure 400 {object} models.Error +// @Failure 404 {object} models.Error +// @Router /hosts/delete_host/{host_id} [delete] +func DeleteHost(c *gin.Context) { + var host models.Host + host_id := c.Param("host_id") + if err := DB.Where("ID = ?", host_id).Delete(&host).Error; err != nil { + c.JSON(http.StatusBadRequest, gin.H{ + "status": "error", + "error": err.Error, + }) + return + } else if DB.RowsAffected < 1 { + c.JSON(http.StatusNotFound, gin.H{ + "status": "error", + "error": "record not found", + }) + return + } + + c.Status(http.StatusNoContent) +} + +// DeleteHostByHostname godoc +// @Summary Delete a host using its hostname +// @Description Delete a host using it hostname +// @Tags Hosts +// @Accept json +// @Produce json +// @Param hostname path string true "The hostname of the host to be deleted" +// @Success 204 +// @Failure 400 {object} models.Error +// @Failure 404 {object} models.Error +// @Router /hosts/delete_host_by_hostname/{hostname} [delete] +func DeleteHostByHostname(c *gin.Context) { + hostname := c.Param("hostname") + var host models.Host + if result := DB.Where("hostname = ?", hostname).Unscoped().Delete(&host); result.Error != nil { + c.JSON(http.StatusBadRequest, gin.H{ + "status": "error", + "error": result.Error, + }) + return + } else if result.RowsAffected < 1 { + c.JSON(http.StatusNotFound, gin.H{ + "status": "error", + "error": "record not found", + }) + return + } + + c.Status(http.StatusNoContent) +} + +// @Summary Get all CPUs in LSM +// @Description Lists all the CPUs in LSM for every host +// @Tags CPUs +// @Accept json +// @Produce json +// @Success 200 {object} []models.CPU +// @Router /cpus/cpus [get] +func GetCPUs(c *gin.Context) { + var CPUs []models.CPU + DB.Find(&CPUs) + c.JSON(http.StatusOK, CPUs) +} + +// AddCPUToHost godoc +// @Summary Create a CPU +// @Description Create a CPU +// @Tags CPUs +// @Accept json +// @Produce json +// @Param host body models.CPU true "The host to create" +// @Success 201 {object} models.CPU +// @Failure 400 {object} models.Error +// @Failure 404 {object} models.Error +// @Failure 409 {object} models.Error +// @Router /cpus/add_cpu_to_host [post] +func AddCPUToHost(c *gin.Context) { + var cpu models.CPU + if err := c.ShouldBindJSON(&cpu); err != nil { + c.JSON(http.StatusBadRequest, gin.H{ + "status": "error", + "error": err.Error, + }) + return + } + + var host models.Host + if err := DB.Where("ID = ?", cpu.HostID).First(&host).Error; err == gorm.ErrRecordNotFound { + c.JSON(http.StatusNotFound, gin.H{ + "status": "failure", + "error": "host not found", + }) + } + result := DB.Create(&cpu) + if errors.Is(result.Error, gorm.ErrDuplicatedKey) { + c.JSON(http.StatusConflict, gin.H{ + "status": "failure", + "error": "host already exists in lsm", + }) + return + } else if result.Error != nil { + c.JSON(http.StatusBadRequest, gin.H{ + "status": "failure", + "error": result.Error, + }) + return + } + + c.JSON(http.StatusCreated, cpu) +}