Merge pull request #2 from kubesphere/master

fork code
This commit is contained in:
alex.fan
2018-06-19 11:42:01 +08:00
committed by GitHub
15 changed files with 261 additions and 240 deletions

View File

@@ -31,6 +31,10 @@ func Register(ws *restful.WebService, subPath string) {
Consumes(restful.MIME_JSON, restful.MIME_XML).
Produces(restful.MIME_JSON)
ws.Route(ws.GET(subPath+"/{namespace}").To(handleGetComponentsByNamespace).Filter(route.RouteLogging)).
Consumes(restful.MIME_JSON, restful.MIME_XML).
Produces(restful.MIME_JSON)
}
//get all components
@@ -50,3 +54,22 @@ func handleGetComponents(request *restful.Request, response *restful.Response) {
}
}
//get components from ns
func handleGetComponentsByNamespace(request *restful.Request, response *restful.Response) {
ns := request.PathParameter("namespace")
result, err := models.GetComponentsByNamespace(ns)
if err != nil {
response.WriteHeaderAndEntity(http.StatusInternalServerError, constants.MessageResponse{Message: err.Error()})
} else {
response.WriteAsJson(result)
}
}

View File

@@ -17,7 +17,6 @@ limitations under the License.
package models
import (
"strings"
"time"
"github.com/golang/glog"
@@ -31,34 +30,151 @@ const OPENPITRIX = "openpitrix-system"
const ISTIO = "istio-system"
const KUBESPHERE = "kubesphere-system"
type ComponentsCount struct {
KubernetesCount int `json:"kubernetesCount"`
OpenpitrixCount int `json:"openpitrixCount"`
KubesphereCount int `json:"kubesphereCount"`
IstioCount int `json:"istioCount"`
}
type Components struct {
Name string `json:"name"`
Version string `json:"version"`
Kind string `json:"kind"`
Namespace string `json:"namespace"`
Label interface{} `json:"label"`
Replicas int `json:"replicas"`
HealthStatus string `json:"healthStatus"`
SelfLink string `json:"selfLink"`
UpdateTime time.Time `json:"updateTime"`
Label interface{} `json:"label"`
HealthStatus string `json:"healthStatus"`
CreateTime time.Time `json:"updateTime"`
}
/***
* get all components from k8s and kubesphere system,
* there are master component, node component,addons component , kubesphere component
* get all components from k8s and kubesphere system
*
*/
func GetComponents() ([]Components, error) {
func GetComponents() (map[string]interface{}, error) {
result := make([]Components, 0)
result := make(map[string]interface{})
componentsList := make([]Components, 0)
k8sClient := client.NewK8sClient()
label := "tier=control-plane"
var count ComponentsCount
var components Components
label := "kubernetes.io/cluster-service=true"
option := meta_v1.ListOptions{
LabelSelector: label,
}
podlists, err := k8sClient.CoreV1().Pods(KUBESYSTEM).List(option)
namespaces := []string{KUBESYSTEM, OPENPITRIX, ISTIO, KUBESPHERE}
for _, ns := range namespaces {
if ns != KUBESYSTEM {
option.LabelSelector = ""
}
servicelists, err := k8sClient.CoreV1().Services(ns).List(option)
if err != nil {
glog.Error(err)
return result, err
}
if len(servicelists.Items) > 0 {
for _, service := range servicelists.Items {
switch ns {
case KUBESYSTEM:
count.KubernetesCount++
case OPENPITRIX:
count.OpenpitrixCount++
case KUBESPHERE:
count.KubesphereCount++
default:
count.IstioCount++
}
components.Name = service.Name
components.Namespace = service.Namespace
components.CreateTime = service.CreationTimestamp.Time
components.Label = service.Spec.Selector
components.SelfLink = service.SelfLink
label := service.Spec.Selector
combination := ""
for key, val := range label {
labelstr := key + "=" + val
if combination == "" {
combination = labelstr
} else {
combination = combination + "," + labelstr
}
}
option := meta_v1.ListOptions{
LabelSelector: combination,
}
podsList, err := k8sClient.CoreV1().Pods(ns).List(option)
if err != nil {
glog.Error(err)
return result, err
}
if len(podsList.Items) > 0 {
for _, pod := range podsList.Items {
if pod.Status.Phase == "Running" {
components.HealthStatus = "health"
} else {
components.HealthStatus = "unhealth"
}
}
}
componentsList = append(componentsList, components)
}
}
}
result["count"] = count
result["item"] = componentsList
return result, nil
}
func GetComponentsByNamespace(ns string) ([]Components, error) {
result := make([]Components, 0)
k8sClient := client.NewK8sClient()
var components Components
label := "kubernetes.io/cluster-service=true"
option := meta_v1.ListOptions{
LabelSelector: label,
}
if ns != KUBESYSTEM {
option.LabelSelector = ""
}
servicelists, err := k8sClient.CoreV1().Services(ns).List(option)
if err != nil {
@@ -67,35 +183,46 @@ func GetComponents() ([]Components, error) {
return result, err
}
var components Components
if len(servicelists.Items) > 0 {
templates := []string{"kube-apiserver", "etcd", "kube-scheduler", "kube-controller-manager", "cloud-controller-manager"}
for _, service := range servicelists.Items {
if len(podlists.Items) > 0 {
components.Name = service.Name
components.Namespace = service.Namespace
components.CreateTime = service.CreationTimestamp.Time
components.SelfLink = service.SelfLink
components.Label = service.Spec.Selector
label := service.Spec.Selector
combination := ""
for key, val := range label {
for _, pod := range podlists.Items {
labelstr := key + "=" + val
for _, template := range templates {
if combination == "" {
if strings.Contains(pod.Name, template) {
combination = labelstr
components.Name = template
components.Kind = "Pod"
components.SelfLink = pod.SelfLink
components.Label = pod.Labels
components.Namespace = pod.Namespace
version := strings.Split(pod.Spec.Containers[0].Image, ":")
} else {
if len(version) < 2 {
combination = combination + "," + labelstr
components.Version = "latest"
}
} else {
}
option := meta_v1.ListOptions{
LabelSelector: combination,
}
podsList, err := k8sClient.CoreV1().Pods(ns).List(option)
components.Version = version[1]
if err != nil {
}
components.Replicas = 1
glog.Error(err)
return result, err
}
if len(podsList.Items) > 0 {
for _, pod := range podsList.Items {
if pod.Status.Phase == "Running" {
@@ -106,190 +233,17 @@ func GetComponents() ([]Components, error) {
components.HealthStatus = "unhealth"
}
components.UpdateTime = pod.Status.Conditions[0].LastTransitionTime.Time
result = append(result, components)
}
}
}
}
label = "component=kube-addon-manager"
option.LabelSelector = label
kubeaddon, err := k8sClient.CoreV1().Pods(KUBESYSTEM).List(option)
if err != nil {
glog.Error(err)
return result, err
}
if len(kubeaddon.Items) > 0 {
for _, pod := range kubeaddon.Items {
components.Name = "kube-addon-manager"
components.Kind = "Pod"
components.SelfLink = pod.SelfLink
components.Label = pod.Labels
components.Namespace = pod.Namespace
version := strings.Split(pod.Spec.Containers[0].Image, ":")
if len(version) < 2 {
components.Version = "latest"
} else {
components.Version = version[1]
}
components.Replicas = 1
if pod.Status.Phase == "Running" {
components.HealthStatus = "health"
} else {
components.HealthStatus = "unhealth"
}
components.UpdateTime = pod.Status.Conditions[0].LastTransitionTime.Time
result = append(result, components)
}
}
option.LabelSelector = ""
dsList, err := k8sClient.AppsV1beta2().DaemonSets(KUBESYSTEM).List(option)
if err != nil {
glog.Error(err)
return result, err
}
templates = []string{"flannel", "kube-proxy", "calico"}
if len(dsList.Items) > 0 {
for _, ds := range dsList.Items {
for _, template := range templates {
if strings.Contains(ds.Name, template) {
components.Name = ds.Name
components.Kind = "Daemonset"
components.SelfLink = ds.SelfLink
components.Label = ds.Spec.Selector.MatchLabels
components.Namespace = ds.Namespace
version := strings.Split(ds.Spec.Template.Spec.Containers[0].Image, ":")
if len(version) < 2 {
components.Version = "latest"
} else {
components.Version = version[1]
}
components.UpdateTime = ds.CreationTimestamp.Time
components.Replicas = int(ds.Status.DesiredNumberScheduled)
if ds.Status.NumberAvailable == ds.Status.DesiredNumberScheduled {
components.HealthStatus = "health"
} else {
components.HealthStatus = "unhealth"
}
result = append(result, components)
}
}
}
}
templates = []string{"kube-dns", "heapster", "monitoring-influxdb", "iam", "openpitrix", "istio", "kubesphere"}
namespaces := []string{KUBESYSTEM, OPENPITRIX, ISTIO, KUBESPHERE}
for _, ns := range namespaces {
deployList, err := k8sClient.AppsV1beta1().Deployments(ns).List(option)
if err != nil {
glog.Error(err)
return result, err
}
if len(deployList.Items) > 0 {
for _, dm := range deployList.Items {
for _, template := range templates {
if strings.Contains(dm.Name, template) {
components.Name = dm.Name
components.Kind = "Deployment"
components.SelfLink = dm.SelfLink
components.Label = dm.Spec.Selector.MatchLabels
components.Namespace = dm.Namespace
components.Replicas = int(dm.Status.Replicas)
version := strings.Split(dm.Spec.Template.Spec.Containers[0].Image, ":")
if len(version) < 2 {
components.Version = "latest"
} else {
components.Version = version[1]
}
components.UpdateTime = dm.Status.Conditions[0].LastUpdateTime.Time
if dm.Status.AvailableReplicas == dm.Status.Replicas {
components.HealthStatus = "health"
} else {
components.HealthStatus = "unhealth"
}
result = append(result, components)
}
}
}
}
}
return result, nil
}

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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)

View File

@@ -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)

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -88,7 +88,7 @@ func RegistryLoginAuth(authinfo AuthInfo) ValidationMsg {
datastr := []byte(authinfo.Username + ":" + authinfo.Password)
auth := base64.StdEncoding.EncodeToString(datastr)
ctx := context.Background()
cli, err := client.NewClientWithOpts()
cli, err := client.NewEnvClient()
if err != nil {

View File

@@ -27,6 +27,7 @@ import (
"k8s.io/api/core/v1"
policy "k8s.io/api/policy/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
types "k8s.io/apimachinery/pkg/types"
"kubesphere.io/kubesphere/pkg/client"
kubeclient "kubesphere.io/kubesphere/pkg/client"
@@ -265,9 +266,29 @@ func DrainNode(nodename string) (msg constants.MessageResponse, err error) {
return msg, err
}
}
}
data := []byte(" {\"spec\":{\"unschedulable\":true}}")
nodestatus, err := k8sclient.CoreV1().Nodes().Patch(nodename, types.StrategicMergePatchType, data)
if err != nil {
glog.Fatal(err)
return msg, err
}
msg.Message = fmt.Sprintf("success")
if nodestatus.Spec.Unschedulable {
msg.Message = fmt.Sprintf("success")
} else {
glog.Fatal(err)
return msg, err
}
return msg, nil
}