Merge pull request #4446 from zhu733756/master
Support importing Grafana templates to the workspace level.
This commit is contained in:
@@ -216,8 +216,8 @@ func (s *APIServer) installKubeSphereAPIs() {
|
||||
|
||||
urlruntime.Must(configv1alpha2.AddToContainer(s.container, s.Config))
|
||||
urlruntime.Must(resourcev1alpha3.AddToContainer(s.container, s.InformerFactory, s.RuntimeCache))
|
||||
urlruntime.Must(monitoringv1alpha3.AddToContainer(s.container, s.KubernetesClient.Kubernetes(), s.MonitoringClient, s.MetricsClient, s.InformerFactory, s.KubernetesClient.KubeSphere(), s.Config.OpenPitrixOptions))
|
||||
urlruntime.Must(meteringv1alpha1.AddToContainer(s.container, s.KubernetesClient.Kubernetes(), s.MonitoringClient, s.InformerFactory, s.KubernetesClient.KubeSphere(), s.RuntimeCache, s.Config.MeteringOptions, nil))
|
||||
urlruntime.Must(monitoringv1alpha3.AddToContainer(s.container, s.KubernetesClient.Kubernetes(), s.MonitoringClient, s.MetricsClient, s.InformerFactory, s.KubernetesClient.KubeSphere(), s.Config.OpenPitrixOptions, s.RuntimeClient))
|
||||
urlruntime.Must(meteringv1alpha1.AddToContainer(s.container, s.KubernetesClient.Kubernetes(), s.MonitoringClient, s.InformerFactory, s.KubernetesClient.KubeSphere(), s.RuntimeCache, s.Config.MeteringOptions, nil, s.RuntimeClient))
|
||||
urlruntime.Must(openpitrixv1.AddToContainer(s.container, s.InformerFactory, s.KubernetesClient.KubeSphere(), s.Config.OpenPitrixOptions))
|
||||
urlruntime.Must(openpitrixv2alpha1.AddToContainer(s.container, s.InformerFactory, s.KubernetesClient.KubeSphere(), s.Config.OpenPitrixOptions))
|
||||
urlruntime.Must(operationsv1alpha2.AddToContainer(s.container, s.KubernetesClient.Kubernetes()))
|
||||
|
||||
@@ -24,6 +24,8 @@ import (
|
||||
|
||||
openpitrixoptions "kubesphere.io/kubesphere/pkg/simple/client/openpitrix"
|
||||
|
||||
runtimeclient "sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/client/clientset/versioned"
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
monitorhle "kubesphere.io/kubesphere/pkg/kapis/monitoring/v1alpha3"
|
||||
@@ -45,6 +47,6 @@ type meterHandler interface {
|
||||
HandlePVCMeterQuery(req *restful.Request, resp *restful.Response)
|
||||
}
|
||||
|
||||
func newHandler(k kubernetes.Interface, m monitoring.Interface, f informers.InformerFactory, ksClient versioned.Interface, resourceGetter *resourcev1alpha3.ResourceGetter, meteringOptions *meteringclient.Options, opOptions *openpitrixoptions.Options) meterHandler {
|
||||
return monitorhle.NewHandler(k, m, nil, f, ksClient, resourceGetter, meteringOptions, opOptions)
|
||||
func newHandler(k kubernetes.Interface, m monitoring.Interface, f informers.InformerFactory, ksClient versioned.Interface, resourceGetter *resourcev1alpha3.ResourceGetter, meteringOptions *meteringclient.Options, opOptions *openpitrixoptions.Options, rtClient runtimeclient.Client) meterHandler {
|
||||
return monitorhle.NewHandler(k, m, nil, f, ksClient, resourceGetter, meteringOptions, opOptions, rtClient)
|
||||
}
|
||||
|
||||
@@ -30,6 +30,8 @@ import (
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"sigs.k8s.io/controller-runtime/pkg/cache"
|
||||
|
||||
runtimeclient "sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/apiserver/runtime"
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
@@ -47,10 +49,10 @@ const (
|
||||
|
||||
var GroupVersion = schema.GroupVersion{Group: groupName, Version: "v1alpha1"}
|
||||
|
||||
func AddToContainer(c *restful.Container, k8sClient kubernetes.Interface, meteringClient monitoring.Interface, factory informers.InformerFactory, ksClient versioned.Interface, cache cache.Cache, meteringOptions *meteringclient.Options, opOptions *openpitrixoptions.Options) error {
|
||||
func AddToContainer(c *restful.Container, k8sClient kubernetes.Interface, meteringClient monitoring.Interface, factory informers.InformerFactory, ksClient versioned.Interface, cache cache.Cache, meteringOptions *meteringclient.Options, opOptions *openpitrixoptions.Options, rtClient runtimeclient.Client) error {
|
||||
ws := runtime.NewWebService(GroupVersion)
|
||||
|
||||
h := newHandler(k8sClient, meteringClient, factory, ksClient, resourcev1alpha3.NewResourceGetter(factory, cache), meteringOptions, opOptions)
|
||||
h := newHandler(k8sClient, meteringClient, factory, ksClient, resourcev1alpha3.NewResourceGetter(factory, cache), meteringOptions, opOptions, rtClient)
|
||||
|
||||
ws.Route(ws.GET("/cluster").
|
||||
To(h.HandleClusterMeterQuery).
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
#! /bin/bash
|
||||
|
||||
curl -d '{"grafanaDashboardUrl":"https://grafana.com/api/dashboards/7362/revisions/5/download", "description":"this is a test dashboard."}' -H "Content-Type: application/json" localhost:9090/kapis/monitoring.kubesphere.io/v1alpha3/clusterdashboards/test1/template
|
||||
@@ -20,7 +20,6 @@ package v1alpha3
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
@@ -41,6 +40,7 @@ import (
|
||||
"github.com/emicklei/go-restful"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
runtimeclient "sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
monitoringdashboardv1alpha2 "kubesphere.io/monitoring-dashboard/api/v1alpha2"
|
||||
|
||||
@@ -57,9 +57,10 @@ type handler struct {
|
||||
mo model.MonitoringOperator
|
||||
opRelease openpitrix.ReleaseInterface
|
||||
meteringOptions *meteringclient.Options
|
||||
rtClient runtimeclient.Client
|
||||
}
|
||||
|
||||
func NewHandler(k kubernetes.Interface, monitoringClient monitoring.Interface, metricsClient monitoring.Interface, f informers.InformerFactory, ksClient versioned.Interface, resourceGetter *resourcev1alpha3.ResourceGetter, meteringOptions *meteringclient.Options, opOptions *openpitrixoptions.Options) *handler {
|
||||
func NewHandler(k kubernetes.Interface, monitoringClient monitoring.Interface, metricsClient monitoring.Interface, f informers.InformerFactory, ksClient versioned.Interface, resourceGetter *resourcev1alpha3.ResourceGetter, meteringOptions *meteringclient.Options, opOptions *openpitrixoptions.Options, rtClient runtimeclient.Client) *handler {
|
||||
var opRelease openpitrix.Interface
|
||||
var s3Client s3.Interface
|
||||
if opOptions != nil && opOptions.S3Options != nil && len(opOptions.S3Options.Endpoint) != 0 {
|
||||
@@ -81,6 +82,7 @@ func NewHandler(k kubernetes.Interface, monitoringClient monitoring.Interface, m
|
||||
mo: model.NewMonitoringOperator(monitoringClient, metricsClient, k, f, resourceGetter, opRelease),
|
||||
opRelease: opRelease,
|
||||
meteringOptions: meteringOptions,
|
||||
rtClient: rtClient,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -345,6 +347,7 @@ func (h handler) handleGrafanaDashboardImport(req *restful.Request, resp *restfu
|
||||
}
|
||||
|
||||
grafanaDashboardName := req.PathParameter("grafanaDashboardName")
|
||||
namespace := req.PathParameter("namespace")
|
||||
|
||||
if grafanaDashboardName == "" {
|
||||
err := errors.New("the requested parameter grafanaDashboardName cannot be empty")
|
||||
@@ -357,6 +360,7 @@ func (h handler) handleGrafanaDashboardImport(req *restful.Request, resp *restfu
|
||||
return
|
||||
}
|
||||
|
||||
// download the Grafana dashboard
|
||||
grafanaDashboardContent := []byte(entity.GrafanaDashboardContent)
|
||||
if entity.GrafanaDashboardUrl != "" {
|
||||
c, err := func(u string) ([]byte, error) {
|
||||
@@ -392,57 +396,89 @@ func (h handler) handleGrafanaDashboardImport(req *restful.Request, resp *restfu
|
||||
grafanaDashboardContent = []byte(c)
|
||||
}
|
||||
|
||||
isClusterCrd := namespace == ""
|
||||
c := converter.NewConverter()
|
||||
convertedDashboard, err := c.ConvertToDashboard(grafanaDashboardContent, true, "", grafanaDashboardName)
|
||||
convertedDashboard, err := c.ConvertToDashboard(grafanaDashboardContent, isClusterCrd, namespace, grafanaDashboardName)
|
||||
if err != nil {
|
||||
api.HandleBadRequest(resp, nil, err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx := context.TODO()
|
||||
annotation := map[string]string{"kubesphere.io/description": entity.Description}
|
||||
|
||||
dashboard := monitoringdashboardv1alpha2.ClusterDashboard{
|
||||
TypeMeta: v1.TypeMeta{
|
||||
APIVersion: convertedDashboard.APIVersion,
|
||||
Kind: convertedDashboard.Kind,
|
||||
},
|
||||
ObjectMeta: v1.ObjectMeta{
|
||||
Name: convertedDashboard.Metadata["name"],
|
||||
Annotations: annotation,
|
||||
},
|
||||
Spec: *convertedDashboard.Spec,
|
||||
// a cluster scope dashboard or a namespaced dashboard with the same name cannot post.
|
||||
if isClusterCrd {
|
||||
clusterdashboard := monitoringdashboardv1alpha2.ClusterDashboard{
|
||||
TypeMeta: v1.TypeMeta{
|
||||
APIVersion: convertedDashboard.APIVersion,
|
||||
Kind: convertedDashboard.Kind,
|
||||
},
|
||||
ObjectMeta: v1.ObjectMeta{
|
||||
Name: convertedDashboard.Metadata["name"],
|
||||
Annotations: annotation,
|
||||
},
|
||||
Spec: *convertedDashboard.Spec,
|
||||
}
|
||||
|
||||
objKey := runtimeclient.ObjectKey{
|
||||
Namespace: "",
|
||||
Name: clusterdashboard.Name,
|
||||
}
|
||||
|
||||
err = h.rtClient.Get(ctx, objKey, &clusterdashboard)
|
||||
|
||||
if err == nil {
|
||||
api.HandleBadRequest(resp, nil, errors.New("dashboards with the same name already exists."))
|
||||
return
|
||||
}
|
||||
|
||||
// create this dashboard
|
||||
err = h.rtClient.Create(ctx, &clusterdashboard)
|
||||
|
||||
if err != nil {
|
||||
api.HandleBadRequest(resp, nil, err)
|
||||
return
|
||||
}
|
||||
|
||||
resp.WriteAsJson(clusterdashboard)
|
||||
|
||||
} else {
|
||||
dashboard := monitoringdashboardv1alpha2.Dashboard{
|
||||
TypeMeta: v1.TypeMeta{
|
||||
APIVersion: convertedDashboard.APIVersion,
|
||||
Kind: convertedDashboard.Kind,
|
||||
},
|
||||
ObjectMeta: v1.ObjectMeta{
|
||||
Name: convertedDashboard.Metadata["name"],
|
||||
Namespace: namespace,
|
||||
Annotations: annotation,
|
||||
},
|
||||
Spec: *convertedDashboard.Spec,
|
||||
}
|
||||
|
||||
objKey := runtimeclient.ObjectKey{
|
||||
Namespace: namespace,
|
||||
Name: dashboard.Name,
|
||||
}
|
||||
|
||||
err = h.rtClient.Get(ctx, objKey, &dashboard)
|
||||
|
||||
if err == nil {
|
||||
api.HandleBadRequest(resp, nil, errors.New("dashboards with the same name already exists."))
|
||||
return
|
||||
}
|
||||
|
||||
// create this dashboard
|
||||
err = h.rtClient.Create(ctx, &dashboard)
|
||||
|
||||
if err != nil {
|
||||
api.HandleBadRequest(resp, nil, err)
|
||||
return
|
||||
}
|
||||
|
||||
resp.WriteAsJson(dashboard)
|
||||
|
||||
}
|
||||
|
||||
jsonDashbaord, err := json.Marshal(dashboard)
|
||||
if err != nil {
|
||||
api.HandleBadRequest(resp, nil, err)
|
||||
return
|
||||
}
|
||||
|
||||
// a dashboard with the same name cannot post.
|
||||
ctx := context.TODO()
|
||||
_, err = h.k.Discovery().RESTClient().
|
||||
Get().
|
||||
AbsPath("/apis/monitoring.kubesphere.io/v1alpha2/clusterdashboards/" + dashboard.Name).
|
||||
DoRaw(ctx)
|
||||
|
||||
if err == nil {
|
||||
api.HandleBadRequest(resp, nil, errors.New("a dashboard with the same name already exists."))
|
||||
return
|
||||
}
|
||||
|
||||
// create this dashboard
|
||||
_, err = h.k.Discovery().RESTClient().
|
||||
Post().
|
||||
AbsPath("/apis/monitoring.kubesphere.io/v1alpha2/clusterdashboards").
|
||||
Body(jsonDashbaord).
|
||||
DoRaw(ctx)
|
||||
|
||||
if err != nil {
|
||||
api.HandleBadRequest(resp, nil, err)
|
||||
return
|
||||
}
|
||||
|
||||
resp.WriteAsJson(dashboard)
|
||||
|
||||
}
|
||||
|
||||
@@ -373,7 +373,7 @@ func TestParseRequestParams(t *testing.T) {
|
||||
|
||||
fakeInformerFactory.KubeSphereSharedInformerFactory()
|
||||
|
||||
handler := NewHandler(client, nil, nil, fakeInformerFactory, ksClient, nil, nil, nil)
|
||||
handler := NewHandler(client, nil, nil, fakeInformerFactory, ksClient, nil, nil, nil, nil)
|
||||
|
||||
result, err := handler.makeQueryOptions(tt.params, tt.lvl)
|
||||
if err != nil {
|
||||
|
||||
@@ -36,6 +36,8 @@ import (
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
model "kubesphere.io/kubesphere/pkg/models/monitoring"
|
||||
"kubesphere.io/kubesphere/pkg/simple/client/monitoring"
|
||||
|
||||
runtimeclient "sigs.k8s.io/controller-runtime/pkg/client"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -45,10 +47,10 @@ const (
|
||||
|
||||
var GroupVersion = schema.GroupVersion{Group: groupName, Version: "v1alpha3"}
|
||||
|
||||
func AddToContainer(c *restful.Container, k8sClient kubernetes.Interface, monitoringClient monitoring.Interface, metricsClient monitoring.Interface, factory informers.InformerFactory, ksClient versioned.Interface, opOptions *openpitrixoptions.Options) error {
|
||||
func AddToContainer(c *restful.Container, k8sClient kubernetes.Interface, monitoringClient monitoring.Interface, metricsClient monitoring.Interface, factory informers.InformerFactory, ksClient versioned.Interface, opOptions *openpitrixoptions.Options, rtClient runtimeclient.Client) error {
|
||||
ws := runtime.NewWebService(GroupVersion)
|
||||
|
||||
h := NewHandler(k8sClient, monitoringClient, metricsClient, factory, ksClient, nil, nil, opOptions)
|
||||
h := NewHandler(k8sClient, monitoringClient, metricsClient, factory, ksClient, nil, nil, opOptions, rtClient)
|
||||
|
||||
ws.Route(ws.GET("/kubesphere").
|
||||
To(h.handleKubeSphereMetricsQuery).
|
||||
@@ -555,6 +557,16 @@ func AddToContainer(c *restful.Container, k8sClient kubernetes.Interface, monito
|
||||
Returns(http.StatusOK, respOK, monitoringdashboardv1alpha2.ClusterDashboard{})).
|
||||
Produces(restful.MIME_JSON)
|
||||
|
||||
ws.Route(ws.POST("/namespaces/{namespace}/dashboards/{grafanaDashboardName}/template").
|
||||
To(h.handleGrafanaDashboardImport).
|
||||
Doc("Convert Grafana templates to KubeSphere dashboards.").
|
||||
Param(ws.PathParameter("grafanaDashboardName", "The name of the Grafana template to be converted").DataType("string").Required(true)).
|
||||
Param(ws.PathParameter("namespace", "The name of the project").DataType("string").Required(true)).
|
||||
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DashboardTag}).
|
||||
Writes(monitoringdashboardv1alpha2.Dashboard{}).
|
||||
Returns(http.StatusOK, respOK, monitoringdashboardv1alpha2.Dashboard{})).
|
||||
Produces(restful.MIME_JSON)
|
||||
|
||||
c.Add(ws)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
#! /bin/bash
|
||||
|
||||
curl -d '{"grafanaDashboardUrl":"https://grafana.com/api/dashboards/7362/revisions/5/download", "description":"this is a test clusterdashboard."}' -H "Content-Type: application/json" localhost:9090/kapis/monitoring.kubesphere.io/v1alpha3/clusterdashboards/test1/template
|
||||
curl -d '{"grafanaDashboardUrl":"https://grafana.com/api/dashboards/7362/revisions/5/download", "description":"this is a test dashboard."}' -H "Content-Type: application/json" localhost:9090/kapis/monitoring.kubesphere.io/v1alpha3/namespaces/default/dashboards/test2/template
|
||||
@@ -53,6 +53,7 @@ type DashboardEntity struct {
|
||||
GrafanaDashboardUrl string `json:"grafanaDashboardUrl,omitempty"`
|
||||
GrafanaDashboardContent string `json:"grafanaDashboardContent,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
Namespace string `json:"namespace,omitempty"`
|
||||
}
|
||||
|
||||
// The first element is the timestamp, the second is the metric value.
|
||||
|
||||
@@ -123,7 +123,7 @@ func generateSwaggerJson() []byte {
|
||||
urlruntime.Must(devopsv1alpha2.AddToContainer(container, ""))
|
||||
urlruntime.Must(devopsv1alpha3.AddToContainer(container, ""))
|
||||
urlruntime.Must(iamv1alpha2.AddToContainer(container, nil, nil, group.New(informerFactory, clientsets.KubeSphere(), clientsets.Kubernetes()), nil))
|
||||
urlruntime.Must(monitoringv1alpha3.AddToContainer(container, clientsets.Kubernetes(), nil, nil, informerFactory, nil, nil))
|
||||
urlruntime.Must(monitoringv1alpha3.AddToContainer(container, clientsets.Kubernetes(), nil, nil, informerFactory, nil, nil, nil))
|
||||
urlruntime.Must(openpitrixv1.AddToContainer(container, informerFactory, fake.NewSimpleClientset(), nil))
|
||||
urlruntime.Must(openpitrixv2.AddToContainer(container, informerFactory, fake.NewSimpleClientset(), nil))
|
||||
urlruntime.Must(operationsv1alpha2.AddToContainer(container, clientsets.Kubernetes()))
|
||||
|
||||
Reference in New Issue
Block a user