Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 17 additions & 3 deletions .github/workflows/deploy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:

steps:
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v4

- name: Build and tag Docker image
run: |
Expand All @@ -21,8 +21,22 @@ jobs:

- name: Deploy container locally
run: |
IMAGE=${{ secrets.DOCKER_HUB_USERNAME }}/control_deploy:latest
IMAGE=${{ secrets.DOCKER_HUB_USERNAME }}/control_dev:latest
docker stop CONTROL_DEPLOY || true
docker rm CONTROL_DEPLOY || true
docker run -d --name CONTROL_DEPLOY -p 8081:8081 $IMAGE
docker run -d --name CONTROL_DEPLOY -p 8083:8081 --restart=always \
--add-host host.docker.internal:host-gateway \
-e CORES="${{ secrets.CORES }}" \
-e DB_USER="${{ secrets.DB_USER }}" \
-e DB_PASSWORD="${{ secrets.DB_PASSWORD }}" \
-e DB_HOST="${{ secrets.DB_HOST }}" \
-e DB_NAME="${{ secrets.DB_NAME }}" \
-e GUAC_DB_USER="${{ secrets.GUAC_DB_USER }}" \
-e GUAC_DB_PASSWORD="${{ secrets.GUAC_DB_PASSWORD }}" \
-e GUAC_DB_HOST="${{ secrets.GUAC_DB_HOST }}" \
-e GUAC_DB_NAME="${{ secrets.GUAC_DB_NAME }}" \
-e REDIS_HOST="${{ secrets.REDIS_HOST }}" \
-e CMS_HOST="${{ secrets.CMS_HOST }}" \
-e GUAC_BASE_URL="${{ secrets.GUAC_BASE_URL }}" \
$IMAGE
docker system prune -af
2 changes: 1 addition & 1 deletion .github/workflows/dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:

steps:
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v4

- name: Build and tag Docker image
run: |
Expand Down
40 changes: 40 additions & 0 deletions .github/workflows/pr-build-check.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: PR Build Verification

on:
pull_request:
types: [opened, synchronize, reopened]
branches:
- main
- Dev

jobs:
build-check:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.23.x'

- name: Download Go modules
run: go mod download

- name: Build
run: go build -o main .

- name: Comment on failure
if: failure()
uses: actions/github-script@v7
with:
script: |
await github.rest.pulls.createReview({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.payload.pull_request.number,
event: 'COMMENT',
body: 'Failed To BUILD! Please check the build logs for details and Resolve the issues before merging.'
});
44 changes: 44 additions & 0 deletions api/connect_vm.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package api

import (
"encoding/json"
"net/http"

"github.com/easy-cloud-Knet/KWS_Control/service"
"github.com/easy-cloud-Knet/KWS_Control/structure"
"github.com/easy-cloud-Knet/KWS_Control/util"
)

type ApiVmConnectRequest struct {
UUID structure.UUID `json:"uuid"`
}

type ApiVmConnectResponse struct {
AuthToken string `json:"authToken"`
}

func (c *handlerContext) vmConnect(w http.ResponseWriter, r *http.Request) {
log := util.GetLogger()

uuidStr := r.URL.Query().Get("uuid")
if uuidStr == "" {
http.Error(w, "Missing 'uuid' query parameter", http.StatusBadRequest)
log.Error("Missing 'uuid' query parameter", nil, true)
return
}

uuid := structure.UUID(uuidStr)
authToken, err := service.GetGuacamoleToken(uuid, c.context)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
log.Error("Failed to get Guacamole token: %v", err, true)
return
}

w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(ApiVmConnectResponse{AuthToken: authToken}); err != nil {
log.Error("Failed to encode response: %v", err, true)
http.Error(w, "Failed to encode response", http.StatusInternalServerError)
return
}
}
28 changes: 28 additions & 0 deletions api/create_vm.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package api

import (
"net/http"

"github.com/easy-cloud-Knet/KWS_Control/service"
"github.com/easy-cloud-Knet/KWS_Control/util"
)

