support configmaps and secrets' paging

This commit is contained in:
richardxz
2018-10-07 22:44:21 -04:00
parent 8ada5d2b45
commit 6658177967
6 changed files with 371 additions and 9 deletions

View File

@@ -34,12 +34,16 @@ func Register(ws *restful.WebService, subPath string) {
tags := []string{"resources"}
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{}))
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 isInvalid(str string) bool {

View File

@@ -0,0 +1,162 @@
/*
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 (
"strings"
"time"
"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"
)
func (ctl *ConfigMapCtl) generateObject(item v1.ConfigMap) *ConfigMap {
var displayName string
if item.Annotations != nil && len(item.Annotations[DisplayName]) > 0 {
displayName = item.Annotations[DisplayName]
}
createTime := item.CreationTimestamp.Time
if createTime.IsZero() {
createTime = time.Now()
}
var entries []string
for entry := range item.Data {
entries = append(entries, entry)
}
object := &ConfigMap{
Name: item.Name,
Namespace: item.Namespace,
CreateTime: createTime,
Annotation: MapString{item.Annotations},
DisplayName: displayName,
Entries: strings.Join(entries, ","),
}
return object
}
func (ctl *ConfigMapCtl) Name() string {
return ctl.CommonAttribute.Name
}
func (ctl *ConfigMapCtl) sync(stopChan chan struct{}) {
db := ctl.DB
if db.HasTable(&ConfigMap{}) {
db.DropTable(&ConfigMap{})
}
db = db.CreateTable(&ConfigMap{})
ctl.initListerAndInformer()
list, err := ctl.lister.List(labels.Everything())
if err != nil {
glog.Error(err)
return
}
for _, item := range list {
obj := ctl.generateObject(*item)
if obj != nil {
db.Create(obj)
}
}
ctl.informer.Run(stopChan)
}
func (ctl *ConfigMapCtl) 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 *ConfigMapCtl) initListerAndInformer() {
db := ctl.DB
informerFactory := informers.NewSharedInformerFactory(ctl.K8sClient, time.Second*resyncCircle)
ctl.lister = informerFactory.Core().V1().ConfigMaps().Lister()
informer := informerFactory.Core().V1().ConfigMaps().Informer()
informer.AddEventHandler(cache.ResourceEventHandlerFuncs{
AddFunc: func(obj interface{}) {
object := obj.(*v1.ConfigMap)
mysqlObject := ctl.generateObject(*object)
if mysqlObject != nil {
db.Create(mysqlObject)
}
},
UpdateFunc: func(old, new interface{}) {
object := new.(*v1.ConfigMap)
mysqlObject := ctl.generateObject(*object)
if mysqlObject != nil {
db.Save(mysqlObject)
}
},
DeleteFunc: func(obj interface{}) {
var item ConfigMap
object := obj.(*v1.ConfigMap)
db.Where("name=?", object.Name).Find(&item)
db.Delete(item)
},
})
ctl.informer = informer
}
func (ctl *ConfigMapCtl) CountWithConditions(conditions string) int {
var object ConfigMap
if strings.Contains(conditions, "namespace") {
conditions = ""
}
return countWithConditions(ctl.DB, conditions, &object)
}
func (ctl *ConfigMapCtl) ListWithConditions(conditions string, paging *Paging, order string) (int, interface{}, error) {
var object ConfigMap
var list []ConfigMap
var total int
if len(order) == 0 {
order = "createTime desc"
}
db := ctl.DB
listWithConditions(db, &total, &object, &list, conditions, paging, order)
return total, list, nil
}
func (ctl *ConfigMapCtl) Lister() interface{} {
return ctl.lister
}

View File

@@ -74,6 +74,10 @@ func (rec *resourceControllers) runContoller(name string, stopChan chan struct{}
ctl = &ReplicaSetCtl{CommonAttribute: attr}
case ControllerRevisions:
ctl = &ControllerRevisionCtl{CommonAttribute: attr}
case ConfigMaps:
ctl = &ConfigMapCtl{CommonAttribute: attr}
case Secrets:
ctl = &SecretCtl{CommonAttribute: attr}
default:
return
}
@@ -112,7 +116,8 @@ func Run(stopChan chan struct{}, wg *sync.WaitGroup) {
ResourceControllers = resourceControllers{k8sClient: k8sClient, Controllers: make(map[string]Controller)}
for _, item := range []string{Deployments, Statefulsets, Daemonsets, PersistentVolumeClaim, Pods, Services,
Ingresses, Roles, ClusterRoles, Namespaces, StorageClasses, Jobs, Cronjobs, Nodes, Replicasets, ControllerRevisions} {
Ingresses, Roles, ClusterRoles, Namespaces, StorageClasses, Jobs, Cronjobs, Nodes, Replicasets,
ControllerRevisions, ConfigMaps, Secrets} {
ResourceControllers.runContoller(item, stopChan, wg)
}
@@ -129,7 +134,7 @@ func Run(stopChan chan struct{}, wg *sync.WaitGroup) {
ResourceControllers.runContoller(ctlName, stopChan, wg)
}
default:
time.Sleep(5 * time.Second)
time.Sleep(3 * time.Second)
}
}
}

View File

@@ -0,0 +1,157 @@
/*
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 (
"strings"
"time"
"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"
)
func (ctl *SecretCtl) generateObject(item v1.Secret) *Secret {
var displayName string
if item.Annotations != nil && len(item.Annotations[DisplayName]) > 0 {
displayName = item.Annotations[DisplayName]
}
createTime := item.CreationTimestamp.Time
if createTime.IsZero() {
createTime = time.Now()
}
object := &Secret{
Name: item.Name,
Namespace: item.Namespace,
CreateTime: createTime,
Annotation: MapString{item.Annotations},
DisplayName: displayName,
Entries: len(item.Data),
Type: string(item.Type),
}
return object
}
func (ctl *SecretCtl) Name() string {
return ctl.CommonAttribute.Name
}
func (ctl *SecretCtl) sync(stopChan chan struct{}) {
db := ctl.DB
if db.HasTable(&Secret{}) {
db.DropTable(&Secret{})
}
db = db.CreateTable(&Secret{})
ctl.initListerAndInformer()
list, err := ctl.lister.List(labels.Everything())
if err != nil {
glog.Error(err)
return
}
for _, item := range list {
obj := ctl.generateObject(*item)
if obj != nil {
db.Create(obj)
}
}
ctl.informer.Run(stopChan)
}
func (ctl *SecretCtl) 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 *SecretCtl) initListerAndInformer() {
db := ctl.DB
informerFactory := informers.NewSharedInformerFactory(ctl.K8sClient, time.Second*resyncCircle)
ctl.lister = informerFactory.Core().V1().Secrets().Lister()
informer := informerFactory.Core().V1().Secrets().Informer()
informer.AddEventHandler(cache.ResourceEventHandlerFuncs{
AddFunc: func(obj interface{}) {
object := obj.(*v1.Secret)
mysqlObject := ctl.generateObject(*object)
if mysqlObject != nil {
db.Create(mysqlObject)
}
},
UpdateFunc: func(old, new interface{}) {
object := new.(*v1.Secret)
mysqlObject := ctl.generateObject(*object)
if mysqlObject != nil {
db.Save(mysqlObject)
}
},
DeleteFunc: func(obj interface{}) {
var item Secret
object := obj.(*v1.Secret)
db.Where("name=?", object.Name).Find(&item)
db.Delete(item)
},
})
ctl.informer = informer
}
func (ctl *SecretCtl) CountWithConditions(conditions string) int {
var object Secret
if strings.Contains(conditions, "namespace") {
conditions = ""
}
return countWithConditions(ctl.DB, conditions, &object)
}
func (ctl *SecretCtl) ListWithConditions(conditions string, paging *Paging, order string) (int, interface{}, error) {
var object Secret
var list []Secret
var total int
if len(order) == 0 {
order = "createTime desc"
}
db := ctl.DB
listWithConditions(db, &total, &object, &list, conditions, paging, order)
return total, list, nil
}
func (ctl *SecretCtl) Lister() interface{} {
return ctl.lister
}

View File

@@ -67,6 +67,8 @@ const (
Nodes = "nodes"
Replicasets = "replicasets"
ControllerRevisions = "controllerrevisions"
ConfigMaps = "configmaps"
Secrets = "secrets"
)
type MapString struct {
@@ -334,6 +336,26 @@ type Node struct {
Role string `json:"role"`
CreateTime time.Time `gorm:"column:createTime" json:"createTime,omitempty"`
}
type ConfigMap struct {
Name string `gorm:"primary_key" json:"name"`
Namespace string `gorm:"primary_key" json:"namespace"`
DisplayName string `json:"displayName,omitempty" gorm:"column:displayName"`
CreateTime time.Time `gorm:"column:createTime" json:"createTime,omitempty"`
Annotation MapString `json:"annotations"`
Entries string `gorm:"type:text" json:"entries"`
}
type Secret struct {
Name string `gorm:"primary_key" json:"name"`
Namespace string `gorm:"primary_key" json:"namespace"`
DisplayName string `json:"displayName,omitempty" gorm:"column:displayName"`
CreateTime time.Time `gorm:"column:createTime" json:"createTime,omitempty"`
Annotation MapString `json:"annotations"`
Entries int `json:"entries"`
Type string `json:"type"`
}
type Paging struct {
Limit, Offset, Page int
}
@@ -469,3 +491,15 @@ type ControllerRevisionCtl struct {
informer cache.SharedIndexInformer
CommonAttribute
}
type ConfigMapCtl struct {
lister coreV1.ConfigMapLister
informer cache.SharedIndexInformer
CommonAttribute
}
type SecretCtl struct {
lister coreV1.SecretLister
informer cache.SharedIndexInformer
CommonAttribute
}

View File

@@ -52,7 +52,7 @@ func getController(resource string) (controllers.Controller, error) {
case controllers.Deployments, controllers.Statefulsets, controllers.Daemonsets, controllers.Ingresses,
controllers.PersistentVolumeClaim, controllers.Roles, controllers.ClusterRoles, controllers.Services,
controllers.Pods, controllers.Namespaces, controllers.StorageClasses, controllers.Jobs, controllers.Cronjobs,
controllers.Nodes:
controllers.Nodes, controllers.Secrets, controllers.ConfigMaps:
return controllers.ResourceControllers.Controllers[resource], nil
default: