refactor the code of resource list function
This commit is contained in:
2
Gopkg.lock
generated
2
Gopkg.lock
generated
@@ -650,6 +650,6 @@
|
|||||||
[solve-meta]
|
[solve-meta]
|
||||||
analyzer-name = "dep"
|
analyzer-name = "dep"
|
||||||
analyzer-version = 1
|
analyzer-version = 1
|
||||||
inputs-digest = "9f1ac4fe878dadee802b8971f67ba69171326c81e2c379247015003f2e0ba134"
|
inputs-digest = "d92e4ea931c670e5ebb04661788db5386ee647b8b6bac4ec6b519a1544b2c400"
|
||||||
solver-name = "gps-cdcl"
|
solver-name = "gps-cdcl"
|
||||||
solver-version = 1
|
solver-version = 1
|
||||||
|
|||||||
@@ -23,6 +23,9 @@ import (
|
|||||||
|
|
||||||
"github.com/emicklei/go-restful-openapi"
|
"github.com/emicklei/go-restful-openapi"
|
||||||
|
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"kubesphere.io/kubesphere/pkg/constants"
|
"kubesphere.io/kubesphere/pkg/constants"
|
||||||
"kubesphere.io/kubesphere/pkg/models"
|
"kubesphere.io/kubesphere/pkg/models"
|
||||||
)
|
)
|
||||||
@@ -31,15 +34,33 @@ func Register(ws *restful.WebService, subPath string) {
|
|||||||
|
|
||||||
tags := []string{"resources"}
|
tags := []string{"resources"}
|
||||||
|
|
||||||
ws.Route(ws.GET(subPath+"/{resource}").To(handleResource).Produces(restful.MIME_JSON).Metadata(restfulspec.KeyOpenAPITags, tags).Doc("Get resource" +
|
ws.Route(ws.GET(subPath+"/{resource}").To(listResource).Produces(restful.MIME_JSON).Metadata(restfulspec.KeyOpenAPITags, tags).Doc("Get resource" +
|
||||||
" list").Param(ws.PathParameter("resource", "resource name").DataType(
|
" list").Param(ws.PathParameter("resource", "resource name").DataType("string")).Param(ws.QueryParameter("conditions",
|
||||||
"string")).Param(ws.QueryParameter("conditions", "search "+
|
"search conditions").DataType("string")).Param(ws.QueryParameter("reverse",
|
||||||
"conditions").DataType("string")).Param(ws.QueryParameter("paging",
|
"support reverse ordering").DataType("bool").DefaultValue("false")).Param(ws.QueryParameter("order",
|
||||||
|
"the field for sorting").DataType("string")).Param(ws.QueryParameter("paging",
|
||||||
"support paging function").DataType("string")).Writes(models.ResourceList{}))
|
"support paging function").DataType("string")).Writes(models.ResourceList{}))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleResource(req *restful.Request, resp *restful.Response) {
|
func isInvalid(str string) bool {
|
||||||
|
invalidList := []string{"exec", "insert", "select", "delete", "update", "count", "*", "%", "truncate", "drop"}
|
||||||
|
str = strings.Replace(str, "=", " ", -1)
|
||||||
|
str = strings.Replace(str, ",", " ", -1)
|
||||||
|
str = strings.Replace(str, "~", " ", -1)
|
||||||
|
items := strings.Split(str, " ")
|
||||||
|
|
||||||
|
for _, invalid := range invalidList {
|
||||||
|
for _, item := range items {
|
||||||
|
if item == invalid || strings.ToLower(item) == invalid {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func listResource(req *restful.Request, resp *restful.Response) {
|
||||||
|
|
||||||
resource := req.PathParameter("resource")
|
resource := req.PathParameter("resource")
|
||||||
if resource == "applications" {
|
if resource == "applications" {
|
||||||
@@ -48,7 +69,23 @@ func handleResource(req *restful.Request, resp *restful.Response) {
|
|||||||
}
|
}
|
||||||
conditions := req.QueryParameter("conditions")
|
conditions := req.QueryParameter("conditions")
|
||||||
paging := req.QueryParameter("paging")
|
paging := req.QueryParameter("paging")
|
||||||
res, err := models.ListResource(resource, conditions, paging)
|
orderField := req.QueryParameter("order")
|
||||||
|
reverse := req.QueryParameter("reverse")
|
||||||
|
|
||||||
|
if len(orderField) > 0 {
|
||||||
|
if reverse == "true" {
|
||||||
|
orderField = fmt.Sprintf("%s %s", orderField, "desc")
|
||||||
|
} else {
|
||||||
|
orderField = fmt.Sprintf("%s %s", orderField, "asc")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if isInvalid(conditions) || isInvalid(paging) || isInvalid(orderField) {
|
||||||
|
resp.WriteHeaderAndEntity(http.StatusBadRequest, constants.MessageResponse{Message: "invalid input"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := models.ListResource(resource, conditions, paging, orderField)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resp.WriteHeaderAndEntity(http.StatusInternalServerError, constants.MessageResponse{Message: err.Error()})
|
resp.WriteHeaderAndEntity(http.StatusInternalServerError, constants.MessageResponse{Message: err.Error()})
|
||||||
return
|
return
|
||||||
@@ -58,7 +95,6 @@ func handleResource(req *restful.Request, resp *restful.Response) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func handleApplication(req *restful.Request, resp *restful.Response) {
|
func handleApplication(req *restful.Request, resp *restful.Response) {
|
||||||
//searchWord := req.QueryParameter("search-word")
|
|
||||||
paging := req.QueryParameter("paging")
|
paging := req.QueryParameter("paging")
|
||||||
clusterId := req.QueryParameter("cluster_id")
|
clusterId := req.QueryParameter("cluster_id")
|
||||||
runtimeId := req.QueryParameter("runtime_id")
|
runtimeId := req.QueryParameter("runtime_id")
|
||||||
|
|||||||
@@ -240,7 +240,7 @@ func (ctl *ApplicationCtl) GetWorkLoads(namespace string, clusterRoles []cluster
|
|||||||
if strings.HasSuffix(workLoadName, deploySurffix) {
|
if strings.HasSuffix(workLoadName, deploySurffix) {
|
||||||
name := strings.Split(workLoadName, deploySurffix)[0]
|
name := strings.Split(workLoadName, deploySurffix)[0]
|
||||||
ctl := ResourceControllers.Controllers[Deployments]
|
ctl := ResourceControllers.Controllers[Deployments]
|
||||||
_, items, _ := ctl.ListWithConditions(fmt.Sprintf("namespace='%s' and name = '%s'", namespace, name), nil)
|
_, items, _ := ctl.ListWithConditions(fmt.Sprintf("namespace='%s' and name = '%s'", namespace, name), nil, "")
|
||||||
works.Deployments = append(works.Deployments, items.([]Deployment)...)
|
works.Deployments = append(works.Deployments, items.([]Deployment)...)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -248,7 +248,7 @@ func (ctl *ApplicationCtl) GetWorkLoads(namespace string, clusterRoles []cluster
|
|||||||
if strings.HasSuffix(workLoadName, daemonSurffix) {
|
if strings.HasSuffix(workLoadName, daemonSurffix) {
|
||||||
name := strings.Split(workLoadName, daemonSurffix)[0]
|
name := strings.Split(workLoadName, daemonSurffix)[0]
|
||||||
ctl := ResourceControllers.Controllers[Daemonsets]
|
ctl := ResourceControllers.Controllers[Daemonsets]
|
||||||
_, items, _ := ctl.ListWithConditions(fmt.Sprintf("namespace='%s' and name = '%s'", namespace, name), nil)
|
_, items, _ := ctl.ListWithConditions(fmt.Sprintf("namespace='%s' and name = '%s'", namespace, name), nil, "")
|
||||||
works.Daemonsets = append(works.Daemonsets, items.([]Daemonset)...)
|
works.Daemonsets = append(works.Daemonsets, items.([]Daemonset)...)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -256,7 +256,7 @@ func (ctl *ApplicationCtl) GetWorkLoads(namespace string, clusterRoles []cluster
|
|||||||
if strings.HasSuffix(workLoadName, stateSurffix) {
|
if strings.HasSuffix(workLoadName, stateSurffix) {
|
||||||
name := strings.Split(workLoadName, stateSurffix)[0]
|
name := strings.Split(workLoadName, stateSurffix)[0]
|
||||||
ctl := ResourceControllers.Controllers[Statefulsets]
|
ctl := ResourceControllers.Controllers[Statefulsets]
|
||||||
_, items, _ := ctl.ListWithConditions(fmt.Sprintf("namespace='%s' and name = '%s'", namespace, name), nil)
|
_, items, _ := ctl.ListWithConditions(fmt.Sprintf("namespace='%s' and name = '%s'", namespace, name), nil, "")
|
||||||
works.Statefulsets = append(works.Statefulsets, items.([]Statefulset)...)
|
works.Statefulsets = append(works.Statefulsets, items.([]Statefulset)...)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -265,16 +265,6 @@ func (ctl *ApplicationCtl) GetWorkLoads(namespace string, clusterRoles []cluster
|
|||||||
return &works
|
return &works
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
//func (ctl *ApplicationCtl) getCreator(desc string) string {
|
|
||||||
// var dc description
|
|
||||||
// err := json.Unmarshal([]byte(desc), &dc)
|
|
||||||
// if err != nil {
|
|
||||||
// return unknown
|
|
||||||
// }
|
|
||||||
// return dc.Creator
|
|
||||||
//}
|
|
||||||
|
|
||||||
func (ctl *ApplicationCtl) getLabels(namespace string, workloads *workLoads) *[]map[string]string {
|
func (ctl *ApplicationCtl) getLabels(namespace string, workloads *workLoads) *[]map[string]string {
|
||||||
k8sClient := client.NewK8sClient()
|
k8sClient := client.NewK8sClient()
|
||||||
|
|
||||||
@@ -349,7 +339,7 @@ func (ctl *ApplicationCtl) getIng(namespace string, services *[]Service) *[]ing
|
|||||||
ingCtl := ResourceControllers.Controllers[Ingresses]
|
ingCtl := ResourceControllers.Controllers[Ingresses]
|
||||||
var ings []ing
|
var ings []ing
|
||||||
for _, svc := range *services {
|
for _, svc := range *services {
|
||||||
_, items, err := ingCtl.ListWithConditions(fmt.Sprintf("namespace = '%s' and rules like '%%%s%%' ", namespace, svc.Name), nil)
|
_, items, err := ingCtl.ListWithConditions(fmt.Sprintf("namespace = '%s' and rules like '%%%s%%' ", namespace, svc.Name), nil, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Error(err)
|
glog.Error(err)
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -30,6 +30,11 @@ import (
|
|||||||
const systemPrefix = "system:"
|
const systemPrefix = "system:"
|
||||||
|
|
||||||
func (ctl *ClusterRoleCtl) generateObject(item v1.ClusterRole) *ClusterRole {
|
func (ctl *ClusterRoleCtl) generateObject(item v1.ClusterRole) *ClusterRole {
|
||||||
|
var displayName string
|
||||||
|
if item.Annotations != nil && len(item.Annotations[DisplayName]) > 0 {
|
||||||
|
displayName = item.Annotations[DisplayName]
|
||||||
|
}
|
||||||
|
|
||||||
name := item.Name
|
name := item.Name
|
||||||
if strings.HasPrefix(name, systemPrefix) {
|
if strings.HasPrefix(name, systemPrefix) {
|
||||||
return nil
|
return nil
|
||||||
@@ -40,7 +45,7 @@ func (ctl *ClusterRoleCtl) generateObject(item v1.ClusterRole) *ClusterRole {
|
|||||||
createTime = time.Now()
|
createTime = time.Now()
|
||||||
}
|
}
|
||||||
|
|
||||||
object := &ClusterRole{Name: name, CreateTime: createTime, Annotation: Annotation{item.Annotations}}
|
object := &ClusterRole{Name: name, CreateTime: createTime, Annotation: MapString{item.Annotations}, DisplayName: displayName}
|
||||||
|
|
||||||
return object
|
return object
|
||||||
}
|
}
|
||||||
@@ -136,15 +141,23 @@ func (ctl *ClusterRoleCtl) CountWithConditions(conditions string) int {
|
|||||||
return countWithConditions(ctl.DB, conditions, &object)
|
return countWithConditions(ctl.DB, conditions, &object)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctl *ClusterRoleCtl) ListWithConditions(conditions string, paging *Paging) (int, interface{}, error) {
|
func (ctl *ClusterRoleCtl) ListWithConditions(conditions string, paging *Paging, order string) (int, interface{}, error) {
|
||||||
var object ClusterRole
|
var object ClusterRole
|
||||||
var list []ClusterRole
|
var list []ClusterRole
|
||||||
var total int
|
var total int
|
||||||
|
|
||||||
order := "createTime desc"
|
if len(order) == 0 {
|
||||||
|
order = "createTime desc"
|
||||||
|
}
|
||||||
|
|
||||||
db := ctl.DB
|
db := ctl.DB
|
||||||
|
|
||||||
listWithConditions(db, &total, &object, &list, conditions, paging, order)
|
listWithConditions(db, &total, &object, &list, conditions, paging, order)
|
||||||
|
|
||||||
return total, list, nil
|
return total, list, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ctl *ClusterRoleCtl) Lister() interface{} {
|
||||||
|
|
||||||
|
return ctl.lister
|
||||||
|
}
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ func checkAndResync(ctl Controller, stopChan chan struct{}) {
|
|||||||
|
|
||||||
func listAndWatch(ctl Controller) {
|
func listAndWatch(ctl Controller) {
|
||||||
defer handleCrash(ctl)
|
defer handleCrash(ctl)
|
||||||
|
defer ctl.CloseDB()
|
||||||
stopChan := make(chan struct{})
|
stopChan := make(chan struct{})
|
||||||
|
|
||||||
go ctl.sync(stopChan)
|
go ctl.sync(stopChan)
|
||||||
|
|||||||
64
pkg/models/controllers/controllerrevisions.go
Normal file
64
pkg/models/controllers/controllerrevisions.go
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2018 The KubeSphere Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package controllers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"k8s.io/client-go/informers"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (ctl *ControllerRevisionCtl) Name() string {
|
||||||
|
return ctl.CommonAttribute.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctl *ControllerRevisionCtl) sync(stopChan chan struct{}) {
|
||||||
|
|
||||||
|
ctl.initListerAndInformer()
|
||||||
|
ctl.informer.Run(stopChan)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctl *ControllerRevisionCtl) total() int {
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctl *ControllerRevisionCtl) initListerAndInformer() {
|
||||||
|
|
||||||
|
informerFactory := informers.NewSharedInformerFactory(ctl.K8sClient, time.Second*resyncCircle)
|
||||||
|
|
||||||
|
ctl.lister = informerFactory.Apps().V1().ControllerRevisions().Lister()
|
||||||
|
|
||||||
|
informer := informerFactory.Apps().V1().ControllerRevisions().Informer()
|
||||||
|
|
||||||
|
ctl.informer = informer
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctl *ControllerRevisionCtl) CountWithConditions(conditions string) int {
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctl *ControllerRevisionCtl) ListWithConditions(conditions string, paging *Paging, order string) (int, interface{}, error) {
|
||||||
|
|
||||||
|
return 0, nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctl *ControllerRevisionCtl) Lister() interface{} {
|
||||||
|
|
||||||
|
return ctl.lister
|
||||||
|
}
|
||||||
158
pkg/models/controllers/cronjobs.go
Normal file
158
pkg/models/controllers/cronjobs.go
Normal file
@@ -0,0 +1,158 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2018 The KubeSphere Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package controllers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/golang/glog"
|
||||||
|
"k8s.io/api/batch/v1beta1"
|
||||||
|
"k8s.io/apimachinery/pkg/labels"
|
||||||
|
"k8s.io/client-go/informers"
|
||||||
|
"k8s.io/client-go/tools/cache"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (ctl *CronJobCtl) generateObject(item v1beta1.CronJob) *CronJob {
|
||||||
|
var status, displayName string
|
||||||
|
var lastScheduleTime *time.Time
|
||||||
|
|
||||||
|
if item.Annotations != nil && len(item.Annotations[DisplayName]) > 0 {
|
||||||
|
displayName = item.Annotations[DisplayName]
|
||||||
|
}
|
||||||
|
|
||||||
|
name := item.Name
|
||||||
|
namespace := item.Namespace
|
||||||
|
|
||||||
|
status = Running
|
||||||
|
if *item.Spec.Suspend {
|
||||||
|
status = Pause
|
||||||
|
}
|
||||||
|
|
||||||
|
schedule := item.Spec.Schedule
|
||||||
|
if item.Status.LastScheduleTime != nil {
|
||||||
|
lastScheduleTime = &item.Status.LastScheduleTime.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
active := len(item.Status.Active)
|
||||||
|
|
||||||
|
object := &CronJob{
|
||||||
|
Namespace: namespace,
|
||||||
|
Name: name,
|
||||||
|
DisplayName: displayName,
|
||||||
|
LastScheduleTime: lastScheduleTime,
|
||||||
|
Active: active,
|
||||||
|
Schedule: schedule,
|
||||||
|
Status: status,
|
||||||
|
Annotation: MapString{item.Annotations},
|
||||||
|
Labels: MapString{item.ObjectMeta.Labels},
|
||||||
|
}
|
||||||
|
|
||||||
|
return object
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctl *CronJobCtl) Name() string {
|
||||||
|
return ctl.CommonAttribute.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctl *CronJobCtl) sync(stopChan chan struct{}) {
|
||||||
|
db := ctl.DB
|
||||||
|
|
||||||
|
if db.HasTable(&CronJob{}) {
|
||||||
|
db.DropTable(&CronJob{})
|
||||||
|
}
|
||||||
|
|
||||||
|
db = db.CreateTable(&CronJob{})
|
||||||
|
|
||||||
|
ctl.initListerAndInformer()
|
||||||
|
list, err := ctl.lister.List(labels.Everything())
|
||||||
|
if err != nil {
|
||||||
|
glog.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, item := range list {
|
||||||
|
obj := ctl.generateObject(*item)
|
||||||
|
db.Create(obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
ctl.informer.Run(stopChan)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctl *CronJobCtl) total() int {
|
||||||
|
list, err := ctl.lister.List(labels.Everything())
|
||||||
|
if err != nil {
|
||||||
|
glog.Errorf("count %s falied, reason:%s", err, ctl.Name())
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return len(list)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctl *CronJobCtl) initListerAndInformer() {
|
||||||
|
db := ctl.DB
|
||||||
|
|
||||||
|
informerFactory := informers.NewSharedInformerFactory(ctl.K8sClient, time.Second*resyncCircle)
|
||||||
|
ctl.lister = informerFactory.Batch().V1beta1().CronJobs().Lister()
|
||||||
|
|
||||||
|
informer := informerFactory.Batch().V1beta1().CronJobs().Informer()
|
||||||
|
informer.AddEventHandler(cache.ResourceEventHandlerFuncs{
|
||||||
|
AddFunc: func(obj interface{}) {
|
||||||
|
|
||||||
|
object := obj.(*v1beta1.CronJob)
|
||||||
|
mysqlObject := ctl.generateObject(*object)
|
||||||
|
db.Create(mysqlObject)
|
||||||
|
},
|
||||||
|
UpdateFunc: func(old, new interface{}) {
|
||||||
|
object := new.(*v1beta1.CronJob)
|
||||||
|
mysqlObject := ctl.generateObject(*object)
|
||||||
|
db.Save(mysqlObject)
|
||||||
|
},
|
||||||
|
DeleteFunc: func(obj interface{}) {
|
||||||
|
var item CronJob
|
||||||
|
object := obj.(*v1beta1.CronJob)
|
||||||
|
db.Where("name=? And namespace=?", object.Name, object.Namespace).Find(&item)
|
||||||
|
db.Delete(item)
|
||||||
|
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
ctl.informer = informer
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctl *CronJobCtl) CountWithConditions(conditions string) int {
|
||||||
|
var object CronJob
|
||||||
|
|
||||||
|
return countWithConditions(ctl.DB, conditions, &object)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctl *CronJobCtl) ListWithConditions(conditions string, paging *Paging, order string) (int, interface{}, error) {
|
||||||
|
var list []CronJob
|
||||||
|
var object CronJob
|
||||||
|
var total int
|
||||||
|
|
||||||
|
if len(order) == 0 {
|
||||||
|
order = "lastScheduleTime desc"
|
||||||
|
}
|
||||||
|
|
||||||
|
listWithConditions(ctl.DB, &total, &object, &list, conditions, paging, order)
|
||||||
|
|
||||||
|
return total, list, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctl *CronJobCtl) Lister() interface{} {
|
||||||
|
|
||||||
|
return ctl.lister
|
||||||
|
}
|
||||||
@@ -28,8 +28,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (ctl *DaemonsetCtl) generateObject(item v1.DaemonSet) *Daemonset {
|
func (ctl *DaemonsetCtl) generateObject(item v1.DaemonSet) *Daemonset {
|
||||||
var app string
|
var app, status, displayName string
|
||||||
var status string
|
|
||||||
|
if item.Annotations != nil && len(item.Annotations[DisplayName]) > 0 {
|
||||||
|
displayName = item.Annotations[DisplayName]
|
||||||
|
}
|
||||||
name := item.Name
|
name := item.Name
|
||||||
namespace := item.Namespace
|
namespace := item.Namespace
|
||||||
availablePodNum := item.Status.NumberAvailable
|
availablePodNum := item.Status.NumberAvailable
|
||||||
@@ -55,8 +58,19 @@ func (ctl *DaemonsetCtl) generateObject(item v1.DaemonSet) *Daemonset {
|
|||||||
status = Updating
|
status = Updating
|
||||||
}
|
}
|
||||||
|
|
||||||
object := &Daemonset{Namespace: namespace, Name: name, Available: availablePodNum, Desire: desirePodNum,
|
object := &Daemonset{
|
||||||
App: app, CreateTime: createTime, Status: status, NodeSelector: string(nodeSelectorStr), Annotation: Annotation{item.Annotations}}
|
Namespace: namespace,
|
||||||
|
Name: name,
|
||||||
|
DisplayName: displayName,
|
||||||
|
Available: availablePodNum,
|
||||||
|
Desire: desirePodNum,
|
||||||
|
App: app,
|
||||||
|
CreateTime: createTime,
|
||||||
|
Status: status,
|
||||||
|
NodeSelector: string(nodeSelectorStr),
|
||||||
|
Annotation: MapString{item.Annotations},
|
||||||
|
Labels: MapString{item.Spec.Selector.MatchLabels},
|
||||||
|
}
|
||||||
|
|
||||||
return object
|
return object
|
||||||
}
|
}
|
||||||
@@ -135,25 +149,21 @@ func (ctl *DaemonsetCtl) CountWithConditions(conditions string) int {
|
|||||||
return countWithConditions(ctl.DB, conditions, &object)
|
return countWithConditions(ctl.DB, conditions, &object)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctl *DaemonsetCtl) ListWithConditions(conditions string, paging *Paging) (int, interface{}, error) {
|
func (ctl *DaemonsetCtl) ListWithConditions(conditions string, paging *Paging, order string) (int, interface{}, error) {
|
||||||
var list []Daemonset
|
var list []Daemonset
|
||||||
var object Daemonset
|
var object Daemonset
|
||||||
var total int
|
var total int
|
||||||
|
|
||||||
order := "createTime desc"
|
if len(order) == 0 {
|
||||||
|
order = "createTime desc"
|
||||||
|
}
|
||||||
|
|
||||||
listWithConditions(ctl.DB, &total, &object, &list, conditions, paging, order)
|
listWithConditions(ctl.DB, &total, &object, &list, conditions, paging, order)
|
||||||
|
|
||||||
return total, list, nil
|
return total, list, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//func (ctl *DaemonsetCtl) Count(namespace string) int {
|
func (ctl *DaemonsetCtl) Lister() interface{} {
|
||||||
// var count int
|
|
||||||
// db := ctl.DB
|
return ctl.lister
|
||||||
// if len(namespace) == 0 {
|
}
|
||||||
// db.Model(&Daemonset{}).Count(&count)
|
|
||||||
// } else {
|
|
||||||
// db.Model(&Daemonset{}).Where("namespace = ?", namespace).Count(&count)
|
|
||||||
// }
|
|
||||||
// return count
|
|
||||||
//}
|
|
||||||
|
|||||||
@@ -27,9 +27,13 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (ctl *DeploymentCtl) generateObject(item v1.Deployment) *Deployment {
|
func (ctl *DeploymentCtl) generateObject(item v1.Deployment) *Deployment {
|
||||||
var app string
|
var app, status, displayName string
|
||||||
var status string
|
|
||||||
var updateTime time.Time
|
var updateTime time.Time
|
||||||
|
|
||||||
|
if item.Annotations != nil && len(item.Annotations[DisplayName]) > 0 {
|
||||||
|
displayName = item.Annotations[DisplayName]
|
||||||
|
}
|
||||||
|
|
||||||
name := item.Name
|
name := item.Name
|
||||||
namespace := item.Namespace
|
namespace := item.Namespace
|
||||||
availablePodNum := item.Status.AvailableReplicas
|
availablePodNum := item.Status.AvailableReplicas
|
||||||
@@ -41,9 +45,13 @@ func (ctl *DeploymentCtl) generateObject(item v1.Deployment) *Deployment {
|
|||||||
app = release + "/" + chart
|
app = release + "/" + chart
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, conditon := range item.Status.Conditions {
|
for _, condition := range item.Status.Conditions {
|
||||||
if conditon.Type == "Available" {
|
if updateTime.IsZero() {
|
||||||
updateTime = conditon.LastUpdateTime.Time
|
updateTime = condition.LastUpdateTime.Time
|
||||||
|
} else {
|
||||||
|
if updateTime.Before(condition.LastUpdateTime.Time) {
|
||||||
|
updateTime = condition.LastUpdateTime.Time
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if updateTime.IsZero() {
|
if updateTime.IsZero() {
|
||||||
@@ -60,8 +68,18 @@ func (ctl *DeploymentCtl) generateObject(item v1.Deployment) *Deployment {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Deployment{Namespace: namespace, Name: name, Available: availablePodNum, Desire: desirePodNum,
|
return &Deployment{
|
||||||
App: app, UpdateTime: updateTime, Status: status, Annotation: Annotation{item.Annotations}}
|
Namespace: namespace,
|
||||||
|
Name: name,
|
||||||
|
Available: availablePodNum,
|
||||||
|
Desire: desirePodNum,
|
||||||
|
App: app,
|
||||||
|
UpdateTime: updateTime,
|
||||||
|
Status: status,
|
||||||
|
Annotation: MapString{item.Annotations},
|
||||||
|
Labels: MapString{item.Spec.Selector.MatchLabels},
|
||||||
|
DisplayName: displayName,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctl *DeploymentCtl) Name() string {
|
func (ctl *DeploymentCtl) Name() string {
|
||||||
@@ -138,14 +156,21 @@ func (ctl *DeploymentCtl) CountWithConditions(conditions string) int {
|
|||||||
return countWithConditions(ctl.DB, conditions, &object)
|
return countWithConditions(ctl.DB, conditions, &object)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctl *DeploymentCtl) ListWithConditions(conditions string, paging *Paging) (int, interface{}, error) {
|
func (ctl *DeploymentCtl) ListWithConditions(conditions string, paging *Paging, order string) (int, interface{}, error) {
|
||||||
var list []Deployment
|
var list []Deployment
|
||||||
var object Deployment
|
var object Deployment
|
||||||
var total int
|
var total int
|
||||||
|
|
||||||
order := "updateTime desc"
|
if len(order) == 0 {
|
||||||
|
order = "updateTime desc"
|
||||||
|
}
|
||||||
|
|
||||||
listWithConditions(ctl.DB, &total, &object, &list, conditions, paging, order)
|
listWithConditions(ctl.DB, &total, &object, &list, conditions, paging, order)
|
||||||
|
|
||||||
return total, list, nil
|
return total, list, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ctl *DeploymentCtl) Lister() interface{} {
|
||||||
|
|
||||||
|
return ctl.lister
|
||||||
|
}
|
||||||
|
|||||||
@@ -30,9 +30,16 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (ctl *IngressCtl) generateObject(item v1beta1.Ingress) *Ingress {
|
func (ctl *IngressCtl) generateObject(item v1beta1.Ingress) *Ingress {
|
||||||
|
|
||||||
|
var ip, tls, displayName string
|
||||||
|
|
||||||
name := item.Name
|
name := item.Name
|
||||||
namespace := item.Namespace
|
namespace := item.Namespace
|
||||||
var ip, tls string
|
|
||||||
|
if item.Annotations != nil && len(item.Annotations[DisplayName]) > 0 {
|
||||||
|
displayName = item.Annotations[DisplayName]
|
||||||
|
}
|
||||||
|
|
||||||
createTime := item.CreationTimestamp.Time
|
createTime := item.CreationTimestamp.Time
|
||||||
if createTime.IsZero() {
|
if createTime.IsZero() {
|
||||||
createTime = time.Now()
|
createTime = time.Now()
|
||||||
@@ -63,7 +70,17 @@ func (ctl *IngressCtl) generateObject(item v1beta1.Ingress) *Ingress {
|
|||||||
|
|
||||||
ruleStr, _ := json.Marshal(ingRules)
|
ruleStr, _ := json.Marshal(ingRules)
|
||||||
|
|
||||||
object := &Ingress{Namespace: namespace, Name: name, TlsTermination: tls, Ip: ip, CreateTime: createTime, Annotation: Annotation{item.Annotations}, Rules: string(ruleStr)}
|
object := &Ingress{
|
||||||
|
Namespace: namespace,
|
||||||
|
Name: name,
|
||||||
|
DisplayName: displayName,
|
||||||
|
TlsTermination: tls,
|
||||||
|
Ip: ip,
|
||||||
|
CreateTime: createTime,
|
||||||
|
Annotation: MapString{item.Annotations},
|
||||||
|
Rules: string(ruleStr),
|
||||||
|
Labels: MapString{item.Labels},
|
||||||
|
}
|
||||||
|
|
||||||
return object
|
return object
|
||||||
}
|
}
|
||||||
@@ -143,25 +160,21 @@ func (ctl *IngressCtl) CountWithConditions(conditions string) int {
|
|||||||
return countWithConditions(ctl.DB, conditions, &object)
|
return countWithConditions(ctl.DB, conditions, &object)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctl *IngressCtl) ListWithConditions(conditions string, paging *Paging) (int, interface{}, error) {
|
func (ctl *IngressCtl) ListWithConditions(conditions string, paging *Paging, order string) (int, interface{}, error) {
|
||||||
var list []Ingress
|
var list []Ingress
|
||||||
var object Ingress
|
var object Ingress
|
||||||
var total int
|
var total int
|
||||||
|
|
||||||
order := "createTime desc"
|
if len(order) == 0 {
|
||||||
|
order = "createTime desc"
|
||||||
|
}
|
||||||
|
|
||||||
listWithConditions(ctl.DB, &total, &object, &list, conditions, paging, order)
|
listWithConditions(ctl.DB, &total, &object, &list, conditions, paging, order)
|
||||||
|
|
||||||
return total, list, nil
|
return total, list, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//func (ctl *IngressCtl) Count(namespace string) int {
|
func (ctl *IngressCtl) Lister() interface{} {
|
||||||
// var count int
|
|
||||||
// db := ctl.DB
|
return ctl.lister
|
||||||
// if len(namespace) == 0 {
|
}
|
||||||
// db.Model(&Ingress{}).Count(&count)
|
|
||||||
// } else {
|
|
||||||
// db.Model(&Ingress{}).Where("namespace = ?", namespace).Count(&count)
|
|
||||||
// }
|
|
||||||
// return count
|
|
||||||
//}
|
|
||||||
|
|||||||
276
pkg/models/controllers/jobs.go
Normal file
276
pkg/models/controllers/jobs.go
Normal file
@@ -0,0 +1,276 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2018 The KubeSphere Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package controllers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/golang/glog"
|
||||||
|
"k8s.io/api/batch/v1"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/labels"
|
||||||
|
"k8s.io/client-go/informers"
|
||||||
|
"k8s.io/client-go/kubernetes"
|
||||||
|
"k8s.io/client-go/tools/cache"
|
||||||
|
|
||||||
|
"kubesphere.io/kubesphere/pkg/client"
|
||||||
|
)
|
||||||
|
|
||||||
|
var k8sClient *kubernetes.Clientset
|
||||||
|
|
||||||
|
func (ctl *JobCtl) generateObject(item v1.Job) *Job {
|
||||||
|
var status, displayName string
|
||||||
|
|
||||||
|
if item.Annotations != nil && len(item.Annotations[DisplayName]) > 0 {
|
||||||
|
displayName = item.Annotations[DisplayName]
|
||||||
|
}
|
||||||
|
|
||||||
|
name := item.Name
|
||||||
|
namespace := item.Namespace
|
||||||
|
succeedPodNum := item.Status.Succeeded
|
||||||
|
desirePodNum := *item.Spec.Completions
|
||||||
|
createTime := item.CreationTimestamp.Time
|
||||||
|
updteTime := createTime
|
||||||
|
for _, condition := range item.Status.Conditions {
|
||||||
|
if condition.Type == "Failed" && condition.Status == "True" {
|
||||||
|
status = Failed
|
||||||
|
}
|
||||||
|
|
||||||
|
if condition.Type == "Complete" && condition.Status == "True" {
|
||||||
|
status = Completed
|
||||||
|
}
|
||||||
|
|
||||||
|
if updteTime.Before(condition.LastProbeTime.Time) {
|
||||||
|
updteTime = condition.LastProbeTime.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
if updteTime.Before(condition.LastTransitionTime.Time) {
|
||||||
|
updteTime = condition.LastTransitionTime.Time
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if desirePodNum > succeedPodNum && len(status) == 0 {
|
||||||
|
status = Running
|
||||||
|
}
|
||||||
|
|
||||||
|
object := &Job{
|
||||||
|
Namespace: namespace,
|
||||||
|
Name: name,
|
||||||
|
DisplayName: displayName,
|
||||||
|
Desire: desirePodNum,
|
||||||
|
Completed: succeedPodNum,
|
||||||
|
UpdateTime: updteTime,
|
||||||
|
CreateTime: createTime,
|
||||||
|
Status: status,
|
||||||
|
Annotation: MapString{item.Annotations},
|
||||||
|
Labels: MapString{item.Labels},
|
||||||
|
}
|
||||||
|
|
||||||
|
return object
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctl *JobCtl) Name() string {
|
||||||
|
return ctl.CommonAttribute.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctl *JobCtl) sync(stopChan chan struct{}) {
|
||||||
|
db := ctl.DB
|
||||||
|
|
||||||
|
if db.HasTable(&Job{}) {
|
||||||
|
db.DropTable(&Job{})
|
||||||
|
}
|
||||||
|
|
||||||
|
db = db.CreateTable(&Job{})
|
||||||
|
|
||||||
|
ctl.initListerAndInformer()
|
||||||
|
list, err := ctl.lister.List(labels.Everything())
|
||||||
|
if err != nil {
|
||||||
|
glog.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, item := range list {
|
||||||
|
obj := ctl.generateObject(*item)
|
||||||
|
db.Create(obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
ctl.informer.Run(stopChan)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctl *JobCtl) total() int {
|
||||||
|
list, err := ctl.lister.List(labels.Everything())
|
||||||
|
if err != nil {
|
||||||
|
glog.Errorf("count %s falied, reason:%s", err, ctl.Name())
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return len(list)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctl *JobCtl) initListerAndInformer() {
|
||||||
|
db := ctl.DB
|
||||||
|
|
||||||
|
informerFactory := informers.NewSharedInformerFactory(ctl.K8sClient, time.Second*resyncCircle)
|
||||||
|
ctl.lister = informerFactory.Batch().V1().Jobs().Lister()
|
||||||
|
|
||||||
|
informer := informerFactory.Batch().V1().Jobs().Informer()
|
||||||
|
informer.AddEventHandler(cache.ResourceEventHandlerFuncs{
|
||||||
|
AddFunc: func(obj interface{}) {
|
||||||
|
|
||||||
|
object := obj.(*v1.Job)
|
||||||
|
mysqlObject := ctl.generateObject(*object)
|
||||||
|
db.Create(mysqlObject)
|
||||||
|
},
|
||||||
|
UpdateFunc: func(old, new interface{}) {
|
||||||
|
object := new.(*v1.Job)
|
||||||
|
mysqlObject := ctl.generateObject(*object)
|
||||||
|
db.Save(mysqlObject)
|
||||||
|
},
|
||||||
|
DeleteFunc: func(obj interface{}) {
|
||||||
|
var item Job
|
||||||
|
object := obj.(*v1.Job)
|
||||||
|
db.Where("name=? And namespace=?", object.Name, object.Namespace).Find(&item)
|
||||||
|
db.Delete(item)
|
||||||
|
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
ctl.informer = informer
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctl *JobCtl) CountWithConditions(conditions string) int {
|
||||||
|
var object Job
|
||||||
|
|
||||||
|
return countWithConditions(ctl.DB, conditions, &object)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctl *JobCtl) ListWithConditions(conditions string, paging *Paging, order string) (int, interface{}, error) {
|
||||||
|
var list []Job
|
||||||
|
var object Job
|
||||||
|
var total int
|
||||||
|
|
||||||
|
if len(order) == 0 {
|
||||||
|
order = "updateTime desc"
|
||||||
|
}
|
||||||
|
|
||||||
|
listWithConditions(ctl.DB, &total, &object, &list, conditions, paging, order)
|
||||||
|
|
||||||
|
return total, list, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctl *JobCtl) Lister() interface{} {
|
||||||
|
|
||||||
|
return ctl.lister
|
||||||
|
}
|
||||||
|
|
||||||
|
func getRevisions(job v1.Job) (JobRevisions, error) {
|
||||||
|
revisions := make(JobRevisions)
|
||||||
|
|
||||||
|
if _, exist := job.Annotations["revisions"]; exist {
|
||||||
|
revisionsStr := job.Annotations["revisions"]
|
||||||
|
|
||||||
|
err := json.Unmarshal([]byte(revisionsStr), &revisions)
|
||||||
|
if err != nil {
|
||||||
|
glog.Errorf("failed to rerun job %s, reason: %s", err, err)
|
||||||
|
return nil, fmt.Errorf("failed to rerun job %s", job.Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return revisions, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getStatus(item *v1.Job) JobStatus {
|
||||||
|
var status JobStatus
|
||||||
|
for _, condition := range item.Status.Conditions {
|
||||||
|
if condition.Type == "Failed" && condition.Status == "True" {
|
||||||
|
status.Status = Failed
|
||||||
|
status.Reasons = append(status.Reasons, condition.Reason)
|
||||||
|
status.Messages = append(status.Messages, condition.Message)
|
||||||
|
}
|
||||||
|
|
||||||
|
if condition.Type == "Complete" && condition.Status == "True" {
|
||||||
|
status.Status = Completed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(status.Status) == 0 {
|
||||||
|
status.Status = Unfinished
|
||||||
|
}
|
||||||
|
|
||||||
|
status.DesirePodNum = *item.Spec.Completions
|
||||||
|
status.Succeed = item.Status.Succeeded
|
||||||
|
status.Failed = item.Status.Failed
|
||||||
|
status.StartTime = item.Status.StartTime.Time
|
||||||
|
if item.Status.CompletionTime != nil {
|
||||||
|
status.CompletionTime = item.Status.CompletionTime.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
return status
|
||||||
|
}
|
||||||
|
|
||||||
|
func deleteJob(namespace, job string) error {
|
||||||
|
deletePolicy := metav1.DeletePropagationBackground
|
||||||
|
err := k8sClient.BatchV1().Jobs(namespace).Delete(job, &metav1.DeleteOptions{PropagationPolicy: &deletePolicy})
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func JobReRun(namespace, jobName string) (string, error) {
|
||||||
|
k8sClient = client.NewK8sClient()
|
||||||
|
job, err := k8sClient.BatchV1().Jobs(namespace).Get(jobName, metav1.GetOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
newJob := *job
|
||||||
|
newJob.ResourceVersion = ""
|
||||||
|
newJob.Status = v1.JobStatus{}
|
||||||
|
newJob.ObjectMeta.UID = ""
|
||||||
|
delete(newJob.Spec.Selector.MatchLabels, "controller-uid")
|
||||||
|
delete(newJob.Spec.Template.ObjectMeta.Labels, "controller-uid")
|
||||||
|
|
||||||
|
revisions, err := getRevisions(*job)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
index := len(revisions) + 1
|
||||||
|
value := getStatus(job)
|
||||||
|
revisions[index] = value
|
||||||
|
|
||||||
|
revisionsByte, err := json.Marshal(revisions)
|
||||||
|
if err != nil {
|
||||||
|
glog.Errorf("failed to rerun job %s, reason: %s", err, err)
|
||||||
|
return "", fmt.Errorf("failed to rerun job %s", jobName)
|
||||||
|
}
|
||||||
|
|
||||||
|
newJob.Annotations["revisions"] = string(revisionsByte)
|
||||||
|
|
||||||
|
err = deleteJob(job.Namespace, job.Name)
|
||||||
|
if err != nil {
|
||||||
|
glog.Errorf("failed to rerun job %s, reason: %s", err, err)
|
||||||
|
return "", fmt.Errorf("failed to rerun job %s", jobName)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = k8sClient.BatchV1().Jobs(namespace).Create(&newJob)
|
||||||
|
if err != nil {
|
||||||
|
glog.Errorf("failed to rerun job %s, reason: %s", err, err)
|
||||||
|
return "", fmt.Errorf("failed to rerun job %s", jobName)
|
||||||
|
}
|
||||||
|
|
||||||
|
return "succeed", nil
|
||||||
|
}
|
||||||
@@ -227,6 +227,11 @@ func (ctl *NamespaceCtl) createRoleAndRuntime(item v1.Namespace) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (ctl *NamespaceCtl) generateObject(item v1.Namespace) *Namespace {
|
func (ctl *NamespaceCtl) generateObject(item v1.Namespace) *Namespace {
|
||||||
|
var displayName string
|
||||||
|
|
||||||
|
if item.Annotations != nil && len(item.Annotations[DisplayName]) > 0 {
|
||||||
|
displayName = item.Annotations[DisplayName]
|
||||||
|
}
|
||||||
|
|
||||||
name := item.Name
|
name := item.Name
|
||||||
createTime := item.CreationTimestamp.Time
|
createTime := item.CreationTimestamp.Time
|
||||||
@@ -236,7 +241,13 @@ func (ctl *NamespaceCtl) generateObject(item v1.Namespace) *Namespace {
|
|||||||
createTime = time.Now()
|
createTime = time.Now()
|
||||||
}
|
}
|
||||||
|
|
||||||
object := &Namespace{Name: name, CreateTime: createTime, Status: status, Annotation: Annotation{item.Annotations}}
|
object := &Namespace{
|
||||||
|
Name: name,
|
||||||
|
DisplayName: displayName,
|
||||||
|
CreateTime: createTime,
|
||||||
|
Status: status,
|
||||||
|
Annotation: MapString{item.Annotations},
|
||||||
|
}
|
||||||
|
|
||||||
return object
|
return object
|
||||||
}
|
}
|
||||||
@@ -320,12 +331,14 @@ func (ctl *NamespaceCtl) CountWithConditions(conditions string) int {
|
|||||||
return countWithConditions(ctl.DB, conditions, &object)
|
return countWithConditions(ctl.DB, conditions, &object)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctl *NamespaceCtl) ListWithConditions(conditions string, paging *Paging) (int, interface{}, error) {
|
func (ctl *NamespaceCtl) ListWithConditions(conditions string, paging *Paging, order string) (int, interface{}, error) {
|
||||||
var list []Namespace
|
var list []Namespace
|
||||||
var object Namespace
|
var object Namespace
|
||||||
var total int
|
var total int
|
||||||
|
|
||||||
order := "createTime desc"
|
if len(order) == 0 {
|
||||||
|
order = "createTime desc"
|
||||||
|
}
|
||||||
|
|
||||||
listWithConditions(ctl.DB, &total, &object, &list, conditions, paging, order)
|
listWithConditions(ctl.DB, &total, &object, &list, conditions, paging, order)
|
||||||
|
|
||||||
@@ -333,7 +346,7 @@ func (ctl *NamespaceCtl) ListWithConditions(conditions string, paging *Paging) (
|
|||||||
for index := range list {
|
for index := range list {
|
||||||
usage, err := ctl.GetNamespaceQuota(list[index].Name)
|
usage, err := ctl.GetNamespaceQuota(list[index].Name)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
list[index].Usaeg = usage
|
list[index].Usage = usage
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -350,7 +363,7 @@ func (ctl *NamespaceCtl) GetNamespaceQuota(namespace string) (v1.ResourceList, e
|
|||||||
|
|
||||||
usage := make(v1.ResourceList)
|
usage := make(v1.ResourceList)
|
||||||
|
|
||||||
resourceList := []string{Daemonsets, Deployments, Ingresses, Roles, Services, Statefulsets, PersistentVolumeClaim, Pods}
|
resourceList := []string{Daemonsets, Deployments, Ingresses, Roles, Services, Statefulsets, PersistentVolumeClaim, Pods, Jobs, Cronjobs}
|
||||||
for _, resourceName := range resourceList {
|
for _, resourceName := range resourceList {
|
||||||
used := getUsage(namespace, resourceName)
|
used := getUsage(namespace, resourceName)
|
||||||
var quantity resource.Quantity
|
var quantity resource.Quantity
|
||||||
@@ -365,3 +378,8 @@ func (ctl *NamespaceCtl) GetNamespaceQuota(namespace string) (v1.ResourceList, e
|
|||||||
usage["runningPods"] = quantity
|
usage["runningPods"] = quantity
|
||||||
return usage, nil
|
return usage, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ctl *NamespaceCtl) Lister() interface{} {
|
||||||
|
|
||||||
|
return ctl.lister
|
||||||
|
}
|
||||||
|
|||||||
183
pkg/models/controllers/nodes.go
Normal file
183
pkg/models/controllers/nodes.go
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2018 The KubeSphere Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package controllers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/golang/glog"
|
||||||
|
"k8s.io/api/core/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/labels"
|
||||||
|
"k8s.io/client-go/informers"
|
||||||
|
"k8s.io/client-go/tools/cache"
|
||||||
|
)
|
||||||
|
|
||||||
|
const nodeRole = "role"
|
||||||
|
|
||||||
|
func (ctl *NodeCtl) generateObject(item v1.Node) *Node {
|
||||||
|
var status, ip, role, displayName, msgStr string
|
||||||
|
var msg []string
|
||||||
|
|
||||||
|
if item.Annotations != nil && len(item.Annotations[DisplayName]) > 0 {
|
||||||
|
displayName = item.Annotations[DisplayName]
|
||||||
|
}
|
||||||
|
|
||||||
|
name := item.Name
|
||||||
|
createTime := item.ObjectMeta.CreationTimestamp.Time
|
||||||
|
annotation := item.Annotations
|
||||||
|
|
||||||
|
if _, exist := item.Labels[nodeRole]; exist {
|
||||||
|
role = item.Labels[nodeRole]
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, condition := range item.Status.Conditions {
|
||||||
|
if condition.Type == "Ready" {
|
||||||
|
if condition.Status == "True" {
|
||||||
|
status = Running
|
||||||
|
} else {
|
||||||
|
status = Error
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if condition.Status == "True" {
|
||||||
|
msg = append(msg, condition.Reason)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(msg) > 0 {
|
||||||
|
msgStr = strings.Join(msg, ",")
|
||||||
|
if status == Running {
|
||||||
|
status = Warning
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, address := range item.Status.Addresses {
|
||||||
|
if address.Type == "InternalIP" {
|
||||||
|
ip = address.Address
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object := &Node{
|
||||||
|
Name: name,
|
||||||
|
DisplayName: displayName,
|
||||||
|
Ip: ip,
|
||||||
|
Status: status,
|
||||||
|
CreateTime: createTime,
|
||||||
|
Annotation: MapString{annotation},
|
||||||
|
Taints: Taints{item.Spec.Taints},
|
||||||
|
Msg: msgStr,
|
||||||
|
Role: role,
|
||||||
|
Labels: MapString{item.Labels}}
|
||||||
|
|
||||||
|
return object
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctl *NodeCtl) Name() string {
|
||||||
|
return ctl.CommonAttribute.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctl *NodeCtl) sync(stopChan chan struct{}) {
|
||||||
|
db := ctl.DB
|
||||||
|
|
||||||
|
if db.HasTable(&Node{}) {
|
||||||
|
db.DropTable(&Node{})
|
||||||
|
}
|
||||||
|
|
||||||
|
db = db.CreateTable(&Node{})
|
||||||
|
|
||||||
|
ctl.initListerAndInformer()
|
||||||
|
list, err := ctl.lister.List(labels.Everything())
|
||||||
|
if err != nil {
|
||||||
|
glog.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, item := range list {
|
||||||
|
obj := ctl.generateObject(*item)
|
||||||
|
db.Create(obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
ctl.informer.Run(stopChan)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctl *NodeCtl) total() int {
|
||||||
|
list, err := ctl.lister.List(labels.Everything())
|
||||||
|
if err != nil {
|
||||||
|
glog.Errorf("count %s falied, reason:%s", err, ctl.Name())
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return len(list)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctl *NodeCtl) initListerAndInformer() {
|
||||||
|
db := ctl.DB
|
||||||
|
|
||||||
|
informerFactory := informers.NewSharedInformerFactory(ctl.K8sClient, time.Second*resyncCircle)
|
||||||
|
|
||||||
|
ctl.lister = informerFactory.Core().V1().Nodes().Lister()
|
||||||
|
|
||||||
|
informer := informerFactory.Core().V1().Nodes().Informer()
|
||||||
|
informer.AddEventHandler(cache.ResourceEventHandlerFuncs{
|
||||||
|
AddFunc: func(obj interface{}) {
|
||||||
|
object := obj.(*v1.Node)
|
||||||
|
mysqlObject := ctl.generateObject(*object)
|
||||||
|
db.Create(mysqlObject)
|
||||||
|
},
|
||||||
|
UpdateFunc: func(old, new interface{}) {
|
||||||
|
object := new.(*v1.Node)
|
||||||
|
mysqlObject := ctl.generateObject(*object)
|
||||||
|
db.Save(mysqlObject)
|
||||||
|
|
||||||
|
},
|
||||||
|
DeleteFunc: func(obj interface{}) {
|
||||||
|
var item Node
|
||||||
|
object := obj.(*v1.Node)
|
||||||
|
db.Where("name=? ", object.Name, object.Namespace).Find(&item)
|
||||||
|
db.Delete(item)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
ctl.informer = informer
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctl *NodeCtl) CountWithConditions(conditions string) int {
|
||||||
|
var object Node
|
||||||
|
|
||||||
|
return countWithConditions(ctl.DB, conditions, &object)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctl *NodeCtl) ListWithConditions(conditions string, paging *Paging, order string) (int, interface{}, error) {
|
||||||
|
var list []Node
|
||||||
|
var object Node
|
||||||
|
var total int
|
||||||
|
|
||||||
|
if len(order) == 0 {
|
||||||
|
order = "createTime desc"
|
||||||
|
}
|
||||||
|
|
||||||
|
listWithConditions(ctl.DB, &total, &object, &list, conditions, paging, order)
|
||||||
|
|
||||||
|
return total, list, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctl *NodeCtl) Lister() interface{} {
|
||||||
|
|
||||||
|
return ctl.lister
|
||||||
|
}
|
||||||
@@ -193,8 +193,19 @@ func (ctl *PodCtl) generateObject(item v1.Pod) *Pod {
|
|||||||
containers = append(containers, container)
|
containers = append(containers, container)
|
||||||
}
|
}
|
||||||
|
|
||||||
object := &Pod{Namespace: namespace, Name: name, Node: nodeName, PodIp: podIp, Status: status, NodeIp: nodeIp,
|
object := &Pod{
|
||||||
CreateTime: createTime, Annotation: Annotation{item.Annotations}, Containers: containers, RestartCount: restartCount}
|
Namespace: namespace,
|
||||||
|
Name: name,
|
||||||
|
Node: nodeName,
|
||||||
|
PodIp: podIp,
|
||||||
|
Status: status,
|
||||||
|
NodeIp: nodeIp,
|
||||||
|
CreateTime: createTime,
|
||||||
|
Annotation: MapString{item.Annotations},
|
||||||
|
Containers: containers,
|
||||||
|
RestartCount: restartCount,
|
||||||
|
Labels: MapString{item.Labels},
|
||||||
|
}
|
||||||
|
|
||||||
return object
|
return object
|
||||||
}
|
}
|
||||||
@@ -277,25 +288,21 @@ func (ctl *PodCtl) CountWithConditions(conditions string) int {
|
|||||||
return countWithConditions(ctl.DB, conditions, &object)
|
return countWithConditions(ctl.DB, conditions, &object)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctl *PodCtl) ListWithConditions(conditions string, paging *Paging) (int, interface{}, error) {
|
func (ctl *PodCtl) ListWithConditions(conditions string, paging *Paging, order string) (int, interface{}, error) {
|
||||||
var list []Pod
|
var list []Pod
|
||||||
var object Pod
|
var object Pod
|
||||||
var total int
|
var total int
|
||||||
|
|
||||||
order := "createTime desc"
|
if len(order) == 0 {
|
||||||
|
order = "createTime desc"
|
||||||
|
}
|
||||||
|
|
||||||
listWithConditions(ctl.DB, &total, &object, &list, conditions, paging, order)
|
listWithConditions(ctl.DB, &total, &object, &list, conditions, paging, order)
|
||||||
|
|
||||||
return total, list, nil
|
return total, list, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//func (ctl *PodCtl) Count(namespace string) int {
|
func (ctl *PodCtl) Lister() interface{} {
|
||||||
// var count int
|
|
||||||
// db := ctl.DB
|
return ctl.lister
|
||||||
// if len(namespace) == 0 {
|
}
|
||||||
// db.Model(&Pod{}).Count(&count)
|
|
||||||
// } else {
|
|
||||||
// db.Model(&Pod{}).Where("namespace = ?", namespace).Count(&count)
|
|
||||||
// }
|
|
||||||
// return count
|
|
||||||
//}
|
|
||||||
|
|||||||
@@ -30,6 +30,12 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (ctl *PvcCtl) generateObject(item *v1.PersistentVolumeClaim) *Pvc {
|
func (ctl *PvcCtl) generateObject(item *v1.PersistentVolumeClaim) *Pvc {
|
||||||
|
var displayName string
|
||||||
|
|
||||||
|
if item.Annotations != nil && len(item.Annotations[DisplayName]) > 0 {
|
||||||
|
displayName = item.Annotations[DisplayName]
|
||||||
|
}
|
||||||
|
|
||||||
name := item.Name
|
name := item.Name
|
||||||
namespace := item.Namespace
|
namespace := item.Namespace
|
||||||
status := fmt.Sprintf("%s", item.Status.Phase)
|
status := fmt.Sprintf("%s", item.Status.Phase)
|
||||||
@@ -58,8 +64,18 @@ func (ctl *PvcCtl) generateObject(item *v1.PersistentVolumeClaim) *Pvc {
|
|||||||
|
|
||||||
accessModeStr = strings.Join(accessModeList, ",")
|
accessModeStr = strings.Join(accessModeList, ",")
|
||||||
|
|
||||||
object := &Pvc{Namespace: namespace, Name: name, Status: status, Capacity: capacity,
|
object := &Pvc{
|
||||||
AccessMode: accessModeStr, StorageClassName: storageClass, CreateTime: createTime, Annotation: Annotation{item.Annotations}}
|
Namespace: namespace,
|
||||||
|
Name: name,
|
||||||
|
DisplayName: displayName,
|
||||||
|
Status: status,
|
||||||
|
Capacity: capacity,
|
||||||
|
AccessMode: accessModeStr,
|
||||||
|
StorageClassName: storageClass,
|
||||||
|
CreateTime: createTime,
|
||||||
|
Annotation: MapString{item.Annotations},
|
||||||
|
Labels: MapString{item.Labels},
|
||||||
|
}
|
||||||
|
|
||||||
return object
|
return object
|
||||||
}
|
}
|
||||||
@@ -138,12 +154,14 @@ func (ctl *PvcCtl) CountWithConditions(conditions string) int {
|
|||||||
return countWithConditions(ctl.DB, conditions, &object)
|
return countWithConditions(ctl.DB, conditions, &object)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctl *PvcCtl) ListWithConditions(conditions string, paging *Paging) (int, interface{}, error) {
|
func (ctl *PvcCtl) ListWithConditions(conditions string, paging *Paging, order string) (int, interface{}, error) {
|
||||||
var list []Pvc
|
var list []Pvc
|
||||||
var object Pvc
|
var object Pvc
|
||||||
var total int
|
var total int
|
||||||
|
|
||||||
order := "createTime desc"
|
if len(order) == 0 {
|
||||||
|
order = "createTime desc"
|
||||||
|
}
|
||||||
|
|
||||||
listWithConditions(ctl.DB, &total, &object, &list, conditions, paging, order)
|
listWithConditions(ctl.DB, &total, &object, &list, conditions, paging, order)
|
||||||
|
|
||||||
@@ -163,13 +181,7 @@ func (ctl *PvcCtl) ListWithConditions(conditions string, paging *Paging) (int, i
|
|||||||
return total, list, nil
|
return total, list, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//func (ctl *PvcCtl) Count(namespace string) int {
|
func (ctl *PvcCtl) Lister() interface{} {
|
||||||
// var count int
|
|
||||||
// db := ctl.DB
|
return ctl.lister
|
||||||
// if len(namespace) == 0 {
|
}
|
||||||
// db.Model(&Pvc{}).Count(&count)
|
|
||||||
// } else {
|
|
||||||
// db.Model(&Pvc{}).Where("namespace = ?", namespace).Count(&count)
|
|
||||||
// }
|
|
||||||
// return count
|
|
||||||
//}
|
|
||||||
|
|||||||
64
pkg/models/controllers/replicasets.go
Normal file
64
pkg/models/controllers/replicasets.go
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2018 The KubeSphere Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package controllers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"k8s.io/client-go/informers"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (ctl *ReplicaSetCtl) Name() string {
|
||||||
|
return ctl.CommonAttribute.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctl *ReplicaSetCtl) sync(stopChan chan struct{}) {
|
||||||
|
|
||||||
|
ctl.initListerAndInformer()
|
||||||
|
ctl.informer.Run(stopChan)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctl *ReplicaSetCtl) total() int {
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctl *ReplicaSetCtl) initListerAndInformer() {
|
||||||
|
|
||||||
|
informerFactory := informers.NewSharedInformerFactory(ctl.K8sClient, time.Second*resyncCircle)
|
||||||
|
|
||||||
|
ctl.lister = informerFactory.Apps().V1().ReplicaSets().Lister()
|
||||||
|
|
||||||
|
informer := informerFactory.Apps().V1().ReplicaSets().Informer()
|
||||||
|
|
||||||
|
ctl.informer = informer
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctl *ReplicaSetCtl) CountWithConditions(conditions string) int {
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctl *ReplicaSetCtl) ListWithConditions(conditions string, paging *Paging, order string) (int, interface{}, error) {
|
||||||
|
|
||||||
|
return 0, nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctl *ReplicaSetCtl) Lister() interface{} {
|
||||||
|
|
||||||
|
return ctl.lister
|
||||||
|
}
|
||||||
@@ -28,6 +28,12 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (ctl *RoleCtl) generateObject(item v1.Role) *Role {
|
func (ctl *RoleCtl) generateObject(item v1.Role) *Role {
|
||||||
|
var displayName string
|
||||||
|
|
||||||
|
if item.Annotations != nil && len(item.Annotations[DisplayName]) > 0 {
|
||||||
|
displayName = item.Annotations[DisplayName]
|
||||||
|
}
|
||||||
|
|
||||||
name := item.Name
|
name := item.Name
|
||||||
if strings.HasPrefix(name, systemPrefix) {
|
if strings.HasPrefix(name, systemPrefix) {
|
||||||
return nil
|
return nil
|
||||||
@@ -38,7 +44,13 @@ func (ctl *RoleCtl) generateObject(item v1.Role) *Role {
|
|||||||
createTime = time.Now()
|
createTime = time.Now()
|
||||||
}
|
}
|
||||||
|
|
||||||
object := &Role{Namespace: namespace, Name: name, CreateTime: createTime, Annotation: Annotation{item.Annotations}}
|
object := &Role{
|
||||||
|
Namespace: namespace,
|
||||||
|
Name: name,
|
||||||
|
DisplayName: displayName,
|
||||||
|
CreateTime: createTime,
|
||||||
|
Annotation: MapString{item.Annotations},
|
||||||
|
}
|
||||||
|
|
||||||
return object
|
return object
|
||||||
}
|
}
|
||||||
@@ -132,21 +144,21 @@ func (ctl *RoleCtl) CountWithConditions(conditions string) int {
|
|||||||
return countWithConditions(ctl.DB, conditions, &object)
|
return countWithConditions(ctl.DB, conditions, &object)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctl *RoleCtl) ListWithConditions(conditions string, paging *Paging) (int, interface{}, error) {
|
func (ctl *RoleCtl) ListWithConditions(conditions string, paging *Paging, order string) (int, interface{}, error) {
|
||||||
var list []Role
|
var list []Role
|
||||||
var object Role
|
var object Role
|
||||||
var total int
|
var total int
|
||||||
|
|
||||||
order := "createTime desc"
|
if len(order) == 0 {
|
||||||
|
order = "createTime desc"
|
||||||
|
}
|
||||||
|
|
||||||
listWithConditions(ctl.DB, &total, &object, &list, conditions, paging, order)
|
listWithConditions(ctl.DB, &total, &object, &list, conditions, paging, order)
|
||||||
|
|
||||||
return total, list, nil
|
return total, list, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//func (ctl *RoleCtl) Count(namespace string) int {
|
func (ctl *RoleCtl) Lister() interface{} {
|
||||||
// var count int
|
|
||||||
// db := ctl.DB
|
return ctl.lister
|
||||||
// db.Model(&Role{}).Where("namespace = ?", namespace).Count(&count)
|
}
|
||||||
// return count
|
|
||||||
//}
|
|
||||||
|
|||||||
@@ -31,10 +31,9 @@ type resourceControllers struct {
|
|||||||
k8sClient *kubernetes.Clientset
|
k8sClient *kubernetes.Clientset
|
||||||
}
|
}
|
||||||
|
|
||||||
var stopChan chan struct{}
|
|
||||||
var ResourceControllers resourceControllers
|
var ResourceControllers resourceControllers
|
||||||
|
|
||||||
func (rec *resourceControllers) runContoller(name string) {
|
func (rec *resourceControllers) runContoller(name string, stopChan chan struct{}) {
|
||||||
var ctl Controller
|
var ctl Controller
|
||||||
attr := CommonAttribute{DB: client.NewDBClient(), K8sClient: rec.k8sClient, stopChan: stopChan,
|
attr := CommonAttribute{DB: client.NewDBClient(), K8sClient: rec.k8sClient, stopChan: stopChan,
|
||||||
aliveChan: make(chan struct{}), Name: name}
|
aliveChan: make(chan struct{}), Name: name}
|
||||||
@@ -61,6 +60,16 @@ func (rec *resourceControllers) runContoller(name string) {
|
|||||||
ctl = &NamespaceCtl{CommonAttribute: attr}
|
ctl = &NamespaceCtl{CommonAttribute: attr}
|
||||||
case StorageClasses:
|
case StorageClasses:
|
||||||
ctl = &StorageClassCtl{CommonAttribute: attr}
|
ctl = &StorageClassCtl{CommonAttribute: attr}
|
||||||
|
case Jobs:
|
||||||
|
ctl = &JobCtl{CommonAttribute: attr}
|
||||||
|
case Cronjobs:
|
||||||
|
ctl = &CronJobCtl{CommonAttribute: attr}
|
||||||
|
case Nodes:
|
||||||
|
ctl = &NodeCtl{CommonAttribute: attr}
|
||||||
|
case Replicasets:
|
||||||
|
ctl = &ReplicaSetCtl{CommonAttribute: attr}
|
||||||
|
case ControllerRevisions:
|
||||||
|
ctl = &ControllerRevisionCtl{CommonAttribute: attr}
|
||||||
default:
|
default:
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -71,6 +80,8 @@ func (rec *resourceControllers) runContoller(name string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func dbHealthCheck(db *gorm.DB) {
|
func dbHealthCheck(db *gorm.DB) {
|
||||||
|
defer db.Close()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
count := 0
|
count := 0
|
||||||
var err error
|
var err error
|
||||||
@@ -79,7 +90,7 @@ func dbHealthCheck(db *gorm.DB) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
count++
|
count++
|
||||||
}
|
}
|
||||||
time.Sleep(1 * time.Second)
|
time.Sleep(5 * time.Second)
|
||||||
}
|
}
|
||||||
|
|
||||||
if count > 3 {
|
if count > 3 {
|
||||||
@@ -98,8 +109,8 @@ func Run() {
|
|||||||
ResourceControllers = resourceControllers{k8sClient: k8sClient, Controllers: make(map[string]Controller)}
|
ResourceControllers = resourceControllers{k8sClient: k8sClient, Controllers: make(map[string]Controller)}
|
||||||
|
|
||||||
for _, item := range []string{Deployments, Statefulsets, Daemonsets, PersistentVolumeClaim, Pods, Services,
|
for _, item := range []string{Deployments, Statefulsets, Daemonsets, PersistentVolumeClaim, Pods, Services,
|
||||||
Ingresses, Roles, ClusterRoles, Namespaces, StorageClasses} {
|
Ingresses, Roles, ClusterRoles, Namespaces, StorageClasses, Jobs, Cronjobs, Nodes, Replicasets, ControllerRevisions} {
|
||||||
ResourceControllers.runContoller(item)
|
ResourceControllers.runContoller(item, stopChan)
|
||||||
}
|
}
|
||||||
|
|
||||||
go dbHealthCheck(client.NewDBClient())
|
go dbHealthCheck(client.NewDBClient())
|
||||||
@@ -110,7 +121,7 @@ func Run() {
|
|||||||
case _, isClose := <-controller.chanAlive():
|
case _, isClose := <-controller.chanAlive():
|
||||||
if !isClose {
|
if !isClose {
|
||||||
glog.Errorf("controller %s have stopped, restart it", ctlName)
|
glog.Errorf("controller %s have stopped, restart it", ctlName)
|
||||||
ResourceControllers.runContoller(ctlName)
|
ResourceControllers.runContoller(ctlName, stopChan)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
time.Sleep(5 * time.Second)
|
time.Sleep(5 * time.Second)
|
||||||
|
|||||||
@@ -69,12 +69,25 @@ func getExternalIp(item v1.Service) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func generateSvcObject(item v1.Service) *Service {
|
func generateSvcObject(item v1.Service) *Service {
|
||||||
|
var app string
|
||||||
|
var displayName string
|
||||||
|
|
||||||
|
if item.Annotations != nil && len(item.Annotations[DisplayName]) > 0 {
|
||||||
|
displayName = item.Annotations[DisplayName]
|
||||||
|
}
|
||||||
name := item.Name
|
name := item.Name
|
||||||
namespace := item.Namespace
|
namespace := item.Namespace
|
||||||
createTime := item.CreationTimestamp.Time
|
createTime := item.CreationTimestamp.Time
|
||||||
externalIp := getExternalIp(item)
|
externalIp := getExternalIp(item)
|
||||||
serviceType := item.Spec.Type
|
serviceType := item.Spec.Type
|
||||||
vip := item.Spec.ClusterIP
|
vip := item.Spec.ClusterIP
|
||||||
|
|
||||||
|
release := item.ObjectMeta.Labels["release"]
|
||||||
|
chart := item.ObjectMeta.Labels["chart"]
|
||||||
|
|
||||||
|
if len(release) > 0 && len(chart) > 0 {
|
||||||
|
app = release + "/" + chart
|
||||||
|
}
|
||||||
ports := ""
|
ports := ""
|
||||||
var nodePorts []string
|
var nodePorts []string
|
||||||
|
|
||||||
@@ -118,13 +131,16 @@ func generateSvcObject(item v1.Service) *Service {
|
|||||||
object := &Service{
|
object := &Service{
|
||||||
Namespace: namespace,
|
Namespace: namespace,
|
||||||
Name: name,
|
Name: name,
|
||||||
|
DisplayName: displayName,
|
||||||
ServiceType: string(serviceType),
|
ServiceType: string(serviceType),
|
||||||
ExternalIp: externalIp,
|
ExternalIp: externalIp,
|
||||||
VirtualIp: vip,
|
VirtualIp: vip,
|
||||||
CreateTime: createTime,
|
CreateTime: createTime,
|
||||||
Ports: ports,
|
Ports: ports,
|
||||||
NodePorts: strings.Join(nodePorts, ","),
|
NodePorts: strings.Join(nodePorts, ","),
|
||||||
Annotation: Annotation{item.Annotations},
|
Annotation: MapString{item.Annotations},
|
||||||
|
Labels: MapString{item.Labels},
|
||||||
|
App: app,
|
||||||
}
|
}
|
||||||
|
|
||||||
return object
|
return object
|
||||||
@@ -209,14 +225,21 @@ func (ctl *ServiceCtl) CountWithConditions(conditions string) int {
|
|||||||
return countWithConditions(ctl.DB, conditions, &object)
|
return countWithConditions(ctl.DB, conditions, &object)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctl *ServiceCtl) ListWithConditions(conditions string, paging *Paging) (int, interface{}, error) {
|
func (ctl *ServiceCtl) ListWithConditions(conditions string, paging *Paging, order string) (int, interface{}, error) {
|
||||||
var list []Service
|
var list []Service
|
||||||
var object Service
|
var object Service
|
||||||
var total int
|
var total int
|
||||||
|
|
||||||
order := "createTime desc"
|
if len(order) == 0 {
|
||||||
|
order = "createTime desc"
|
||||||
|
}
|
||||||
|
|
||||||
listWithConditions(ctl.DB, &total, &object, &list, conditions, paging, order)
|
listWithConditions(ctl.DB, &total, &object, &list, conditions, paging, order)
|
||||||
|
|
||||||
return total, list, nil
|
return total, list, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ctl *ServiceCtl) Lister() interface{} {
|
||||||
|
|
||||||
|
return ctl.lister
|
||||||
|
}
|
||||||
|
|||||||
@@ -30,6 +30,11 @@ import (
|
|||||||
func (ctl *StatefulsetCtl) generateObject(item v1.StatefulSet) *Statefulset {
|
func (ctl *StatefulsetCtl) generateObject(item v1.StatefulSet) *Statefulset {
|
||||||
var app string
|
var app string
|
||||||
var status string
|
var status string
|
||||||
|
var displayName string
|
||||||
|
|
||||||
|
if item.Annotations != nil && len(item.Annotations[DisplayName]) > 0 {
|
||||||
|
displayName = item.Annotations[DisplayName]
|
||||||
|
}
|
||||||
name := item.Name
|
name := item.Name
|
||||||
namespace := item.Namespace
|
namespace := item.Namespace
|
||||||
availablePodNum := item.Status.ReadyReplicas
|
availablePodNum := item.Status.ReadyReplicas
|
||||||
@@ -56,8 +61,18 @@ func (ctl *StatefulsetCtl) generateObject(item v1.StatefulSet) *Statefulset {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
statefulSetObject := &Statefulset{Namespace: namespace, Name: name, Available: availablePodNum, Desire: desirePodNum,
|
statefulSetObject := &Statefulset{
|
||||||
App: app, CreateTime: createTime, Status: status, Annotation: Annotation{item.Annotations}}
|
Namespace: namespace,
|
||||||
|
Name: name,
|
||||||
|
DisplayName: displayName,
|
||||||
|
Available: availablePodNum,
|
||||||
|
Desire: desirePodNum,
|
||||||
|
App: app,
|
||||||
|
CreateTime: createTime,
|
||||||
|
Status: status,
|
||||||
|
Annotation: MapString{item.Annotations},
|
||||||
|
Labels: MapString{item.Spec.Selector.MatchLabels},
|
||||||
|
}
|
||||||
|
|
||||||
return statefulSetObject
|
return statefulSetObject
|
||||||
}
|
}
|
||||||
@@ -137,14 +152,21 @@ func (ctl *StatefulsetCtl) CountWithConditions(conditions string) int {
|
|||||||
return countWithConditions(ctl.DB, conditions, &object)
|
return countWithConditions(ctl.DB, conditions, &object)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctl *StatefulsetCtl) ListWithConditions(conditions string, paging *Paging) (int, interface{}, error) {
|
func (ctl *StatefulsetCtl) ListWithConditions(conditions string, paging *Paging, order string) (int, interface{}, error) {
|
||||||
var list []Statefulset
|
var list []Statefulset
|
||||||
var object Statefulset
|
var object Statefulset
|
||||||
var total int
|
var total int
|
||||||
|
|
||||||
order := "createTime desc"
|
if len(order) == 0 {
|
||||||
|
order = "createTime desc"
|
||||||
|
}
|
||||||
|
|
||||||
listWithConditions(ctl.DB, &total, &object, &list, conditions, paging, order)
|
listWithConditions(ctl.DB, &total, &object, &list, conditions, paging, order)
|
||||||
|
|
||||||
return total, list, nil
|
return total, list, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ctl *StatefulsetCtl) Lister() interface{} {
|
||||||
|
|
||||||
|
return ctl.lister
|
||||||
|
}
|
||||||
|
|||||||
@@ -30,6 +30,12 @@ import (
|
|||||||
|
|
||||||
func (ctl *StorageClassCtl) generateObject(item v1.StorageClass) *StorageClass {
|
func (ctl *StorageClassCtl) generateObject(item v1.StorageClass) *StorageClass {
|
||||||
|
|
||||||
|
var displayName string
|
||||||
|
|
||||||
|
if item.Annotations != nil && len(item.Annotations[DisplayName]) > 0 {
|
||||||
|
displayName = item.Annotations[DisplayName]
|
||||||
|
}
|
||||||
|
|
||||||
name := item.Name
|
name := item.Name
|
||||||
createTime := item.CreationTimestamp.Time
|
createTime := item.CreationTimestamp.Time
|
||||||
isDefault := false
|
isDefault := false
|
||||||
@@ -41,7 +47,13 @@ func (ctl *StorageClassCtl) generateObject(item v1.StorageClass) *StorageClass {
|
|||||||
createTime = time.Now()
|
createTime = time.Now()
|
||||||
}
|
}
|
||||||
|
|
||||||
object := &StorageClass{Name: name, CreateTime: createTime, IsDefault: isDefault, Annotation: Annotation{item.Annotations}}
|
object := &StorageClass{
|
||||||
|
Name: name,
|
||||||
|
DisplayName: displayName,
|
||||||
|
CreateTime: createTime,
|
||||||
|
IsDefault: isDefault,
|
||||||
|
Annotation: MapString{item.Annotations},
|
||||||
|
}
|
||||||
|
|
||||||
return object
|
return object
|
||||||
}
|
}
|
||||||
@@ -120,12 +132,14 @@ func (ctl *StorageClassCtl) CountWithConditions(conditions string) int {
|
|||||||
return countWithConditions(ctl.DB, conditions, &object)
|
return countWithConditions(ctl.DB, conditions, &object)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctl *StorageClassCtl) ListWithConditions(conditions string, paging *Paging) (int, interface{}, error) {
|
func (ctl *StorageClassCtl) ListWithConditions(conditions string, paging *Paging, order string) (int, interface{}, error) {
|
||||||
var list []StorageClass
|
var list []StorageClass
|
||||||
var object StorageClass
|
var object StorageClass
|
||||||
var total int
|
var total int
|
||||||
|
|
||||||
order := "createTime desc"
|
if len(order) == 0 {
|
||||||
|
order = "createTime desc"
|
||||||
|
}
|
||||||
|
|
||||||
listWithConditions(ctl.DB, &total, &object, &list, conditions, paging, order)
|
listWithConditions(ctl.DB, &total, &object, &list, conditions, paging, order)
|
||||||
|
|
||||||
@@ -138,3 +152,8 @@ func (ctl *StorageClassCtl) ListWithConditions(conditions string, paging *Paging
|
|||||||
|
|
||||||
return total, list, nil
|
return total, list, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ctl *StorageClassCtl) Lister() interface{} {
|
||||||
|
|
||||||
|
return ctl.lister
|
||||||
|
}
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ import (
|
|||||||
"k8s.io/api/core/v1"
|
"k8s.io/api/core/v1"
|
||||||
"k8s.io/client-go/kubernetes"
|
"k8s.io/client-go/kubernetes"
|
||||||
appV1 "k8s.io/client-go/listers/apps/v1"
|
appV1 "k8s.io/client-go/listers/apps/v1"
|
||||||
|
batchv1 "k8s.io/client-go/listers/batch/v1"
|
||||||
|
batchv1beta1 "k8s.io/client-go/listers/batch/v1beta1"
|
||||||
coreV1 "k8s.io/client-go/listers/core/v1"
|
coreV1 "k8s.io/client-go/listers/core/v1"
|
||||||
"k8s.io/client-go/listers/extensions/v1beta1"
|
"k8s.io/client-go/listers/extensions/v1beta1"
|
||||||
rbacV1 "k8s.io/client-go/listers/rbac/v1"
|
rbacV1 "k8s.io/client-go/listers/rbac/v1"
|
||||||
@@ -35,22 +37,18 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
resyncCircle = 600
|
resyncCircle = 600
|
||||||
Stopped = "stopped"
|
Stopped = "stopped"
|
||||||
PvcPending = "Pending"
|
PvcPending = "pending"
|
||||||
Running = "running"
|
Running = "running"
|
||||||
Updating = "updating"
|
Updating = "updating"
|
||||||
tablePods = "pods"
|
Failed = "failed"
|
||||||
tableDeployments = "deployments"
|
Unfinished = "unfinished"
|
||||||
tableDaemonsets = "daemonsets"
|
Completed = "completed"
|
||||||
tableStatefulsets = "statefulsets"
|
Pause = "pause"
|
||||||
tableNamespaces = "namespaces"
|
Warning = "warning"
|
||||||
tableIngresses = "ingresses"
|
Error = "error"
|
||||||
tablePersistentVolumeClaim = "pvcs"
|
DisplayName = "displayName"
|
||||||
tableRoles = "roles"
|
|
||||||
tableClusterRoles = "cluster_roles"
|
|
||||||
tableServices = "services"
|
|
||||||
tableStorageClasses = "storage_classes"
|
|
||||||
|
|
||||||
Pods = "pods"
|
Pods = "pods"
|
||||||
Deployments = "deployments"
|
Deployments = "deployments"
|
||||||
@@ -64,13 +62,18 @@ const (
|
|||||||
Services = "services"
|
Services = "services"
|
||||||
StorageClasses = "storage-classes"
|
StorageClasses = "storage-classes"
|
||||||
Applications = "applications"
|
Applications = "applications"
|
||||||
|
Jobs = "jobs"
|
||||||
|
Cronjobs = "cronjobs"
|
||||||
|
Nodes = "nodes"
|
||||||
|
Replicasets = "replicasets"
|
||||||
|
ControllerRevisions = "controllerrevisions"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Annotation struct {
|
type MapString struct {
|
||||||
Values map[string]string `gorm:"type:TEXT"`
|
Values map[string]string `json:"values" gorm:"type:TEXT"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (annotation *Annotation) Scan(val interface{}) error {
|
func (annotation *MapString) Scan(val interface{}) error {
|
||||||
switch val := val.(type) {
|
switch val := val.(type) {
|
||||||
case string:
|
case string:
|
||||||
return json.Unmarshal([]byte(val), annotation)
|
return json.Unmarshal([]byte(val), annotation)
|
||||||
@@ -82,92 +85,104 @@ func (annotation *Annotation) Scan(val interface{}) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (annotation Annotation) Value() (driver.Value, error) {
|
func (annotation MapString) Value() (driver.Value, error) {
|
||||||
bytes, err := json.Marshal(annotation)
|
bytes, err := json.Marshal(annotation)
|
||||||
return string(bytes), err
|
return string(bytes), err
|
||||||
}
|
}
|
||||||
|
|
||||||
type Deployment struct {
|
type Taints struct {
|
||||||
Name string `gorm:"primary_key" json:"name"`
|
Values []v1.Taint `json:"values" gorm:"type:TEXT"`
|
||||||
Namespace string `gorm:"primary_key" json:"namespace"`
|
|
||||||
App string `json:"app,omitempty"`
|
|
||||||
|
|
||||||
Available int32 `json:"available"`
|
|
||||||
Desire int32 `json:"desire"`
|
|
||||||
Status string `json:"status"`
|
|
||||||
Annotation Annotation `json:"annotations"`
|
|
||||||
UpdateTime time.Time `gorm:"column:updateTime" json:"updateTime,omitempty"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (Deployment) TableName() string {
|
func (taints *Taints) Scan(val interface{}) error {
|
||||||
return tableDeployments
|
switch val := val.(type) {
|
||||||
|
case string:
|
||||||
|
return json.Unmarshal([]byte(val), taints)
|
||||||
|
case []byte:
|
||||||
|
return json.Unmarshal(val, taints)
|
||||||
|
default:
|
||||||
|
return errors.New("not support")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (taints Taints) Value() (driver.Value, error) {
|
||||||
|
bytes, err := json.Marshal(taints)
|
||||||
|
return string(bytes), err
|
||||||
|
}
|
||||||
|
|
||||||
|
type Deployment struct {
|
||||||
|
Name string `gorm:"primary_key" json:"name"`
|
||||||
|
DisplayName string `json:"displayName,omitempty" gorm:"column:displayName"`
|
||||||
|
Namespace string `gorm:"primary_key" json:"namespace"`
|
||||||
|
App string `json:"app,omitempty"`
|
||||||
|
|
||||||
|
Available int32 `json:"available"`
|
||||||
|
Desire int32 `json:"desire"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
Labels MapString `json:"labels"`
|
||||||
|
Annotation MapString `json:"annotations"`
|
||||||
|
UpdateTime time.Time `gorm:"column:updateTime" json:"updateTime,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Statefulset struct {
|
type Statefulset struct {
|
||||||
Name string `gorm:"primary_key" json:"name,omitempty"`
|
Name string `gorm:"primary_key" json:"name,omitempty"`
|
||||||
Namespace string `gorm:"primary_key" json:"namespace,omitempty"`
|
DisplayName string `json:"displayName,omitempty" gorm:"column:displayName"`
|
||||||
App string `json:"app,omitempty"`
|
Namespace string `gorm:"primary_key" json:"namespace,omitempty"`
|
||||||
|
App string `json:"app,omitempty"`
|
||||||
|
|
||||||
Available int32 `json:"available"`
|
Available int32 `json:"available"`
|
||||||
Desire int32 `json:"desire"`
|
Desire int32 `json:"desire"`
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
Annotation Annotation `json:"annotations"`
|
Annotation MapString `json:"annotations"`
|
||||||
CreateTime time.Time `gorm:"column:createTime" json:"createTime,omitempty"`
|
Labels MapString `json:"labels"`
|
||||||
}
|
CreateTime time.Time `gorm:"column:createTime" json:"createTime,omitempty"`
|
||||||
|
|
||||||
func (Statefulset) TableName() string {
|
|
||||||
return tableStatefulsets
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Daemonset struct {
|
type Daemonset struct {
|
||||||
Name string `gorm:"primary_key" json:"name,omitempty"`
|
Name string `gorm:"primary_key" json:"name,omitempty"`
|
||||||
Namespace string `gorm:"primary_key" json:"namespace,omitempty"`
|
DisplayName string `json:"displayName,omitempty" gorm:"column:displayName"`
|
||||||
App string `json:"app,omitempty"`
|
Namespace string `gorm:"primary_key" json:"namespace,omitempty"`
|
||||||
|
App string `json:"app,omitempty"`
|
||||||
|
|
||||||
Available int32 `json:"available"`
|
Available int32 `json:"available"`
|
||||||
Desire int32 `json:"desire"`
|
Desire int32 `json:"desire"`
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
NodeSelector string `json:"nodeSelector, omitempty"`
|
NodeSelector string `json:"nodeSelector, omitempty"`
|
||||||
Annotation Annotation `json:"annotations"`
|
Annotation MapString `json:"annotations"`
|
||||||
CreateTime time.Time `gorm:"column:createTime" json:"createTime,omitempty"`
|
Labels MapString `json:"labels"`
|
||||||
}
|
CreateTime time.Time `gorm:"column:createTime" json:"createTime,omitempty"`
|
||||||
|
|
||||||
func (Daemonset) TableName() string {
|
|
||||||
return tableDaemonsets
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Service struct {
|
type Service struct {
|
||||||
Name string `gorm:"primary_key" json:"name"`
|
Name string `gorm:"primary_key" json:"name"`
|
||||||
|
DisplayName string `json:"displayName,omitempty" gorm:"column:displayName"`
|
||||||
Namespace string `gorm:"primary_key" json:"namespace"`
|
Namespace string `gorm:"primary_key" json:"namespace"`
|
||||||
ServiceType string `json:"type,omitempty"`
|
ServiceType string `gorm:"column:type" json:"type,omitempty"`
|
||||||
|
|
||||||
VirtualIp string `json:"virtualIp,omitempty"`
|
App string `json:"app,omitempty"`
|
||||||
ExternalIp string `json:"externalIp,omitempty"`
|
VirtualIp string `gorm:"column:virtualIp" json:"virtualIp,omitempty"`
|
||||||
|
ExternalIp string `gorm:"column:externalIp" json:"externalIp,omitempty"`
|
||||||
|
|
||||||
Ports string `json:"ports,omitempty"`
|
Ports string `json:"ports,omitempty"`
|
||||||
NodePorts string `json:"nodePorts,omitempty"`
|
NodePorts string `gorm:"column:nodePorts" json:"nodePorts,omitempty"`
|
||||||
Annotation Annotation `json:"annotations"`
|
Annotation MapString `json:"annotations"`
|
||||||
CreateTime time.Time `gorm:"column:createTime" json:"createTime,omitempty"`
|
Labels MapString `json:"labels"`
|
||||||
}
|
CreateTime time.Time `gorm:"column:createTime" json:"createTime,omitempty"`
|
||||||
|
|
||||||
func (Service) TableName() string {
|
|
||||||
return tableServices
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Pvc struct {
|
type Pvc struct {
|
||||||
Name string `gorm:"primary_key" json:"name"`
|
Name string `gorm:"primary_key" json:"name"`
|
||||||
Namespace string `gorm:"primary_key" json:"namespace"`
|
DisplayName string `json:"displayName,omitempty" gorm:"column:displayName"`
|
||||||
Status string `json:"status,omitempty"`
|
Namespace string `gorm:"primary_key" json:"namespace"`
|
||||||
Capacity string `json:"capacity,omitempty"`
|
Status string `json:"status,omitempty"`
|
||||||
AccessMode string `json:"accessMode,omitempty"`
|
Capacity string `json:"capacity,omitempty"`
|
||||||
Annotation Annotation `json:"annotations"`
|
AccessMode string `gorm:"column:accessMode" json:"accessMode,omitempty"`
|
||||||
CreateTime time.Time `gorm:"column:createTime" json:"createTime,omitempty"`
|
Annotation MapString `json:"annotations"`
|
||||||
StorageClassName string `gorm:"column:storage_class" json:"storage_class,omitempty"`
|
Labels MapString `json:"labels"`
|
||||||
InUse bool `gorm:"-" json:"inUse"`
|
CreateTime time.Time `gorm:"column:createTime" json:"createTime,omitempty"`
|
||||||
}
|
StorageClassName string `gorm:"column:storage_class" json:"storage_class,omitempty"`
|
||||||
|
InUse bool `gorm:"column:inUse" json:"inUse"`
|
||||||
func (Pvc) TableName() string {
|
|
||||||
return tablePersistentVolumeClaim
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type ingressRule struct {
|
type ingressRule struct {
|
||||||
@@ -178,17 +193,15 @@ type ingressRule struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Ingress struct {
|
type Ingress struct {
|
||||||
Name string `gorm:"primary_key" json:"name"`
|
Name string `gorm:"primary_key" json:"name"`
|
||||||
Namespace string `gorm:"primary_key" json:"namespace"`
|
DisplayName string `json:"displayName,omitempty" gorm:"column:displayName"`
|
||||||
Ip string `json:"ip,omitempty"`
|
Namespace string `gorm:"primary_key" json:"namespace"`
|
||||||
Rules string `gorm:"type:text" json:"rules, omitempty"`
|
Ip string `json:"ip,omitempty"`
|
||||||
TlsTermination string `json:"tlsTermination,omitempty"`
|
Rules string `gorm:"type:text" json:"rules, omitempty"`
|
||||||
Annotation Annotation `json:"annotations"`
|
TlsTermination string `gorm:"column:tlsTermination" json:"tlsTermination,omitempty"`
|
||||||
CreateTime time.Time `gorm:"column:createTime" json:"createTime,omitempty"`
|
Annotation MapString `json:"annotations"`
|
||||||
}
|
Labels MapString `json:"labels"`
|
||||||
|
CreateTime time.Time `gorm:"column:createTime" json:"createTime,omitempty"`
|
||||||
func (Ingress) TableName() string {
|
|
||||||
return tableIngresses
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Pod struct {
|
type Pod struct {
|
||||||
@@ -196,10 +209,11 @@ type Pod struct {
|
|||||||
Namespace string `gorm:"primary_key" json:"namespace"`
|
Namespace string `gorm:"primary_key" json:"namespace"`
|
||||||
Status string `json:"status,omitempty"`
|
Status string `json:"status,omitempty"`
|
||||||
Node string `json:"node,omitempty"`
|
Node string `json:"node,omitempty"`
|
||||||
NodeIp string `json:"nodeIp,omitempty"`
|
NodeIp string `gorm:"column:nodeIp" json:"nodeIp,omitempty"`
|
||||||
PodIp string `json:"podIp,omitempty"`
|
PodIp string `gorm:"column:podIp" json:"podIp,omitempty"`
|
||||||
Containers Containers `gorm:"type:text" json:"containers,omitempty"`
|
Containers Containers `gorm:"type:text" json:"containers,omitempty"`
|
||||||
Annotation Annotation `json:"annotations"`
|
Annotation MapString `json:"annotations"`
|
||||||
|
Labels MapString `json:"labels"`
|
||||||
RestartCount int `json:"restartCount"`
|
RestartCount int `json:"restartCount"`
|
||||||
CreateTime time.Time `gorm:"column:createTime" json:"createTime,omitempty"`
|
CreateTime time.Time `gorm:"column:createTime" json:"createTime,omitempty"`
|
||||||
}
|
}
|
||||||
@@ -230,61 +244,97 @@ func (containers Containers) Value() (driver.Value, error) {
|
|||||||
return string(bytes), err
|
return string(bytes), err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (Pod) TableName() string {
|
|
||||||
return tablePods
|
|
||||||
}
|
|
||||||
|
|
||||||
type Role struct {
|
type Role struct {
|
||||||
Name string `gorm:"primary_key" json:"name"`
|
Name string `gorm:"primary_key" json:"name"`
|
||||||
Namespace string `gorm:"primary_key" json:"namespace"`
|
DisplayName string `json:"displayName,omitempty" gorm:"column:displayName"`
|
||||||
Annotation Annotation `json:"annotations"`
|
Namespace string `gorm:"primary_key" json:"namespace"`
|
||||||
CreateTime time.Time `gorm:"column:createTime" json:"createTime,omitempty"`
|
Annotation MapString `json:"annotations"`
|
||||||
}
|
CreateTime time.Time `gorm:"column:createTime" json:"createTime,omitempty"`
|
||||||
|
|
||||||
func (Role) TableName() string {
|
|
||||||
return tableRoles
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type ClusterRole struct {
|
type ClusterRole struct {
|
||||||
Name string `gorm:"primary_key" json:"name"`
|
Name string `gorm:"primary_key" json:"name"`
|
||||||
Annotation Annotation `json:"annotations"`
|
DisplayName string `json:"displayName,omitempty" gorm:"column:displayName"`
|
||||||
CreateTime time.Time `gorm:"column:createTime" json:"createTime,omitempty"`
|
Annotation MapString `json:"annotations"`
|
||||||
}
|
CreateTime time.Time `gorm:"column:createTime" json:"createTime,omitempty"`
|
||||||
|
|
||||||
func (ClusterRole) TableName() string {
|
|
||||||
return tableClusterRoles
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Namespace struct {
|
type Namespace struct {
|
||||||
Name string `gorm:"primary_key" json:"name"`
|
Name string `gorm:"primary_key" json:"name"`
|
||||||
Creator string `json:"creator,omitempty"`
|
DisplayName string `json:"displayName,omitempty" gorm:"column:displayName"`
|
||||||
Status string `json:"status"`
|
Creator string `json:"creator,omitempty"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
|
||||||
Descrition string `json:"description,omitempty"`
|
Descrition string `json:"description,omitempty"`
|
||||||
Annotation Annotation `json:"annotations"`
|
Annotation MapString `json:"annotations"`
|
||||||
CreateTime time.Time `gorm:"column:createTime" json:"createTime,omitempty"`
|
CreateTime time.Time `gorm:"column:createTime" json:"createTime,omitempty"`
|
||||||
Usaeg v1.ResourceList `gorm:"-" json:"usage,omitempty"`
|
Usage v1.ResourceList `gorm:"-" json:"usage,omitempty"`
|
||||||
}
|
|
||||||
|
|
||||||
func (Namespace) TableName() string {
|
|
||||||
return tableNamespaces
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type StorageClass struct {
|
type StorageClass struct {
|
||||||
Name string `gorm:"primary_key" json:"name"`
|
Name string `gorm:"primary_key" json:"name"`
|
||||||
Creator string `json:"creator,omitempty"`
|
DisplayName string `json:"displayName,omitempty" gorm:"column:displayName"`
|
||||||
Annotation Annotation `json:"annotations"`
|
Creator string `json:"creator,omitempty"`
|
||||||
CreateTime time.Time `gorm:"column:createTime" json:"createTime,omitempty"`
|
Annotation MapString `json:"annotations"`
|
||||||
IsDefault bool `json:"default"`
|
CreateTime time.Time `gorm:"column:createTime" json:"createTime,omitempty"`
|
||||||
Count int `json:"count"`
|
IsDefault bool `json:"default"`
|
||||||
|
Count int `json:"count"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (StorageClass) TableName() string {
|
type JobRevisions map[int]JobStatus
|
||||||
return tableStorageClasses
|
|
||||||
|
type JobStatus struct {
|
||||||
|
Status string `json:"status"`
|
||||||
|
Reasons []string `json:"reasons"`
|
||||||
|
Messages []string `json:"messages"`
|
||||||
|
Succeed int32 `json:"succeed"`
|
||||||
|
DesirePodNum int32 `json:"desire"`
|
||||||
|
Failed int32 `json:"failed"`
|
||||||
|
StartTime time.Time `json:"start-time"`
|
||||||
|
CompletionTime time.Time `json:"completion-time"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Job struct {
|
||||||
|
Name string `gorm:"primary_key" json:"name,omitempty"`
|
||||||
|
DisplayName string `json:"displayName,omitempty" gorm:"column:displayName"`
|
||||||
|
Namespace string `gorm:"primary_key" json:"namespace,omitempty"`
|
||||||
|
|
||||||
|
Completed int32 `json:"completed"`
|
||||||
|
Desire int32 `json:"desire"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
Annotation MapString `json:"annotations"`
|
||||||
|
Labels MapString `json:"labels"`
|
||||||
|
CreateTime time.Time `gorm:"column:createTime" json:"createTime,omitempty"`
|
||||||
|
UpdateTime time.Time `gorm:"column:updateTime" json:"updateTime,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type CronJob struct {
|
||||||
|
Name string `gorm:"primary_key" json:"name,omitempty"`
|
||||||
|
DisplayName string `json:"displayName,omitempty" gorm:"column:displayName"`
|
||||||
|
Namespace string `gorm:"primary_key" json:"namespace,omitempty"`
|
||||||
|
|
||||||
|
Active int `json:"active"`
|
||||||
|
Schedule string `json:"schedule"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
Annotation MapString `json:"annotations"`
|
||||||
|
Labels MapString `json:"labels"`
|
||||||
|
LastScheduleTime *time.Time `gorm:"column:lastScheduleTime" json:"lastScheduleTime,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Node struct {
|
||||||
|
Name string `gorm:"primary_key" json:"name,omitempty"`
|
||||||
|
DisplayName string `json:"displayName,omitempty" gorm:"column:displayName"`
|
||||||
|
Ip string `json:"ip"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
Annotation MapString `json:"annotations"`
|
||||||
|
Labels MapString `json:"labels"`
|
||||||
|
Taints Taints `json:"taints"`
|
||||||
|
Msg string `json:"msg"`
|
||||||
|
Role string `json:"role"`
|
||||||
|
CreateTime time.Time `gorm:"column:createTime" json:"createTime,omitempty"`
|
||||||
|
}
|
||||||
type Paging struct {
|
type Paging struct {
|
||||||
Limit, Offset int
|
Limit, Offset, Page int
|
||||||
}
|
}
|
||||||
|
|
||||||
type Controller interface {
|
type Controller interface {
|
||||||
@@ -295,7 +345,9 @@ type Controller interface {
|
|||||||
initListerAndInformer()
|
initListerAndInformer()
|
||||||
sync(stopChan chan struct{})
|
sync(stopChan chan struct{})
|
||||||
Name() string
|
Name() string
|
||||||
ListWithConditions(condition string, paging *Paging) (int, interface{}, error)
|
CloseDB()
|
||||||
|
Lister() interface{}
|
||||||
|
ListWithConditions(condition string, paging *Paging, order string) (int, interface{}, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type CommonAttribute struct {
|
type CommonAttribute struct {
|
||||||
@@ -316,6 +368,11 @@ func (ca *CommonAttribute) chanAlive() chan struct{} {
|
|||||||
return ca.aliveChan
|
return ca.aliveChan
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ca *CommonAttribute) CloseDB() {
|
||||||
|
|
||||||
|
ca.DB.Close()
|
||||||
|
}
|
||||||
|
|
||||||
type DeploymentCtl struct {
|
type DeploymentCtl struct {
|
||||||
CommonAttribute
|
CommonAttribute
|
||||||
lister appV1.DeploymentLister
|
lister appV1.DeploymentLister
|
||||||
@@ -381,3 +438,33 @@ type ClusterRoleCtl struct {
|
|||||||
informer cache.SharedIndexInformer
|
informer cache.SharedIndexInformer
|
||||||
CommonAttribute
|
CommonAttribute
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type JobCtl struct {
|
||||||
|
lister batchv1.JobLister
|
||||||
|
informer cache.SharedIndexInformer
|
||||||
|
CommonAttribute
|
||||||
|
}
|
||||||
|
|
||||||
|
type CronJobCtl struct {
|
||||||
|
lister batchv1beta1.CronJobLister
|
||||||
|
informer cache.SharedIndexInformer
|
||||||
|
CommonAttribute
|
||||||
|
}
|
||||||
|
|
||||||
|
type NodeCtl struct {
|
||||||
|
lister coreV1.NodeLister
|
||||||
|
informer cache.SharedIndexInformer
|
||||||
|
CommonAttribute
|
||||||
|
}
|
||||||
|
|
||||||
|
type ReplicaSetCtl struct {
|
||||||
|
lister appV1.ReplicaSetLister
|
||||||
|
informer cache.SharedIndexInformer
|
||||||
|
CommonAttribute
|
||||||
|
}
|
||||||
|
|
||||||
|
type ControllerRevisionCtl struct {
|
||||||
|
lister appV1.ControllerRevisionLister
|
||||||
|
informer cache.SharedIndexInformer
|
||||||
|
CommonAttribute
|
||||||
|
}
|
||||||
|
|||||||
@@ -40,12 +40,15 @@ const (
|
|||||||
persistentvolumeclaimsKey = "persistentvolumeclaims"
|
persistentvolumeclaimsKey = "persistentvolumeclaims"
|
||||||
storageClassesKey = "count/storageClass"
|
storageClassesKey = "count/storageClass"
|
||||||
namespaceKey = "count/namespace"
|
namespaceKey = "count/namespace"
|
||||||
|
jobsKey = "count/jobs.batch"
|
||||||
|
cronJobsKey = "count/cronjobs.batch"
|
||||||
)
|
)
|
||||||
|
|
||||||
var resourceMap = map[string]string{daemonsetsKey: controllers.Daemonsets, deploymentsKey: controllers.Deployments,
|
var resourceMap = map[string]string{daemonsetsKey: controllers.Daemonsets, deploymentsKey: controllers.Deployments,
|
||||||
ingressKey: controllers.Ingresses, rolesKey: controllers.Roles, servicesKey: controllers.Services,
|
ingressKey: controllers.Ingresses, rolesKey: controllers.Roles, servicesKey: controllers.Services,
|
||||||
statefulsetsKey: controllers.Statefulsets, persistentvolumeclaimsKey: controllers.PersistentVolumeClaim, podsKey: controllers.Pods,
|
statefulsetsKey: controllers.Statefulsets, persistentvolumeclaimsKey: controllers.PersistentVolumeClaim, podsKey: controllers.Pods,
|
||||||
namespaceKey: controllers.Namespaces, storageClassesKey: controllers.StorageClasses, clusterRolesKey: controllers.ClusterRoles}
|
namespaceKey: controllers.Namespaces, storageClassesKey: controllers.StorageClasses, clusterRolesKey: controllers.ClusterRoles,
|
||||||
|
jobsKey: controllers.Jobs, cronJobsKey: controllers.Cronjobs}
|
||||||
|
|
||||||
type ResourceQuota struct {
|
type ResourceQuota struct {
|
||||||
NameSpace string `json:"namespace"`
|
NameSpace string `json:"namespace"`
|
||||||
|
|||||||
@@ -1,3 +1,19 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2018 The KubeSphere Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -24,11 +40,19 @@ type ResourceList struct {
|
|||||||
Items interface{} `json:"items,omitempty"`
|
Items interface{} `json:"items,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type searchConditions struct {
|
||||||
|
match map[string]string
|
||||||
|
fuzzy map[string]string
|
||||||
|
matchOr map[string]string
|
||||||
|
fuzzyOr map[string]string
|
||||||
|
}
|
||||||
|
|
||||||
func getController(resource string) (controllers.Controller, error) {
|
func getController(resource string) (controllers.Controller, error) {
|
||||||
switch resource {
|
switch resource {
|
||||||
case controllers.Deployments, controllers.Statefulsets, controllers.Daemonsets, controllers.Ingresses,
|
case controllers.Deployments, controllers.Statefulsets, controllers.Daemonsets, controllers.Ingresses,
|
||||||
controllers.PersistentVolumeClaim, controllers.Roles, controllers.ClusterRoles, controllers.Services,
|
controllers.PersistentVolumeClaim, controllers.Roles, controllers.ClusterRoles, controllers.Services,
|
||||||
controllers.Pods, controllers.Namespaces, controllers.StorageClasses:
|
controllers.Pods, controllers.Namespaces, controllers.StorageClasses, controllers.Jobs, controllers.Cronjobs,
|
||||||
|
controllers.Nodes:
|
||||||
|
|
||||||
return controllers.ResourceControllers.Controllers[resource], nil
|
return controllers.ResourceControllers.Controllers[resource], nil
|
||||||
default:
|
default:
|
||||||
@@ -38,20 +62,21 @@ func getController(resource string) (controllers.Controller, error) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func getConditions(str string) (map[string]string, map[string]string, error) {
|
func getConditions(str string) (*searchConditions, map[string]string, error) {
|
||||||
match := make(map[string]string)
|
match := make(map[string]string)
|
||||||
fuzzy := make(map[string]string)
|
fuzzy := make(map[string]string)
|
||||||
|
matchOr := make(map[string]string)
|
||||||
|
fuzzyOr := make(map[string]string)
|
||||||
|
orderField := make(map[string]string)
|
||||||
|
|
||||||
if len(str) == 0 {
|
if len(str) == 0 {
|
||||||
return nil, nil, nil
|
return nil, nil, nil
|
||||||
}
|
}
|
||||||
list := strings.Split(str, ",")
|
|
||||||
for _, item := range list {
|
|
||||||
if strings.Count(item, "=") >= 2 {
|
|
||||||
return nil, nil, errors.New("invalid condition input, invalid character \"=\"")
|
|
||||||
}
|
|
||||||
|
|
||||||
if strings.Count(item, "~") >= 2 {
|
conditions := strings.Split(str, ",")
|
||||||
return nil, nil, errors.New("invalid condition input, invalid character \"~\"")
|
for _, item := range conditions {
|
||||||
|
if strings.Count(item, "=") >= 2 || strings.Count(item, "~") >= 2 {
|
||||||
|
return nil, nil, errors.New("invalid condition input")
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.Count(item, "=") == 1 {
|
if strings.Count(item, "=") == 1 {
|
||||||
@@ -59,7 +84,17 @@ func getConditions(str string) (map[string]string, map[string]string, error) {
|
|||||||
if len(kvs) < 2 || len(kvs[1]) == 0 {
|
if len(kvs) < 2 || len(kvs[1]) == 0 {
|
||||||
return nil, nil, errors.New("invalid condition input")
|
return nil, nil, errors.New("invalid condition input")
|
||||||
}
|
}
|
||||||
match[kvs[0]] = kvs[1]
|
|
||||||
|
if !strings.Contains(kvs[0], "|") {
|
||||||
|
match[kvs[0]] = kvs[1]
|
||||||
|
} else {
|
||||||
|
multiFields := strings.Split(kvs[0], "|")
|
||||||
|
for _, filed := range multiFields {
|
||||||
|
if len(filed) > 0 {
|
||||||
|
matchOr[filed] = kvs[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,86 +103,130 @@ func getConditions(str string) (map[string]string, map[string]string, error) {
|
|||||||
if len(kvs) < 2 || len(kvs[1]) == 0 {
|
if len(kvs) < 2 || len(kvs[1]) == 0 {
|
||||||
return nil, nil, errors.New("invalid condition input")
|
return nil, nil, errors.New("invalid condition input")
|
||||||
}
|
}
|
||||||
fuzzy[kvs[0]] = kvs[1]
|
if !strings.Contains(kvs[0], "|") {
|
||||||
|
fuzzy[kvs[0]] = kvs[1]
|
||||||
|
} else {
|
||||||
|
multiFields := strings.Split(kvs[0], "|")
|
||||||
|
if len(multiFields) > 1 && len(multiFields[1]) > 0 {
|
||||||
|
orderField[multiFields[0]] = kvs[1]
|
||||||
|
}
|
||||||
|
for _, filed := range multiFields {
|
||||||
|
if len(filed) > 0 {
|
||||||
|
fuzzyOr[filed] = kvs[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil, errors.New("invalid condition input")
|
return nil, nil, errors.New("invalid condition input")
|
||||||
|
|
||||||
}
|
}
|
||||||
return match, fuzzy, nil
|
|
||||||
|
return &searchConditions{match: match, fuzzyOr: fuzzyOr, matchOr: matchOr, fuzzy: fuzzy}, orderField, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getPaging(resourceName, pagingStr string) (*controllers.Paging, map[string]int, error) {
|
func getPaging(resourceName, pagingStr string) (*controllers.Paging, error) {
|
||||||
defaultPaging := &controllers.Paging{Limit: 10, Offset: 0}
|
defaultPaging := &controllers.Paging{Limit: 10, Offset: 0, Page: 1}
|
||||||
defautlPagingMap := map[string]int{"page": 1, "limit": 10}
|
paging := controllers.Paging{}
|
||||||
|
|
||||||
if resourceName == controllers.Namespaces {
|
if resourceName == controllers.Namespaces {
|
||||||
defaultPaging = nil
|
defaultPaging = nil
|
||||||
defautlPagingMap = map[string]int{"page": 0, "limit": 0}
|
|
||||||
}
|
}
|
||||||
pagingMap := make(map[string]int)
|
|
||||||
|
|
||||||
if len(pagingStr) == 0 {
|
if len(pagingStr) == 0 {
|
||||||
return defaultPaging, defautlPagingMap, nil
|
return defaultPaging, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
list := strings.Split(pagingStr, ",")
|
list := strings.Split(pagingStr, ",")
|
||||||
for _, item := range list {
|
for _, item := range list {
|
||||||
kvs := strings.Split(item, "=")
|
kvs := strings.Split(item, "=")
|
||||||
if len(kvs) < 2 {
|
if len(kvs) < 2 {
|
||||||
return nil, nil, errors.New("invalid Paging input")
|
return nil, errors.New("invalid Paging input")
|
||||||
}
|
}
|
||||||
|
|
||||||
value, err := strconv.Atoi(kvs[1])
|
value, err := strconv.Atoi(kvs[1])
|
||||||
if err != nil {
|
if err != nil || value <= 0 {
|
||||||
return nil, nil, errors.New("invalid Paging input")
|
return nil, errors.New("invalid Paging input")
|
||||||
}
|
}
|
||||||
|
|
||||||
pagingMap[kvs[0]] = value
|
if kvs[0] == limit {
|
||||||
|
paging.Limit = value
|
||||||
|
}
|
||||||
|
|
||||||
|
if kvs[0] == page {
|
||||||
|
paging.Page = value
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if pagingMap[limit] <= 0 || pagingMap[page] <= 0 {
|
if paging.Limit > 0 && paging.Page > 0 {
|
||||||
return nil, nil, errors.New("invalid Paging input")
|
paging.Offset = (paging.Page - 1) * paging.Limit
|
||||||
|
return &paging, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if pagingMap[limit] > 0 && pagingMap[page] > 0 {
|
return defaultPaging, nil
|
||||||
offset := (pagingMap[page] - 1) * pagingMap[limit]
|
|
||||||
return &controllers.Paging{Limit: pagingMap[limit], Offset: offset}, pagingMap, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return defaultPaging, defautlPagingMap, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func ListResource(resourceName, conditonSrt, pagingStr string) (*ResourceList, error) {
|
func generateOrder(orderField map[string]string, order string) string {
|
||||||
match, fuzzy, err := getConditions(conditonSrt)
|
if len(orderField) == 0 {
|
||||||
|
return order
|
||||||
|
}
|
||||||
|
|
||||||
|
var str string
|
||||||
|
for k, v := range orderField {
|
||||||
|
if len(str) > 0 {
|
||||||
|
str = fmt.Sprintf("%s, (%s like '%%%s%%')", str, k, v)
|
||||||
|
} else {
|
||||||
|
str = fmt.Sprintf("(%s like '%%%s%%')", k, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(order) == 0 {
|
||||||
|
return fmt.Sprintf("%s desc", str)
|
||||||
|
} else {
|
||||||
|
return fmt.Sprintf("%s, %s", str, order)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ListResource(resourceName, conditonSrt, pagingStr, order string) (*ResourceList, error) {
|
||||||
|
conditions, OrderFields, err := getConditions(conditonSrt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
paging, pagingMap, err := getPaging(resourceName, pagingStr)
|
order = generateOrder(OrderFields, order)
|
||||||
|
conditionStr := generateConditionStr(conditions)
|
||||||
|
|
||||||
|
paging, err := getPaging(resourceName, pagingStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
conditionStr := generateConditionStr(match, fuzzy)
|
|
||||||
|
|
||||||
ctl, err := getController(resourceName)
|
ctl, err := getController(resourceName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
total, items, err := ctl.ListWithConditions(conditionStr, paging)
|
total, items, err := ctl.ListWithConditions(conditionStr, paging, order)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &ResourceList{Total: total, Items: items, Page: pagingMap[page], Limit: pagingMap[limit]}, nil
|
if paging != nil {
|
||||||
|
return &ResourceList{Total: total, Items: items, Page: paging.Page, Limit: paging.Limit}, nil
|
||||||
|
} else {
|
||||||
|
return &ResourceList{Total: total, Items: items}, nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateConditionStr(match map[string]string, fuzzy map[string]string) string {
|
func generateConditionStr(conditions *searchConditions) string {
|
||||||
conditionStr := ""
|
conditionStr := ""
|
||||||
|
|
||||||
for k, v := range match {
|
if conditions == nil {
|
||||||
|
return conditionStr
|
||||||
|
}
|
||||||
|
|
||||||
|
for k, v := range conditions.match {
|
||||||
if len(conditionStr) == 0 {
|
if len(conditionStr) == 0 {
|
||||||
conditionStr = fmt.Sprintf("%s = \"%s\" ", k, v)
|
conditionStr = fmt.Sprintf("%s = \"%s\" ", k, v)
|
||||||
} else {
|
} else {
|
||||||
@@ -155,7 +234,7 @@ func generateConditionStr(match map[string]string, fuzzy map[string]string) stri
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for k, v := range fuzzy {
|
for k, v := range conditions.fuzzy {
|
||||||
if len(conditionStr) == 0 {
|
if len(conditionStr) == 0 {
|
||||||
conditionStr = fmt.Sprintf("%s like '%%%s%%' ", k, v)
|
conditionStr = fmt.Sprintf("%s like '%%%s%%' ", k, v)
|
||||||
} else {
|
} else {
|
||||||
@@ -163,6 +242,22 @@ func generateConditionStr(match map[string]string, fuzzy map[string]string) stri
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for k, v := range conditions.matchOr {
|
||||||
|
if len(conditionStr) == 0 {
|
||||||
|
conditionStr = fmt.Sprintf("%s = \"%s\" ", k, v)
|
||||||
|
} else {
|
||||||
|
conditionStr = fmt.Sprintf("%s OR %s = \"%s\" ", conditionStr, k, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for k, v := range conditions.fuzzyOr {
|
||||||
|
if len(conditionStr) == 0 {
|
||||||
|
conditionStr = fmt.Sprintf("%s like '%%%s%%' ", k, v)
|
||||||
|
} else {
|
||||||
|
conditionStr = fmt.Sprintf("%s OR %s like '%%%s%%' ", conditionStr, k, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return conditionStr
|
return conditionStr
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -182,9 +277,9 @@ func GetNamespacesResourceStatus(namespace string) (*workLoadStatus, error) {
|
|||||||
notReadyStatus = controllers.PvcPending
|
notReadyStatus = controllers.PvcPending
|
||||||
}
|
}
|
||||||
if len(namespace) > 0 {
|
if len(namespace) > 0 {
|
||||||
status, err = ListResource(resource, fmt.Sprintf("status=%s,namespace=%s", notReadyStatus, namespace), "")
|
status, err = ListResource(resource, fmt.Sprintf("status=%s,namespace=%s", notReadyStatus, namespace), "", "")
|
||||||
} else {
|
} else {
|
||||||
status, err = ListResource(resource, fmt.Sprintf("status=%s", notReadyStatus), "")
|
status, err = ListResource(resource, fmt.Sprintf("status=%s", notReadyStatus), "", "")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -208,25 +303,30 @@ func GetApplication(clusterId string) (interface{}, error) {
|
|||||||
return ctl.GetApp(clusterId)
|
return ctl.GetApp(clusterId)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ListApplication(runtimeId, conditions, pagingStr string) (*ResourceList, error) {
|
func ListApplication(runtimeId, conditionStr, pagingStr string) (*ResourceList, error) {
|
||||||
paging, pagingMap, err := getPaging(controllers.Applications, pagingStr)
|
paging, err := getPaging(controllers.Applications, pagingStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
match, fuzzy, err := getConditions(conditions)
|
conditions, _, err := getConditions(conditionStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Error(err)
|
glog.Error(err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if conditions == nil {
|
||||||
|
conditions = &searchConditions{}
|
||||||
|
}
|
||||||
|
|
||||||
ctl := &controllers.ApplicationCtl{OpenpitrixAddr: options.ServerOptions.GetOpAddress()}
|
ctl := &controllers.ApplicationCtl{OpenpitrixAddr: options.ServerOptions.GetOpAddress()}
|
||||||
total, items, err := ctl.ListApplication(runtimeId, match, fuzzy, paging)
|
|
||||||
|
total, items, err := ctl.ListApplication(runtimeId, conditions.match, conditions.fuzzy, paging)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Errorf("get application list failed, reason: %s", err)
|
glog.Errorf("get application list failed, reason: %s", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &ResourceList{Total: total, Items: items, Page: pagingMap[page], Limit: pagingMap[limit]}, nil
|
return &ResourceList{Total: total, Items: items, Page: paging.Page, Limit: paging.Limit}, nil
|
||||||
}
|
}
|
||||||
|
|||||||
112
pkg/models/revisions.go
Normal file
112
pkg/models/revisions.go
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2018 The KubeSphere Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/golang/glog"
|
||||||
|
"k8s.io/api/apps/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/api/errors"
|
||||||
|
"k8s.io/apimachinery/pkg/labels"
|
||||||
|
appsV1 "k8s.io/client-go/listers/apps/v1"
|
||||||
|
|
||||||
|
"kubesphere.io/kubesphere/pkg/models/controllers"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetDeployRevision(namespace, name, revision string) (*v1.ReplicaSet, error) {
|
||||||
|
deployLister := controllers.ResourceControllers.Controllers[controllers.Deployments].Lister().(appsV1.DeploymentLister)
|
||||||
|
deploy, err := deployLister.Deployments(namespace).Get(name)
|
||||||
|
if err != nil {
|
||||||
|
glog.Errorf("get deployment %s failed, reason: %s", name, err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
labelMap := deploy.Spec.Template.Labels
|
||||||
|
labelSelector := labels.Set(labelMap).AsSelector()
|
||||||
|
|
||||||
|
rsLister := controllers.ResourceControllers.Controllers[controllers.Replicasets].Lister().(appsV1.ReplicaSetLister)
|
||||||
|
rsList, err := rsLister.ReplicaSets(namespace).List(labelSelector)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, rs := range rsList {
|
||||||
|
if rs.Annotations["deployment.kubernetes.io/revision"] == revision {
|
||||||
|
return rs, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, errors.NewNotFound(v1.Resource("deployment revision"), fmt.Sprintf("%s#%s", name, revision))
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetDaemonSetRevision(namespace, name, revision string) (*v1.ControllerRevision, error) {
|
||||||
|
revisionInt, err := strconv.Atoi(revision)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
dsLister := controllers.ResourceControllers.Controllers[controllers.Daemonsets].Lister().(appsV1.DaemonSetLister)
|
||||||
|
ds, err := dsLister.DaemonSets(namespace).Get(name)
|
||||||
|
if err != nil {
|
||||||
|
glog.Errorf("get Daemonset %s failed, reason: %s", name, err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
labels := ds.Spec.Template.Labels
|
||||||
|
|
||||||
|
return getControllerRevision(namespace, name, labels, revisionInt)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetStatefulSetRevision(namespace, name, revision string) (*v1.ControllerRevision, error) {
|
||||||
|
revisionInt, err := strconv.Atoi(revision)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
stLister := controllers.ResourceControllers.Controllers[controllers.Statefulsets].Lister().(appsV1.StatefulSetLister)
|
||||||
|
st, err := stLister.StatefulSets(namespace).Get(name)
|
||||||
|
if err != nil {
|
||||||
|
glog.Errorf("get Daemonset %s failed, reason: %s", name, err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
labels := st.Spec.Template.Labels
|
||||||
|
|
||||||
|
return getControllerRevision(namespace, name, labels, revisionInt)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getControllerRevision(namespace, name string, labelMap map[string]string, revision int) (*v1.ControllerRevision, error) {
|
||||||
|
|
||||||
|
labelSelector := labels.Set(labelMap).AsSelector()
|
||||||
|
|
||||||
|
revisionLister := controllers.ResourceControllers.Controllers[controllers.ControllerRevisions].Lister().(appsV1.ControllerRevisionLister)
|
||||||
|
revisions, err := revisionLister.ControllerRevisions(namespace).List(labelSelector)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, controllerRevision := range revisions {
|
||||||
|
if controllerRevision.Revision == int64(revision) {
|
||||||
|
return controllerRevision, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, errors.NewNotFound(v1.Resource("revision"), fmt.Sprintf("%s#%s", name, revision))
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user