From fdf928cd13a161a367595c3678444f825729a38c Mon Sep 17 00:00:00 2001 From: yanmingfan Date: Fri, 1 Jun 2018 18:15:44 +0800 Subject: [PATCH 1/2] add component model --- .../v1alpha/components/components_handler.go | 47 ++++ pkg/apis/v1alpha/install.go | 2 + .../v1alpha/registries/registries_handler.go | 3 +- pkg/models/components.go | 263 ++++++++++++++++++ pkg/models/registries.go | 33 ++- 5 files changed, 330 insertions(+), 18 deletions(-) create mode 100644 pkg/apis/v1alpha/components/components_handler.go create mode 100644 pkg/models/components.go diff --git a/pkg/apis/v1alpha/components/components_handler.go b/pkg/apis/v1alpha/components/components_handler.go new file mode 100644 index 000000000..daacb2f79 --- /dev/null +++ b/pkg/apis/v1alpha/components/components_handler.go @@ -0,0 +1,47 @@ +/* +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 components + +import ( + "github.com/emicklei/go-restful" + "kubesphere.io/kubesphere/pkg/filter/route" + "kubesphere.io/kubesphere/pkg/models" + "net/http" + "kubesphere.io/kubesphere/pkg/constants" +) + +func Register(ws *restful.WebService, subPath string) { + ws.Route(ws.GET(subPath).To(handleGetComponents).Filter(route.RouteLogging)). + Consumes(restful.MIME_JSON, restful.MIME_XML). + Produces(restful.MIME_JSON) + +} + +//get all components + +func handleGetComponents(request *restful.Request, response *restful.Response) { + + result, err := models.GetComponents() + + if err != nil { + + response.WriteHeaderAndEntity(http.StatusInternalServerError, constants.MessageResponse{Message: err.Error()}) + } + + response.WriteAsJson(result) + +} diff --git a/pkg/apis/v1alpha/install.go b/pkg/apis/v1alpha/install.go index 3202c3106..43549ab9c 100644 --- a/pkg/apis/v1alpha/install.go +++ b/pkg/apis/v1alpha/install.go @@ -27,6 +27,7 @@ import ( "kubesphere.io/kubesphere/pkg/apis/v1alpha/storage" "kubesphere.io/kubesphere/pkg/apis/v1alpha/volumes" "kubesphere.io/kubesphere/pkg/apis/v1alpha/iam" + "kubesphere.io/kubesphere/pkg/apis/v1alpha/components" ) func init() { @@ -43,6 +44,7 @@ func init() { pods.Register(ws) containers.Register(ws) iam.Register(ws) + components.Register(ws,"/components") // add webservice to default container restful.Add(ws) diff --git a/pkg/apis/v1alpha/registries/registries_handler.go b/pkg/apis/v1alpha/registries/registries_handler.go index f3b663b01..69f4cf996 100644 --- a/pkg/apis/v1alpha/registries/registries_handler.go +++ b/pkg/apis/v1alpha/registries/registries_handler.go @@ -21,6 +21,7 @@ import ( "kubesphere.io/kubesphere/pkg/models" "kubesphere.io/kubesphere/pkg/filter/route" "net/http" + "kubesphere.io/kubesphere/pkg/constants" ) func Register(ws *restful.WebService, subPath string) { @@ -39,7 +40,7 @@ func handlerRegistryValidation(request *restful.Request, response *restful.Respo if err != nil { - response.WriteError(http.StatusInternalServerError, err) + response.WriteHeaderAndEntity(http.StatusInternalServerError, constants.MessageResponse{Message: err.Error()}) } diff --git a/pkg/models/components.go b/pkg/models/components.go new file mode 100644 index 000000000..ddf5b9133 --- /dev/null +++ b/pkg/models/components.go @@ -0,0 +1,263 @@ +/* +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 models + +import ( + "kubesphere.io/kubesphere/pkg/client" + meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "time" + "github.com/golang/glog" + "strings" +) + +const KUBESYSTEM = "kube-system" +const OPENPITRIX = "openpitrix" + +type Components struct { + Name string `json:"name"` + Version string `json:"version"` + Kind string `json:"kind"` + HealthStatus string `json:"healthStatus"` + Replicas int `json:"replicas"` + AvailableReplicas int `json:"availableReplicas"` + SelfLink string `json:"selfLink"` + UpdateTime time.Time `json:"updateTime"` +} + +/*** +* get all components from k8s and kubesphere system, +* there are master component, node component,addons component , kubesphere component +* + */ +func GetComponents() (result []Components, err error) { + + k8sClient := client.NewK8sClient() + + label := "tier=control-plane" + + option := meta_v1.ListOptions{ + + LabelSelector: label, + } + + podlists, err := k8sClient.CoreV1().Pods(KUBESYSTEM).List(option) + + if err != nil { + + glog.Error(err) + + return result, err + } + + var components Components + + templates := [] string{"kube-apiserver", "etcd", "kube-scheduler", "kube-controller-manager", "cloud-controller-manager"} + + if len(podlists.Items) > 0 { + + for _, pod := range podlists.Items { + + for _, template := range templates { + + if strings.Contains(pod.Name, template) { + + components.Name = template + components.Kind = "Pod" + components.SelfLink = pod.SelfLink + version := strings.Split(pod.Spec.Containers[0].Image, ":") + components.Version = version[1] + + if pod.Status.Phase == "Running" { + + components.HealthStatus = "health" + components.Replicas = 1 + components.AvailableReplicas = 1 + + } else { + + components.HealthStatus = "fault" + components.Replicas = 1 + components.AvailableReplicas = 0 + + } + 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 + version := strings.Split(pod.Spec.Containers[0].Image, ":") + components.Version = version[1] + + if pod.Status.Phase == "Running" { + + components.HealthStatus = "health" + components.Replicas = 1 + components.AvailableReplicas = 1 + + } else { + + components.HealthStatus = "fault" + components.Replicas = 1 + components.AvailableReplicas = 0 + + } + 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 + } + + if len(dsList.Items) > 0 { + + for _, ds := range dsList.Items { + + if strings.Contains(ds.Name, "fluent-bit") { + + continue + } + + components.Name = ds.Name + components.Kind = "Daemonset" + components.SelfLink = ds.SelfLink + version := strings.Split(ds.Spec.Template.Spec.Containers[0].Image, ":") + components.Version = version[1] + components.UpdateTime = ds.CreationTimestamp.Time + components.AvailableReplicas = int(ds.Status.NumberAvailable) + components.Replicas = int(ds.Status.DesiredNumberScheduled) + + if components.AvailableReplicas == components.Replicas { + + components.HealthStatus = "health" + + } else { + + components.HealthStatus = "fault" + + } + + result = append(result, components) + + } + + } + + templates = []string{"kube-dns", "heapster", "monitoring-influxdb", "iam", "openpitrix"} + + namespaces := []string{KUBESYSTEM, OPENPITRIX} + + 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 + 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 + components.AvailableReplicas = int(dm.Status.AvailableReplicas) + components.Replicas = int(dm.Status.Replicas) + + if components.AvailableReplicas == components.Replicas { + + components.HealthStatus = "health" + + } else { + + components.HealthStatus = "fault" + + } + + result = append(result, components) + + } + + } + + } + + } + + } + + return result, nil + +} diff --git a/pkg/models/registries.go b/pkg/models/registries.go index 04ba8b885..2a4b2d4e9 100644 --- a/pkg/models/registries.go +++ b/pkg/models/registries.go @@ -22,9 +22,7 @@ import ( "github.com/docker/docker/client" "github.com/docker/docker/api/types" - - "kubesphere.io/kubesphere/pkg/constants" - + "github.com/golang/glog" ) @@ -34,14 +32,19 @@ type AuthInfo struct { ServerHost string `json:"serverhost"` } +type ValidationMsg struct { + + Message string `json:"message"` + Reason string `json:"reason"` +} + + const DOCKERCLIENTERROR = "Docker client error" -func RegistryLoginAuth(authinfo AuthInfo) constants.ResultMessage { +func RegistryLoginAuth(authinfo AuthInfo) ValidationMsg { - var result constants.ResultMessage - - data := make(map[string]interface{}) + var result ValidationMsg datastr := []byte(authinfo.Username + ":" + authinfo.Password) auth := base64.StdEncoding.EncodeToString(datastr) @@ -50,8 +53,8 @@ func RegistryLoginAuth(authinfo AuthInfo) constants.ResultMessage { if err != nil { - data["message"] = DOCKERCLIENTERROR - data["reason"] = err.Error() + glog.Error(err) + } authcfg := types.AuthConfig{ @@ -68,25 +71,21 @@ func RegistryLoginAuth(authinfo AuthInfo) constants.ResultMessage { if err != nil { - data["message"] = DOCKERCLIENTERROR - data["reason"] = err.Error() + glog.Error(err) } if authmsg.Status == "Login Succeeded" { - data["message"] = "Verified" + result.Message = "Verified" } else { - data["message"] = "Unverified" - data["reason"] = "Username or password is incorrect " + result.Message = "Unverified" + result.Reason = "Username or password is incorrect " } - result.Data = data - - return result } From c8236735ae67d9036d44f005b6d957bba81515a1 Mon Sep 17 00:00:00 2001 From: yanmingfan Date: Fri, 1 Jun 2018 20:02:33 +0800 Subject: [PATCH 2/2] add component model --- pkg/models/components.go | 70 +++++++++++++++++++++++++--------------- 1 file changed, 44 insertions(+), 26 deletions(-) diff --git a/pkg/models/components.go b/pkg/models/components.go index ddf5b9133..485a84c92 100644 --- a/pkg/models/components.go +++ b/pkg/models/components.go @@ -25,17 +25,16 @@ import ( ) const KUBESYSTEM = "kube-system" -const OPENPITRIX = "openpitrix" +const OPENPITRIX = "openpitrix-system" type Components struct { - Name string `json:"name"` - Version string `json:"version"` - Kind string `json:"kind"` - HealthStatus string `json:"healthStatus"` - Replicas int `json:"replicas"` - AvailableReplicas int `json:"availableReplicas"` - SelfLink string `json:"selfLink"` - UpdateTime time.Time `json:"updateTime"` + Name string `json:"name"` + Version string `json:"version"` + Kind string `json:"kind"` + Replicas int `json:"replicas"` + HealthStatus string `json:"healthStatus"` + SelfLink string `json:"selfLink"` + UpdateTime time.Time `json:"updateTime"` } /*** @@ -79,19 +78,25 @@ func GetComponents() (result []Components, err error) { components.Kind = "Pod" components.SelfLink = pod.SelfLink version := strings.Split(pod.Spec.Containers[0].Image, ":") - components.Version = version[1] + + if len(version) < 2 { + + components.Version = "latest" + + } else { + + components.Version = version[1] + + } + components.Replicas = 1 if pod.Status.Phase == "Running" { components.HealthStatus = "health" - components.Replicas = 1 - components.AvailableReplicas = 1 } else { - components.HealthStatus = "fault" - components.Replicas = 1 - components.AvailableReplicas = 0 + components.HealthStatus = "unhealth" } components.UpdateTime = pod.Status.Conditions[0].LastTransitionTime.Time @@ -127,19 +132,25 @@ func GetComponents() (result []Components, err error) { components.Kind = "Pod" components.SelfLink = pod.SelfLink version := strings.Split(pod.Spec.Containers[0].Image, ":") - components.Version = version[1] + + if len(version) < 2 { + + components.Version = "latest" + + } else { + + components.Version = version[1] + + } + components.Replicas = 1 if pod.Status.Phase == "Running" { components.HealthStatus = "health" - components.Replicas = 1 - components.AvailableReplicas = 1 } else { components.HealthStatus = "fault" - components.Replicas = 1 - components.AvailableReplicas = 0 } components.UpdateTime = pod.Status.Conditions[0].LastTransitionTime.Time @@ -174,12 +185,20 @@ func GetComponents() (result []Components, err error) { components.Kind = "Daemonset" components.SelfLink = ds.SelfLink version := strings.Split(ds.Spec.Template.Spec.Containers[0].Image, ":") - components.Version = version[1] + + if len(version) < 2 { + + components.Version = "latest" + + } else { + + components.Version = version[1] + + } components.UpdateTime = ds.CreationTimestamp.Time - components.AvailableReplicas = int(ds.Status.NumberAvailable) components.Replicas = int(ds.Status.DesiredNumberScheduled) - if components.AvailableReplicas == components.Replicas { + if ds.Status.NumberAvailable == ds.Status.DesiredNumberScheduled { components.HealthStatus = "health" @@ -221,6 +240,7 @@ func GetComponents() (result []Components, err error) { components.Name = dm.Name components.Kind = "Deployment" components.SelfLink = dm.SelfLink + components.Replicas = int(dm.Status.Replicas) version := strings.Split(dm.Spec.Template.Spec.Containers[0].Image, ":") if len(version) < 2 { @@ -233,10 +253,8 @@ func GetComponents() (result []Components, err error) { } components.UpdateTime = dm.Status.Conditions[0].LastUpdateTime.Time - components.AvailableReplicas = int(dm.Status.AvailableReplicas) - components.Replicas = int(dm.Status.Replicas) - if components.AvailableReplicas == components.Replicas { + if dm.Status.AvailableReplicas == dm.Status.Replicas { components.HealthStatus = "health"