Merge pull request #160 from richardxz/master
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]
|
||||
analyzer-name = "dep"
|
||||
analyzer-version = 1
|
||||
inputs-digest = "9f1ac4fe878dadee802b8971f67ba69171326c81e2c379247015003f2e0ba134"
|
||||
inputs-digest = "d92e4ea931c670e5ebb04661788db5386ee647b8b6bac4ec6b519a1544b2c400"
|
||||
solver-name = "gps-cdcl"
|
||||
solver-version = 1
|
||||
|
||||
@@ -23,6 +23,9 @@ import (
|
||||
|
||||
"github.com/emicklei/go-restful-openapi"
|
||||
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
"kubesphere.io/kubesphere/pkg/models"
|
||||
)
|
||||
@@ -31,15 +34,33 @@ func Register(ws *restful.WebService, subPath string) {
|
||||
|
||||
tags := []string{"resources"}
|
||||
|
||||
ws.Route(ws.GET(subPath+"/{resource}").To(handleResource).Produces(restful.MIME_JSON).Metadata(restfulspec.KeyOpenAPITags, tags).Doc("Get resource" +
|
||||
" list").Param(ws.PathParameter("resource", "resource name").DataType(
|
||||
"string")).Param(ws.QueryParameter("conditions", "search "+
|
||||
"conditions").DataType("string")).Param(ws.QueryParameter("paging",
|
||||
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("string")).Param(ws.QueryParameter("conditions",
|
||||
"search conditions").DataType("string")).Param(ws.QueryParameter("reverse",
|
||||
"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{}))
|
||||
|
||||
}
|
||||
|
||||
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")
|
||||
if resource == "applications" {
|
||||
@@ -48,7 +69,23 @@ func handleResource(req *restful.Request, resp *restful.Response) {
|
||||
}
|
||||
conditions := req.QueryParameter("conditions")
|
||||
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 {
|
||||
resp.WriteHeaderAndEntity(http.StatusInternalServerError, constants.MessageResponse{Message: err.Error()})
|
||||
return
|
||||
@@ -58,7 +95,6 @@ func handleResource(req *restful.Request, resp *restful.Response) {
|
||||
}
|
||||
|
||||
func handleApplication(req *restful.Request, resp *restful.Response) {
|
||||
//searchWord := req.QueryParameter("search-word")
|
||||
paging := req.QueryParameter("paging")
|
||||
clusterId := req.QueryParameter("cluster_id")
|
||||
runtimeId := req.QueryParameter("runtime_id")
|
||||
|
||||
@@ -240,7 +240,7 @@ func (ctl *ApplicationCtl) GetWorkLoads(namespace string, clusterRoles []cluster
|
||||
if strings.HasSuffix(workLoadName, deploySurffix) {
|
||||
name := strings.Split(workLoadName, deploySurffix)[0]
|
||||
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)...)
|
||||
continue
|
||||
}
|
||||
@@ -248,7 +248,7 @@ func (ctl *ApplicationCtl) GetWorkLoads(namespace string, clusterRoles []cluster
|
||||
if strings.HasSuffix(workLoadName, daemonSurffix) {
|
||||
name := strings.Split(workLoadName, daemonSurffix)[0]
|
||||
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)...)
|
||||
continue
|
||||
}
|
||||
@@ -256,7 +256,7 @@ func (ctl *ApplicationCtl) GetWorkLoads(namespace string, clusterRoles []cluster
|
||||
if strings.HasSuffix(workLoadName, stateSurffix) {
|
||||
name := strings.Split(workLoadName, stateSurffix)[0]
|
||||
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)...)
|
||||
continue
|
||||
}
|
||||
@@ -265,16 +265,6 @@ func (ctl *ApplicationCtl) GetWorkLoads(namespace string, clusterRoles []cluster
|
||||
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 {
|
||||
k8sClient := client.NewK8sClient()
|
||||
|
||||
@@ -349,7 +339,7 @@ func (ctl *ApplicationCtl) getIng(namespace string, services *[]Service) *[]ing
|
||||
ingCtl := ResourceControllers.Controllers[Ingresses]
|
||||
var ings []ing
|
||||
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 {
|
||||
glog.Error(err)
|
||||
return nil
|
||||
|
||||
@@ -30,6 +30,11 @@ import (
|
||||
const systemPrefix = "system:"
|
||||
|
||||
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
|
||||
if strings.HasPrefix(name, systemPrefix) {
|
||||
return nil
|
||||
@@ -40,7 +45,7 @@ func (ctl *ClusterRoleCtl) generateObject(item v1.ClusterRole) *ClusterRole {
|
||||
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
|
||||
}
|
||||
@@ -136,15 +141,23 @@ func (ctl *ClusterRoleCtl) CountWithConditions(conditions string) int {
|
||||
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 list []ClusterRole
|
||||
var total int
|
||||
|
||||
order := "createTime desc"
|
||||
if len(order) == 0 {
|
||||
order = "createTime desc"
|
||||
}
|
||||
|
||||
db := ctl.DB
|
||||
|
||||
listWithConditions(db, &total, &object, &list, conditions, paging, order)
|
||||
|
||||
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) {
|
||||
defer handleCrash(ctl)
|
||||
|
||||
defer ctl.CloseDB()
|
||||
stopChan := make(chan struct{})
|
||||
|
||||
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 {
|
||||
var app string
|
||||
var status string
|
||||
var app, status, displayName string
|
||||
|
||||
if item.Annotations != nil && len(item.Annotations[DisplayName]) > 0 {
|
||||
displayName = item.Annotations[DisplayName]
|
||||
}
|
||||
name := item.Name
|
||||
namespace := item.Namespace
|
||||
availablePodNum := item.Status.NumberAvailable
|
||||
@@ -55,8 +58,19 @@ func (ctl *DaemonsetCtl) generateObject(item v1.DaemonSet) *Daemonset {
|
||||
status = Updating
|
||||
}
|
||||
|
||||
object := &Daemonset{Namespace: namespace, Name: name, Available: availablePodNum, Desire: desirePodNum,
|
||||
App: app, CreateTime: createTime, Status: status, NodeSelector: string(nodeSelectorStr), Annotation: Annotation{item.Annotations}}
|
||||
object := &Daemonset{
|
||||
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
|
||||
}
|
||||
@@ -135,25 +149,21 @@ func (ctl *DaemonsetCtl) CountWithConditions(conditions string) int {
|
||||
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 object Daemonset
|
||||
var total int
|
||||
|
||||
order := "createTime desc"
|
||||
if len(order) == 0 {
|
||||
order = "createTime desc"
|
||||
}
|
||||
|
||||
listWithConditions(ctl.DB, &total, &object, &list, conditions, paging, order)
|
||||
|
||||
return total, list, nil
|
||||
}
|
||||
|
||||
//func (ctl *DaemonsetCtl) Count(namespace string) int {
|
||||
// var count int
|
||||
// db := ctl.DB
|
||||
// if len(namespace) == 0 {
|
||||
// db.Model(&Daemonset{}).Count(&count)
|
||||
// } else {
|
||||
// db.Model(&Daemonset{}).Where("namespace = ?", namespace).Count(&count)
|
||||
// }
|
||||
// return count
|
||||
//}
|
||||
func (ctl *DaemonsetCtl) Lister() interface{} {
|
||||
|
||||
return ctl.lister
|
||||
}
|
||||
|
||||
@@ -27,9 +27,13 @@ import (
|
||||
)
|
||||
|
||||
func (ctl *DeploymentCtl) generateObject(item v1.Deployment) *Deployment {
|
||||
var app string
|
||||
var status string
|
||||
var app, status, displayName string
|
||||
var updateTime time.Time
|
||||
|
||||
if item.Annotations != nil && len(item.Annotations[DisplayName]) > 0 {
|
||||
displayName = item.Annotations[DisplayName]
|
||||
}
|
||||
|
||||
name := item.Name
|
||||
namespace := item.Namespace
|
||||
availablePodNum := item.Status.AvailableReplicas
|
||||
@@ -41,9 +45,13 @@ func (ctl *DeploymentCtl) generateObject(item v1.Deployment) *Deployment {
|
||||
app = release + "/" + chart
|
||||
}
|
||||
|
||||
for _, conditon := range item.Status.Conditions {
|
||||
if conditon.Type == "Available" {
|
||||
updateTime = conditon.LastUpdateTime.Time
|
||||
for _, condition := range item.Status.Conditions {
|
||||
if updateTime.IsZero() {
|
||||
updateTime = condition.LastUpdateTime.Time
|
||||
} else {
|
||||
if updateTime.Before(condition.LastUpdateTime.Time) {
|
||||
updateTime = condition.LastUpdateTime.Time
|
||||
}
|
||||
}
|
||||
}
|
||||
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,
|
||||
App: app, UpdateTime: updateTime, Status: status, Annotation: Annotation{item.Annotations}}
|
||||
return &Deployment{
|
||||
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 {
|
||||
@@ -138,14 +156,21 @@ func (ctl *DeploymentCtl) CountWithConditions(conditions string) int {
|
||||
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 object Deployment
|
||||
var total int
|
||||
|
||||
order := "updateTime desc"
|
||||
if len(order) == 0 {
|
||||
order = "updateTime desc"
|
||||
}
|
||||
|
||||
listWithConditions(ctl.DB, &total, &object, &list, conditions, paging, order)
|
||||
|
||||
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 {
|
||||
|
||||
var ip, tls, displayName string
|
||||
|
||||
name := item.Name
|
||||
namespace := item.Namespace
|
||||
var ip, tls string
|
||||
|
||||
if item.Annotations != nil && len(item.Annotations[DisplayName]) > 0 {
|
||||
displayName = item.Annotations[DisplayName]
|
||||
}
|
||||
|
||||
createTime := item.CreationTimestamp.Time
|
||||
if createTime.IsZero() {
|
||||
createTime = time.Now()
|
||||
@@ -63,7 +70,17 @@ func (ctl *IngressCtl) generateObject(item v1beta1.Ingress) *Ingress {
|
||||
|
||||
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
|
||||
}
|
||||
@@ -143,25 +160,21 @@ func (ctl *IngressCtl) CountWithConditions(conditions string) int {
|
||||
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 object Ingress
|
||||
var total int
|
||||
|
||||
order := "createTime desc"
|
||||
if len(order) == 0 {
|
||||
order = "createTime desc"
|
||||
}
|
||||
|
||||
listWithConditions(ctl.DB, &total, &object, &list, conditions, paging, order)
|
||||
|
||||
return total, list, nil
|
||||
}
|
||||
|
||||
//func (ctl *IngressCtl) Count(namespace string) int {
|
||||
// var count int
|
||||
// db := ctl.DB
|
||||
// if len(namespace) == 0 {
|
||||
// db.Model(&Ingress{}).Count(&count)
|
||||
// } else {
|
||||
// db.Model(&Ingress{}).Where("namespace = ?", namespace).Count(&count)
|
||||
// }
|
||||
// return count
|
||||
//}
|
||||
func (ctl *IngressCtl) Lister() interface{} {
|
||||
|
||||
return ctl.lister
|
||||
}
|
||||
|
||||
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 {
|
||||
var displayName string
|
||||
|
||||
if item.Annotations != nil && len(item.Annotations[DisplayName]) > 0 {
|
||||
displayName = item.Annotations[DisplayName]
|
||||
}
|
||||
|
||||
name := item.Name
|
||||
createTime := item.CreationTimestamp.Time
|
||||
@@ -236,7 +241,13 @@ func (ctl *NamespaceCtl) generateObject(item v1.Namespace) *Namespace {
|
||||
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
|
||||
}
|
||||
@@ -320,12 +331,14 @@ func (ctl *NamespaceCtl) CountWithConditions(conditions string) int {
|
||||
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 object Namespace
|
||||
var total int
|
||||
|
||||
order := "createTime desc"
|
||||
if len(order) == 0 {
|
||||
order = "createTime desc"
|
||||
}
|
||||
|
||||
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 {
|
||||
usage, err := ctl.GetNamespaceQuota(list[index].Name)
|
||||
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)
|
||||
|
||||
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 {
|
||||
used := getUsage(namespace, resourceName)
|
||||
var quantity resource.Quantity
|
||||
@@ -365,3 +378,8 @@ func (ctl *NamespaceCtl) GetNamespaceQuota(namespace string) (v1.ResourceList, e
|
||||
usage["runningPods"] = quantity
|
||||
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)
|
||||
}
|
||||
|
||||
object := &Pod{Namespace: namespace, Name: name, Node: nodeName, PodIp: podIp, Status: status, NodeIp: nodeIp,
|
||||
CreateTime: createTime, Annotation: Annotation{item.Annotations}, Containers: containers, RestartCount: restartCount}
|
||||
object := &Pod{
|
||||
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
|
||||
}
|
||||
@@ -277,25 +288,21 @@ func (ctl *PodCtl) CountWithConditions(conditions string) int {
|
||||
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 object Pod
|
||||
var total int
|
||||
|
||||
order := "createTime desc"
|
||||
if len(order) == 0 {
|
||||
order = "createTime desc"
|
||||
}
|
||||
|
||||
listWithConditions(ctl.DB, &total, &object, &list, conditions, paging, order)
|
||||
|
||||
return total, list, nil
|
||||
}
|
||||
|
||||
//func (ctl *PodCtl) Count(namespace string) int {
|
||||
// var count int
|
||||
// db := ctl.DB
|
||||
// if len(namespace) == 0 {
|
||||
// db.Model(&Pod{}).Count(&count)
|
||||
// } else {
|
||||
// db.Model(&Pod{}).Where("namespace = ?", namespace).Count(&count)
|
||||
// }
|
||||
// return count
|
||||
//}
|
||||
func (ctl *PodCtl) Lister() interface{} {
|
||||
|
||||
return ctl.lister
|
||||
}
|
||||
|
||||
@@ -30,6 +30,12 @@ import (
|
||||
)
|
||||
|
||||
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
|
||||
namespace := item.Namespace
|
||||
status := fmt.Sprintf("%s", item.Status.Phase)
|
||||
@@ -58,8 +64,18 @@ func (ctl *PvcCtl) generateObject(item *v1.PersistentVolumeClaim) *Pvc {
|
||||
|
||||
accessModeStr = strings.Join(accessModeList, ",")
|
||||
|
||||
object := &Pvc{Namespace: namespace, Name: name, Status: status, Capacity: capacity,
|
||||
AccessMode: accessModeStr, StorageClassName: storageClass, CreateTime: createTime, Annotation: Annotation{item.Annotations}}
|
||||
object := &Pvc{
|
||||
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
|
||||
}
|
||||
@@ -138,12 +154,14 @@ func (ctl *PvcCtl) CountWithConditions(conditions string) int {
|
||||
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 object Pvc
|
||||
var total int
|
||||
|
||||
order := "createTime desc"
|
||||
if len(order) == 0 {
|
||||
order = "createTime desc"
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
//func (ctl *PvcCtl) Count(namespace string) int {
|
||||
// var count int
|
||||
// db := ctl.DB
|
||||
// if len(namespace) == 0 {
|
||||
// db.Model(&Pvc{}).Count(&count)
|
||||
// } else {
|
||||
// db.Model(&Pvc{}).Where("namespace = ?", namespace).Count(&count)
|
||||
// }
|
||||
// return count
|
||||
//}
|
||||
func (ctl *PvcCtl) Lister() interface{} {
|
||||
|
||||
return ctl.lister
|
||||
}
|
||||
|
||||
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 {
|
||||
var displayName string
|
||||
|
||||
if item.Annotations != nil && len(item.Annotations[DisplayName]) > 0 {
|
||||
displayName = item.Annotations[DisplayName]
|
||||
}
|
||||
|
||||
name := item.Name
|
||||
if strings.HasPrefix(name, systemPrefix) {
|
||||
return nil
|
||||
@@ -38,7 +44,13 @@ func (ctl *RoleCtl) generateObject(item v1.Role) *Role {
|
||||
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
|
||||
}
|
||||
@@ -132,21 +144,21 @@ func (ctl *RoleCtl) CountWithConditions(conditions string) int {
|
||||
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 object Role
|
||||
var total int
|
||||
|
||||
order := "createTime desc"
|
||||
if len(order) == 0 {
|
||||
order = "createTime desc"
|
||||
}
|
||||
|
||||
listWithConditions(ctl.DB, &total, &object, &list, conditions, paging, order)
|
||||
|
||||
return total, list, nil
|
||||
}
|
||||
|
||||
//func (ctl *RoleCtl) Count(namespace string) int {
|
||||
// var count int
|
||||
// db := ctl.DB
|
||||
// db.Model(&Role{}).Where("namespace = ?", namespace).Count(&count)
|
||||
// return count
|
||||
//}
|
||||
func (ctl *RoleCtl) Lister() interface{} {
|
||||
|
||||
return ctl.lister
|
||||
}
|
||||
|
||||
@@ -31,10 +31,9 @@ type resourceControllers struct {
|
||||
k8sClient *kubernetes.Clientset
|
||||
}
|
||||
|
||||
var stopChan chan struct{}
|
||||
var ResourceControllers resourceControllers
|
||||
|
||||
func (rec *resourceControllers) runContoller(name string) {
|
||||
func (rec *resourceControllers) runContoller(name string, stopChan chan struct{}) {
|
||||
var ctl Controller
|
||||
attr := CommonAttribute{DB: client.NewDBClient(), K8sClient: rec.k8sClient, stopChan: stopChan,
|
||||
aliveChan: make(chan struct{}), Name: name}
|
||||
@@ -61,6 +60,16 @@ func (rec *resourceControllers) runContoller(name string) {
|
||||
ctl = &NamespaceCtl{CommonAttribute: attr}
|
||||
case StorageClasses:
|
||||
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:
|
||||
return
|
||||
}
|
||||
@@ -71,6 +80,8 @@ func (rec *resourceControllers) runContoller(name string) {
|
||||
}
|
||||
|
||||
func dbHealthCheck(db *gorm.DB) {
|
||||
defer db.Close()
|
||||
|
||||
for {
|
||||
count := 0
|
||||
var err error
|
||||
@@ -79,7 +90,7 @@ func dbHealthCheck(db *gorm.DB) {
|
||||
if err != nil {
|
||||
count++
|
||||
}
|
||||
time.Sleep(1 * time.Second)
|
||||
time.Sleep(5 * time.Second)
|
||||
}
|
||||
|
||||
if count > 3 {
|
||||
@@ -98,8 +109,8 @@ func Run() {
|
||||
ResourceControllers = resourceControllers{k8sClient: k8sClient, Controllers: make(map[string]Controller)}
|
||||
|
||||
for _, item := range []string{Deployments, Statefulsets, Daemonsets, PersistentVolumeClaim, Pods, Services,
|
||||
Ingresses, Roles, ClusterRoles, Namespaces, StorageClasses} {
|
||||
ResourceControllers.runContoller(item)
|
||||
Ingresses, Roles, ClusterRoles, Namespaces, StorageClasses, Jobs, Cronjobs, Nodes, Replicasets, ControllerRevisions} {
|
||||
ResourceControllers.runContoller(item, stopChan)
|
||||
}
|
||||
|
||||
go dbHealthCheck(client.NewDBClient())
|
||||
@@ -110,7 +121,7 @@ func Run() {
|
||||
case _, isClose := <-controller.chanAlive():
|
||||
if !isClose {
|
||||
glog.Errorf("controller %s have stopped, restart it", ctlName)
|
||||
ResourceControllers.runContoller(ctlName)
|
||||
ResourceControllers.runContoller(ctlName, stopChan)
|
||||
}
|
||||
default:
|
||||
time.Sleep(5 * time.Second)
|
||||
|
||||
@@ -69,12 +69,25 @@ func getExternalIp(item v1.Service) string {
|
||||
}
|
||||
|
||||
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
|
||||
namespace := item.Namespace
|
||||
createTime := item.CreationTimestamp.Time
|
||||
externalIp := getExternalIp(item)
|
||||
serviceType := item.Spec.Type
|
||||
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 := ""
|
||||
var nodePorts []string
|
||||
|
||||
@@ -118,13 +131,16 @@ func generateSvcObject(item v1.Service) *Service {
|
||||
object := &Service{
|
||||
Namespace: namespace,
|
||||
Name: name,
|
||||
DisplayName: displayName,
|
||||
ServiceType: string(serviceType),
|
||||
ExternalIp: externalIp,
|
||||
VirtualIp: vip,
|
||||
CreateTime: createTime,
|
||||
Ports: ports,
|
||||
NodePorts: strings.Join(nodePorts, ","),
|
||||
Annotation: Annotation{item.Annotations},
|
||||
Annotation: MapString{item.Annotations},
|
||||
Labels: MapString{item.Labels},
|
||||
App: app,
|
||||
}
|
||||
|
||||
return object
|
||||
@@ -209,14 +225,21 @@ func (ctl *ServiceCtl) CountWithConditions(conditions string) int {
|
||||
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 object Service
|
||||
var total int
|
||||
|
||||
order := "createTime desc"
|
||||
if len(order) == 0 {
|
||||
order = "createTime desc"
|
||||
}
|
||||
|
||||
listWithConditions(ctl.DB, &total, &object, &list, conditions, paging, order)
|
||||
|
||||
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 {
|
||||
var app string
|
||||
var status string
|
||||
var displayName string
|
||||
|
||||
if item.Annotations != nil && len(item.Annotations[DisplayName]) > 0 {
|
||||
displayName = item.Annotations[DisplayName]
|
||||
}
|
||||
name := item.Name
|
||||
namespace := item.Namespace
|
||||
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,
|
||||
App: app, CreateTime: createTime, Status: status, Annotation: Annotation{item.Annotations}}
|
||||
statefulSetObject := &Statefulset{
|
||||
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
|
||||
}
|
||||
@@ -137,14 +152,21 @@ func (ctl *StatefulsetCtl) CountWithConditions(conditions string) int {
|
||||
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 object Statefulset
|
||||
var total int
|
||||
|
||||
order := "createTime desc"
|
||||
if len(order) == 0 {
|
||||
order = "createTime desc"
|
||||
}
|
||||
|
||||
listWithConditions(ctl.DB, &total, &object, &list, conditions, paging, order)
|
||||
|
||||
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 {
|
||||
|
||||
var displayName string
|
||||
|
||||
if item.Annotations != nil && len(item.Annotations[DisplayName]) > 0 {
|
||||
displayName = item.Annotations[DisplayName]
|
||||
}
|
||||
|
||||
name := item.Name
|
||||
createTime := item.CreationTimestamp.Time
|
||||
isDefault := false
|
||||
@@ -41,7 +47,13 @@ func (ctl *StorageClassCtl) generateObject(item v1.StorageClass) *StorageClass {
|
||||
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
|
||||
}
|
||||
@@ -120,12 +132,14 @@ func (ctl *StorageClassCtl) CountWithConditions(conditions string) int {
|
||||
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 object StorageClass
|
||||
var total int
|
||||
|
||||
order := "createTime desc"
|
||||
if len(order) == 0 {
|
||||
order = "createTime desc"
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
func (ctl *StorageClassCtl) Lister() interface{} {
|
||||
|
||||
return ctl.lister
|
||||
}
|
||||
|
||||
@@ -27,6 +27,8 @@ import (
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
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"
|
||||
"k8s.io/client-go/listers/extensions/v1beta1"
|
||||
rbacV1 "k8s.io/client-go/listers/rbac/v1"
|
||||
@@ -35,22 +37,18 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
resyncCircle = 600
|
||||
Stopped = "stopped"
|
||||
PvcPending = "Pending"
|
||||
Running = "running"
|
||||
Updating = "updating"
|
||||
tablePods = "pods"
|
||||
tableDeployments = "deployments"
|
||||
tableDaemonsets = "daemonsets"
|
||||
tableStatefulsets = "statefulsets"
|
||||
tableNamespaces = "namespaces"
|
||||
tableIngresses = "ingresses"
|
||||
tablePersistentVolumeClaim = "pvcs"
|
||||
tableRoles = "roles"
|
||||
tableClusterRoles = "cluster_roles"
|
||||
tableServices = "services"
|
||||
tableStorageClasses = "storage_classes"
|
||||
resyncCircle = 600
|
||||
Stopped = "stopped"
|
||||
PvcPending = "pending"
|
||||
Running = "running"
|
||||
Updating = "updating"
|
||||
Failed = "failed"
|
||||
Unfinished = "unfinished"
|
||||
Completed = "completed"
|
||||
Pause = "pause"
|
||||
Warning = "warning"
|
||||
Error = "error"
|
||||
DisplayName = "displayName"
|
||||
|
||||
Pods = "pods"
|
||||
Deployments = "deployments"
|
||||
@@ -64,13 +62,18 @@ const (
|
||||
Services = "services"
|
||||
StorageClasses = "storage-classes"
|
||||
Applications = "applications"
|
||||
Jobs = "jobs"
|
||||
Cronjobs = "cronjobs"
|
||||
Nodes = "nodes"
|
||||
Replicasets = "replicasets"
|
||||
ControllerRevisions = "controllerrevisions"
|
||||
)
|
||||
|
||||
type Annotation struct {
|
||||
Values map[string]string `gorm:"type:TEXT"`
|
||||
type MapString struct {
|
||||
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) {
|
||||
case string:
|
||||
return json.Unmarshal([]byte(val), annotation)
|
||||
@@ -82,92 +85,104 @@ func (annotation *Annotation) Scan(val interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (annotation Annotation) Value() (driver.Value, error) {
|
||||
func (annotation MapString) Value() (driver.Value, error) {
|
||||
bytes, err := json.Marshal(annotation)
|
||||
return string(bytes), err
|
||||
}
|
||||
|
||||
type Deployment struct {
|
||||
Name string `gorm:"primary_key" json:"name"`
|
||||
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"`
|
||||
type Taints struct {
|
||||
Values []v1.Taint `json:"values" gorm:"type:TEXT"`
|
||||
}
|
||||
|
||||
func (Deployment) TableName() string {
|
||||
return tableDeployments
|
||||
func (taints *Taints) Scan(val interface{}) error {
|
||||
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 {
|
||||
Name string `gorm:"primary_key" json:"name,omitempty"`
|
||||
Namespace string `gorm:"primary_key" json:"namespace,omitempty"`
|
||||
App string `json:"app,omitempty"`
|
||||
Name string `gorm:"primary_key" json:"name,omitempty"`
|
||||
DisplayName string `json:"displayName,omitempty" gorm:"column:displayName"`
|
||||
Namespace string `gorm:"primary_key" json:"namespace,omitempty"`
|
||||
App string `json:"app,omitempty"`
|
||||
|
||||
Available int32 `json:"available"`
|
||||
Desire int32 `json:"desire"`
|
||||
Status string `json:"status"`
|
||||
Annotation Annotation `json:"annotations"`
|
||||
CreateTime time.Time `gorm:"column:createTime" json:"createTime,omitempty"`
|
||||
}
|
||||
|
||||
func (Statefulset) TableName() string {
|
||||
return tableStatefulsets
|
||||
Available int32 `json:"available"`
|
||||
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"`
|
||||
}
|
||||
|
||||
type Daemonset struct {
|
||||
Name string `gorm:"primary_key" json:"name,omitempty"`
|
||||
Namespace string `gorm:"primary_key" json:"namespace,omitempty"`
|
||||
App string `json:"app,omitempty"`
|
||||
Name string `gorm:"primary_key" json:"name,omitempty"`
|
||||
DisplayName string `json:"displayName,omitempty" gorm:"column:displayName"`
|
||||
Namespace string `gorm:"primary_key" json:"namespace,omitempty"`
|
||||
App string `json:"app,omitempty"`
|
||||
|
||||
Available int32 `json:"available"`
|
||||
Desire int32 `json:"desire"`
|
||||
Status string `json:"status"`
|
||||
NodeSelector string `json:"nodeSelector, omitempty"`
|
||||
Annotation Annotation `json:"annotations"`
|
||||
CreateTime time.Time `gorm:"column:createTime" json:"createTime,omitempty"`
|
||||
}
|
||||
|
||||
func (Daemonset) TableName() string {
|
||||
return tableDaemonsets
|
||||
Available int32 `json:"available"`
|
||||
Desire int32 `json:"desire"`
|
||||
Status string `json:"status"`
|
||||
NodeSelector string `json:"nodeSelector, omitempty"`
|
||||
Annotation MapString `json:"annotations"`
|
||||
Labels MapString `json:"labels"`
|
||||
CreateTime time.Time `gorm:"column:createTime" json:"createTime,omitempty"`
|
||||
}
|
||||
|
||||
type Service struct {
|
||||
Name string `gorm:"primary_key" json:"name"`
|
||||
DisplayName string `json:"displayName,omitempty" gorm:"column:displayName"`
|
||||
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"`
|
||||
ExternalIp string `json:"externalIp,omitempty"`
|
||||
App string `json:"app,omitempty"`
|
||||
VirtualIp string `gorm:"column:virtualIp" json:"virtualIp,omitempty"`
|
||||
ExternalIp string `gorm:"column:externalIp" json:"externalIp,omitempty"`
|
||||
|
||||
Ports string `json:"ports,omitempty"`
|
||||
NodePorts string `json:"nodePorts,omitempty"`
|
||||
Annotation Annotation `json:"annotations"`
|
||||
CreateTime time.Time `gorm:"column:createTime" json:"createTime,omitempty"`
|
||||
}
|
||||
|
||||
func (Service) TableName() string {
|
||||
return tableServices
|
||||
Ports string `json:"ports,omitempty"`
|
||||
NodePorts string `gorm:"column:nodePorts" json:"nodePorts,omitempty"`
|
||||
Annotation MapString `json:"annotations"`
|
||||
Labels MapString `json:"labels"`
|
||||
CreateTime time.Time `gorm:"column:createTime" json:"createTime,omitempty"`
|
||||
}
|
||||
|
||||
type Pvc struct {
|
||||
Name string `gorm:"primary_key" json:"name"`
|
||||
Namespace string `gorm:"primary_key" json:"namespace"`
|
||||
Status string `json:"status,omitempty"`
|
||||
Capacity string `json:"capacity,omitempty"`
|
||||
AccessMode string `json:"accessMode,omitempty"`
|
||||
Annotation Annotation `json:"annotations"`
|
||||
CreateTime time.Time `gorm:"column:createTime" json:"createTime,omitempty"`
|
||||
StorageClassName string `gorm:"column:storage_class" json:"storage_class,omitempty"`
|
||||
InUse bool `gorm:"-" json:"inUse"`
|
||||
}
|
||||
|
||||
func (Pvc) TableName() string {
|
||||
return tablePersistentVolumeClaim
|
||||
Name string `gorm:"primary_key" json:"name"`
|
||||
DisplayName string `json:"displayName,omitempty" gorm:"column:displayName"`
|
||||
Namespace string `gorm:"primary_key" json:"namespace"`
|
||||
Status string `json:"status,omitempty"`
|
||||
Capacity string `json:"capacity,omitempty"`
|
||||
AccessMode string `gorm:"column:accessMode" json:"accessMode,omitempty"`
|
||||
Annotation MapString `json:"annotations"`
|
||||
Labels MapString `json:"labels"`
|
||||
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"`
|
||||
}
|
||||
|
||||
type ingressRule struct {
|
||||
@@ -178,17 +193,15 @@ type ingressRule struct {
|
||||
}
|
||||
|
||||
type Ingress struct {
|
||||
Name string `gorm:"primary_key" json:"name"`
|
||||
Namespace string `gorm:"primary_key" json:"namespace"`
|
||||
Ip string `json:"ip,omitempty"`
|
||||
Rules string `gorm:"type:text" json:"rules, omitempty"`
|
||||
TlsTermination string `json:"tlsTermination,omitempty"`
|
||||
Annotation Annotation `json:"annotations"`
|
||||
CreateTime time.Time `gorm:"column:createTime" json:"createTime,omitempty"`
|
||||
}
|
||||
|
||||
func (Ingress) TableName() string {
|
||||
return tableIngresses
|
||||
Name string `gorm:"primary_key" json:"name"`
|
||||
DisplayName string `json:"displayName,omitempty" gorm:"column:displayName"`
|
||||
Namespace string `gorm:"primary_key" json:"namespace"`
|
||||
Ip string `json:"ip,omitempty"`
|
||||
Rules string `gorm:"type:text" json:"rules, omitempty"`
|
||||
TlsTermination string `gorm:"column:tlsTermination" json:"tlsTermination,omitempty"`
|
||||
Annotation MapString `json:"annotations"`
|
||||
Labels MapString `json:"labels"`
|
||||
CreateTime time.Time `gorm:"column:createTime" json:"createTime,omitempty"`
|
||||
}
|
||||
|
||||
type Pod struct {
|
||||
@@ -196,10 +209,11 @@ type Pod struct {
|
||||
Namespace string `gorm:"primary_key" json:"namespace"`
|
||||
Status string `json:"status,omitempty"`
|
||||
Node string `json:"node,omitempty"`
|
||||
NodeIp string `json:"nodeIp,omitempty"`
|
||||
PodIp string `json:"podIp,omitempty"`
|
||||
NodeIp string `gorm:"column:nodeIp" json:"nodeIp,omitempty"`
|
||||
PodIp string `gorm:"column:podIp" json:"podIp,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"`
|
||||
CreateTime time.Time `gorm:"column:createTime" json:"createTime,omitempty"`
|
||||
}
|
||||
@@ -230,61 +244,97 @@ func (containers Containers) Value() (driver.Value, error) {
|
||||
return string(bytes), err
|
||||
}
|
||||
|
||||
func (Pod) TableName() string {
|
||||
return tablePods
|
||||
}
|
||||
|
||||
type Role struct {
|
||||
Name string `gorm:"primary_key" json:"name"`
|
||||
Namespace string `gorm:"primary_key" json:"namespace"`
|
||||
Annotation Annotation `json:"annotations"`
|
||||
CreateTime time.Time `gorm:"column:createTime" json:"createTime,omitempty"`
|
||||
}
|
||||
|
||||
func (Role) TableName() string {
|
||||
return tableRoles
|
||||
Name string `gorm:"primary_key" json:"name"`
|
||||
DisplayName string `json:"displayName,omitempty" gorm:"column:displayName"`
|
||||
Namespace string `gorm:"primary_key" json:"namespace"`
|
||||
Annotation MapString `json:"annotations"`
|
||||
CreateTime time.Time `gorm:"column:createTime" json:"createTime,omitempty"`
|
||||
}
|
||||
|
||||
type ClusterRole struct {
|
||||
Name string `gorm:"primary_key" json:"name"`
|
||||
Annotation Annotation `json:"annotations"`
|
||||
CreateTime time.Time `gorm:"column:createTime" json:"createTime,omitempty"`
|
||||
}
|
||||
|
||||
func (ClusterRole) TableName() string {
|
||||
return tableClusterRoles
|
||||
Name string `gorm:"primary_key" json:"name"`
|
||||
DisplayName string `json:"displayName,omitempty" gorm:"column:displayName"`
|
||||
Annotation MapString `json:"annotations"`
|
||||
CreateTime time.Time `gorm:"column:createTime" json:"createTime,omitempty"`
|
||||
}
|
||||
|
||||
type Namespace struct {
|
||||
Name string `gorm:"primary_key" json:"name"`
|
||||
Creator string `json:"creator,omitempty"`
|
||||
Status string `json:"status"`
|
||||
Name string `gorm:"primary_key" json:"name"`
|
||||
DisplayName string `json:"displayName,omitempty" gorm:"column:displayName"`
|
||||
Creator string `json:"creator,omitempty"`
|
||||
Status string `json:"status"`
|
||||
|
||||
Descrition string `json:"description,omitempty"`
|
||||
Annotation Annotation `json:"annotations"`
|
||||
Annotation MapString `json:"annotations"`
|
||||
CreateTime time.Time `gorm:"column:createTime" json:"createTime,omitempty"`
|
||||
Usaeg v1.ResourceList `gorm:"-" json:"usage,omitempty"`
|
||||
}
|
||||
|
||||
func (Namespace) TableName() string {
|
||||
return tableNamespaces
|
||||
Usage v1.ResourceList `gorm:"-" json:"usage,omitempty"`
|
||||
}
|
||||
|
||||
type StorageClass struct {
|
||||
Name string `gorm:"primary_key" json:"name"`
|
||||
Creator string `json:"creator,omitempty"`
|
||||
Annotation Annotation `json:"annotations"`
|
||||
CreateTime time.Time `gorm:"column:createTime" json:"createTime,omitempty"`
|
||||
IsDefault bool `json:"default"`
|
||||
Count int `json:"count"`
|
||||
Name string `gorm:"primary_key" json:"name"`
|
||||
DisplayName string `json:"displayName,omitempty" gorm:"column:displayName"`
|
||||
Creator string `json:"creator,omitempty"`
|
||||
Annotation MapString `json:"annotations"`
|
||||
CreateTime time.Time `gorm:"column:createTime" json:"createTime,omitempty"`
|
||||
IsDefault bool `json:"default"`
|
||||
Count int `json:"count"`
|
||||
}
|
||||
|
||||
func (StorageClass) TableName() string {
|
||||
return tableStorageClasses
|
||||
type JobRevisions map[int]JobStatus
|
||||
|
||||
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 {
|
||||
Limit, Offset int
|
||||
Limit, Offset, Page int
|
||||
}
|
||||
|
||||
type Controller interface {
|
||||
@@ -295,7 +345,9 @@ type Controller interface {
|
||||
initListerAndInformer()
|
||||
sync(stopChan chan struct{})
|
||||
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 {
|
||||
@@ -316,6 +368,11 @@ func (ca *CommonAttribute) chanAlive() chan struct{} {
|
||||
return ca.aliveChan
|
||||
}
|
||||
|
||||
func (ca *CommonAttribute) CloseDB() {
|
||||
|
||||
ca.DB.Close()
|
||||
}
|
||||
|
||||
type DeploymentCtl struct {
|
||||
CommonAttribute
|
||||
lister appV1.DeploymentLister
|
||||
@@ -381,3 +438,33 @@ type ClusterRoleCtl struct {
|
||||
informer cache.SharedIndexInformer
|
||||
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"
|
||||
storageClassesKey = "count/storageClass"
|
||||
namespaceKey = "count/namespace"
|
||||
jobsKey = "count/jobs.batch"
|
||||
cronJobsKey = "count/cronjobs.batch"
|
||||
)
|
||||
|
||||
var resourceMap = map[string]string{daemonsetsKey: controllers.Daemonsets, deploymentsKey: controllers.Deployments,
|
||||
ingressKey: controllers.Ingresses, rolesKey: controllers.Roles, servicesKey: controllers.Services,
|
||||
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 {
|
||||
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
|
||||
|
||||
import (
|
||||
@@ -24,11 +40,19 @@ type ResourceList struct {
|
||||
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) {
|
||||
switch resource {
|
||||
case controllers.Deployments, controllers.Statefulsets, controllers.Daemonsets, controllers.Ingresses,
|
||||
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
|
||||
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)
|
||||
fuzzy := make(map[string]string)
|
||||
matchOr := make(map[string]string)
|
||||
fuzzyOr := make(map[string]string)
|
||||
orderField := make(map[string]string)
|
||||
|
||||
if len(str) == 0 {
|
||||
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 {
|
||||
return nil, nil, errors.New("invalid condition input, invalid character \"~\"")
|
||||
conditions := strings.Split(str, ",")
|
||||
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 {
|
||||
@@ -59,7 +84,17 @@ func getConditions(str string) (map[string]string, map[string]string, error) {
|
||||
if len(kvs) < 2 || len(kvs[1]) == 0 {
|
||||
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
|
||||
}
|
||||
|
||||
@@ -68,86 +103,130 @@ func getConditions(str string) (map[string]string, map[string]string, error) {
|
||||
if len(kvs) < 2 || len(kvs[1]) == 0 {
|
||||
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
|
||||
}
|
||||
|
||||
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) {
|
||||
defaultPaging := &controllers.Paging{Limit: 10, Offset: 0}
|
||||
defautlPagingMap := map[string]int{"page": 1, "limit": 10}
|
||||
func getPaging(resourceName, pagingStr string) (*controllers.Paging, error) {
|
||||
defaultPaging := &controllers.Paging{Limit: 10, Offset: 0, Page: 1}
|
||||
paging := controllers.Paging{}
|
||||
|
||||
if resourceName == controllers.Namespaces {
|
||||
defaultPaging = nil
|
||||
defautlPagingMap = map[string]int{"page": 0, "limit": 0}
|
||||
}
|
||||
pagingMap := make(map[string]int)
|
||||
|
||||
if len(pagingStr) == 0 {
|
||||
return defaultPaging, defautlPagingMap, nil
|
||||
return defaultPaging, nil
|
||||
}
|
||||
|
||||
list := strings.Split(pagingStr, ",")
|
||||
for _, item := range list {
|
||||
kvs := strings.Split(item, "=")
|
||||
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])
|
||||
if err != nil {
|
||||
return nil, nil, errors.New("invalid Paging input")
|
||||
if err != nil || value <= 0 {
|
||||
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 {
|
||||
return nil, nil, errors.New("invalid Paging input")
|
||||
if paging.Limit > 0 && paging.Page > 0 {
|
||||
paging.Offset = (paging.Page - 1) * paging.Limit
|
||||
return &paging, nil
|
||||
}
|
||||
|
||||
if pagingMap[limit] > 0 && pagingMap[page] > 0 {
|
||||
offset := (pagingMap[page] - 1) * pagingMap[limit]
|
||||
return &controllers.Paging{Limit: pagingMap[limit], Offset: offset}, pagingMap, nil
|
||||
}
|
||||
|
||||
return defaultPaging, defautlPagingMap, nil
|
||||
return defaultPaging, nil
|
||||
}
|
||||
|
||||
func ListResource(resourceName, conditonSrt, pagingStr string) (*ResourceList, error) {
|
||||
match, fuzzy, err := getConditions(conditonSrt)
|
||||
func generateOrder(orderField map[string]string, order string) string {
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
paging, pagingMap, err := getPaging(resourceName, pagingStr)
|
||||
order = generateOrder(OrderFields, order)
|
||||
conditionStr := generateConditionStr(conditions)
|
||||
|
||||
paging, err := getPaging(resourceName, pagingStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
conditionStr := generateConditionStr(match, fuzzy)
|
||||
|
||||
ctl, err := getController(resourceName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
total, items, err := ctl.ListWithConditions(conditionStr, paging)
|
||||
total, items, err := ctl.ListWithConditions(conditionStr, paging, order)
|
||||
if err != nil {
|
||||
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 := ""
|
||||
|
||||
for k, v := range match {
|
||||
if conditions == nil {
|
||||
return conditionStr
|
||||
}
|
||||
|
||||
for k, v := range conditions.match {
|
||||
if len(conditionStr) == 0 {
|
||||
conditionStr = fmt.Sprintf("%s = \"%s\" ", k, v)
|
||||
} 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 {
|
||||
conditionStr = fmt.Sprintf("%s like '%%%s%%' ", k, v)
|
||||
} 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
|
||||
}
|
||||
|
||||
@@ -182,9 +277,9 @@ func GetNamespacesResourceStatus(namespace string) (*workLoadStatus, error) {
|
||||
notReadyStatus = controllers.PvcPending
|
||||
}
|
||||
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 {
|
||||
status, err = ListResource(resource, fmt.Sprintf("status=%s", notReadyStatus), "")
|
||||
status, err = ListResource(resource, fmt.Sprintf("status=%s", notReadyStatus), "", "")
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
@@ -208,25 +303,30 @@ func GetApplication(clusterId string) (interface{}, error) {
|
||||
return ctl.GetApp(clusterId)
|
||||
}
|
||||
|
||||
func ListApplication(runtimeId, conditions, pagingStr string) (*ResourceList, error) {
|
||||
paging, pagingMap, err := getPaging(controllers.Applications, pagingStr)
|
||||
func ListApplication(runtimeId, conditionStr, pagingStr string) (*ResourceList, error) {
|
||||
paging, err := getPaging(controllers.Applications, pagingStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
match, fuzzy, err := getConditions(conditions)
|
||||
conditions, _, err := getConditions(conditionStr)
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if conditions == nil {
|
||||
conditions = &searchConditions{}
|
||||
}
|
||||
|
||||
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 {
|
||||
glog.Errorf("get application list failed, reason: %s", 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