diff --git a/Makefile b/Makefile index af69c67..1d2a70e 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -TAG ?= v1.1.17 +TAG ?= v1.2.0 IMAGE_TAG ?= docker.educg.net/cg/k8s-manager:$(TAG) build: export CGO_ENABLED=0 diff --git a/main.go b/main.go index ca01d50..0c7c360 100644 --- a/main.go +++ b/main.go @@ -13,6 +13,7 @@ import ( log "github.com/sirupsen/logrus" "io/fs" m "k8s-manager/src" + "k8s-manager/src/controller" "net/http" "strings" ) @@ -40,7 +41,7 @@ func Cors() gin.HandlerFunc { func main() { m.InitConfig() - m.InitClient() + controller.InitClient() r := gin.Default() // r.Use(cors.Default()) @@ -52,24 +53,24 @@ func main() { r.GET("/index", m.JWTAuthMiddleware, func(c *gin.Context) { c.FileFromFS("/template/app_view.html", http.FS(f)) }) - r.GET("/apps", m.JWTAuthMiddleware, m.GetAppsController) - r.POST("/app", m.JWTAuthMiddleware, m.CreateUpdateDeleteApp) - r.PUT("/app", m.JWTAuthMiddleware, m.CreateUpdateDeleteApp) - r.DELETE("/app", m.JWTAuthMiddleware, m.CreateUpdateDeleteApp) + r.GET("/apps", m.JWTAuthMiddleware, controller.GetAppsController) + r.POST("/app", m.JWTAuthMiddleware, controller.CreateUpdateDeleteApp) + r.PUT("/app", m.JWTAuthMiddleware, controller.CreateUpdateDeleteApp) + r.DELETE("/app", m.JWTAuthMiddleware, controller.CreateUpdateDeleteApp) - r.POST("/dep", m.JWTAuthMiddleware, m.CreateDeleteDeployment) - r.DELETE("/dep", m.JWTAuthMiddleware, m.CreateDeleteDeployment) + r.POST("/dep", m.JWTAuthMiddleware, controller.CreateDeleteDeployment) + r.DELETE("/dep", m.JWTAuthMiddleware, controller.CreateDeleteDeployment) - r.GET("/pod", m.JWTAuthMiddleware, m.GetPodStatus) + r.GET("/pod", m.JWTAuthMiddleware, controller.GetPodStatus) r.GET("/login", LoginToken) r.Any("/test_token", TestToken) - r.GET("/username", m.JWTAuthMiddleware, m.GetUsername) + r.GET("/username", m.JWTAuthMiddleware, controller.GetUsername) - r.GET("/files/:app", m.JWTAuthMiddleware, m.GetFiles) - r.GET("/file/:app/:filename", m.JWTAuthMiddleware, m.GetPostOrDeleteFile) - r.POST("/file/:app/:filename", m.JWTAuthMiddleware, m.GetPostOrDeleteFile) - r.DELETE("/file/:app/:filename", m.JWTAuthMiddleware, m.GetPostOrDeleteFile) + r.GET("/files/:app", m.JWTAuthMiddleware, controller.GetFiles) + r.GET("/file/:app/:filename", m.JWTAuthMiddleware, controller.GetPostOrDeleteFile) + r.POST("/file/:app/:filename", m.JWTAuthMiddleware, controller.GetPostOrDeleteFile) + r.DELETE("/file/:app/:filename", m.JWTAuthMiddleware, controller.GetPostOrDeleteFile) err := r.Run(":8000") if err != nil { diff --git a/src/app_viewmodel.go b/src/controller/app_controller.go similarity index 91% rename from src/app_viewmodel.go rename to src/controller/app_controller.go index 4e4350c..01b8732 100644 --- a/src/app_viewmodel.go +++ b/src/controller/app_controller.go @@ -1,16 +1,17 @@ -package k8s_manager +package controller import ( "encoding/json" "github.com/gin-gonic/gin" log "github.com/sirupsen/logrus" "github.com/thoas/go-funk" + "k8s-manager/src/model" "net/http" "strings" ) type AppViewModel struct { - *AppModel + *model.AppModel Status string ServiceDisplayName string } @@ -53,7 +54,7 @@ func AppPage(c *gin.Context) { } func AppMiddleware(c *gin.Context) { - app := &AppModel{} + app := &model.AppModel{} err := c.ShouldBindJSON(&app) if err == nil { username := c.MustGet("username") @@ -66,7 +67,7 @@ func AppMiddleware(c *gin.Context) { } func CreateUpdateDeleteApp(c *gin.Context) { - app := &AppModel{} + app := &model.AppModel{} err := c.BindJSON(app) if err != nil { log.WithError(err).Error("CreateUpdateDeleteApp") @@ -96,7 +97,7 @@ func CreateUpdateDeleteApp(c *gin.Context) { func GetAppsController(c *gin.Context) { username := c.MustGet("username").(string) - appsvm := funk.Map(GetApps(username), func(a AppModel) AppViewModel { return AppViewModel{AppModel: &a} }).([]AppViewModel) + appsvm := funk.Map(model.GetApps(username), func(a model.AppModel) AppViewModel { return AppViewModel{AppModel: &a} }).([]AppViewModel) for i := range appsvm { a := &appsvm[i] a.Status = statusString(a) diff --git a/src/deployment_manager.go b/src/controller/deployment_controller.go similarity index 87% rename from src/deployment_manager.go rename to src/controller/deployment_controller.go index b86f0bf..1125346 100644 --- a/src/deployment_manager.go +++ b/src/controller/deployment_controller.go @@ -1,17 +1,19 @@ -package k8s_manager +package controller import ( "github.com/gin-gonic/gin" + "k8s-manager/src/model" + "k8s-manager/src/service" "k8s.io/api/apps/v1" "net/http" "strconv" "strings" ) -var K *K8sClient = nil +var K *service.K8sClient = nil func InitClient() { - K = CreateClient() + K = service.CreateClient() } type DeployStatusObject struct { @@ -31,7 +33,7 @@ func CreateDeleteDeployment(c *gin.Context) { c.JSON(http.StatusBadRequest, gin.H{"msg": "wrong id"}) return } - app := AppModel{Id: appId} + app := model.AppModel{Id: appId} if app.Fill() != nil { c.JSON(http.StatusBadRequest, gin.H{"msg": "wrong id"}) return @@ -61,7 +63,7 @@ func GetPodStatus(c *gin.Context) { c.JSON(http.StatusBadRequest, gin.H{"msg": "wrong id"}) return } - app := AppModel{Id: appId} + app := model.AppModel{Id: appId} app.Fill() pod := K.GetPodFromDeployment(app.DeploymentName()) c.JSON(http.StatusOK, pod.Status) diff --git a/src/persistent_file_manager.go b/src/controller/persistent_file_controller.go similarity index 87% rename from src/persistent_file_manager.go rename to src/controller/persistent_file_controller.go index 8582977..59056be 100644 --- a/src/persistent_file_manager.go +++ b/src/controller/persistent_file_controller.go @@ -1,8 +1,9 @@ -package k8s_manager +package controller import ( "github.com/gin-gonic/gin" log "github.com/sirupsen/logrus" + "k8s-manager/src" "net/http" "os" "path" @@ -11,7 +12,7 @@ import ( func GetFiles(c *gin.Context) { username := c.MustGet("username").(string) appName := c.Param("app") - dirPath := path.Join(config.NFSPath, username, appName) + dirPath := path.Join(k8s_manager.GetConfig().NFSPath, username, appName) dir, err := os.ReadDir(dirPath) if err != nil { if !os.IsNotExist(err) { @@ -32,8 +33,8 @@ func GetPostOrDeleteFile(c *gin.Context) { username := c.MustGet("username").(string) appName := c.Param("app") fileName := c.Param("filename") - dirPath := path.Join(config.NFSPath, username, appName) - filePath := path.Join(config.NFSPath, username, appName, fileName) + dirPath := path.Join(k8s_manager.GetConfig().NFSPath, username, appName) + filePath := path.Join(k8s_manager.GetConfig().NFSPath, username, appName, fileName) if c.Request.Method == http.MethodGet { c.FileAttachment(filePath, fileName) } else if c.Request.Method == http.MethodPost { diff --git a/src/app_model.go b/src/model/app_model.go similarity index 93% rename from src/app_model.go rename to src/model/app_model.go index 7186d85..ea068a4 100644 --- a/src/app_model.go +++ b/src/model/app_model.go @@ -1,7 +1,8 @@ -package k8s_manager +package model import ( "fmt" + "k8s-manager/src" v1 "k8s.io/api/core/v1" "strings" "unicode" @@ -26,14 +27,14 @@ func (*AppModel) TableName() string { } func GetApps(username string) []AppModel { - db := DB() + db := k8s_manager.DB() ans := make([]AppModel, 0) db.Where("user_name = ?", username).Find(&ans) return ans } func (a *AppModel) Fill() error { - db := DB() + db := k8s_manager.DB() res := db.First(a, a.Id) return res.Error } @@ -50,20 +51,20 @@ func (a *AppModel) fillDefaults() { func (a *AppModel) Update() error { a.fillDefaults() - db := DB() + db := k8s_manager.DB() db.Save(a) return nil } func (a *AppModel) Create() error { a.fillDefaults() - db := DB() + db := k8s_manager.DB() db.Create(a) return nil } func (a *AppModel) Delete() error { - db := DB() + db := k8s_manager.DB() db.Delete(a, a.Id) return nil } @@ -161,7 +162,7 @@ func (a *AppModel) PersistentVolumeName() string { } func (a *AppModel) NFSPath() string { - return GetConfig().NFSPath + "/" + a.UserName + "/" + a.AppName + return k8s_manager.GetConfig().NFSPath + "/" + a.UserName + "/" + a.AppName } func (a *AppModel) PersistentVolumeClaimName() string { diff --git a/src/k8s_client.go b/src/service/k8s_service.go similarity index 93% rename from src/k8s_client.go rename to src/service/k8s_service.go index 477e6f2..a35ffea 100644 --- a/src/k8s_client.go +++ b/src/service/k8s_service.go @@ -1,10 +1,12 @@ -package k8s_manager +package service import ( "context" "fmt" log "github.com/sirupsen/logrus" "github.com/thoas/go-funk" + "k8s-manager/src" + "k8s-manager/src/model" appv1 "k8s.io/api/apps/v1" v1 "k8s.io/api/core/v1" netv1 "k8s.io/api/networking/v1" @@ -70,7 +72,7 @@ func (c *K8sClient) DeploymentExists(deploymentName string) bool { return false } -func (c *K8sClient) UpdateDeployment(app *AppModel) { +func (c *K8sClient) UpdateDeployment(app *model.AppModel) { labelKey, labelValue := app.GetLabel() l := map[string]string{labelKey: labelValue} if _, err := os.Stat(app.NFSPath()); os.IsNotExist(err) { @@ -94,7 +96,7 @@ func (c *K8sClient) UpdateDeployment(app *AppModel) { Labels: l, }, Spec: appv1.DeploymentSpec{ - Replicas: UnnamedPointer(int32(1)), + Replicas: k8s_manager.UnnamedPointer(int32(1)), Selector: &metav1.LabelSelector{ MatchLabels: l, }, @@ -120,7 +122,7 @@ func (c *K8sClient) UpdateDeployment(app *AppModel) { }, Ports: containerPorts, SecurityContext: &v1.SecurityContext{ - RunAsUser: UnnamedPointer(int64(0)), + RunAsUser: k8s_manager.UnnamedPointer(int64(0)), }, }}, Volumes: []v1.Volume{ @@ -128,7 +130,7 @@ func (c *K8sClient) UpdateDeployment(app *AppModel) { Name: app.PersistentVolumeMountName(), VolumeSource: v1.VolumeSource{ NFS: &v1.NFSVolumeSource{ - Server: config.NFSHost, + Server: k8s_manager.GetConfig().NFSHost, Path: app.NFSPath(), ReadOnly: false, }, @@ -163,7 +165,7 @@ func (c *K8sClient) ServiceExists(servername string) bool { return false } -func (c *K8sClient) UpdateService(app *AppModel) { +func (c *K8sClient) UpdateService(app *model.AppModel) { ports := app.GetPorts() if len(ports) == 0 { return @@ -207,19 +209,19 @@ func (c *K8sClient) UpdateService(app *AppModel) { } -func (c *K8sClient) CreateApp(app *AppModel) { +func (c *K8sClient) CreateApp(app *model.AppModel) { c.UpdateDeployment(app) c.UpdateService(app) c.UpdateIngress(app) } -func (c *K8sClient) DeleteApp(app *AppModel) { +func (c *K8sClient) DeleteApp(app *model.AppModel) { c.DeleteDeployment(app.DeploymentName()) c.DeleteAppService(app) c.DeleteIngress(app.IngressName()) } -func (c *K8sClient) DeleteAppService(app *AppModel) { +func (c *K8sClient) DeleteAppService(app *model.AppModel) { k, v := app.GetLabel() label := labels.FormatLabels(map[string]string{k: v}) svcs, err := c.CoreV1().Services(c.Namespace).List(context.Background(), metav1.ListOptions{ @@ -291,7 +293,7 @@ func (c *K8sClient) IngressExists(name string) bool { return false } -func (c *K8sClient) UpdateIngress(a *AppModel) { +func (c *K8sClient) UpdateIngress(a *model.AppModel) { ports := a.GetPorts() if len(ports) == 0 { return @@ -313,15 +315,15 @@ func (c *K8sClient) UpdateIngress(a *AppModel) { Annotations: annotations, }, Spec: netv1.IngressSpec{ - IngressClassName: UnnamedPointer("nginx"), + IngressClassName: k8s_manager.UnnamedPointer("nginx"), Rules: []netv1.IngressRule{ { IngressRuleValue: netv1.IngressRuleValue{ HTTP: &netv1.HTTPIngressRuleValue{ Paths: []netv1.HTTPIngressPath{ { - Path: "/" + a.ServiceName() + "(/|$)(.*)", - PathType: UnnamedPointer(netv1.PathTypePrefix), + Path: "/svc/" + a.ServiceName() + "(/|$)(.*)", + PathType: k8s_manager.UnnamedPointer(netv1.PathTypePrefix), Backend: netv1.IngressBackend{ Service: &netv1.IngressServiceBackend{ Name: a.ServiceName(),