use package

This commit is contained in:
w-mj 2023-03-14 19:35:12 +08:00
parent 094ad14dfc
commit 5954615bea
No known key found for this signature in database
GPG Key ID: 3A2CB5BE2F835897
7 changed files with 56 additions and 48 deletions

View File

@ -1,4 +1,4 @@
TAG ?= v1.1.17 TAG ?= v1.2.0
IMAGE_TAG ?= docker.educg.net/cg/k8s-manager:$(TAG) IMAGE_TAG ?= docker.educg.net/cg/k8s-manager:$(TAG)
build: export CGO_ENABLED=0 build: export CGO_ENABLED=0

27
main.go
View File

@ -13,6 +13,7 @@ import (
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"io/fs" "io/fs"
m "k8s-manager/src" m "k8s-manager/src"
"k8s-manager/src/controller"
"net/http" "net/http"
"strings" "strings"
) )
@ -40,7 +41,7 @@ func Cors() gin.HandlerFunc {
func main() { func main() {
m.InitConfig() m.InitConfig()
m.InitClient() controller.InitClient()
r := gin.Default() r := gin.Default()
// r.Use(cors.Default()) // r.Use(cors.Default())
@ -52,24 +53,24 @@ func main() {
r.GET("/index", m.JWTAuthMiddleware, func(c *gin.Context) { r.GET("/index", m.JWTAuthMiddleware, func(c *gin.Context) {
c.FileFromFS("/template/app_view.html", http.FS(f)) c.FileFromFS("/template/app_view.html", http.FS(f))
}) })
r.GET("/apps", m.JWTAuthMiddleware, m.GetAppsController) r.GET("/apps", m.JWTAuthMiddleware, controller.GetAppsController)
r.POST("/app", m.JWTAuthMiddleware, m.CreateUpdateDeleteApp) r.POST("/app", m.JWTAuthMiddleware, controller.CreateUpdateDeleteApp)
r.PUT("/app", m.JWTAuthMiddleware, m.CreateUpdateDeleteApp) r.PUT("/app", m.JWTAuthMiddleware, controller.CreateUpdateDeleteApp)
r.DELETE("/app", m.JWTAuthMiddleware, m.CreateUpdateDeleteApp) r.DELETE("/app", m.JWTAuthMiddleware, controller.CreateUpdateDeleteApp)
r.POST("/dep", m.JWTAuthMiddleware, m.CreateDeleteDeployment) r.POST("/dep", m.JWTAuthMiddleware, controller.CreateDeleteDeployment)
r.DELETE("/dep", m.JWTAuthMiddleware, m.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.GET("/login", LoginToken)
r.Any("/test_token", TestToken) 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("/files/:app", m.JWTAuthMiddleware, controller.GetFiles)
r.GET("/file/:app/:filename", m.JWTAuthMiddleware, m.GetPostOrDeleteFile) r.GET("/file/:app/:filename", m.JWTAuthMiddleware, controller.GetPostOrDeleteFile)
r.POST("/file/:app/:filename", m.JWTAuthMiddleware, m.GetPostOrDeleteFile) r.POST("/file/:app/:filename", m.JWTAuthMiddleware, controller.GetPostOrDeleteFile)
r.DELETE("/file/:app/:filename", m.JWTAuthMiddleware, m.GetPostOrDeleteFile) r.DELETE("/file/:app/:filename", m.JWTAuthMiddleware, controller.GetPostOrDeleteFile)
err := r.Run(":8000") err := r.Run(":8000")
if err != nil { if err != nil {

View File

@ -1,16 +1,17 @@
package k8s_manager package controller
import ( import (
"encoding/json" "encoding/json"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"github.com/thoas/go-funk" "github.com/thoas/go-funk"
"k8s-manager/src/model"
"net/http" "net/http"
"strings" "strings"
) )
type AppViewModel struct { type AppViewModel struct {
*AppModel *model.AppModel
Status string Status string
ServiceDisplayName string ServiceDisplayName string
} }
@ -53,7 +54,7 @@ func AppPage(c *gin.Context) {
} }
func AppMiddleware(c *gin.Context) { func AppMiddleware(c *gin.Context) {
app := &AppModel{} app := &model.AppModel{}
err := c.ShouldBindJSON(&app) err := c.ShouldBindJSON(&app)
if err == nil { if err == nil {
username := c.MustGet("username") username := c.MustGet("username")
@ -66,7 +67,7 @@ func AppMiddleware(c *gin.Context) {
} }
func CreateUpdateDeleteApp(c *gin.Context) { func CreateUpdateDeleteApp(c *gin.Context) {
app := &AppModel{} app := &model.AppModel{}
err := c.BindJSON(app) err := c.BindJSON(app)
if err != nil { if err != nil {
log.WithError(err).Error("CreateUpdateDeleteApp") log.WithError(err).Error("CreateUpdateDeleteApp")
@ -96,7 +97,7 @@ func CreateUpdateDeleteApp(c *gin.Context) {
func GetAppsController(c *gin.Context) { func GetAppsController(c *gin.Context) {
username := c.MustGet("username").(string) 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 { for i := range appsvm {
a := &appsvm[i] a := &appsvm[i]
a.Status = statusString(a) a.Status = statusString(a)

View File

@ -1,17 +1,19 @@
package k8s_manager package controller
import ( import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"k8s-manager/src/model"
"k8s-manager/src/service"
"k8s.io/api/apps/v1" "k8s.io/api/apps/v1"
"net/http" "net/http"
"strconv" "strconv"
"strings" "strings"
) )
var K *K8sClient = nil var K *service.K8sClient = nil
func InitClient() { func InitClient() {
K = CreateClient() K = service.CreateClient()
} }
type DeployStatusObject struct { type DeployStatusObject struct {
@ -31,7 +33,7 @@ func CreateDeleteDeployment(c *gin.Context) {
c.JSON(http.StatusBadRequest, gin.H{"msg": "wrong id"}) c.JSON(http.StatusBadRequest, gin.H{"msg": "wrong id"})
return return
} }
app := AppModel{Id: appId} app := model.AppModel{Id: appId}
if app.Fill() != nil { if app.Fill() != nil {
c.JSON(http.StatusBadRequest, gin.H{"msg": "wrong id"}) c.JSON(http.StatusBadRequest, gin.H{"msg": "wrong id"})
return return
@ -61,7 +63,7 @@ func GetPodStatus(c *gin.Context) {
c.JSON(http.StatusBadRequest, gin.H{"msg": "wrong id"}) c.JSON(http.StatusBadRequest, gin.H{"msg": "wrong id"})
return return
} }
app := AppModel{Id: appId} app := model.AppModel{Id: appId}
app.Fill() app.Fill()
pod := K.GetPodFromDeployment(app.DeploymentName()) pod := K.GetPodFromDeployment(app.DeploymentName())
c.JSON(http.StatusOK, pod.Status) c.JSON(http.StatusOK, pod.Status)

View File

@ -1,8 +1,9 @@
package k8s_manager package controller
import ( import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"k8s-manager/src"
"net/http" "net/http"
"os" "os"
"path" "path"
@ -11,7 +12,7 @@ import (
func GetFiles(c *gin.Context) { func GetFiles(c *gin.Context) {
username := c.MustGet("username").(string) username := c.MustGet("username").(string)
appName := c.Param("app") 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) dir, err := os.ReadDir(dirPath)
if err != nil { if err != nil {
if !os.IsNotExist(err) { if !os.IsNotExist(err) {
@ -32,8 +33,8 @@ func GetPostOrDeleteFile(c *gin.Context) {
username := c.MustGet("username").(string) username := c.MustGet("username").(string)
appName := c.Param("app") appName := c.Param("app")
fileName := c.Param("filename") fileName := c.Param("filename")
dirPath := path.Join(config.NFSPath, username, appName) dirPath := path.Join(k8s_manager.GetConfig().NFSPath, username, appName)
filePath := path.Join(config.NFSPath, username, appName, fileName) filePath := path.Join(k8s_manager.GetConfig().NFSPath, username, appName, fileName)
if c.Request.Method == http.MethodGet { if c.Request.Method == http.MethodGet {
c.FileAttachment(filePath, fileName) c.FileAttachment(filePath, fileName)
} else if c.Request.Method == http.MethodPost { } else if c.Request.Method == http.MethodPost {

View File

@ -1,7 +1,8 @@
package k8s_manager package model
import ( import (
"fmt" "fmt"
"k8s-manager/src"
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
"strings" "strings"
"unicode" "unicode"
@ -26,14 +27,14 @@ func (*AppModel) TableName() string {
} }
func GetApps(username string) []AppModel { func GetApps(username string) []AppModel {
db := DB() db := k8s_manager.DB()
ans := make([]AppModel, 0) ans := make([]AppModel, 0)
db.Where("user_name = ?", username).Find(&ans) db.Where("user_name = ?", username).Find(&ans)
return ans return ans
} }
func (a *AppModel) Fill() error { func (a *AppModel) Fill() error {
db := DB() db := k8s_manager.DB()
res := db.First(a, a.Id) res := db.First(a, a.Id)
return res.Error return res.Error
} }
@ -50,20 +51,20 @@ func (a *AppModel) fillDefaults() {
func (a *AppModel) Update() error { func (a *AppModel) Update() error {
a.fillDefaults() a.fillDefaults()
db := DB() db := k8s_manager.DB()
db.Save(a) db.Save(a)
return nil return nil
} }
func (a *AppModel) Create() error { func (a *AppModel) Create() error {
a.fillDefaults() a.fillDefaults()
db := DB() db := k8s_manager.DB()
db.Create(a) db.Create(a)
return nil return nil
} }
func (a *AppModel) Delete() error { func (a *AppModel) Delete() error {
db := DB() db := k8s_manager.DB()
db.Delete(a, a.Id) db.Delete(a, a.Id)
return nil return nil
} }
@ -161,7 +162,7 @@ func (a *AppModel) PersistentVolumeName() string {
} }
func (a *AppModel) NFSPath() 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 { func (a *AppModel) PersistentVolumeClaimName() string {

View File

@ -1,10 +1,12 @@
package k8s_manager package service
import ( import (
"context" "context"
"fmt" "fmt"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"github.com/thoas/go-funk" "github.com/thoas/go-funk"
"k8s-manager/src"
"k8s-manager/src/model"
appv1 "k8s.io/api/apps/v1" appv1 "k8s.io/api/apps/v1"
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
netv1 "k8s.io/api/networking/v1" netv1 "k8s.io/api/networking/v1"
@ -70,7 +72,7 @@ func (c *K8sClient) DeploymentExists(deploymentName string) bool {
return false return false
} }
func (c *K8sClient) UpdateDeployment(app *AppModel) { func (c *K8sClient) UpdateDeployment(app *model.AppModel) {
labelKey, labelValue := app.GetLabel() labelKey, labelValue := app.GetLabel()
l := map[string]string{labelKey: labelValue} l := map[string]string{labelKey: labelValue}
if _, err := os.Stat(app.NFSPath()); os.IsNotExist(err) { if _, err := os.Stat(app.NFSPath()); os.IsNotExist(err) {
@ -94,7 +96,7 @@ func (c *K8sClient) UpdateDeployment(app *AppModel) {
Labels: l, Labels: l,
}, },
Spec: appv1.DeploymentSpec{ Spec: appv1.DeploymentSpec{
Replicas: UnnamedPointer(int32(1)), Replicas: k8s_manager.UnnamedPointer(int32(1)),
Selector: &metav1.LabelSelector{ Selector: &metav1.LabelSelector{
MatchLabels: l, MatchLabels: l,
}, },
@ -120,7 +122,7 @@ func (c *K8sClient) UpdateDeployment(app *AppModel) {
}, },
Ports: containerPorts, Ports: containerPorts,
SecurityContext: &v1.SecurityContext{ SecurityContext: &v1.SecurityContext{
RunAsUser: UnnamedPointer(int64(0)), RunAsUser: k8s_manager.UnnamedPointer(int64(0)),
}, },
}}, }},
Volumes: []v1.Volume{ Volumes: []v1.Volume{
@ -128,7 +130,7 @@ func (c *K8sClient) UpdateDeployment(app *AppModel) {
Name: app.PersistentVolumeMountName(), Name: app.PersistentVolumeMountName(),
VolumeSource: v1.VolumeSource{ VolumeSource: v1.VolumeSource{
NFS: &v1.NFSVolumeSource{ NFS: &v1.NFSVolumeSource{
Server: config.NFSHost, Server: k8s_manager.GetConfig().NFSHost,
Path: app.NFSPath(), Path: app.NFSPath(),
ReadOnly: false, ReadOnly: false,
}, },
@ -163,7 +165,7 @@ func (c *K8sClient) ServiceExists(servername string) bool {
return false return false
} }
func (c *K8sClient) UpdateService(app *AppModel) { func (c *K8sClient) UpdateService(app *model.AppModel) {
ports := app.GetPorts() ports := app.GetPorts()
if len(ports) == 0 { if len(ports) == 0 {
return 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.UpdateDeployment(app)
c.UpdateService(app) c.UpdateService(app)
c.UpdateIngress(app) c.UpdateIngress(app)
} }
func (c *K8sClient) DeleteApp(app *AppModel) { func (c *K8sClient) DeleteApp(app *model.AppModel) {
c.DeleteDeployment(app.DeploymentName()) c.DeleteDeployment(app.DeploymentName())
c.DeleteAppService(app) c.DeleteAppService(app)
c.DeleteIngress(app.IngressName()) c.DeleteIngress(app.IngressName())
} }
func (c *K8sClient) DeleteAppService(app *AppModel) { func (c *K8sClient) DeleteAppService(app *model.AppModel) {
k, v := app.GetLabel() k, v := app.GetLabel()
label := labels.FormatLabels(map[string]string{k: v}) label := labels.FormatLabels(map[string]string{k: v})
svcs, err := c.CoreV1().Services(c.Namespace).List(context.Background(), metav1.ListOptions{ 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 return false
} }
func (c *K8sClient) UpdateIngress(a *AppModel) { func (c *K8sClient) UpdateIngress(a *model.AppModel) {
ports := a.GetPorts() ports := a.GetPorts()
if len(ports) == 0 { if len(ports) == 0 {
return return
@ -313,15 +315,15 @@ func (c *K8sClient) UpdateIngress(a *AppModel) {
Annotations: annotations, Annotations: annotations,
}, },
Spec: netv1.IngressSpec{ Spec: netv1.IngressSpec{
IngressClassName: UnnamedPointer("nginx"), IngressClassName: k8s_manager.UnnamedPointer("nginx"),
Rules: []netv1.IngressRule{ Rules: []netv1.IngressRule{
{ {
IngressRuleValue: netv1.IngressRuleValue{ IngressRuleValue: netv1.IngressRuleValue{
HTTP: &netv1.HTTPIngressRuleValue{ HTTP: &netv1.HTTPIngressRuleValue{
Paths: []netv1.HTTPIngressPath{ Paths: []netv1.HTTPIngressPath{
{ {
Path: "/" + a.ServiceName() + "(/|$)(.*)", Path: "/svc/" + a.ServiceName() + "(/|$)(.*)",
PathType: UnnamedPointer(netv1.PathTypePrefix), PathType: k8s_manager.UnnamedPointer(netv1.PathTypePrefix),
Backend: netv1.IngressBackend{ Backend: netv1.IngressBackend{
Service: &netv1.IngressServiceBackend{ Service: &netv1.IngressServiceBackend{
Name: a.ServiceName(), Name: a.ServiceName(),