提交 867129cd 编写于 作者: J Jeff 提交者: zryfish

add controllers

change kiali mux to go-restful

add knative

add health api
上级 4b738830
package app
import (
"k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"kubesphere.io/kubesphere/pkg/controller/destinationrule"
"kubesphere.io/kubesphere/pkg/controller/virtualservice"
"kubesphere.io/kubesphere/pkg/informers"
"kubesphere.io/kubesphere/pkg/simple/controller/namespace"
"sigs.k8s.io/controller-runtime/pkg/manager"
"time"
......@@ -35,7 +35,7 @@ func AddControllers(mgr manager.Manager, cfg *rest.Config, stopCh <-chan struct{
return err
}
informerFactory := informers.SharedInformerFactory()
informerFactory := informers.NewSharedInformerFactory(kubeClient, defaultResync)
istioInformer := istioinformers.NewSharedInformerFactory(istioclient, defaultResync)
servicemeshclient, err := servicemeshclientset.NewForConfig(cfg)
......
......@@ -30,14 +30,25 @@ import (
"sigs.k8s.io/controller-runtime/pkg/runtime/signals"
)
func main() {
var metricsAddr, kubeConfigPath, masterURL string
var (
masterURL string
kubeconfig string
metricsAddr string
)
func init() {
flag.StringVar(&masterURL, "master-url", "", "only need if out of cluster")
flag.StringVar(&kubeconfig, "kubeconfig", "", "only need if out of cluster")
flag.StringVar(&metricsAddr, "metrics-addr", ":8080", "The address the metric endpoint binds to.")
}
func main() {
flag.Parse()
logf.SetLogger(logf.ZapLogger(false))
log := logf.Log.WithName("controller-manager")
kubeConfig, err := clientcmd.BuildConfigFromFlags(masterURL, kubeConfigPath)
cfg, err := clientcmd.BuildConfigFromFlags(masterURL, kubeconfig)
if err != nil {
log.Error(err, "failed to build kubeconfig")
os.Exit(1)
......@@ -46,7 +57,7 @@ func main() {
stopCh := signals.SetupSignalHandler()
log.Info("setting up manager")
mgr, err := manager.New(kubeConfig, manager.Options{})
mgr, err := manager.New(cfg, manager.Options{})
if err != nil {
log.Error(err, "unable to set up overall controller manager")
os.Exit(1)
......@@ -64,7 +75,7 @@ func main() {
os.Exit(1)
}
if err := app.AddControllers(mgr, kubeConfig, stopCh); err != nil {
if err := app.AddControllers(mgr, cfg, stopCh); err != nil {
log.Error(err, "unable to register controllers to the manager")
os.Exit(1)
}
......
......@@ -122,11 +122,12 @@ func initializeESClientConfig() {
db := mysql.Client()
if !db.HasTable(&logging.OutputDBBinding{}) {
// Panic
log.Fatal("Flyway migration is not completed")
log.Print("Flyway migration is not completed")
}
err := db.Find(&outputs).Error
if err != nil {
log.Printf("get logging config failed. Error: %v", err)
return
}
......
......@@ -4,4 +4,4 @@
docker build -f build/ks-apiserver/Dockerfile -t kubespheredev/ks-apiserver:latest .
docker build -f build/ks-iam/Dockerfile -t kubespheredev/ks-iam:latest .
docker build -f build/controller-manager/Dockerfile -t kubespheredev/controller-manager:latest .
\ No newline at end of file
docker build -f build/controller-manager/Dockerfile -t kubespheredev/ks-controller-manager:latest .
......@@ -68,8 +68,8 @@ func addWebService(c *restful.Container) error {
To(metrics.GetWorkloadMetrics).
Metadata(restfulspec.KeyOpenAPITags, tags).
Doc("Get workload metrics from a specific namespace").
Param(webservice.PathParameter("namespace", "name of the namespace")).
Param(webservice.PathParameter("workload", "name of the workload")).
Param(webservice.PathParameter("namespace", "name of the namespace").Required(true)).
Param(webservice.PathParameter("workload", "name of the workload").Required(true)).
Param(webservice.QueryParameter("filters[]", "type of metrics type, e.g. request_count, request_duration, request_error_count")).
Param(webservice.QueryParameter("queryTime", "from which UNIX time to extract metrics")).
Param(webservice.QueryParameter("duration", "metrics duration, in seconds")).
......@@ -87,7 +87,7 @@ func addWebService(c *restful.Container) error {
To(metrics.GetNamespaceMetrics).
Metadata(restfulspec.KeyOpenAPITags, tags).
Doc("Get workload metrics from a specific namespace").
Param(webservice.PathParameter("namespace", "name of the namespace")).
Param(webservice.PathParameter("namespace", "name of the namespace").Required(true)).
Param(webservice.QueryParameter("filters[]", "type of metrics type, e.g. request_count, request_duration, request_error_count")).
Param(webservice.QueryParameter("queryTime", "from which UNIX time to extract metrics")).
Param(webservice.QueryParameter("duration", "metrics duration, in seconds")).
......@@ -105,7 +105,7 @@ func addWebService(c *restful.Container) error {
To(metrics.GetNamespaceGraph).
Metadata(restfulspec.KeyOpenAPITags, tags).
Doc("Get service graph for a specific namespace").
Param(webservice.PathParameter("namespace", "name of a namespace")).
Param(webservice.PathParameter("namespace", "name of a namespace").Required(true)).
Param(webservice.QueryParameter("graphType", "type of the generated service graph, eg. ")).
Param(webservice.QueryParameter("groupBy", "group nodes by kind")).
Param(webservice.QueryParameter("queryTime", "from which time point, default now")).
......@@ -118,7 +118,7 @@ func addWebService(c *restful.Container) error {
To(metrics.GetNamespacesGraph).
Metadata(restfulspec.KeyOpenAPITags, tags).
Doc("Get service graph for a specific namespace").
Param(webservice.PathParameter("namespace", "name of a namespace")).
Param(webservice.PathParameter("namespace", "name of a namespace").Required(true)).
Param(webservice.QueryParameter("graphType", "type of the generated service graph, eg. ")).
Param(webservice.QueryParameter("groupBy", "group nodes by kind")).
Param(webservice.QueryParameter("queryTime", "from which time point, default now")).
......@@ -126,6 +126,39 @@ func addWebService(c *restful.Container) error {
Param(webservice.QueryParameter("namespaces", "names of namespaces")).
Writes(errors.Error{})).Produces(restful.MIME_JSON)
// Get workloads health
webservice.Route(webservice.GET("/namespaces/{namespace}/workloads/{workload}/health").
To(metrics.GetWorkloadHealth).
Metadata(restfulspec.KeyOpenAPITags, tags).
Doc("Get workload health").
Param(webservice.PathParameter("namespace", "name of a namespace").Required(true)).
Param(webservice.PathParameter("workload", "workload name").Required(true)).
Param(webservice.QueryParameter("rateInterval", "the rate interval used for fetching error rate").DefaultValue("10m").Required(true)).
Param(webservice.QueryParameter("queryTime", "the time to use for query")).
Writes(errors.Error{})).Produces(restful.MIME_JSON)
// Get app health
webservice.Route(webservice.GET("/namespaces/{namespace}/apps/{app}/health").
To(metrics.GetAppHealth).
Metadata(restfulspec.KeyOpenAPITags, tags).
Doc("Get workload health").
Param(webservice.PathParameter("namespace", "name of a namespace").Required(true)).
Param(webservice.PathParameter("app", "app name").Required(true)).
Param(webservice.QueryParameter("rateInterval", "the rate interval used for fetching error rate").DefaultValue("10m").Required(true)).
Param(webservice.QueryParameter("queryTime", "the time to use for query")).
Writes(errors.Error{})).Produces(restful.MIME_JSON)
// Get service health
webservice.Route(webservice.GET("/namespaces/{namespace}/services/{service}/health").
To(metrics.GetServiceHealth).
Metadata(restfulspec.KeyOpenAPITags, tags).
Doc("Get workload health").
Param(webservice.PathParameter("namespace", "name of a namespace").Required(true)).
Param(webservice.PathParameter("service", "service name").Required(true)).
Param(webservice.QueryParameter("rateInterval", "the rate interval used for fetching error rate").DefaultValue("10m").Required(true)).
Param(webservice.QueryParameter("queryTime", "the time to use for query")).
Writes(errors.Error{})).Produces(restful.MIME_JSON)
c.Add(webservice)
return nil
......
......@@ -23,7 +23,7 @@ import (
)
const (
ApiRootPath = "/apis"
ApiRootPath = "/kapis"
)
// container holds all webservice of apiserver
......
......@@ -48,3 +48,18 @@ func GetNamespaceGraph(request *restful.Request, response *restful.Response) {
func GetNamespacesGraph(request *restful.Request, response *restful.Response) {
handlers.GraphNamespaces(request, response)
}
// Get workload health
func GetWorkloadHealth(request *restful.Request, response *restful.Response) {
handlers.WorkloadHealth(request, response)
}
// Get app health
func GetAppHealth(request *restful.Request, response *restful.Response) {
handlers.AppHealth(request, response)
}
// Get service health
func GetServiceHealth(request *restful.Request, response *restful.Response) {
handlers.ServiceHealth(request, response)
}
......@@ -139,10 +139,6 @@ func (v *DestinationRuleController) Run(workers int, stopCh <-chan struct{}) {
go wait.Until(v.worker, v.workerLoopPeriod, stopCh)
}
go func() {
defer utilruntime.HandleCrash()
}()
<-stopCh
}
......@@ -222,9 +218,9 @@ func (v *DestinationRuleController) syncService(key string) error {
}
subset := v1alpha3.Subset{
Name: util.NormalizeVersionName(name),
Name: util.NormalizeVersionName(version),
Labels: map[string]string{
util.VersionLabel: name,
util.VersionLabel: version,
},
}
......@@ -239,10 +235,15 @@ func (v *DestinationRuleController) syncService(key string) error {
Name: service.Name,
Labels: service.Labels,
},
Spec: v1alpha3.DestinationRuleSpec{
Host: name,
},
}
} else {
log.Error(err, "Couldn't get destinationrule for service", "key", key)
return err
}
log.Error(err, "Couldn't get destinationrule for service", "key", key)
return err
}
createDestinationRule := len(currentDestinationRule.Spec.Subsets) == 0
......
......@@ -18,6 +18,7 @@ func getAppNameByStrategy(strategy *v1alpha2.Strategy) string {
return ""
}
// if virtualservice not specified with port number, then fill with service first port
func fillDestinationPort(vs *v1alpha3.VirtualService, service *v1.Service) error {
if len(service.Spec.Ports) == 0 {
......@@ -27,14 +28,22 @@ func fillDestinationPort(vs *v1alpha3.VirtualService, service *v1.Service) error
// fill http port
for i := range vs.Spec.Http {
for j := range vs.Spec.Http[i].Route {
vs.Spec.Http[i].Route[j].Destination.Port.Number = uint32(service.Spec.Ports[0].Port)
if vs.Spec.Http[i].Route[j].Destination.Port.Number == 0 {
vs.Spec.Http[i].Route[j].Destination.Port.Number = uint32(service.Spec.Ports[0].Port)
}
}
if vs.Spec.Http[i].Mirror != nil && vs.Spec.Http[i].Mirror.Port.Number == 0 {
vs.Spec.Http[i].Mirror.Port.Number = uint32(service.Spec.Ports[0].Port)
}
}
// fill tcp port
for i := range vs.Spec.Tcp {
for j := range vs.Spec.Tcp[i].Route {
vs.Spec.Tcp[i].Route[j].Destination.Port.Number = uint32(service.Spec.Ports[0].Port)
if vs.Spec.Tcp[i].Route[j].Destination.Port.Number == 0 {
vs.Spec.Tcp[i].Route[j].Destination.Port.Number = uint32(service.Spec.Ports[0].Port)
}
}
}
......
......@@ -16,7 +16,6 @@ const (
// resource with these following labels considered as part of servicemesh
var ApplicationLabels = [...]string{
ApplicationNameLabel,
ApplicationVersionLabel,
ServiceMeshEnabledLabel,
AppLabel,
}
......
......@@ -128,7 +128,7 @@ func NewVirtualServiceController(serviceInformer coreinformers.ServiceInformer,
}
func (v *VirtualServiceController) Start(stopCh <-chan struct{}) error {
v.Run(5, stopCh)
v.Run(1, stopCh)
return nil
}
......@@ -147,10 +147,6 @@ func (v *VirtualServiceController) Run(workers int, stopCh <-chan struct{}) {
go wait.Until(v.worker, v.workerLoopPeriod, stopCh)
}
go func() {
defer utilruntime.HandleCrash()
}()
<-stopCh
}
......@@ -202,7 +198,6 @@ func (v *VirtualServiceController) syncService(key string) error {
if err != nil && !errors.IsNotFound(err) {
return err
}
return nil
}
......@@ -278,9 +273,7 @@ func (v *VirtualServiceController) syncService(key string) error {
if len(vs.Spec.Http) > 0 || len(vs.Spec.Tcp) > 0 {
_, err := v.virtualServiceClient.NetworkingV1alpha3().VirtualServices(namespace).Create(vs)
if err != nil {
v.eventRecorder.Eventf(vs, v1.EventTypeWarning, "FailedToCreateVirtualService", "Failed to create virtualservice for service %v/%v: %v", service.Namespace, service.Name, err)
log.Error(err, "create virtualservice for service failed.", "service", service)
return err
}
......@@ -288,7 +281,6 @@ func (v *VirtualServiceController) syncService(key string) error {
log.Info("service doesn't have a tcp port.")
return nil
}
}
return nil
......@@ -328,7 +320,6 @@ func (v *VirtualServiceController) addDestinationRule(obj interface{}) {
func (v *VirtualServiceController) deleteStrategy(obj interface{}) {
// nothing to do right now
}
func (v *VirtualServiceController) handleErr(err error, key interface{}) {
......@@ -343,7 +334,7 @@ func (v *VirtualServiceController) handleErr(err error, key interface{}) {
return
}
log.V(0).Info("Dropping service %q out of the queue: %v", "key", key, "error", err)
log.V(4).Info("Dropping service out of the queue.", "key", key, "error", err)
v.queue.Forget(key)
utilruntime.HandleError(err)
}
......@@ -20,13 +20,10 @@ package k8s
import (
"flag"
"fmt"
"log"
"os"
"sync"
"github.com/mitchellh/go-homedir"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
......@@ -37,10 +34,12 @@ var (
k8sClient *kubernetes.Clientset
k8sClientOnce sync.Once
KubeConfig *rest.Config
masterURL string
)
func init() {
flag.StringVar(&kubeConfigFile, "kubeconfig", fmt.Sprintf("%s/.kube/config", os.Getenv("HOME")), "path to kubeconfig file")
flag.StringVar(&kubeConfigFile, "kubeconfig", "", "path to kubeconfig file")
flag.StringVar(&masterURL, "master-url","", "kube-apiserver url, only needed when out of cluster")
}
func Client() *kubernetes.Clientset {
......@@ -63,18 +62,8 @@ func Client() *kubernetes.Clientset {
func Config() (kubeConfig *rest.Config, err error) {
if kubeConfigFile == "" {
if env := os.Getenv("KUBECONFIG"); env != "" {
kubeConfigFile = env
} else {
if home, err := homedir.Dir(); err == nil {
kubeConfigFile = fmt.Sprintf("%s/.kube/config", home)
}
}
}
if _, err = os.Stat(kubeConfigFile); err == nil {
kubeConfig, err = clientcmd.BuildConfigFromFlags("", kubeConfigFile)
kubeConfig, err = clientcmd.BuildConfigFromFlags(masterURL, kubeConfigFile)
} else {
kubeConfig, err = rest.InClusterConfig()
}
......
......@@ -19,9 +19,10 @@ package namespace
import (
"fmt"
"github.com/golang/glog"
logf "sigs.k8s.io/controller-runtime/pkg/runtime/log"
"time"
"github.com/golang/glog"
corev1 "k8s.io/api/core/v1"
rbac "k8s.io/api/rbac/v1"
"k8s.io/apimachinery/pkg/api/errors"
......@@ -36,6 +37,8 @@ import (
"k8s.io/client-go/util/workqueue"
)
var log = logf.Log.WithName("namespace-controller")
const threadiness = 2
var (
......@@ -54,18 +57,18 @@ type NamespaceController struct {
}
func NewNamespaceController(
kubeclientset kubernetes.Interface,
clientset kubernetes.Interface,
namespaceInformer coreinformers.NamespaceInformer,
roleInformer rbacinformers.RoleInformer) *NamespaceController {
controller := &NamespaceController{
clientset: kubeclientset,
clientset: clientset,
namespaceInformer: namespaceInformer,
roleInformer: roleInformer,
workqueue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "namespaces"),
}
glog.Info("setting up event handlers")
log.V(3).Info("setting up event handlers")
namespaceInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
AddFunc: controller.handleObject,
......@@ -86,29 +89,24 @@ func NewNamespaceController(
}
func (c *NamespaceController) Start(stopCh <-chan struct{}) error {
go func() {
defer utilruntime.HandleCrash()
defer c.workqueue.ShutDown()
// Start the informer factories to begin populating the informer caches
glog.Info("starting namespace controller")
defer utilruntime.HandleCrash()
defer c.workqueue.ShutDown()
// Wait for the caches to be synced before starting workers
glog.Info("waiting for informer caches to sync")
if ok := cache.WaitForCacheSync(stopCh, c.namespaceInformer.Informer().HasSynced, c.roleInformer.Informer().HasSynced); !ok {
glog.Fatalf("controller exit with error: failed to wait for caches to sync")
}
log.V(3).Info("starting namespace controller")
defer glog.Info("shutting down namespace controller")
glog.Info("starting workers")
// Wait for the caches to be synced before starting workers
log.Info("waiting for informer caches to sync")
if ok := cache.WaitForCacheSync(stopCh, c.namespaceInformer.Informer().HasSynced, c.roleInformer.Informer().HasSynced); !ok {
glog.Fatalf("controller exit with error: failed to wait for caches to sync")
}
for i := 0; i < threadiness; i++ {
go wait.Until(c.runWorker, time.Second, stopCh)
}
log.V(3).Info("starting workers")
for i := 0; i < threadiness; i++ {
go wait.Until(c.runWorker, time.Second, stopCh)
}
glog.Info("started workers")
<-stopCh
glog.Info("shutting down workers")
}()
<-stopCh
return nil
}
......@@ -142,7 +140,7 @@ func (c *NamespaceController) processNextWorkItem() bool {
}
c.workqueue.Forget(obj)
glog.Infof("successfully namespace synced '%s'", namespace)
log.V(4).Info("successfully namespace synced ", "namespace", namespace)
return nil
}(obj)
......
package handlers
import (
"github.com/emicklei/go-restful"
"net/http"
"time"
"github.com/gorilla/mux"
"k8s.io/apimachinery/pkg/api/errors"
"github.com/kiali/kiali/business"
......@@ -15,25 +15,25 @@ import (
const defaultHealthRateInterval = "10m"
// NamespaceHealth is the API handler to get app-based health of every services in the given namespace
func NamespaceHealth(w http.ResponseWriter, r *http.Request) {
func NamespaceHealth(request *restful.Request, response *restful.Response) {
// Get business layer
business, err := business.Get()
if err != nil {
RespondWithError(w, http.StatusInternalServerError, "Services initialization error: "+err.Error())
RespondWithError(response.ResponseWriter, http.StatusInternalServerError, "Services initialization error: "+err.Error())
return
}
p := namespaceHealthParams{}
if ok, err := p.extract(r); !ok {
if ok, err := p.extract(request); !ok {
// Bad request
RespondWithError(w, http.StatusBadRequest, err)
RespondWithError(response.ResponseWriter, http.StatusBadRequest, err)
return
}
// Adjust rate interval
rateInterval, err := adjustRateInterval(business, p.Namespace, p.RateInterval, p.QueryTime)
if err != nil {
RespondWithError(w, http.StatusInternalServerError, "Adjust rate interval error: "+err.Error())
RespondWithError(response.ResponseWriter, http.StatusInternalServerError, "Adjust rate interval error: "+err.Error())
return
}
......@@ -41,86 +41,86 @@ func NamespaceHealth(w http.ResponseWriter, r *http.Request) {
case "app":
health, err := business.Health.GetNamespaceAppHealth(p.Namespace, rateInterval, p.QueryTime)
if err != nil {
RespondWithError(w, http.StatusInternalServerError, "Error while fetching app health: "+err.Error())
RespondWithError(response.ResponseWriter, http.StatusInternalServerError, "Error while fetching app health: "+err.Error())
return
}
RespondWithJSON(w, http.StatusOK, health)
RespondWithJSON(response.ResponseWriter, http.StatusOK, health)
case "service":
health, err := business.Health.GetNamespaceServiceHealth(p.Namespace, rateInterval, p.QueryTime)
if err != nil {
RespondWithError(w, http.StatusInternalServerError, "Error while fetching service health: "+err.Error())
RespondWithError(response.ResponseWriter, http.StatusInternalServerError, "Error while fetching service health: "+err.Error())
return
}
RespondWithJSON(w, http.StatusOK, health)
RespondWithJSON(response.ResponseWriter, http.StatusOK, health)
case "workload":
health, err := business.Health.GetNamespaceWorkloadHealth(p.Namespace, rateInterval, p.QueryTime)
if err != nil {
RespondWithError(w, http.StatusInternalServerError, "Error while fetching workload health: "+err.Error())
RespondWithError(response.ResponseWriter, http.StatusInternalServerError, "Error while fetching workload health: "+err.Error())
return
}
RespondWithJSON(w, http.StatusOK, health)
RespondWithJSON(response.ResponseWriter, http.StatusOK, health)
}
}
// AppHealth is the API handler to get health of a single app
func AppHealth(w http.ResponseWriter, r *http.Request) {
func AppHealth(request *restful.Request, response *restful.Response) {
business, err := business.Get()
if err != nil {
RespondWithError(w, http.StatusInternalServerError, "Services initialization error: "+err.Error())
RespondWithError(response.ResponseWriter, http.StatusInternalServerError, "Services initialization error: "+err.Error())
return
}
p := appHealthParams{}
p.extract(r)
p.extract(request)
rateInterval, err := adjustRateInterval(business, p.Namespace, p.RateInterval, p.QueryTime)
if err != nil {
RespondWithError(w, http.StatusInternalServerError, "Adjust rate interval error: "+err.Error())
RespondWithError(response.ResponseWriter, http.StatusInternalServerError, "Adjust rate interval error: "+err.Error())
return
}
health, err := business.Health.GetAppHealth(p.Namespace, p.App, rateInterval, p.QueryTime)
handleHealthResponse(w, health, err)
handleHealthResponse(response.ResponseWriter, health, err)
}
// WorkloadHealth is the API handler to get health of a single workload
func WorkloadHealth(w http.ResponseWriter, r *http.Request) {
func WorkloadHealth(request *restful.Request, response *restful.Response) {
business, err := business.Get()
if err != nil {
RespondWithError(w, http.StatusInternalServerError, "Services initialization error: "+err.Error())
RespondWithError(response.ResponseWriter, http.StatusInternalServerError, "Services initialization error: "+err.Error())
return
}
p := workloadHealthParams{}
p.extract(r)
p.extract(request)
rateInterval, err := adjustRateInterval(business, p.Namespace, p.RateInterval, p.QueryTime)
if err != nil {
RespondWithError(w, http.StatusInternalServerError, "Adjust rate interval error: "+err.Error())
RespondWithError(response.ResponseWriter, http.StatusInternalServerError, "Adjust rate interval error: "+err.Error())
return
}
p.RateInterval = rateInterval
health, err := business.Health.GetWorkloadHealth(p.Namespace, p.Workload, rateInterval, p.QueryTime)
handleHealthResponse(w, health, err)
handleHealthResponse(response.ResponseWriter, health, err)
}
// ServiceHealth is the API handler to get health of a single service
func ServiceHealth(w http.ResponseWriter, r *http.Request) {
func ServiceHealth(request *restful.Request, response *restful.Response) {
business, err := business.Get()
if err != nil {
RespondWithError(w, http.StatusInternalServerError, "Services initialization error: "+err.Error())
RespondWithError(response.ResponseWriter, http.StatusInternalServerError, "Services initialization error: "+err.Error())
return
}
p := serviceHealthParams{}
p.extract(r)
p.extract(request)
rateInterval, err := adjustRateInterval(business, p.Namespace, p.RateInterval, p.QueryTime)
if err != nil {
RespondWithError(w, http.StatusInternalServerError, "Adjust rate interval error: "+err.Error())
RespondWithError(response.ResponseWriter, http.StatusInternalServerError, "Adjust rate interval error: "+err.Error())
return
}
health, err := business.Health.GetServiceHealth(p.Namespace, p.Service, rateInterval, p.QueryTime)
handleHealthResponse(w, health, err)
handleHealthResponse(response.ResponseWriter, health, err)
}
func handleHealthResponse(w http.ResponseWriter, health interface{}, err error) {
......@@ -152,14 +152,12 @@ type baseHealthParams struct {
QueryTime time.Time
}
func (p *baseHealthParams) baseExtract(r *http.Request, vars map[string]string) {
func (p *baseHealthParams) baseExtract(request *restful.Request) {
p.RateInterval = defaultHealthRateInterval
p.QueryTime = util.Clock.Now()
queryParams := r.URL.Query()
if rateIntervals, ok := queryParams["rateInterval"]; ok && len(rateIntervals) > 0 {
p.RateInterval = rateIntervals[0]
}
p.Namespace = vars["namespace"]
p.RateInterval = request.QueryParameter("rateInterval")
p.Namespace = request.PathParameters()["namespace"]
}
// namespaceHealthParams holds the path and query parameters for NamespaceHealth
......@@ -175,19 +173,17 @@ type namespaceHealthParams struct {
Type string `json:"type"`
}
func (p *namespaceHealthParams) extract(r *http.Request) (bool, string) {
vars := mux.Vars(r)
p.baseExtract(r, vars)
func (p *namespaceHealthParams) extract(request *restful.Request) (bool, string) {
p.baseExtract(request)
p.Type = "app"
queryParams := r.URL.Query()
if healthTypes, ok := queryParams["type"]; ok && len(healthTypes) > 0 {
if healthTypes[0] != "app" && healthTypes[0] != "service" && healthTypes[0] != "workload" {
// Bad request
return false, "Bad request, query parameter 'type' must be one of ['app','service','workload']"
}
p.Type = healthTypes[0]
tp := request.QueryParameter("type")
switch tp {
case "app", "service", "workload":
p.Type = tp
return true, ""
}
return true, ""
return false, "Bad request, query parameter 'type' must be one of ['app','service','workload']"
}
// appHealthParams holds the path and query parameters for AppHealth
......@@ -201,10 +197,9 @@ type appHealthParams struct {
App string `json:"app"`
}
func (p *appHealthParams) extract(r *http.Request) {
vars := mux.Vars(r)
p.baseExtract(r, vars)
p.App = vars["app"]
func (p *appHealthParams) extract(request *restful.Request) {
p.baseExtract(request)
p.App = request.PathParameter("app")
}
// serviceHealthParams holds the path and query parameters for ServiceHealth
......@@ -218,10 +213,9 @@ type serviceHealthParams struct {
Service string `json:"service"`
}
func (p *serviceHealthParams) extract(r *http.Request) {
vars := mux.Vars(r)
p.baseExtract(r, vars)
p.Service = vars["service"]
func (p *serviceHealthParams) extract(request *restful.Request) {
p.baseExtract(request)
p.Service = request.PathParameter("service")
}
// workloadHealthParams holds the path and query parameters for WorkloadHealth
......@@ -235,10 +229,9 @@ type workloadHealthParams struct {
Workload string `json:"workload"`
}
func (p *workloadHealthParams) extract(r *http.Request) {
vars := mux.Vars(r)
p.baseExtract(r, vars)
p.Workload = vars["workload"]
func (p *workloadHealthParams) extract(request *restful.Request) {
p.baseExtract(request)
p.Workload = request.PathParameter("workload")
}
func adjustRateInterval(business *business.Layer, namespace, rateInterval string, queryTime time.Time) (string, error) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册