func (c *handlerContext) createVm(w http.ResponseWriter, r *http.Request) {
log := util.GetLogger()

err := service.CreateVM(w, r, c.context, c.rdb)
if err != nil {
h := w.Header()
h.Del("Content-Length")
h.Set("Content-Type", "text/plain; charset=utf-8")
h.Set("X-Content-Type-Options", "nosniff")
w.WriteHeader(http.StatusMethodNotAllowed)

log.Error("Failed to create VM: %v", err, true)
return
}
defer r.Body.Close()

w.WriteHeader(http.StatusCreated)
_, _ = w.Write([]byte("VM created successfully"))
}
30 changes: 30 additions & 0 deletions api/delete_vm.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package api

import (
"encoding/json"
"net/http"

"github.com/easy-cloud-Knet/KWS_Control/service"
"github.com/easy-cloud-Knet/KWS_Control/structure"
)

type ApiDeleteVmRequest struct {
UUID structure.UUID `json:"uuid"`
}

func (c *handlerContext) deleteVm(w http.ResponseWriter, r *http.Request) {
var req ApiDeleteVmRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
w.WriteHeader(http.StatusBadRequest)
return
}
defer r.Body.Close()

err := service.DeleteVM(req.UUID, c.context, c.rdb)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}

w.WriteHeader(http.StatusOK)
}
58 changes: 58 additions & 0 deletions api/get_vm_info.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package api

import (
"encoding/json"
"net/http"

"github.com/easy-cloud-Knet/KWS_Control/service"
"github.com/easy-cloud-Knet/KWS_Control/structure"
"github.com/easy-cloud-Knet/KWS_Control/util"
)

type ApiVmInfoRequest struct {
UUID structure.UUID `json:"uuid"`
}

type ApiVmInfoResponse struct {
UUID structure.UUID `json:"uuid"`
CPU uint32 `json:"cpu"`
Memory uint32 `json:"memory"` // MiB
Disk uint32 `json:"disk"` // MiB
IP string `json:"ip"`
}

func (c *handlerContext) vmInfo(w http.ResponseWriter, r *http.Request) {
log := util.GetLogger()

var req ApiVmInfoRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "invalid request body", http.StatusBadRequest)
log.Error("Invalid request body: %v", err, true)
return
}
defer r.Body.Close()

vmInfo, err := service.GetVMInfoFromRedis(r.Context(), c.rdb, req.UUID)
if err != nil {
http.Error(w, err.Error(), http.StatusNotFound)
log.Error("failed to get vm info from redis: %v", err, true)
return
}

response := ApiVmInfoResponse{
UUID: vmInfo.UUID,
CPU: vmInfo.CPU,
Memory: vmInfo.Memory,
Disk: vmInfo.Disk,
IP: vmInfo.IP,
}

w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(response); err != nil {
log.Error("failed to encode vm info response: %v", err, true)
http.Error(w, "failed to encode response", http.StatusInternalServerError)
return
}

log.Info("retrieved vm info from redis: UUID=%s", string(req.UUID), true)
}
58 changes: 58 additions & 0 deletions api/get_vm_status.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package api

import (
"encoding/json"
"net/http"

"github.com/easy-cloud-Knet/KWS_Control/service"
"github.com/easy-cloud-Knet/KWS_Control/structure"
"github.com/easy-cloud-Knet/KWS_Control/util"
)

type ApiVmStatusRequest struct {
UUID structure.UUID `json:"uuid"`
Type string `json:"type"` // "cpu", "memory", or "disk"
}

func (c *handlerContext) vmStatus(w http.ResponseWriter, r *http.Request) {
log := util.GetLogger()

var req ApiVmStatusRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "Invalid request body", http.StatusBadRequest)
log.Error("Failed to decode request body: %v", err, true)
return
}
defer r.Body.Close()

statusType := req.Type
if statusType != "cpu" && statusType != "memory" && statusType != "disk" {
http.Error(w, "Invalid status type. Must be 'cpu', 'memory', or 'disk'", http.StatusBadRequest)
return
}

var data any
var err error

switch statusType {
case "cpu":
data, err = service.GetVMCpuInfo(req.UUID, c.context)
case "memory":
data, err = service.GetVMMemoryInfo(req.UUID, c.context)
case "disk":
data, err = service.GetVMDiskInfo(req.UUID, c.context)
}

if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
log.Error("Failed to get VM status: %v", err, true)
return
}

w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(data); err != nil {
log.Error("Failed to encode response: %v", err, true)
http.Error(w, "Failed to encode response", http.StatusInternalServerError)
return
}
}
75 changes: 0 additions & 75 deletions api/model/vm.go

This file was deleted.

Loading
Loading