create deployment
This commit is contained in:
parent
ef982d7a05
commit
04dae7da4e
4
Makefile
4
Makefile
|
|
@ -14,3 +14,7 @@ install: docker
|
|||
|
||||
uninstall:
|
||||
kubectl delete -f install.yaml
|
||||
|
||||
restart: docker
|
||||
kubectl delete -f install.yaml
|
||||
kubectl apply -f install.yaml
|
||||
|
|
|
|||
16
go.mod
16
go.mod
|
|
@ -3,7 +3,14 @@ module k8s-manager
|
|||
go 1.19
|
||||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/emicklei/go-restful/v3 v3.9.0 // indirect
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/gin-gonic/gin v1.8.2
|
||||
github.com/go-logr/logr v1.2.3 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.19.5 // indirect
|
||||
github.com/go-openapi/jsonreference v0.20.0 // indirect
|
||||
github.com/go-openapi/swag v0.19.14 // indirect
|
||||
github.com/golang-jwt/jwt/v4 v4.3.0
|
||||
github.com/sirupsen/logrus v1.9.0
|
||||
gorm.io/driver/mysql v1.4.6
|
||||
|
|
@ -11,17 +18,9 @@ require (
|
|||
k8s.io/api v0.26.1
|
||||
k8s.io/apimachinery v0.26.1
|
||||
k8s.io/client-go v0.26.1
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/emicklei/go-restful/v3 v3.9.0 // indirect
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/go-logr/logr v1.2.3 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.19.5 // indirect
|
||||
github.com/go-openapi/jsonreference v0.20.0 // indirect
|
||||
github.com/go-openapi/swag v0.19.14 // indirect
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.11.2 // indirect
|
||||
|
|
@ -44,6 +43,7 @@ require (
|
|||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.6 // indirect
|
||||
github.com/thoas/go-funk v0.9.3 // indirect
|
||||
github.com/ugorji/go/codec v1.2.9 // indirect
|
||||
golang.org/x/crypto v0.6.0 // indirect
|
||||
golang.org/x/net v0.6.0 // indirect
|
||||
|
|
|
|||
2
go.sum
2
go.sum
|
|
@ -194,6 +194,8 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
|||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/thoas/go-funk v0.9.3 h1:7+nAEx3kn5ZJcnDm2Bh23N2yOtweO14bi//dvRtgLpw=
|
||||
github.com/thoas/go-funk v0.9.3/go.mod h1:+IWnUfUmFO1+WVYQWQtIJHeRRdaIyyYglZN7xzUPe4Q=
|
||||
github.com/ugorji/go/codec v1.2.9 h1:rmenucSohSTiyL09Y+l2OCk+FrMxGMzho2+tjr5ticU=
|
||||
github.com/ugorji/go/codec v1.2.9/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
|
|
|
|||
|
|
@ -20,6 +20,13 @@ spec:
|
|||
image: docker.educg.net/k8s/manager:dev
|
||||
ports:
|
||||
- containerPort: 8080
|
||||
env:
|
||||
- name: DB_HOST
|
||||
value: 192.168.131.191
|
||||
- name: DB_USER
|
||||
value: app
|
||||
- name: DB_PASS
|
||||
value: 1PQlNf9*9Ulo
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
|
|
@ -35,4 +42,4 @@ spec:
|
|||
protocol: TCP
|
||||
nodePort: 30001
|
||||
selector:
|
||||
app: k8s-manager-deployment
|
||||
app: k8s-manager
|
||||
7
main.go
7
main.go
|
|
@ -14,7 +14,8 @@ import (
|
|||
var f embed.FS
|
||||
|
||||
func main() {
|
||||
go m.ListPods()
|
||||
m.InitClient()
|
||||
|
||||
r := gin.Default()
|
||||
|
||||
r.SetFuncMap(template.FuncMap{
|
||||
|
|
@ -35,6 +36,10 @@ func main() {
|
|||
r.POST("/app", m.JWTAuthMiddleware, m.CreateUpdateDeleteApp)
|
||||
r.PUT("/app", m.JWTAuthMiddleware, m.CreateUpdateDeleteApp)
|
||||
r.DELETE("/app", m.JWTAuthMiddleware, m.CreateUpdateDeleteApp)
|
||||
|
||||
r.POST("/dep", m.JWTAuthMiddleware, m.CreateDeleteDeployment)
|
||||
r.DELETE("/dep", m.JWTAuthMiddleware, m.CreateDeleteDeployment)
|
||||
|
||||
r.GET("/login/:username", Test)
|
||||
err := r.Run()
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -28,6 +28,12 @@ func GetApps(username string) []AppModel {
|
|||
return ans
|
||||
}
|
||||
|
||||
func (a *AppModel) Fill() error {
|
||||
db := DB()
|
||||
res := db.First(a, a.Id)
|
||||
return res.Error
|
||||
}
|
||||
|
||||
func (a *AppModel) Update() error {
|
||||
db := DB()
|
||||
db.Save(a)
|
||||
|
|
@ -59,6 +65,9 @@ func (a *AppModel) ContainerName() string {
|
|||
}
|
||||
|
||||
func (a *AppModel) ServiceName() string {
|
||||
if strings.TrimSpace(a.SvcName) != "" {
|
||||
return a.SvcName
|
||||
}
|
||||
return fmt.Sprintf("%s-service", a.NamePrefix())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,28 +3,71 @@ package k8s_manager
|
|||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/thoas/go-funk"
|
||||
v1 "k8s.io/api/apps/v1"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type AppViewModel struct {
|
||||
*AppModel
|
||||
Status string
|
||||
}
|
||||
|
||||
type AppsViewModel struct {
|
||||
Username string
|
||||
Apps []AppModel
|
||||
Apps []AppViewModel
|
||||
}
|
||||
|
||||
func statusString(status *v1.DeploymentStatus, err error) string {
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "not found") {
|
||||
return "Stopped"
|
||||
}
|
||||
return err.Error()
|
||||
} else {
|
||||
if status.AvailableReplicas > 0 {
|
||||
return "Running"
|
||||
} else {
|
||||
return "Error"
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func AppPage(c *gin.Context) {
|
||||
username := c.MustGet("username").(string)
|
||||
vm := &AppViewModel{
|
||||
appsvm := funk.Map(GetApps(username), func(a AppModel) AppViewModel { return AppViewModel{AppModel: &a} }).([]AppViewModel)
|
||||
for i := range appsvm {
|
||||
a := &appsvm[i]
|
||||
d, e := K.GetAppStatus(a.AppModel)
|
||||
a.Status = statusString(d, e)
|
||||
}
|
||||
vm := &AppsViewModel{
|
||||
Username: username,
|
||||
Apps: GetApps(username),
|
||||
Apps: appsvm,
|
||||
}
|
||||
c.HTML(http.StatusOK, "app_view.html", vm)
|
||||
}
|
||||
|
||||
func AppMiddleware(c *gin.Context) {
|
||||
app := &AppModel{}
|
||||
err := c.ShouldBindJSON(&app)
|
||||
if err == nil {
|
||||
username := c.MustGet("username")
|
||||
if app.UserName != username {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"msg": "user error."})
|
||||
c.Abort()
|
||||
}
|
||||
c.Set("app", app)
|
||||
}
|
||||
}
|
||||
|
||||
func CreateUpdateDeleteApp(c *gin.Context) {
|
||||
app := &AppModel{}
|
||||
err := c.BindJSON(app)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("AddApp")
|
||||
log.WithError(err).Error("CreateUpdateDeleteApp")
|
||||
c.JSON(http.StatusBadRequest, gin.H{"msg": "Cannot get data."})
|
||||
} else {
|
||||
username := c.MustGet("username").(string)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,51 @@
|
|||
package k8s_manager
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"k8s.io/api/apps/v1"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var K *K8sClient = nil
|
||||
|
||||
func InitClient() {
|
||||
K = CreateClient()
|
||||
}
|
||||
|
||||
type DeployStatusObject struct {
|
||||
E string `json:"e"`
|
||||
S *v1.DeploymentStatus `json:"s"`
|
||||
}
|
||||
|
||||
func CreateDeleteDeployment(c *gin.Context) {
|
||||
tokenUsername := c.MustGet("username").(string)
|
||||
id := c.Query("id")
|
||||
if strings.TrimSpace(id) == "" {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"msg": "no app id"})
|
||||
return
|
||||
}
|
||||
appId, err := strconv.Atoi(id)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"msg": "wrong id"})
|
||||
return
|
||||
}
|
||||
app := AppModel{Id: appId}
|
||||
if app.Fill() != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"msg": "wrong id"})
|
||||
return
|
||||
}
|
||||
if app.UserName != tokenUsername {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"msg": "user error."})
|
||||
return
|
||||
}
|
||||
if c.Request.Method == http.MethodPost {
|
||||
K.CreateApp(&app)
|
||||
} else if c.Request.Method == http.MethodDelete {
|
||||
K.DeleteApp(&app)
|
||||
} else {
|
||||
c.JSON(http.StatusMethodNotAllowed, gin.H{"msg": "unsupported method"})
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{"msg": "ok"})
|
||||
}
|
||||
|
|
@ -3,8 +3,9 @@ package k8s_manager
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/goccy/go-json"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"k8s.io/api/apps/v1beta1"
|
||||
appv1 "k8s.io/api/apps/v1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
|
|
@ -16,7 +17,7 @@ type K8sClient struct {
|
|||
Namespace string
|
||||
}
|
||||
|
||||
func InitClient() *K8sClient {
|
||||
func CreateClient() *K8sClient {
|
||||
var err error
|
||||
config, err := rest.InClusterConfig()
|
||||
if err != nil {
|
||||
|
|
@ -40,17 +41,22 @@ func (c *K8sClient) ListPods() {
|
|||
}
|
||||
}
|
||||
|
||||
func (c *K8sClient) CreateApp(app *AppModel) {
|
||||
func (c *K8sClient) GetAppStatus(app *AppModel) (*appv1.DeploymentStatus, error) {
|
||||
get, err := c.AppsV1().Deployments(c.Namespace).Get(context.Background(), app.DeploymentName(), metav1.GetOptions{})
|
||||
// log.WithError(err).WithField("dep", get).WithField("name", app.DeploymentName()).Info("GetAppStatus")
|
||||
return &get.Status, err
|
||||
}
|
||||
|
||||
func (c *K8sClient) CreateApp(app *AppModel) {
|
||||
var rep int32 = 1
|
||||
labelKey, labelValue := app.GetLabel()
|
||||
labels := map[string]string{labelKey: labelValue}
|
||||
deployment := &v1beta1.Deployment{
|
||||
deployment := &appv1.Deployment{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: app.DeploymentName(),
|
||||
Labels: labels,
|
||||
},
|
||||
Spec: v1beta1.DeploymentSpec{
|
||||
Spec: appv1.DeploymentSpec{
|
||||
Replicas: &rep,
|
||||
Selector: &metav1.LabelSelector{
|
||||
MatchLabels: labels,
|
||||
|
|
@ -71,8 +77,10 @@ func (c *K8sClient) CreateApp(app *AppModel) {
|
|||
},
|
||||
},
|
||||
}
|
||||
deployment, err := c.AppsV1beta1().Deployments(c.Namespace).Create(context.Background(), deployment, metav1.CreateOptions{})
|
||||
deployment, err := c.AppsV1().Deployments(c.Namespace).Create(context.Background(), deployment, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
d, _ := json.Marshal(deployment)
|
||||
fmt.Println(string(d))
|
||||
log.WithError(err).Error("Create Deployment error.")
|
||||
}
|
||||
|
||||
|
|
@ -82,6 +90,7 @@ func (c *K8sClient) CreateApp(app *AppModel) {
|
|||
},
|
||||
Spec: v1.ServiceSpec{
|
||||
Type: v1.ServiceTypeClusterIP,
|
||||
ClusterIP: "None",
|
||||
Selector: labels,
|
||||
},
|
||||
}
|
||||
|
|
@ -91,3 +100,11 @@ func (c *K8sClient) CreateApp(app *AppModel) {
|
|||
log.WithError(err).Error("Create Service ")
|
||||
}
|
||||
}
|
||||
|
||||
func (c *K8sClient) DeleteApp(app *AppModel) {
|
||||
err := c.AppsV1().Deployments(c.Namespace).Delete(context.Background(), app.DeploymentName(), metav1.DeleteOptions{})
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Delete error ", app.DeploymentName())
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
<th>镜像名</th>
|
||||
<th>启动命令</th>
|
||||
<th>环境变量</th>
|
||||
<th>状态</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
|
@ -46,8 +47,11 @@
|
|||
<td class="app-field-image"> {{ $v.Image }}</td>
|
||||
<td class="app-field-cmd"> {{ $v.Command }}</td>
|
||||
<td class="app-field-env"> {{ $v.Env }}</td>
|
||||
<td class="app-field-status" id="app-status-{{ $v.Id }}"> {{ $v.Status }} </td>
|
||||
<td>
|
||||
<div class="btn-group">
|
||||
<button class="btn btn-success" onclick="startApp('{{$v.Id}}')">启动</button>
|
||||
<button class="btn btn-dark" onclick="stopApp('{{$v.Id}}')">停止</button>
|
||||
<button class="btn btn-primary" onclick="showModal('app-list-{{ $v.Id }}')">修改</button>
|
||||
<button class="btn btn-danger" onclick="deleteApp('{{ $v.Id }}')">删除</button>
|
||||
</div>
|
||||
|
|
@ -202,5 +206,17 @@
|
|||
})
|
||||
}
|
||||
|
||||
function startApp(id) {
|
||||
axios.post("dep?id=" + id).then(e=>{
|
||||
console.log(e.data)
|
||||
})
|
||||
}
|
||||
|
||||
function stopApp(id) {
|
||||
axios.delete("dep?id=" + id).then(e=>{
|
||||
console.log(e.data)
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
</html>
|
||||
Loading…
Reference in New Issue