From bd4121d69b1a40ff1413d98c23276820aeba9524 Mon Sep 17 00:00:00 2001 From: richardxz Date: Sun, 17 Jun 2018 00:38:14 +0800 Subject: [PATCH] add default rolebinding, and provide a workaround to process nil object when use k8s watch --- pkg/models/controllers/clusterRoles.go | 2 +- pkg/models/controllers/daemonsets.go | 8 ++-- pkg/models/controllers/deployments.go | 11 +++--- pkg/models/controllers/ingresses.go | 2 +- pkg/models/controllers/namespaces.go | 50 +++++++++++++++++------- pkg/models/controllers/pods.go | 2 +- pkg/models/controllers/pvcs.go | 2 +- pkg/models/controllers/roles.go | 4 +- pkg/models/controllers/services.go | 6 ++- pkg/models/controllers/statefulsets.go | 2 +- pkg/models/controllers/storageclasses.go | 2 +- 11 files changed, 57 insertions(+), 34 deletions(-) diff --git a/pkg/models/controllers/clusterRoles.go b/pkg/models/controllers/clusterRoles.go index 8e41315ed..28b308534 100644 --- a/pkg/models/controllers/clusterRoles.go +++ b/pkg/models/controllers/clusterRoles.go @@ -91,7 +91,7 @@ func (ctl *ClusterRoleCtl) listAndWatch() { case event := <-clusterRoleWatcher.ResultChan(): var role ClusterRole if event.Object == nil { - break + panic("watch timeout, restart clusterRole controller") } object := event.Object.(*v1.ClusterRole) if event.Type == watch.Deleted { diff --git a/pkg/models/controllers/daemonsets.go b/pkg/models/controllers/daemonsets.go index 48e874d48..2792b1bae 100644 --- a/pkg/models/controllers/daemonsets.go +++ b/pkg/models/controllers/daemonsets.go @@ -22,7 +22,7 @@ import ( "github.com/golang/glog" "k8s.io/api/apps/v1beta2" - meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/watch" "kubesphere.io/kubesphere/pkg/client" @@ -87,7 +87,7 @@ func (ctl *DaemonsetCtl) listAndWatch() { db = db.CreateTable(&Daemonset{}) k8sClient := client.NewK8sClient() - deoloyList, err := k8sClient.AppsV1beta2().DaemonSets("").List(meta_v1.ListOptions{}) + deoloyList, err := k8sClient.AppsV1beta2().DaemonSets("").List(metaV1.ListOptions{}) if err != nil { glog.Error(err) return @@ -98,7 +98,7 @@ func (ctl *DaemonsetCtl) listAndWatch() { db.Create(obj) } - watcher, err := k8sClient.AppsV1beta2().DaemonSets("").Watch(meta_v1.ListOptions{}) + watcher, err := k8sClient.AppsV1beta2().DaemonSets("").Watch(metaV1.ListOptions{}) if err != nil { glog.Error(err) return @@ -111,7 +111,7 @@ func (ctl *DaemonsetCtl) listAndWatch() { case event := <-watcher.ResultChan(): var ss Daemonset if event.Object == nil { - break + panic("watch timeout, restart daemonset controller") } object := event.Object.(*v1beta2.DaemonSet) if event.Type == watch.Deleted { diff --git a/pkg/models/controllers/deployments.go b/pkg/models/controllers/deployments.go index 3c96fd190..87f3b7892 100644 --- a/pkg/models/controllers/deployments.go +++ b/pkg/models/controllers/deployments.go @@ -24,8 +24,6 @@ import ( "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 { @@ -46,7 +44,7 @@ func (ctl *DeploymentCtl) generateObject(item v1beta2.Deployment) *Deployment { } for _, conditon := range item.Status.Conditions { - if conditon.Type == "Progressing" { + if conditon.Type == "Available" { updateTime = conditon.LastUpdateTime.Time } } @@ -86,7 +84,7 @@ func (ctl *DeploymentCtl) listAndWatch() { db = db.CreateTable(&Deployment{}) - k8sClient := client.NewK8sClient() + k8sClient := ctl.K8sClient deoloyList, err := k8sClient.AppsV1beta2().Deployments("").List(metaV1.ListOptions{}) if err != nil { glog.Error(err) @@ -96,6 +94,7 @@ func (ctl *DeploymentCtl) listAndWatch() { for _, item := range deoloyList.Items { obj := ctl.generateObject(item) db.Create(obj) + } watcher, err := k8sClient.AppsV1beta2().Deployments("").Watch(metaV1.ListOptions{}) @@ -105,13 +104,14 @@ func (ctl *DeploymentCtl) listAndWatch() { } for { + glog.Error("here") select { case <-ctl.stopChan: return case event := <-watcher.ResultChan(): var deploy Deployment if event.Object == nil { - break + panic("watch timeout, restart deployment controller") } object := event.Object.(*v1beta2.Deployment) if event.Type == watch.Deleted { @@ -123,6 +123,7 @@ func (ctl *DeploymentCtl) listAndWatch() { db.Save(obj) } } + } func (ctl *DeploymentCtl) CountWithConditions(conditions string) int { diff --git a/pkg/models/controllers/ingresses.go b/pkg/models/controllers/ingresses.go index cc70cc799..cd644cefb 100644 --- a/pkg/models/controllers/ingresses.go +++ b/pkg/models/controllers/ingresses.go @@ -98,7 +98,7 @@ func (ctl *IngressCtl) listAndWatch() { case event := <-watcher.ResultChan(): var ing Ingress if event.Object == nil { - break + panic("watch timeout, restart ingress controller") } object := event.Object.(*v1beta1.Ingress) if event.Type == watch.Deleted { diff --git a/pkg/models/controllers/namespaces.go b/pkg/models/controllers/namespaces.go index b17945ac1..f0d013420 100644 --- a/pkg/models/controllers/namespaces.go +++ b/pkg/models/controllers/namespaces.go @@ -35,12 +35,13 @@ import ( ) const ( - provider = "kubernetes" - admin = "admin" - normal = "normal" - view = "view" - kubectlNamespace = "kubesphere" - kubectlConfigKey = "config" + provider = "kubernetes" + admin = "admin" + normal = "normal" + view = "view" + kubectlNamespace = "kubesphere" + kubectlConfigKey = "config" + openpitrix_runtime = "openpitrix_runtime" ) var adminRules = []rbac.PolicyRule{rbac.PolicyRule{Verbs: []string{"*"}, APIGroups: []string{"*"}, Resources: []string{"*"}}} @@ -132,13 +133,26 @@ func (ctl *NamespaceCtl) createOpRuntime(namespace, user string) ([]byte, error) return makeHttpRequest("POST", url, string(body)) } -func (ctl *NamespaceCtl) createDefaultRole(ns string) error { - defer func() { - if err := recover(); err != nil { - glog.Error(err) - } - }() +func (ctl *NamespaceCtl) createDefaultRoleBinding(ns, user string) error { + rolebinding, _ := ctl.K8sClient.RbacV1().RoleBindings(ns).Get(admin, metaV1.GetOptions{}) + if rolebinding.Name != admin { + + roleBinding := &rbac.RoleBinding{ObjectMeta: metaV1.ObjectMeta{Name: admin, Namespace: ns}, + Subjects: []rbac.Subject{{Name: user, Kind: rbac.UserKind}}, RoleRef: rbac.RoleRef{Kind: "Role", Name: admin}} + + _, err := ctl.K8sClient.RbacV1().RoleBindings(ns).Create(roleBinding) + + if err != nil { + glog.Error(err) + return err + } + } + + return nil +} + +func (ctl *NamespaceCtl) createDefaultRole(ns string) error { 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} @@ -178,11 +192,17 @@ func (ctl *NamespaceCtl) createDefaultRole(ns string) error { func (ctl *NamespaceCtl) createRoleAndRuntime(item v1.Namespace) { user := item.Annotations["creator"] ns := item.Name - if len(user) > 0 && len(item.Annotations["openpitrix_runtime"]) == 0 { + if len(user) > 0 && len(item.Annotations[openpitrix_runtime]) == 0 { err := ctl.createDefaultRole(ns) if err != nil { return } + + err = ctl.createDefaultRoleBinding(ns, user) + if err != nil { + return + } + resp, err := ctl.createOpRuntime(ns, user) if err != nil { return @@ -194,7 +214,7 @@ func (ctl *NamespaceCtl) createRoleAndRuntime(item v1.Namespace) { return } - item.Annotations["openpitrix_runtime"] = runtime.RuntimeId + item.Annotations[openpitrix_runtime] = runtime.RuntimeId ctl.K8sClient.CoreV1().Namespaces().Update(&item) } } @@ -259,7 +279,7 @@ func (ctl *NamespaceCtl) listAndWatch() { case event := <-watcher.ResultChan(): var ns Namespace if event.Object == nil { - break + panic("watch timeout, restart namespace controller") } object := event.Object.(*v1.Namespace) if event.Type == watch.Deleted { diff --git a/pkg/models/controllers/pods.go b/pkg/models/controllers/pods.go index 32e043b27..666858282 100644 --- a/pkg/models/controllers/pods.go +++ b/pkg/models/controllers/pods.go @@ -106,7 +106,7 @@ func (ctl *PodCtl) listAndWatch() { case event := <-watcher.ResultChan(): var po Pod if event.Object == nil { - break + panic("watch timeout, restart pod controller") } object := event.Object.(*v1.Pod) if event.Type == watch.Deleted { diff --git a/pkg/models/controllers/pvcs.go b/pkg/models/controllers/pvcs.go index bc25c765f..8956c61ff 100644 --- a/pkg/models/controllers/pvcs.go +++ b/pkg/models/controllers/pvcs.go @@ -111,7 +111,7 @@ func (ctl *PvcCtl) listAndWatch() { case event := <-watcher.ResultChan(): var pvc Pvc if event.Object == nil { - break + panic("watch timeout, restart pvc controller") } object := event.Object.(*v1.PersistentVolumeClaim) if event.Type == watch.Deleted { diff --git a/pkg/models/controllers/roles.go b/pkg/models/controllers/roles.go index d032ccaa7..866b77f05 100644 --- a/pkg/models/controllers/roles.go +++ b/pkg/models/controllers/roles.go @@ -92,10 +92,10 @@ func (ctl *RoleCtl) listAndWatch() { return case event := <-roleWatcher.ResultChan(): var role Role - object := event.Object.(*v1.Role) if event.Object == nil { - break + panic("watch timeout, restart role controller") } + object := event.Object.(*v1.Role) if event.Type == watch.Deleted { db.Where("name=? And namespace=?", object.Name, object.Namespace).Find(&role) db.Delete(role) diff --git a/pkg/models/controllers/services.go b/pkg/models/controllers/services.go index 2865bd127..a20b2cf6c 100644 --- a/pkg/models/controllers/services.go +++ b/pkg/models/controllers/services.go @@ -167,10 +167,12 @@ func (ctl *ServiceCtl) listAndWatch() { return case event := <-watcher.ResultChan(): var svc Service - object := event.Object.(*v1.Service) + if event.Object == nil { - break + panic("watch timeout, restart service controller") } + object := event.Object.(*v1.Service) + if event.Type == watch.Deleted { db.Where("name=? And namespace=?", object.Name, object.Namespace).Find(&svc) db.Delete(svc) diff --git a/pkg/models/controllers/statefulsets.go b/pkg/models/controllers/statefulsets.go index ddbd832ba..babc211c2 100644 --- a/pkg/models/controllers/statefulsets.go +++ b/pkg/models/controllers/statefulsets.go @@ -106,7 +106,7 @@ func (ctl *StatefulsetCtl) listAndWatch() { case event := <-watcher.ResultChan(): var tmp Statefulset if event.Object == nil { - break + panic("watch timeout, restart statefulset controller") } object := event.Object.(*v1beta2.StatefulSet) if event.Type == watch.Deleted { diff --git a/pkg/models/controllers/storageclasses.go b/pkg/models/controllers/storageclasses.go index 64d922928..2d07843c2 100644 --- a/pkg/models/controllers/storageclasses.go +++ b/pkg/models/controllers/storageclasses.go @@ -90,7 +90,7 @@ func (ctl *StorageClassCtl) listAndWatch() { case event := <-watcher.ResultChan(): var sc StorageClass if event.Object == nil { - break + panic("watch timeout, restart storageClass controller") } object := event.Object.(*v1beta1.StorageClass) if event.Type == watch.Deleted {