mapping data to etcd
This commit is contained in:
140
pkg/models/controllers/clusterRoles.go
Normal file
140
pkg/models/controllers/clusterRoles.go
Normal file
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
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"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/api/rbac/v1"
|
||||
metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
)
|
||||
|
||||
func (ctl *ClusterRoleCtl) generateObjec(item v1.ClusterRole) *ClusterRole {
|
||||
name := item.Name
|
||||
if strings.HasPrefix(name, "system:") {
|
||||
return nil
|
||||
}
|
||||
|
||||
createTime := item.CreationTimestamp.Time
|
||||
if createTime.IsZero() {
|
||||
createTime = time.Now()
|
||||
}
|
||||
|
||||
annotation, _ := json.Marshal(item.Annotations)
|
||||
|
||||
object := &ClusterRole{Name: name, CreateTime: createTime, AnnotationStr: string(annotation)}
|
||||
|
||||
return object
|
||||
}
|
||||
|
||||
func (ctl *ClusterRoleCtl) listAndWatch() {
|
||||
defer func() {
|
||||
close(ctl.aliveChan)
|
||||
if err := recover(); err != nil {
|
||||
glog.Error(err)
|
||||
return
|
||||
}
|
||||
}()
|
||||
|
||||
db := ctl.DB
|
||||
|
||||
if db.HasTable(&ClusterRole{}) {
|
||||
db.DropTable(&ClusterRole{})
|
||||
|
||||
}
|
||||
|
||||
db = db.CreateTable(&ClusterRole{})
|
||||
|
||||
k8sClient := ctl.K8sClient
|
||||
|
||||
clusterRoleList, err := k8sClient.RbacV1().ClusterRoles().List(metaV1.ListOptions{})
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
for _, item := range clusterRoleList.Items {
|
||||
obj := ctl.generateObjec(item)
|
||||
if obj != nil {
|
||||
db.Create(obj)
|
||||
}
|
||||
}
|
||||
|
||||
clusterRoleWatcher, err := k8sClient.RbacV1().ClusterRoles().Watch(metaV1.ListOptions{})
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ctl.stopChan:
|
||||
return
|
||||
case event := <-clusterRoleWatcher.ResultChan():
|
||||
var role ClusterRole
|
||||
if event.Object == nil {
|
||||
break
|
||||
}
|
||||
object := event.Object.(*v1.ClusterRole)
|
||||
if event.Type == watch.Deleted {
|
||||
db.Where("name=? And namespace=?", object.Name, "\"\"").Find(&role)
|
||||
db.Delete(role)
|
||||
break
|
||||
}
|
||||
obj := ctl.generateObjec(*object)
|
||||
if obj != nil {
|
||||
db.Save(obj)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (ctl *ClusterRoleCtl) CountWithConditions(conditions string) int {
|
||||
var object ClusterRole
|
||||
|
||||
return countWithConditions(ctl.DB, conditions, &object)
|
||||
}
|
||||
|
||||
func (ctl *ClusterRoleCtl) ListWithConditions(conditions string, paging *Paging) (int, interface{}, error) {
|
||||
var object ClusterRole
|
||||
var list []ClusterRole
|
||||
var total int
|
||||
|
||||
order := "createTime desc"
|
||||
db := ctl.DB
|
||||
|
||||
listWithConditions(db, &total, &object, &list, conditions, paging, order)
|
||||
|
||||
for index, item := range list {
|
||||
annotation := make(map[string]string)
|
||||
json.Unmarshal([]byte(item.AnnotationStr), &annotation)
|
||||
list[index].Annotation = annotation
|
||||
list[index].AnnotationStr = ""
|
||||
}
|
||||
return total, list, nil
|
||||
}
|
||||
|
||||
func (ctl *ClusterRoleCtl) Count(namespace string) int {
|
||||
var count int
|
||||
db := ctl.DB
|
||||
db.Model(&ClusterRole{}).Count(&count)
|
||||
return count
|
||||
}
|
||||
161
pkg/models/controllers/daemonsets.go
Normal file
161
pkg/models/controllers/daemonsets.go
Normal file
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
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"
|
||||
"time"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/api/apps/v1beta2"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/client"
|
||||
)
|
||||
|
||||
func (ctl *DaemonsetCtl) generateObject(item v1beta2.DaemonSet) *Daemonset {
|
||||
var app string
|
||||
var status string
|
||||
name := item.Name
|
||||
namespace := item.Namespace
|
||||
availablePodNum := item.Status.CurrentNumberScheduled
|
||||
desirePodNum := item.Status.DesiredNumberScheduled
|
||||
createTime := item.CreationTimestamp.Time
|
||||
release := item.ObjectMeta.Labels["release"]
|
||||
nodeSelector := item.Spec.Template.Spec.NodeSelector
|
||||
nodeSelectorStr, _ := json.Marshal(nodeSelector)
|
||||
|
||||
chart := item.ObjectMeta.Labels["chart"]
|
||||
|
||||
if len(release) > 0 && len(chart) > 0 {
|
||||
app = release + "/" + chart
|
||||
} else {
|
||||
app = "-"
|
||||
}
|
||||
|
||||
if createTime.IsZero() {
|
||||
createTime = time.Now()
|
||||
}
|
||||
|
||||
if availablePodNum >= desirePodNum {
|
||||
status = running
|
||||
} else {
|
||||
status = updating
|
||||
}
|
||||
|
||||
annotation, _ := json.Marshal(item.Annotations)
|
||||
|
||||
object := &Daemonset{Namespace: namespace, Name: name, Available: availablePodNum, Desire: desirePodNum,
|
||||
App: app, CreateTime: createTime, Status: status, NodeSelector: string(nodeSelectorStr), AnnotationStr: string(annotation)}
|
||||
|
||||
return object
|
||||
}
|
||||
|
||||
func (ctl *DaemonsetCtl) listAndWatch() {
|
||||
defer func() {
|
||||
|
||||
close(ctl.aliveChan)
|
||||
|
||||
if err := recover(); err != nil {
|
||||
glog.Error(err)
|
||||
return
|
||||
}
|
||||
}()
|
||||
|
||||
db := ctl.DB
|
||||
|
||||
if db.HasTable(&Daemonset{}) {
|
||||
db.DropTable(&Daemonset{})
|
||||
|
||||
}
|
||||
|
||||
db = db.CreateTable(&Daemonset{})
|
||||
|
||||
k8sClient := client.NewK8sClient()
|
||||
deoloyList, err := k8sClient.AppsV1beta2().DaemonSets("").List(meta_v1.ListOptions{})
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
for _, item := range deoloyList.Items {
|
||||
obj := ctl.generateObject(item)
|
||||
db.Create(obj)
|
||||
}
|
||||
|
||||
watcher, err := k8sClient.AppsV1beta2().DaemonSets("").Watch(meta_v1.ListOptions{})
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ctl.stopChan:
|
||||
return
|
||||
case event := <-watcher.ResultChan():
|
||||
var ss Daemonset
|
||||
if event.Object == nil {
|
||||
break
|
||||
}
|
||||
object := event.Object.(*v1beta2.DaemonSet)
|
||||
if event.Type == watch.Deleted {
|
||||
db.Where("name=? And namespace=?", object.Name, object.Namespace).Find(&ss)
|
||||
db.Delete(ss)
|
||||
break
|
||||
}
|
||||
obj := ctl.generateObject(*object)
|
||||
db.Save(obj)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (ctl *DaemonsetCtl) CountWithConditions(conditions string) int {
|
||||
var object Daemonset
|
||||
|
||||
return countWithConditions(ctl.DB, conditions, &object)
|
||||
}
|
||||
|
||||
func (ctl *DaemonsetCtl) ListWithConditions(conditions string, paging *Paging) (int, interface{}, error) {
|
||||
var list []Daemonset
|
||||
var object Daemonset
|
||||
var total int
|
||||
|
||||
order := "createTime desc"
|
||||
|
||||
listWithConditions(ctl.DB, &total, &object, &list, conditions, paging, order)
|
||||
|
||||
for index, item := range list {
|
||||
annotation := make(map[string]string)
|
||||
json.Unmarshal([]byte(item.AnnotationStr), &annotation)
|
||||
list[index].Annotation = annotation
|
||||
list[index].AnnotationStr = ""
|
||||
}
|
||||
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
|
||||
}
|
||||
161
pkg/models/controllers/deployments.go
Normal file
161
pkg/models/controllers/deployments.go
Normal file
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
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"
|
||||
"time"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/api/apps/v1beta2"
|
||||
metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/client"
|
||||
)
|
||||
|
||||
func (ctl *DeploymentCtl) generateObject(item v1beta2.Deployment) *Deployment {
|
||||
var app string
|
||||
var status string
|
||||
var updateTime time.Time
|
||||
name := item.Name
|
||||
namespace := item.Namespace
|
||||
availablePodNum := item.Status.AvailableReplicas
|
||||
desirePodNum := *item.Spec.Replicas
|
||||
release := item.ObjectMeta.Labels["release"]
|
||||
chart := item.ObjectMeta.Labels["chart"]
|
||||
|
||||
if len(release) > 0 && len(chart) > 0 {
|
||||
app = release + "/" + chart
|
||||
} else {
|
||||
app = "-"
|
||||
}
|
||||
|
||||
for _, conditon := range item.Status.Conditions {
|
||||
if conditon.Type == "Progressing" {
|
||||
updateTime = conditon.LastUpdateTime.Time
|
||||
}
|
||||
}
|
||||
if updateTime.IsZero() {
|
||||
updateTime = time.Now()
|
||||
}
|
||||
|
||||
if item.Annotations["state"] == "stop" {
|
||||
status = stopping
|
||||
} else {
|
||||
if availablePodNum >= desirePodNum {
|
||||
status = running
|
||||
} else {
|
||||
status = updating
|
||||
}
|
||||
}
|
||||
|
||||
annotation, _ := json.Marshal(item.Annotations)
|
||||
|
||||
return &Deployment{Namespace: namespace, Name: name, Available: availablePodNum, Desire: desirePodNum,
|
||||
App: app, UpdateTime: updateTime, Status: status, AnnotationStr: string(annotation)}
|
||||
}
|
||||
|
||||
func (ctl *DeploymentCtl) listAndWatch() {
|
||||
defer func() {
|
||||
close(ctl.aliveChan)
|
||||
if err := recover(); err != nil {
|
||||
glog.Error(err)
|
||||
return
|
||||
}
|
||||
}()
|
||||
|
||||
db := ctl.DB
|
||||
if db.HasTable(&Deployment{}) {
|
||||
db.DropTable(&Deployment{})
|
||||
}
|
||||
|
||||
db = db.CreateTable(&Deployment{})
|
||||
|
||||
k8sClient := client.NewK8sClient()
|
||||
deoloyList, err := k8sClient.AppsV1beta2().Deployments("").List(metaV1.ListOptions{})
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
for _, item := range deoloyList.Items {
|
||||
obj := ctl.generateObject(item)
|
||||
db.Create(obj)
|
||||
}
|
||||
|
||||
watcher, err := k8sClient.AppsV1beta2().Deployments("").Watch(metaV1.ListOptions{})
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ctl.stopChan:
|
||||
return
|
||||
case event := <-watcher.ResultChan():
|
||||
var deploy Deployment
|
||||
if event.Object == nil {
|
||||
break
|
||||
}
|
||||
object := event.Object.(*v1beta2.Deployment)
|
||||
if event.Type == watch.Deleted {
|
||||
db.Where("name=? And namespace=?", object.Name, object.Namespace).Find(&deploy)
|
||||
db.Delete(deploy)
|
||||
break
|
||||
}
|
||||
obj := ctl.generateObject(*object)
|
||||
db.Save(obj)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (ctl *DeploymentCtl) CountWithConditions(conditions string) int {
|
||||
var object Deployment
|
||||
|
||||
return countWithConditions(ctl.DB, conditions, &object)
|
||||
}
|
||||
|
||||
func (ctl *DeploymentCtl) ListWithConditions(conditions string, paging *Paging) (int, interface{}, error) {
|
||||
var list []Deployment
|
||||
var object Deployment
|
||||
var total int
|
||||
|
||||
order := "updateTime desc"
|
||||
|
||||
listWithConditions(ctl.DB, &total, &object, &list, conditions, paging, order)
|
||||
|
||||
for index, item := range list {
|
||||
annotation := make(map[string]string)
|
||||
json.Unmarshal([]byte(item.AnnotationStr), &annotation)
|
||||
list[index].Annotation = annotation
|
||||
list[index].AnnotationStr = ""
|
||||
}
|
||||
return total, list, nil
|
||||
}
|
||||
|
||||
func (ctl *DeploymentCtl) Count(namespace string) int {
|
||||
var count int
|
||||
db := ctl.DB
|
||||
if len(namespace) == 0 {
|
||||
db.Model(&Deployment{}).Count(&count)
|
||||
} else {
|
||||
db.Model(&Deployment{}).Where("namespace = ?", namespace).Count(&count)
|
||||
}
|
||||
return count
|
||||
}
|
||||
148
pkg/models/controllers/ingresses.go
Normal file
148
pkg/models/controllers/ingresses.go
Normal file
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
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"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/api/extensions/v1beta1"
|
||||
metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/client"
|
||||
)
|
||||
|
||||
func (ctl *IngressCtl) generateObject(item v1beta1.Ingress) *Ingress {
|
||||
name := item.Name
|
||||
namespace := item.Namespace
|
||||
ip := "-"
|
||||
tls := "-"
|
||||
createTime := item.CreationTimestamp.Time
|
||||
if createTime.IsZero() {
|
||||
createTime = time.Now()
|
||||
}
|
||||
|
||||
var ipList []string
|
||||
for _, lb := range item.Status.LoadBalancer.Ingress {
|
||||
if len(lb.IP) > 0 {
|
||||
ipList = append(ipList, lb.IP)
|
||||
}
|
||||
}
|
||||
if len(ipList) > 0 {
|
||||
ip = strings.Join(ipList, ",")
|
||||
}
|
||||
|
||||
annotation, _ := json.Marshal(item.Annotations)
|
||||
object := &Ingress{Namespace: namespace, Name: name, TlsTermination: tls, Ip: ip, CreateTime: createTime, AnnotationStr: string(annotation)}
|
||||
|
||||
return object
|
||||
}
|
||||
|
||||
func (ctl *IngressCtl) listAndWatch() {
|
||||
defer func() {
|
||||
defer close(ctl.aliveChan)
|
||||
if err := recover(); err != nil {
|
||||
glog.Error(err)
|
||||
return
|
||||
}
|
||||
}()
|
||||
|
||||
db := ctl.DB
|
||||
|
||||
if db.HasTable(&Ingress{}) {
|
||||
db.DropTable(&Ingress{})
|
||||
|
||||
}
|
||||
|
||||
db = db.CreateTable(&Ingress{})
|
||||
|
||||
k8sClient := client.NewK8sClient()
|
||||
list, err := k8sClient.ExtensionsV1beta1().Ingresses("").List(metaV1.ListOptions{})
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
for _, item := range list.Items {
|
||||
obj := ctl.generateObject(item)
|
||||
db.Create(obj)
|
||||
}
|
||||
|
||||
watcher, err := k8sClient.ExtensionsV1beta1().Ingresses("").Watch(metaV1.ListOptions{})
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ctl.stopChan:
|
||||
return
|
||||
case event := <-watcher.ResultChan():
|
||||
var ing Ingress
|
||||
if event.Object == nil {
|
||||
break
|
||||
}
|
||||
object := event.Object.(*v1beta1.Ingress)
|
||||
if event.Type == watch.Deleted {
|
||||
db.Where("name=? And namespace=?", object.Name, object.Namespace).Find(&ing)
|
||||
db.Delete(ing)
|
||||
break
|
||||
}
|
||||
obj := ctl.generateObject(*object)
|
||||
db.Save(obj)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (ctl *IngressCtl) CountWithConditions(conditions string) int {
|
||||
var object Ingress
|
||||
|
||||
return countWithConditions(ctl.DB, conditions, &object)
|
||||
}
|
||||
|
||||
func (ctl *IngressCtl) ListWithConditions(conditions string, paging *Paging) (int, interface{}, error) {
|
||||
var list []Ingress
|
||||
var object Ingress
|
||||
var total int
|
||||
|
||||
order := "createTime desc"
|
||||
|
||||
listWithConditions(ctl.DB, &total, &object, &list, conditions, paging, order)
|
||||
|
||||
for index, item := range list {
|
||||
annotation := make(map[string]string)
|
||||
json.Unmarshal([]byte(item.AnnotationStr), &annotation)
|
||||
list[index].Annotation = annotation
|
||||
list[index].AnnotationStr = ""
|
||||
}
|
||||
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
|
||||
}
|
||||
310
pkg/models/controllers/namespaces.go
Normal file
310
pkg/models/controllers/namespaces.go
Normal file
@@ -0,0 +1,310 @@
|
||||
/*
|
||||
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"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/api/core/v1"
|
||||
rbac "k8s.io/api/rbac/v1"
|
||||
metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/client"
|
||||
"kubesphere.io/kubesphere/pkg/options"
|
||||
)
|
||||
|
||||
const (
|
||||
provider = "kubernetes"
|
||||
admin = "admin"
|
||||
normal = "normal"
|
||||
view = "view"
|
||||
kubectlNamespace = "kubesphere"
|
||||
kubectlConfigKey = "config"
|
||||
)
|
||||
|
||||
var adminRules = []rbac.PolicyRule{rbac.PolicyRule{Verbs: []string{"*"}, APIGroups: []string{"*"}, Resources: []string{"*"}}}
|
||||
var normalRules = []rbac.PolicyRule{rbac.PolicyRule{Verbs: []string{"*"}, APIGroups: []string{"", "apps", "extensions"}, Resources: []string{"*"}}}
|
||||
var viewRules = []rbac.PolicyRule{rbac.PolicyRule{Verbs: []string{"list", "get"}, APIGroups: []string{"", "apps", "extensions"}, Resources: []string{"*"}}}
|
||||
|
||||
type runTime struct {
|
||||
RuntimeId string `json:"runtime_id"`
|
||||
RuntimeUrl string `json:"runtime_url"`
|
||||
Name string `json:"name"`
|
||||
Provider string `json:"provider"`
|
||||
Zone string `json:"zone"`
|
||||
RuntimeCredential string `json:"runtime_credential"`
|
||||
}
|
||||
|
||||
type DeleteRunTime struct {
|
||||
RuntimeId []string `json:"runtime_id"`
|
||||
}
|
||||
|
||||
func makeHttpRequest(method, url, data string) ([]byte, error) {
|
||||
req, err := http.NewRequest(method, url, strings.NewReader(data))
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
httpClient := &http.Client{}
|
||||
resp, err := httpClient.Do(req)
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
glog.Error(string(body))
|
||||
defer resp.Body.Close()
|
||||
return body, nil
|
||||
}
|
||||
|
||||
func (ctl *NamespaceCtl) getKubeConfig(user string) (string, error) {
|
||||
k8sClient := client.NewK8sClient()
|
||||
configmap, err := k8sClient.CoreV1().ConfigMaps(kubectlNamespace).Get(user, metaV1.GetOptions{})
|
||||
if err != nil {
|
||||
glog.Errorln(err)
|
||||
return "", err
|
||||
}
|
||||
return configmap.Data[kubectlConfigKey], nil
|
||||
}
|
||||
|
||||
func (ctl *NamespaceCtl) deleteOpRuntime(item v1.Namespace) {
|
||||
|
||||
runtimeId := item.Annotations["openpitrix_runtime"]
|
||||
if len(runtimeId) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
url := options.ServerOptions.GetOpAddress() + "/v1/runtimes"
|
||||
|
||||
var deleteRuntime = DeleteRunTime{RuntimeId: []string{runtimeId}}
|
||||
|
||||
body, err := json.Marshal(deleteRuntime)
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
// todo: if delete failed, what's to be done?
|
||||
makeHttpRequest("DELETE", url, string(body))
|
||||
}
|
||||
|
||||
func (ctl *NamespaceCtl) createOpRuntime(namespace, user string) ([]byte, error) {
|
||||
zone := namespace
|
||||
name := namespace
|
||||
kubeConfig, err := ctl.getKubeConfig(user)
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
url := options.ServerOptions.GetOpAddress() + "/v1/runtimes"
|
||||
|
||||
option := runTime{Name: name, Provider: provider, RuntimeCredential: kubeConfig, Zone: zone}
|
||||
body, err := json.Marshal(option)
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return makeHttpRequest("POST", url, string(body))
|
||||
}
|
||||
|
||||
func (ctl *NamespaceCtl) createDefaultRole(ns string) error {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
glog.Error(err)
|
||||
}
|
||||
}()
|
||||
|
||||
adminRole := &rbac.Role{ObjectMeta: metaV1.ObjectMeta{Name: admin, Namespace: ns}, Rules: adminRules}
|
||||
normalRole := &rbac.Role{ObjectMeta: metaV1.ObjectMeta{Name: normal, Namespace: ns}, Rules: normalRules}
|
||||
viewRole := &rbac.Role{ObjectMeta: metaV1.ObjectMeta{Name: view, Namespace: ns}, Rules: viewRules}
|
||||
|
||||
role, _ := ctl.K8sClient.RbacV1().Roles(ns).Get(admin, metaV1.GetOptions{})
|
||||
|
||||
if role.Name != admin {
|
||||
_, err := ctl.K8sClient.RbacV1().Roles(ns).Create(adminRole)
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
role, _ = ctl.K8sClient.RbacV1().Roles(ns).Get(normal, metaV1.GetOptions{})
|
||||
|
||||
if role.Name != normal {
|
||||
_, err := ctl.K8sClient.RbacV1().Roles(ns).Create(normalRole)
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
role, _ = ctl.K8sClient.RbacV1().Roles(ns).Get(view, metaV1.GetOptions{})
|
||||
|
||||
if role.Name != view {
|
||||
_, err := ctl.K8sClient.RbacV1().Roles(ns).Create(viewRole)
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ctl *NamespaceCtl) createRoleAndRuntime(item v1.Namespace) {
|
||||
user := item.Annotations["creator"]
|
||||
ns := item.Name
|
||||
if len(user) > 0 && len(item.Annotations["openpitrix_runtime"]) == 0 {
|
||||
err := ctl.createDefaultRole(ns)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
resp, err := ctl.createOpRuntime(ns, user)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var runtime runTime
|
||||
err = json.Unmarshal(resp, &runtime)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
item.Annotations["openpitrix_runtime"] = runtime.RuntimeId
|
||||
ctl.K8sClient.CoreV1().Namespaces().Update(&item)
|
||||
}
|
||||
}
|
||||
|
||||
func (ctl *NamespaceCtl) generateObject(item v1.Namespace) *Namespace {
|
||||
|
||||
name := item.Name
|
||||
createTime := item.CreationTimestamp.Time
|
||||
status := fmt.Sprintf("%v", item.Status.Phase)
|
||||
|
||||
if createTime.IsZero() {
|
||||
createTime = time.Now()
|
||||
}
|
||||
|
||||
annotation, _ := json.Marshal(item.Annotations)
|
||||
object := &Namespace{Name: name, CreateTime: createTime, Status: status, AnnotationStr: string(annotation)}
|
||||
|
||||
return object
|
||||
}
|
||||
|
||||
func (ctl *NamespaceCtl) listAndWatch() {
|
||||
defer func() {
|
||||
defer close(ctl.aliveChan)
|
||||
if err := recover(); err != nil {
|
||||
glog.Error(err)
|
||||
return
|
||||
}
|
||||
}()
|
||||
|
||||
db := ctl.DB
|
||||
|
||||
if db.HasTable(&Namespace{}) {
|
||||
db.DropTable(&Namespace{})
|
||||
}
|
||||
|
||||
db = db.CreateTable(&Namespace{})
|
||||
|
||||
k8sClient := client.NewK8sClient()
|
||||
list, err := k8sClient.CoreV1().Namespaces().List(metaV1.ListOptions{})
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
for _, item := range list.Items {
|
||||
obj := ctl.generateObject(item)
|
||||
db.Create(obj)
|
||||
|
||||
ctl.createRoleAndRuntime(item)
|
||||
}
|
||||
|
||||
watcher, err := k8sClient.CoreV1().Namespaces().Watch(metaV1.ListOptions{})
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ctl.stopChan:
|
||||
return
|
||||
case event := <-watcher.ResultChan():
|
||||
var ns Namespace
|
||||
if event.Object == nil {
|
||||
break
|
||||
}
|
||||
object := event.Object.(*v1.Namespace)
|
||||
if event.Type == watch.Deleted {
|
||||
db.Where("name=?", object.Name).Find(&ns)
|
||||
db.Delete(ns)
|
||||
|
||||
ctl.deleteOpRuntime(*object)
|
||||
break
|
||||
}
|
||||
|
||||
ctl.createRoleAndRuntime(*object)
|
||||
|
||||
obj := ctl.generateObject(*object)
|
||||
db.Save(obj)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (ctl *NamespaceCtl) CountWithConditions(conditions string) int {
|
||||
var object Namespace
|
||||
|
||||
return countWithConditions(ctl.DB, conditions, &object)
|
||||
}
|
||||
|
||||
func (ctl *NamespaceCtl) ListWithConditions(conditions string, paging *Paging) (int, interface{}, error) {
|
||||
var list []Namespace
|
||||
var object Namespace
|
||||
var total int
|
||||
|
||||
order := "createTime desc"
|
||||
|
||||
listWithConditions(ctl.DB, &total, &object, &list, conditions, paging, order)
|
||||
|
||||
for index, item := range list {
|
||||
annotation := make(map[string]string)
|
||||
json.Unmarshal([]byte(item.AnnotationStr), &annotation)
|
||||
list[index].Annotation = annotation
|
||||
list[index].AnnotationStr = ""
|
||||
}
|
||||
return total, list, nil
|
||||
}
|
||||
|
||||
func (ctl *NamespaceCtl) Count(namespace string) int {
|
||||
var count int
|
||||
db := ctl.DB
|
||||
db.Model(&Namespace{}).Count(&count)
|
||||
return count
|
||||
}
|
||||
161
pkg/models/controllers/pods.go
Normal file
161
pkg/models/controllers/pods.go
Normal file
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
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"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/api/core/v1"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/client"
|
||||
)
|
||||
|
||||
func (ctl *PodCtl) generateObject(item v1.Pod) *Pod {
|
||||
name := item.Name
|
||||
namespace := item.Namespace
|
||||
podIp := item.Status.PodIP
|
||||
nodeName := item.Spec.NodeName
|
||||
nodeIp := item.Status.HostIP
|
||||
status := string(item.Status.Phase)
|
||||
createTime := item.CreationTimestamp.Time
|
||||
containerStatus := item.Status.ContainerStatuses
|
||||
containerSpecs := item.Spec.Containers
|
||||
var containers []Container
|
||||
|
||||
for _, containerSpec := range containerSpecs {
|
||||
var container Container
|
||||
container.Name = containerSpec.Name
|
||||
container.Image = containerSpec.Image
|
||||
container.Ports = containerSpec.Ports
|
||||
for _, status := range containerStatus {
|
||||
if container.Name == status.Name {
|
||||
container.Ready = status.Ready
|
||||
}
|
||||
}
|
||||
|
||||
containers = append(containers, container)
|
||||
}
|
||||
|
||||
containerStr, _ := json.Marshal(containers)
|
||||
|
||||
annotation, _ := json.Marshal(item.Annotations)
|
||||
|
||||
object := &Pod{Namespace: namespace, Name: name, Node: nodeName, PodIp: podIp, Status: status, NodeIp: nodeIp,
|
||||
CreateTime: createTime, ContainerStr: string(containerStr), AnnotationStr: string(annotation)}
|
||||
|
||||
return object
|
||||
}
|
||||
|
||||
func (ctl *PodCtl) listAndWatch() {
|
||||
defer func() {
|
||||
defer close(ctl.aliveChan)
|
||||
if err := recover(); err != nil {
|
||||
glog.Error(err)
|
||||
return
|
||||
}
|
||||
}()
|
||||
|
||||
db := ctl.DB
|
||||
|
||||
if db.HasTable(&Pod{}) {
|
||||
db.DropTable(&Pod{})
|
||||
|
||||
}
|
||||
|
||||
db = db.CreateTable(&Pod{})
|
||||
|
||||
k8sClient := client.NewK8sClient()
|
||||
list, err := k8sClient.CoreV1().Pods("").List(meta_v1.ListOptions{})
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
for _, item := range list.Items {
|
||||
obj := ctl.generateObject(item)
|
||||
db.Create(obj)
|
||||
}
|
||||
|
||||
watcher, err := k8sClient.CoreV1().Pods("").Watch(meta_v1.ListOptions{})
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ctl.stopChan:
|
||||
return
|
||||
case event := <-watcher.ResultChan():
|
||||
var po Pod
|
||||
if event.Object == nil {
|
||||
break
|
||||
}
|
||||
object := event.Object.(*v1.Pod)
|
||||
if event.Type == watch.Deleted {
|
||||
db.Where("name=? And namespace=?", object.Name, object.Namespace).Find(&po)
|
||||
db.Delete(po)
|
||||
break
|
||||
}
|
||||
obj := ctl.generateObject(*object)
|
||||
db.Save(obj)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (ctl *PodCtl) CountWithConditions(conditions string) int {
|
||||
var object Pod
|
||||
|
||||
return countWithConditions(ctl.DB, conditions, &object)
|
||||
}
|
||||
|
||||
func (ctl *PodCtl) ListWithConditions(conditions string, paging *Paging) (int, interface{}, error) {
|
||||
var list []Pod
|
||||
var object Pod
|
||||
var total int
|
||||
|
||||
order := "createTime desc"
|
||||
|
||||
listWithConditions(ctl.DB, &total, &object, &list, conditions, paging, order)
|
||||
|
||||
for index, item := range list {
|
||||
var containers []Container
|
||||
json.Unmarshal([]byte(item.ContainerStr), &containers)
|
||||
list[index].Containers = containers
|
||||
list[index].ContainerStr = ""
|
||||
|
||||
annotation := make(Annotation)
|
||||
json.Unmarshal([]byte(item.AnnotationStr), &annotation)
|
||||
list[index].Annotation = annotation
|
||||
list[index].AnnotationStr = ""
|
||||
}
|
||||
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
|
||||
}
|
||||
162
pkg/models/controllers/pvcs.go
Normal file
162
pkg/models/controllers/pvcs.go
Normal 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 (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/api/core/v1"
|
||||
metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/client"
|
||||
)
|
||||
|
||||
const creator = "creator"
|
||||
|
||||
func (ctl *PvcCtl) generateObject(item *v1.PersistentVolumeClaim) *Pvc {
|
||||
name := item.Name
|
||||
namespace := item.Namespace
|
||||
status := fmt.Sprintf("%s", item.Status.Phase)
|
||||
createTime := item.CreationTimestamp.Time
|
||||
capacity := "-"
|
||||
|
||||
if createTime.IsZero() {
|
||||
createTime = time.Now()
|
||||
}
|
||||
|
||||
if storage, exist := item.Status.Capacity["storage"]; exist {
|
||||
capacity = storage.String()
|
||||
}
|
||||
|
||||
storageClass := "-"
|
||||
if item.Spec.StorageClassName != nil {
|
||||
storageClass = *item.Spec.StorageClassName
|
||||
}
|
||||
|
||||
accessModeStr := "-"
|
||||
|
||||
var accessModeList []string
|
||||
for _, accessMode := range item.Status.AccessModes {
|
||||
accessModeList = append(accessModeList, string(accessMode))
|
||||
}
|
||||
|
||||
accessModeStr = strings.Join(accessModeList, ",")
|
||||
annotation, _ := json.Marshal(item.Annotations)
|
||||
|
||||
object := &Pvc{Namespace: namespace, Name: name, Status: status, Capacity: capacity,
|
||||
AccessMode: accessModeStr, StorageClassName: storageClass, CreateTime: createTime, AnnotationStr: string(annotation)}
|
||||
|
||||
return object
|
||||
}
|
||||
|
||||
func (ctl *PvcCtl) listAndWatch() {
|
||||
defer func() {
|
||||
defer close(ctl.aliveChan)
|
||||
if err := recover(); err != nil {
|
||||
glog.Error(err)
|
||||
return
|
||||
}
|
||||
}()
|
||||
|
||||
db := ctl.DB
|
||||
|
||||
if db.HasTable(&Pvc{}) {
|
||||
db.DropTable(&Pvc{})
|
||||
|
||||
}
|
||||
|
||||
db = db.CreateTable(&Pvc{})
|
||||
|
||||
k8sClient := client.NewK8sClient()
|
||||
pvcList, err := k8sClient.CoreV1().PersistentVolumeClaims("").List(metaV1.ListOptions{})
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
for _, item := range pvcList.Items {
|
||||
obj := ctl.generateObject(&item)
|
||||
db.Create(obj)
|
||||
}
|
||||
|
||||
watcher, err := k8sClient.CoreV1().PersistentVolumeClaims("").Watch(metaV1.ListOptions{})
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ctl.stopChan:
|
||||
return
|
||||
case event := <-watcher.ResultChan():
|
||||
var pvc Pvc
|
||||
if event.Object == nil {
|
||||
break
|
||||
}
|
||||
object := event.Object.(*v1.PersistentVolumeClaim)
|
||||
if event.Type == watch.Deleted {
|
||||
db.Where("name=? And namespace=?", object.Name, object.Namespace).Find(&pvc)
|
||||
db.Delete(pvc)
|
||||
break
|
||||
}
|
||||
obj := ctl.generateObject(object)
|
||||
db.Save(obj)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (ctl *PvcCtl) CountWithConditions(conditions string) int {
|
||||
var object Pvc
|
||||
|
||||
return countWithConditions(ctl.DB, conditions, &object)
|
||||
}
|
||||
|
||||
func (ctl *PvcCtl) ListWithConditions(conditions string, paging *Paging) (int, interface{}, error) {
|
||||
var list []Pvc
|
||||
var object Pvc
|
||||
var total int
|
||||
|
||||
order := "createTime desc"
|
||||
|
||||
listWithConditions(ctl.DB, &total, &object, &list, conditions, paging, order)
|
||||
|
||||
for index, item := range list {
|
||||
annotation := make(map[string]string)
|
||||
json.Unmarshal([]byte(item.AnnotationStr), &annotation)
|
||||
list[index].Annotation = annotation
|
||||
list[index].AnnotationStr = ""
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
142
pkg/models/controllers/roles.go
Normal file
142
pkg/models/controllers/roles.go
Normal file
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
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"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/api/rbac/v1"
|
||||
metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/client"
|
||||
)
|
||||
|
||||
func (ctl *RoleCtl) generateObject(item v1.Role) *Role {
|
||||
name := item.Name
|
||||
if strings.HasPrefix(name, "system:") {
|
||||
return nil
|
||||
}
|
||||
namespace := item.Namespace
|
||||
createTime := item.CreationTimestamp.Time
|
||||
if createTime.IsZero() {
|
||||
createTime = time.Now()
|
||||
}
|
||||
|
||||
annotation, _ := json.Marshal(item.Annotations)
|
||||
|
||||
object := &Role{Namespace: namespace, Name: name, CreateTime: createTime, AnnotationStr: string(annotation)}
|
||||
|
||||
return object
|
||||
}
|
||||
|
||||
func (ctl *RoleCtl) listAndWatch() {
|
||||
defer func() {
|
||||
close(ctl.aliveChan)
|
||||
if err := recover(); err != nil {
|
||||
glog.Error(err)
|
||||
return
|
||||
}
|
||||
}()
|
||||
|
||||
db := ctl.DB
|
||||
|
||||
if db.HasTable(&Role{}) {
|
||||
db.DropTable(&Role{})
|
||||
|
||||
}
|
||||
|
||||
db = db.CreateTable(&Role{})
|
||||
|
||||
k8sClient := client.NewK8sClient()
|
||||
roleList, err := k8sClient.RbacV1().Roles("").List(metaV1.ListOptions{})
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
for _, item := range roleList.Items {
|
||||
obj := ctl.generateObject(item)
|
||||
if obj != nil {
|
||||
db.Create(obj)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
roleWatcher, err := k8sClient.RbacV1().Roles("").Watch(metaV1.ListOptions{})
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ctl.stopChan:
|
||||
return
|
||||
case event := <-roleWatcher.ResultChan():
|
||||
var role Role
|
||||
object := event.Object.(*v1.Role)
|
||||
if event.Object == nil {
|
||||
break
|
||||
}
|
||||
if event.Type == watch.Deleted {
|
||||
db.Where("name=? And namespace=?", object.Name, object.Namespace).Find(&role)
|
||||
db.Delete(role)
|
||||
break
|
||||
}
|
||||
obj := ctl.generateObject(*object)
|
||||
if obj != nil {
|
||||
db.Save(obj)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (ctl *RoleCtl) CountWithConditions(conditions string) int {
|
||||
var object Role
|
||||
|
||||
return countWithConditions(ctl.DB, conditions, &object)
|
||||
}
|
||||
|
||||
func (ctl *RoleCtl) ListWithConditions(conditions string, paging *Paging) (int, interface{}, error) {
|
||||
var list []Role
|
||||
var object Role
|
||||
var total int
|
||||
|
||||
order := "createTime desc"
|
||||
|
||||
listWithConditions(ctl.DB, &total, &object, &list, conditions, paging, order)
|
||||
|
||||
for index, item := range list {
|
||||
annotation := make(map[string]string)
|
||||
json.Unmarshal([]byte(item.AnnotationStr), &annotation)
|
||||
list[index].Annotation = annotation
|
||||
list[index].AnnotationStr = ""
|
||||
}
|
||||
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
|
||||
}
|
||||
100
pkg/models/controllers/run.go
Normal file
100
pkg/models/controllers/run.go
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
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"
|
||||
"github.com/jinzhu/gorm"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/client"
|
||||
)
|
||||
|
||||
type resourceControllers struct {
|
||||
controllers map[string]Controller
|
||||
db *gorm.DB
|
||||
k8sClient *kubernetes.Clientset
|
||||
}
|
||||
|
||||
var stopChan chan struct{}
|
||||
|
||||
func (rec *resourceControllers) runContoller(name string) {
|
||||
var ctl Controller
|
||||
attr := CommonAttribute{DB: rec.db, K8sClient: rec.k8sClient, stopChan: stopChan, aliveChan: make(chan struct{})}
|
||||
switch name {
|
||||
case Deployments:
|
||||
ctl = &DeploymentCtl{attr}
|
||||
case Statefulsets:
|
||||
ctl = &StatefulsetCtl{attr}
|
||||
case Daemonsets:
|
||||
ctl = &DaemonsetCtl{attr}
|
||||
case Ingresses:
|
||||
ctl = &IngressCtl{attr}
|
||||
case PersistentVolumeClaim:
|
||||
ctl = &PvcCtl{attr}
|
||||
case Roles:
|
||||
ctl = &RoleCtl{attr}
|
||||
case ClusterRoles:
|
||||
ctl = &ClusterRoleCtl{attr}
|
||||
case Services:
|
||||
ctl = &ServiceCtl{attr}
|
||||
case Pods:
|
||||
ctl = &PodCtl{attr}
|
||||
case Namespaces:
|
||||
ctl = &NamespaceCtl{attr}
|
||||
case StorageClasses:
|
||||
ctl = &StorageClassCtl{attr}
|
||||
default:
|
||||
return
|
||||
}
|
||||
|
||||
rec.controllers[name] = ctl
|
||||
go ctl.listAndWatch()
|
||||
|
||||
}
|
||||
|
||||
func Run() {
|
||||
db := client.NewDBClient()
|
||||
|
||||
stopChan := make(chan struct{})
|
||||
defer db.Commit()
|
||||
defer db.Close()
|
||||
defer close(stopChan)
|
||||
|
||||
rec := resourceControllers{k8sClient: client.NewK8sClient(), db: db, controllers: make(map[string]Controller)}
|
||||
|
||||
for _, item := range []string{Deployments, Statefulsets, Daemonsets, PersistentVolumeClaim, Pods, Services,
|
||||
Ingresses, Roles, ClusterRoles, Namespaces, StorageClasses} {
|
||||
rec.runContoller(item)
|
||||
}
|
||||
|
||||
for {
|
||||
for ctlName, controller := range rec.controllers {
|
||||
select {
|
||||
case _, isClose := <-controller.chanAlive():
|
||||
if !isClose {
|
||||
glog.Errorf("controller %s have stopped, restart it", ctlName)
|
||||
rec.runContoller(ctlName)
|
||||
}
|
||||
default:
|
||||
time.Sleep(5 * time.Second)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
218
pkg/models/controllers/services.go
Normal file
218
pkg/models/controllers/services.go
Normal file
@@ -0,0 +1,218 @@
|
||||
/*
|
||||
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"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/api/core/v1"
|
||||
metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/client"
|
||||
)
|
||||
|
||||
const (
|
||||
headlessSelector = "Headless(Selector)"
|
||||
headlessExternal = "Headless(ExternalName)"
|
||||
virtualIp = "Virtual IP"
|
||||
)
|
||||
|
||||
func (ctl *ServiceCtl) loadBalancerStatusStringer(item v1.Service) string {
|
||||
ingress := item.Status.LoadBalancer.Ingress
|
||||
result := sets.NewString()
|
||||
for i := range ingress {
|
||||
if ingress[i].IP != "" {
|
||||
result.Insert(ingress[i].IP)
|
||||
} else if ingress[i].Hostname != "" {
|
||||
result.Insert(ingress[i].Hostname)
|
||||
}
|
||||
}
|
||||
|
||||
r := strings.Join(result.List(), ",")
|
||||
return r
|
||||
}
|
||||
|
||||
func (ctl *ServiceCtl) getExternalIp(item v1.Service) string {
|
||||
switch item.Spec.Type {
|
||||
case "ClusterIP", "NodePort":
|
||||
if len(item.Spec.ExternalIPs) > 0 {
|
||||
return strings.Join(item.Spec.ExternalIPs, ",")
|
||||
}
|
||||
case "ExternalName":
|
||||
return item.Spec.ExternalName
|
||||
|
||||
case "LoadBalancer":
|
||||
lbIps := ctl.loadBalancerStatusStringer(item)
|
||||
if len(item.Spec.ExternalIPs) > 0 {
|
||||
results := []string{}
|
||||
if len(lbIps) > 0 {
|
||||
results = append(results, strings.Split(lbIps, ",")...)
|
||||
}
|
||||
results = append(results, item.Spec.ExternalIPs...)
|
||||
return strings.Join(results, ",")
|
||||
}
|
||||
if len(lbIps) > 0 {
|
||||
return lbIps
|
||||
}
|
||||
return "<pending>"
|
||||
}
|
||||
return "-"
|
||||
}
|
||||
|
||||
func (ctl *ServiceCtl) generateObject(item v1.Service) *Service {
|
||||
|
||||
name := item.Name
|
||||
namespace := item.Namespace
|
||||
createTime := item.CreationTimestamp.Time
|
||||
externalIp := ctl.getExternalIp(item)
|
||||
serviceType := virtualIp
|
||||
vip := item.Spec.ClusterIP
|
||||
ports := ""
|
||||
|
||||
if createTime.IsZero() {
|
||||
createTime = time.Now()
|
||||
}
|
||||
|
||||
if item.Spec.ClusterIP == "None" {
|
||||
serviceType = headlessSelector
|
||||
vip = "-"
|
||||
}
|
||||
|
||||
if len(item.Spec.ExternalName) > 0 {
|
||||
serviceType = headlessExternal
|
||||
vip = "-"
|
||||
}
|
||||
|
||||
if len(item.Spec.ExternalIPs) > 0 {
|
||||
externalIp = strings.Join(item.Spec.ExternalIPs, ",")
|
||||
}
|
||||
|
||||
for _, portItem := range item.Spec.Ports {
|
||||
port := portItem.Port
|
||||
targetPort := portItem.TargetPort.String()
|
||||
protocol := portItem.Protocol
|
||||
ports += fmt.Sprintf("%d:%s/%s,", port, targetPort, protocol)
|
||||
}
|
||||
if len(ports) == 0 {
|
||||
ports = "-"
|
||||
} else {
|
||||
ports = ports[0 : len(ports)-1]
|
||||
}
|
||||
|
||||
annotation, _ := json.Marshal(item.Annotations)
|
||||
object := &Service{Namespace: namespace, Name: name, ServiceType: serviceType, ExternalIp: externalIp,
|
||||
VirtualIp: vip, CreateTime: createTime, Ports: ports, AnnotationStr: string(annotation)}
|
||||
|
||||
return object
|
||||
}
|
||||
|
||||
func (ctl *ServiceCtl) listAndWatch() {
|
||||
defer func() {
|
||||
defer close(ctl.aliveChan)
|
||||
if err := recover(); err != nil {
|
||||
glog.Error(err)
|
||||
return
|
||||
}
|
||||
}()
|
||||
|
||||
db := ctl.DB
|
||||
|
||||
if db.HasTable(&Service{}) {
|
||||
db.DropTable(&Service{})
|
||||
}
|
||||
|
||||
db = db.CreateTable(&Service{})
|
||||
|
||||
k8sClient := client.NewK8sClient()
|
||||
svcList, err := k8sClient.CoreV1().Services("").List(metaV1.ListOptions{})
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
for _, item := range svcList.Items {
|
||||
obj := ctl.generateObject(item)
|
||||
db.Create(obj)
|
||||
}
|
||||
|
||||
watcher, err := k8sClient.CoreV1().Services("").Watch(metaV1.ListOptions{})
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ctl.stopChan:
|
||||
return
|
||||
case event := <-watcher.ResultChan():
|
||||
var svc Service
|
||||
object := event.Object.(*v1.Service)
|
||||
if event.Object == nil {
|
||||
break
|
||||
}
|
||||
if event.Type == watch.Deleted {
|
||||
db.Where("name=? And namespace=?", object.Name, object.Namespace).Find(&svc)
|
||||
db.Delete(svc)
|
||||
break
|
||||
}
|
||||
obj := ctl.generateObject(*object)
|
||||
db.Save(obj)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (ctl *ServiceCtl) CountWithConditions(conditions string) int {
|
||||
var object Service
|
||||
|
||||
return countWithConditions(ctl.DB, conditions, &object)
|
||||
}
|
||||
|
||||
func (ctl *ServiceCtl) ListWithConditions(conditions string, paging *Paging) (int, interface{}, error) {
|
||||
var list []Service
|
||||
var object Service
|
||||
var total int
|
||||
|
||||
order := "createTime desc"
|
||||
|
||||
listWithConditions(ctl.DB, &total, &object, &list, conditions, paging, order)
|
||||
|
||||
for index, item := range list {
|
||||
annotation := make(map[string]string)
|
||||
json.Unmarshal([]byte(item.AnnotationStr), &annotation)
|
||||
list[index].Annotation = annotation
|
||||
list[index].AnnotationStr = ""
|
||||
}
|
||||
return total, list, nil
|
||||
}
|
||||
|
||||
func (ctl *ServiceCtl) Count(namespace string) int {
|
||||
var count int
|
||||
db := ctl.DB
|
||||
if len(namespace) == 0 {
|
||||
db.Model(&Service{}).Count(&count)
|
||||
} else {
|
||||
db.Model(&Service{}).Where("namespace = ?", namespace).Count(&count)
|
||||
}
|
||||
return count
|
||||
}
|
||||
156
pkg/models/controllers/statefulsets.go
Normal file
156
pkg/models/controllers/statefulsets.go
Normal file
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
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"
|
||||
"time"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/api/apps/v1beta2"
|
||||
metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/client"
|
||||
)
|
||||
|
||||
func (ctl *StatefulsetCtl) generateObject(item v1beta2.StatefulSet) *Statefulset {
|
||||
var app string
|
||||
var status string
|
||||
name := item.Name
|
||||
namespace := item.Namespace
|
||||
availablePodNum := item.Status.ReadyReplicas
|
||||
desirePodNum := *item.Spec.Replicas
|
||||
createTime := item.CreationTimestamp.Time
|
||||
release := item.ObjectMeta.Labels["release"]
|
||||
chart := item.ObjectMeta.Labels["chart"]
|
||||
|
||||
if createTime.IsZero() {
|
||||
createTime = time.Now()
|
||||
}
|
||||
|
||||
if len(release) > 0 && len(chart) > 0 {
|
||||
app = release + "/" + chart
|
||||
} else {
|
||||
app = "-"
|
||||
}
|
||||
|
||||
if item.Annotations["state"] == "stop" {
|
||||
status = stopping
|
||||
} else {
|
||||
if availablePodNum >= desirePodNum {
|
||||
status = running
|
||||
} else {
|
||||
status = updating
|
||||
}
|
||||
}
|
||||
|
||||
annotation, _ := json.Marshal(item.Annotations)
|
||||
|
||||
statefulSetObject := &Statefulset{Namespace: namespace, Name: name, Available: availablePodNum, Desire: desirePodNum,
|
||||
App: app, CreateTime: createTime, Status: status, AnnotationStr: string(annotation)}
|
||||
|
||||
return statefulSetObject
|
||||
}
|
||||
|
||||
func (ctl *StatefulsetCtl) listAndWatch() {
|
||||
defer func() {
|
||||
defer close(ctl.aliveChan)
|
||||
if err := recover(); err != nil {
|
||||
glog.Error(err)
|
||||
return
|
||||
}
|
||||
}()
|
||||
|
||||
db := ctl.DB
|
||||
if db.HasTable(&Statefulset{}) {
|
||||
db.DropTable(&Statefulset{})
|
||||
}
|
||||
|
||||
db = db.CreateTable(&Statefulset{})
|
||||
k8sClient := client.NewK8sClient()
|
||||
deoloyList, err := k8sClient.AppsV1beta2().StatefulSets("").List(metaV1.ListOptions{})
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
}
|
||||
|
||||
for _, item := range deoloyList.Items {
|
||||
obj := ctl.generateObject(item)
|
||||
db.Create(obj)
|
||||
}
|
||||
|
||||
watcher, err := k8sClient.AppsV1beta2().StatefulSets("").Watch(metaV1.ListOptions{})
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ctl.stopChan:
|
||||
return
|
||||
case event := <-watcher.ResultChan():
|
||||
var tmp Statefulset
|
||||
if event.Object == nil {
|
||||
break
|
||||
}
|
||||
object := event.Object.(*v1beta2.StatefulSet)
|
||||
if event.Type == watch.Deleted {
|
||||
db.Where("name=? And namespace=?", object.Name, object.Namespace).Find(&tmp)
|
||||
db.Delete(tmp)
|
||||
break
|
||||
}
|
||||
obj := ctl.generateObject(*object)
|
||||
db.Save(obj)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (ctl *StatefulsetCtl) CountWithConditions(conditions string) int {
|
||||
var object Statefulset
|
||||
|
||||
return countWithConditions(ctl.DB, conditions, &object)
|
||||
}
|
||||
|
||||
func (ctl *StatefulsetCtl) ListWithConditions(conditions string, paging *Paging) (int, interface{}, error) {
|
||||
var list []Statefulset
|
||||
var object Statefulset
|
||||
var total int
|
||||
|
||||
order := "createTime desc"
|
||||
|
||||
listWithConditions(ctl.DB, &total, &object, &list, conditions, paging, order)
|
||||
|
||||
for index, item := range list {
|
||||
annotation := make(map[string]string)
|
||||
json.Unmarshal([]byte(item.AnnotationStr), &annotation)
|
||||
list[index].Annotation = annotation
|
||||
list[index].AnnotationStr = ""
|
||||
}
|
||||
return total, list, nil
|
||||
}
|
||||
|
||||
func (ctl *StatefulsetCtl) Count(namespace string) int {
|
||||
var count int
|
||||
db := ctl.DB
|
||||
if len(namespace) == 0 {
|
||||
db.Model(&Statefulset{}).Count(&count)
|
||||
} else {
|
||||
db.Model(&Statefulset{}).Where("namespace = ?", namespace).Count(&count)
|
||||
}
|
||||
return count
|
||||
}
|
||||
141
pkg/models/controllers/storageclasses.go
Normal file
141
pkg/models/controllers/storageclasses.go
Normal file
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
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/storage/v1beta1"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/client"
|
||||
)
|
||||
|
||||
func (ctl *StorageClassCtl) generateObject(item v1beta1.StorageClass) *StorageClass {
|
||||
|
||||
name := item.Name
|
||||
createTime := item.CreationTimestamp.Time
|
||||
isDefault := false
|
||||
if item.Annotations["storageclass.beta.kubernetes.io/is-default-class"] == "true" {
|
||||
isDefault = true
|
||||
}
|
||||
|
||||
if createTime.IsZero() {
|
||||
createTime = time.Now()
|
||||
}
|
||||
|
||||
annotation, _ := json.Marshal(item.Annotations)
|
||||
object := &StorageClass{Name: name, CreateTime: createTime, IsDefault: isDefault, AnnotationStr: string(annotation)}
|
||||
|
||||
return object
|
||||
}
|
||||
|
||||
func (ctl *StorageClassCtl) listAndWatch() {
|
||||
defer func() {
|
||||
defer close(ctl.aliveChan)
|
||||
if err := recover(); err != nil {
|
||||
glog.Error(err)
|
||||
return
|
||||
}
|
||||
}()
|
||||
|
||||
db := ctl.DB
|
||||
|
||||
if db.HasTable(&StorageClass{}) {
|
||||
db.DropTable(&StorageClass{})
|
||||
}
|
||||
|
||||
db = db.CreateTable(&StorageClass{})
|
||||
|
||||
k8sClient := client.NewK8sClient()
|
||||
list, err := k8sClient.StorageV1beta1().StorageClasses().List(meta_v1.ListOptions{})
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
for _, item := range list.Items {
|
||||
obj := ctl.generateObject(item)
|
||||
db.Create(obj)
|
||||
}
|
||||
|
||||
watcher, err := k8sClient.StorageV1beta1().StorageClasses().Watch(meta_v1.ListOptions{})
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ctl.stopChan:
|
||||
return
|
||||
case event := <-watcher.ResultChan():
|
||||
var sc StorageClass
|
||||
if event.Object == nil {
|
||||
break
|
||||
}
|
||||
object := event.Object.(*v1beta1.StorageClass)
|
||||
if event.Type == watch.Deleted {
|
||||
db.Where("name=?", object.Name).Find(&sc)
|
||||
db.Delete(sc)
|
||||
break
|
||||
}
|
||||
obj := ctl.generateObject(*object)
|
||||
db.Save(obj)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (ctl *StorageClassCtl) CountWithConditions(conditions string) int {
|
||||
var object StorageClass
|
||||
|
||||
return countWithConditions(ctl.DB, conditions, &object)
|
||||
}
|
||||
|
||||
func (ctl *StorageClassCtl) ListWithConditions(conditions string, paging *Paging) (int, interface{}, error) {
|
||||
var list []StorageClass
|
||||
var object StorageClass
|
||||
var total int
|
||||
|
||||
order := "createTime desc"
|
||||
|
||||
listWithConditions(ctl.DB, &total, &object, &list, conditions, paging, order)
|
||||
|
||||
for index, storageClass := range list {
|
||||
name := storageClass.Name
|
||||
annotation := make(map[string]string)
|
||||
json.Unmarshal([]byte(storageClass.AnnotationStr), &annotation)
|
||||
list[index].Annotation = annotation
|
||||
list[index].AnnotationStr = ""
|
||||
pvcCtl := PvcCtl{CommonAttribute{K8sClient: ctl.K8sClient, DB: ctl.DB}}
|
||||
|
||||
list[index].Count = pvcCtl.CountWithConditions(fmt.Sprintf("storage_class=\"%s\"", name))
|
||||
}
|
||||
|
||||
return total, list, nil
|
||||
}
|
||||
|
||||
func (ctl *StorageClassCtl) Count(name string) int {
|
||||
var count int
|
||||
db := ctl.DB
|
||||
db.Model(&StorageClass{}).Count(&count)
|
||||
return count
|
||||
}
|
||||
361
pkg/models/controllers/types.go
Normal file
361
pkg/models/controllers/types.go
Normal file
@@ -0,0 +1,361 @@
|
||||
/*
|
||||
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/jinzhu/gorm"
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
)
|
||||
|
||||
const (
|
||||
stopping = "stopped"
|
||||
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"
|
||||
|
||||
Pods = "pods"
|
||||
Deployments = "deployments"
|
||||
Daemonsets = "daemonsets"
|
||||
Statefulsets = "statefulsets"
|
||||
Namespaces = "namespaces"
|
||||
Ingresses = "ingresses"
|
||||
PersistentVolumeClaim = "persistent-volume-claims"
|
||||
Roles = "roles"
|
||||
ClusterRoles = "cluster-roles"
|
||||
Services = "services"
|
||||
StorageClasses = "storage-classes"
|
||||
)
|
||||
|
||||
var ResourceTable = map[string]string{Deployments: tableDeployments, Statefulsets: tableStatefulsets, Daemonsets: tableDaemonsets,
|
||||
Pods: tablePods, Namespaces: tableNamespaces, Ingresses: tableIngresses, PersistentVolumeClaim: tablePersistentVolumeClaim, Roles: tableRoles,
|
||||
Services: tableServices, StorageClasses: tableStorageClasses, ClusterRoles: tableClusterRoles}
|
||||
|
||||
type Annotation map[string]string
|
||||
|
||||
//
|
||||
//func (annotation *Annotation)Scan(val interface{}) error{
|
||||
// switch val := val.(type){
|
||||
// case string:
|
||||
// return json.Unmarshal([]byte(val), annotation)
|
||||
// case []byte:
|
||||
// return json.Unmarshal(val, annotation)
|
||||
// default:
|
||||
// return errors.New("not support")
|
||||
// }
|
||||
// return nil
|
||||
//}
|
||||
//
|
||||
//func (annotation *Annotation)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"`
|
||||
AnnotationStr string `gorm:"type:text" json:"annotationStr,omitempty"`
|
||||
Annotation Annotation `gorm:"-" json:"annotation"`
|
||||
UpdateTime time.Time `gorm:"column:updateTime" json:"updateTime,omitempty"`
|
||||
}
|
||||
|
||||
func (Deployment) TableName() string {
|
||||
return tableDeployments
|
||||
}
|
||||
|
||||
type Statefulset struct {
|
||||
Name string `gorm:"primary_key" json:"name,omitempty"`
|
||||
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"`
|
||||
AnnotationStr string `gorm:"type:text" json:"annotationStr,omitempty"`
|
||||
Annotation Annotation `gorm:"-" json:"annotation"`
|
||||
CreateTime time.Time `gorm:"column:createTime" json:"createTime,omitempty"`
|
||||
}
|
||||
|
||||
func (Statefulset) TableName() string {
|
||||
return tableStatefulsets
|
||||
}
|
||||
|
||||
type Daemonset struct {
|
||||
Name string `gorm:"primary_key" json:"name,omitempty"`
|
||||
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"`
|
||||
AnnotationStr string `gorm:"type:text" json:"annotationStr,omitempty"`
|
||||
Annotation Annotation `gorm:"-" json:"annotation"`
|
||||
CreateTime time.Time `gorm:"column:createTime" json:"createTime,omitempty"`
|
||||
}
|
||||
|
||||
func (Daemonset) TableName() string {
|
||||
return tableDaemonsets
|
||||
}
|
||||
|
||||
type Service struct {
|
||||
Name string `gorm:"primary_key" json:"name"`
|
||||
Namespace string `gorm:"primary_key" json:"namespace"`
|
||||
ServiceType string `json:"type,omitempty"`
|
||||
|
||||
VirtualIp string `json:"virtualIp,omitempty"`
|
||||
ExternalIp string `json:"externalIp,omitempty"`
|
||||
|
||||
Ports string `json:"ports,omitempty"`
|
||||
AnnotationStr string `gorm:"type:text" json:"annotationStr,omitempty"`
|
||||
Annotation Annotation `gorm:"-" json:"annotation"`
|
||||
CreateTime time.Time `gorm:"column:createTime" json:"createTime,omitempty"`
|
||||
}
|
||||
|
||||
func (Service) TableName() string {
|
||||
return tableServices
|
||||
}
|
||||
|
||||
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"`
|
||||
AnnotationStr string `gorm:"type:text" json:"annotationStr,omitempty"`
|
||||
Annotation Annotation `gorm:"-" json:"annotation"`
|
||||
CreateTime time.Time `gorm:"column:createTime" json:"createTime,omitempty"`
|
||||
StorageClassName string `gorm:"column:storage_class" json:"storage_class,omitempty"`
|
||||
}
|
||||
|
||||
func (Pvc) TableName() string {
|
||||
return tablePersistentVolumeClaim
|
||||
}
|
||||
|
||||
type Ingress struct {
|
||||
Name string `gorm:"primary_key" json:"name"`
|
||||
Namespace string `gorm:"primary_key" json:"namespace"`
|
||||
Ip string `json:"ip,omitempty"`
|
||||
TlsTermination string `json:"tlsTermination,omitempty"`
|
||||
AnnotationStr string `gorm:"type:text" json:"annotationStr,omitempty"`
|
||||
Annotation Annotation `gorm:"-" json:"annotation"`
|
||||
CreateTime time.Time `gorm:"column:createTime" json:"createTime,omitempty"`
|
||||
}
|
||||
|
||||
func (Ingress) TableName() string {
|
||||
return tableIngresses
|
||||
}
|
||||
|
||||
type Pod struct {
|
||||
Name string `gorm:"primary_key" json:"name"`
|
||||
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"`
|
||||
ContainerStr string `gorm:"type:text" json:",omitempty"`
|
||||
Containers []Container `json:"containers,omitempty"`
|
||||
AnnotationStr string `gorm:"type:text" json:"annotationStr,omitempty"`
|
||||
Annotation Annotation `gorm:"-" json:"annotation"`
|
||||
CreateTime time.Time `gorm:"column:createTime" json:"createTime,omitempty"`
|
||||
}
|
||||
|
||||
type Container struct {
|
||||
Name string `json:"name"`
|
||||
Ready bool `json:"ready,omitempty"`
|
||||
Image string `json:"image"`
|
||||
Ports []v1.ContainerPort `json:"ports"`
|
||||
}
|
||||
|
||||
func (Pod) TableName() string {
|
||||
return tablePods
|
||||
}
|
||||
|
||||
type Role struct {
|
||||
Name string `gorm:"primary_key" json:"name"`
|
||||
Namespace string `gorm:"primary_key" json:"namespace"`
|
||||
AnnotationStr string `gorm:"type:text" json:"annotationStr,omitempty"`
|
||||
Annotation Annotation `gorm:"-" json:"annotation"`
|
||||
CreateTime time.Time `gorm:"column:createTime" json:"createTime,omitempty"`
|
||||
}
|
||||
|
||||
func (Role) TableName() string {
|
||||
return tableRoles
|
||||
}
|
||||
|
||||
type ClusterRole struct {
|
||||
Name string `gorm:"primary_key" json:"name"`
|
||||
AnnotationStr string `gorm:"type:text" json:"annotationStr,omitempty"`
|
||||
Annotation Annotation `gorm:"-" json:"annotation"`
|
||||
CreateTime time.Time `gorm:"column:createTime" json:"createTime,omitempty"`
|
||||
}
|
||||
|
||||
func (ClusterRole) TableName() string {
|
||||
return tableClusterRoles
|
||||
}
|
||||
|
||||
type Namespace struct {
|
||||
Name string `gorm:"primary_key" json:"name"`
|
||||
Creator string `json:"creator,omitempty"`
|
||||
Status string `json:"status"`
|
||||
|
||||
Descrition string `json:"description,omitempty"`
|
||||
AnnotationStr string `gorm:"type:text" json:"annotationStr,omitempty"`
|
||||
Annotation Annotation `gorm:"-" json:"annotation"`
|
||||
CreateTime time.Time `gorm:"column:createTime" json:"createTime,omitempty"`
|
||||
}
|
||||
|
||||
func (Namespace) TableName() string {
|
||||
return tableNamespaces
|
||||
}
|
||||
|
||||
type StorageClass struct {
|
||||
Name string `gorm:"primary_key" json:"name"`
|
||||
Creator string `json:"creator,omitempty"`
|
||||
AnnotationStr string `gorm:"type:text" json:"annotationStr,omitempty"`
|
||||
Annotation Annotation `gorm:"-" json:"annotation"`
|
||||
CreateTime time.Time `gorm:"column:createTime" json:"createTime,omitempty"`
|
||||
IsDefault bool `json:"default"`
|
||||
Count int `json:"count"`
|
||||
}
|
||||
|
||||
func (StorageClass) TableName() string {
|
||||
return tableStorageClasses
|
||||
}
|
||||
|
||||
type Paging struct {
|
||||
Limit, Offset int
|
||||
}
|
||||
|
||||
type Controller interface {
|
||||
listAndWatch()
|
||||
chanStop() chan struct{}
|
||||
chanAlive() chan struct{}
|
||||
Count(conditions string) int
|
||||
ListWithConditions(condition string, paging *Paging) (int, interface{}, error)
|
||||
}
|
||||
|
||||
type CommonAttribute struct {
|
||||
K8sClient *kubernetes.Clientset
|
||||
DB *gorm.DB
|
||||
stopChan chan struct{}
|
||||
aliveChan chan struct{}
|
||||
}
|
||||
|
||||
func (ca *CommonAttribute) chanStop() chan struct{} {
|
||||
|
||||
return ca.stopChan
|
||||
}
|
||||
|
||||
func (ca *CommonAttribute) chanAlive() chan struct{} {
|
||||
|
||||
return ca.aliveChan
|
||||
}
|
||||
|
||||
type DeploymentCtl struct {
|
||||
CommonAttribute
|
||||
}
|
||||
|
||||
type StatefulsetCtl struct {
|
||||
CommonAttribute
|
||||
}
|
||||
|
||||
type DaemonsetCtl struct {
|
||||
CommonAttribute
|
||||
}
|
||||
|
||||
type ServiceCtl struct {
|
||||
CommonAttribute
|
||||
}
|
||||
|
||||
type PvcCtl struct {
|
||||
CommonAttribute
|
||||
}
|
||||
|
||||
type PodCtl struct {
|
||||
CommonAttribute
|
||||
}
|
||||
|
||||
type IngressCtl struct {
|
||||
CommonAttribute
|
||||
}
|
||||
|
||||
type NamespaceCtl struct {
|
||||
CommonAttribute
|
||||
}
|
||||
|
||||
type StorageClassCtl struct {
|
||||
CommonAttribute
|
||||
}
|
||||
|
||||
type RoleCtl struct {
|
||||
CommonAttribute
|
||||
}
|
||||
|
||||
type ClusterRoleCtl struct {
|
||||
CommonAttribute
|
||||
}
|
||||
|
||||
func listWithConditions(db *gorm.DB, total *int, object, list interface{}, conditions string, paging *Paging, order string) {
|
||||
if len(conditions) == 0 {
|
||||
db.Model(object).Count(total)
|
||||
} else {
|
||||
db.Model(object).Where(conditions).Count(total)
|
||||
}
|
||||
|
||||
if paging != nil {
|
||||
if len(conditions) > 0 {
|
||||
db.Where(conditions).Order(order).Limit(paging.Limit).Offset(paging.Offset).Find(list)
|
||||
} else {
|
||||
db.Order(order).Limit(paging.Limit).Offset(paging.Offset).Find(list)
|
||||
}
|
||||
|
||||
} else {
|
||||
if len(conditions) > 0 {
|
||||
db.Where(conditions).Order(order).Find(list)
|
||||
} else {
|
||||
db.Order(order).Find(list)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func countWithConditions(db *gorm.DB, conditions string, object interface{}) int {
|
||||
var count int
|
||||
if len(conditions) == 0 {
|
||||
db.Model(object).Count(&count)
|
||||
} else {
|
||||
db.Model(object).Where(conditions).Count(&count)
|
||||
}
|
||||
return count
|
||||
}
|
||||
Reference in New Issue
Block a user