use package
This commit is contained in:
parent
094ad14dfc
commit
5954615bea
2
Makefile
2
Makefile
|
|
@ -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
27
main.go
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
@ -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)
|
||||||
|
|
@ -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 {
|
||||||
|
|
@ -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 {
|
||||||
|
|
@ -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(),
|
||||||
Loading…
Reference in New Issue