mapping data to etcd

This commit is contained in:
richardxz
2018-06-16 11:38:37 +08:00
parent 663a17f230
commit b72e332aff
627 changed files with 26684 additions and 26115 deletions

View 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
}

View 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
}

View 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
}

View 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
}

View 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
}

View 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
}

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 (
"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
}

View 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
}

View 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)
}
}
}
}

View 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
}

View 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
}

View 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
}

View 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
}