diff --git a/pkg/apis/servicemesh/metrics/v1alpha2/register.go b/pkg/apis/servicemesh/metrics/v1alpha2/register.go index 0990ee9be..6c1b27b3e 100644 --- a/pkg/apis/servicemesh/metrics/v1alpha2/register.go +++ b/pkg/apis/servicemesh/metrics/v1alpha2/register.go @@ -7,7 +7,7 @@ import ( "kubesphere.io/kubesphere/pkg/apiserver/runtime" "kubesphere.io/kubesphere/pkg/apiserver/servicemesh/metrics" "kubesphere.io/kubesphere/pkg/apiserver/servicemesh/tracing" - "kubesphere.io/kubesphere/pkg/errors" + "net/http" ) const GroupName = "servicemesh.kubesphere.io" @@ -30,19 +30,21 @@ func addWebService(c *restful.Container) error { webservice.Route(webservice.GET("/namespaces/{namespace}/services/{service}/metrics"). To(metrics.GetServiceMetrics). Metadata(restfulspec.KeyOpenAPITags, tags). - Doc("Get app metrics from a specific namespace"). + Doc("Get service metrics from a specific namespace"). Param(webservice.PathParameter("namespace", "name of the namespace")). Param(webservice.PathParameter("service", "name of the service")). - Param(webservice.QueryParameter("filters[]", "type of metrics type, e.g. request_count, request_duration, request_error_count")). + Param(webservice.QueryParameter("filters[]", "type of metrics type, fetch all metrics when empty, e.g. request_count, request_duration, request_error_count").DefaultValue("[]")). Param(webservice.QueryParameter("queryTime", "from which UNIX time to extract metrics")). - Param(webservice.QueryParameter("duration", "metrics duration, in seconds")). - Param(webservice.QueryParameter("step", "metrics step")). - Param(webservice.QueryParameter("rateInterval", "metrics rate intervals, e.g. 20s")). - Param(webservice.QueryParameter("quantiles[]", "metrics quantiles, 0.5, 0.9, 0.99")). - Param(webservice.QueryParameter("byLabels[]", "by which labels to group node, e.g. source_workload, destination_service_name")). - Param(webservice.QueryParameter("requestProtocol", "request protocol, http/tcp")). - Param(webservice.QueryParameter("reporter", "destination")). - Writes(errors.Error{})).Produces(restful.MIME_JSON) + Param(webservice.QueryParameter("duration", "duration of the query period, in seconds").DefaultValue("1800")). + Param(webservice.QueryParameter("step", "step between graph data points, in seconds.").DefaultValue("15")). + Param(webservice.QueryParameter("rateInterval", "metrics rate intervals, e.g. 20s").DefaultValue("1m")). + Param(webservice.QueryParameter("direction", "traffic direction: 'inbound' or 'outbound'").DefaultValue("outbound")). + Param(webservice.QueryParameter("quantiles[]", "list of quantiles to fetch, fetch no quantiles when empty. eg. 0.5, 0.9, 0.99").DefaultValue("[]")). + Param(webservice.QueryParameter("byLabels[]", "list of labels to use for grouping metrics(via Prometheus 'by' clause), e.g. source_workload, destination_service_name").DefaultValue("[]")). + Param(webservice.QueryParameter("requestProtocol", "request protocol for the telemetry, e.g. http/tcp/grpc").DefaultValue("all protocols")). + Param(webservice.QueryParameter("reporter", "istio telemetry reporter, 'source' or 'destination'").DefaultValue("source")). + Returns(http.StatusOK, "ok", MetricsResponse{}). + Writes(MetricsResponse{})).Produces(restful.MIME_JSON) // Get app metrics // Get /namespaces/{namespace}/apps/{app}/metrics @@ -51,17 +53,20 @@ func addWebService(c *restful.Container) error { Metadata(restfulspec.KeyOpenAPITags, tags). Doc("Get app metrics from a specific namespace"). Param(webservice.PathParameter("namespace", "name of the namespace")). - Param(webservice.PathParameter("app", "name of the workload label app value")). - Param(webservice.QueryParameter("filters[]", "type of metrics type, e.g. request_count, request_duration, request_error_count")). + Param(webservice.PathParameter("app", "name of the app")). + Param(webservice.QueryParameter("filters[]", "type of metrics type, fetch all metrics when empty, e.g. request_count, request_duration, request_error_count").DefaultValue("[]")). Param(webservice.QueryParameter("queryTime", "from which UNIX time to extract metrics")). - Param(webservice.QueryParameter("duration", "metrics duration, in seconds")). - Param(webservice.QueryParameter("step", "metrics step")). - Param(webservice.QueryParameter("rateInterval", "metrics rate intervals, e.g. 20s")). - Param(webservice.QueryParameter("quantiles[]", "metrics quantiles, 0.5, 0.9, 0.99")). - Param(webservice.QueryParameter("byLabels[]", "by which labels to group node, e.g. source_workload, destination_service_name")). - Param(webservice.QueryParameter("requestProtocol", "request protocol, http/tcp")). - Param(webservice.QueryParameter("reporter", "destination")). - Writes(errors.Error{})).Produces(restful.MIME_JSON) + Param(webservice.QueryParameter("duration", "duration of the query period, in seconds").DefaultValue("1800")). + Param(webservice.QueryParameter("step", "step between graph data points, in seconds.").DefaultValue("15")). + Param(webservice.QueryParameter("rateInterval", "metrics rate intervals, e.g. 20s").DefaultValue("1m")). + Param(webservice.QueryParameter("direction", "traffic direction: 'inbound' or 'outbound'").DefaultValue("outbound")). + Param(webservice.QueryParameter("quantiles[]", "list of quantiles to fetch, fetch no quantiles when empty. eg. 0.5, 0.9, 0.99").DefaultValue("[]")). + Param(webservice.QueryParameter("byLabels[]", "list of labels to use for grouping metrics(via Prometheus 'by' clause), e.g. source_workload, destination_service_name").DefaultValue("[]")). + Param(webservice.QueryParameter("requestProtocol", "request protocol for the telemetry, e.g. http/tcp/grpc").DefaultValue("all protocols")). + Param(webservice.QueryParameter("reporter", "istio telemetry reporter, 'source' or 'destination'").DefaultValue("source")). + Returns(http.StatusOK, "ok", MetricsResponse{}). + Writes(MetricsResponse{})). + Produces(restful.MIME_JSON) // Get workload metrics // Get /namespaces/{namespace}/workloads/{workload}/metrics @@ -71,16 +76,20 @@ func addWebService(c *restful.Container) error { Doc("Get workload metrics from a specific namespace"). 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.PathParameter("service", "name of the service")). + Param(webservice.QueryParameter("filters[]", "type of metrics type, fetch all metrics when empty, e.g. request_count, request_duration, request_error_count").DefaultValue("[]")). Param(webservice.QueryParameter("queryTime", "from which UNIX time to extract metrics")). - Param(webservice.QueryParameter("duration", "metrics duration, in seconds")). - Param(webservice.QueryParameter("step", "metrics step")). - Param(webservice.QueryParameter("rateInterval", "metrics rate intervals, e.g. 20s")). - Param(webservice.QueryParameter("quantiles[]", "metrics quantiles, 0.5, 0.9, 0.99")). - Param(webservice.QueryParameter("byLabels[]", "by which labels to group node, e.g. source_workload, destination_service_name")). - Param(webservice.QueryParameter("requestProtocol", "request protocol, http/tcp")). - Param(webservice.QueryParameter("reporter", "destination")). - Writes(errors.Error{})).Produces(restful.MIME_JSON) + Param(webservice.QueryParameter("duration", "duration of the query period, in seconds").DefaultValue("1800")). + Param(webservice.QueryParameter("step", "step between graph data points, in seconds.").DefaultValue("15")). + Param(webservice.QueryParameter("rateInterval", "metrics rate intervals, e.g. 20s").DefaultValue("1m")). + Param(webservice.QueryParameter("direction", "traffic direction: 'inbound' or 'outbound'").DefaultValue("outbound")). + Param(webservice.QueryParameter("quantiles[]", "list of quantiles to fetch, fetch no quantiles when empty. eg. 0.5, 0.9, 0.99").DefaultValue("[]")). + Param(webservice.QueryParameter("byLabels[]", "list of labels to use for grouping metrics(via Prometheus 'by' clause), e.g. source_workload, destination_service_name").DefaultValue("[]")). + Param(webservice.QueryParameter("requestProtocol", "request protocol for the telemetry, e.g. http/tcp/grpc").DefaultValue("all protocols")). + Param(webservice.QueryParameter("reporter", "istio telemetry reporter, 'source' or 'destination'").DefaultValue("source")). + Returns(http.StatusOK, "ok", MetricsResponse{}). + Writes(MetricsResponse{})). + Produces(restful.MIME_JSON) // Get namespace metrics // Get /namespaces/{namespace}/metrics @@ -89,16 +98,19 @@ func addWebService(c *restful.Container) error { Metadata(restfulspec.KeyOpenAPITags, tags). Doc("Get workload metrics from a specific 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.PathParameter("service", "name of the service")). + Param(webservice.QueryParameter("filters[]", "type of metrics type, fetch all metrics when empty, e.g. request_count, request_duration, request_error_count").DefaultValue("[]")). Param(webservice.QueryParameter("queryTime", "from which UNIX time to extract metrics")). - Param(webservice.QueryParameter("duration", "metrics duration, in seconds")). - Param(webservice.QueryParameter("step", "metrics step")). - Param(webservice.QueryParameter("rateInterval", "metrics rate intervals, e.g. 20s")). - Param(webservice.QueryParameter("quantiles[]", "metrics quantiles, 0.5, 0.9, 0.99")). - Param(webservice.QueryParameter("byLabels[]", "by which labels to group node, e.g. source_workload, destination_service_name")). - Param(webservice.QueryParameter("requestProtocol", "request protocol, http/tcp")). - Param(webservice.QueryParameter("reporter", "destination")). - Writes(errors.Error{})).Produces(restful.MIME_JSON) + Param(webservice.QueryParameter("duration", "duration of the query period, in seconds").DefaultValue("1800")). + Param(webservice.QueryParameter("step", "step between graph data points, in seconds.").DefaultValue("15")). + Param(webservice.QueryParameter("rateInterval", "metrics rate intervals, e.g. 20s").DefaultValue("1m")). + Param(webservice.QueryParameter("direction", "traffic direction: 'inbound' or 'outbound'").DefaultValue("outbound")). + Param(webservice.QueryParameter("quantiles[]", "list of quantiles to fetch, fetch no quantiles when empty. eg. 0.5, 0.9, 0.99").DefaultValue("[]")). + Param(webservice.QueryParameter("byLabels[]", "list of labels to use for grouping metrics(via Prometheus 'by' clause), e.g. source_workload, destination_service_name").DefaultValue("[]")). + Param(webservice.QueryParameter("requestProtocol", "request protocol for the telemetry, e.g. http/tcp/grpc").DefaultValue("all protocols")). + Param(webservice.QueryParameter("reporter", "istio telemetry reporter, 'source' or 'destination'").DefaultValue("source")). + Returns(http.StatusOK, "ok", MetricsResponse{}). + Writes(MetricsResponse{})).Produces(restful.MIME_JSON) // Get namespace graph // Get /namespaces/{namespace}/graph @@ -107,25 +119,31 @@ func addWebService(c *restful.Container) error { Metadata(restfulspec.KeyOpenAPITags, tags). Doc("Get service graph for a specific 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")). - Param(webservice.QueryParameter("injectServiceNodes", "whether to inject service ndoes")). - Writes(errors.Error{})).Produces(restful.MIME_JSON) + Param(webservice.QueryParameter("duration", "duration of the query period, in seconds").DefaultValue("10m")). + Param(webservice.QueryParameter("graphType", "type of the generated service graph. Available graph types: [app, service, versionedApp, workload].").DefaultValue("workload")). + Param(webservice.QueryParameter("groupBy", "app box grouping characteristic. Available groupings: [app, none, version].").DefaultValue("none")). + Param(webservice.QueryParameter("queryTime", "from which time point in UNIX timestamp, default now")). + Param(webservice.QueryParameter("injectServiceNodes", "flag for injecting the requested service node between source and destination nodes.").DefaultValue("false")). + Returns(http.StatusBadRequest, "bad request", BadRequestError{}). + Returns(http.StatusNotFound, "not found", NotFoundError{}). + Returns(http.StatusOK, "ok", GraphResponse{}). + Writes(GraphResponse{})).Produces(restful.MIME_JSON) // Get namespaces graph, for multiple namespaces // Get /namespaces/graph - webservice.Route(webservice.GET("/namespaces/{namespace}/graph"). + webservice.Route(webservice.GET("/namespaces/graph"). To(metrics.GetNamespacesGraph). Metadata(restfulspec.KeyOpenAPITags, tags). - Doc("Get service graph for a specific 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")). - Param(webservice.QueryParameter("injectServiceNodes", "whether to inject service ndoes")). - Param(webservice.QueryParameter("namespaces", "names of namespaces")). - Writes(errors.Error{})).Produces(restful.MIME_JSON) + Doc("Get graph from all namespaces"). + Param(webservice.QueryParameter("duration", "duration of the query period, in seconds").DefaultValue("10m")). + Param(webservice.QueryParameter("graphType", "type of the generated service graph. Available graph types: [app, service, versionedApp, workload].").DefaultValue("workload")). + Param(webservice.QueryParameter("groupBy", "app box grouping characteristic. Available groupings: [app, none, version].").DefaultValue("none")). + Param(webservice.QueryParameter("queryTime", "from which time point in UNIX timestamp, default now")). + Param(webservice.QueryParameter("injectServiceNodes", "flag for injecting the requested service node between source and destination nodes.").DefaultValue("false")). + Returns(http.StatusBadRequest, "bad request", BadRequestError{}). + Returns(http.StatusNotFound, "not found", NotFoundError{}). + Returns(http.StatusOK, "ok", GraphResponse{}). + Writes(GraphResponse{})).Produces(restful.MIME_JSON) // Get namespace health webservice.Route(webservice.GET("/namespaces/{namespace}/health"). @@ -136,7 +154,10 @@ func addWebService(c *restful.Container) error { Param(webservice.PathParameter("type", "the type of health, app/service/workload, default app").DefaultValue("app")). 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) + Returns(http.StatusBadRequest, "bad request", BadRequestError{}). + Returns(http.StatusNotFound, "not found", NotFoundError{}). + Returns(http.StatusOK, "ok", namespaceAppHealthResponse{}). + Writes(namespaceAppHealthResponse{})).Produces(restful.MIME_JSON) // Get workloads health webservice.Route(webservice.GET("/namespaces/{namespace}/workloads/{workload}/health"). @@ -147,7 +168,8 @@ func addWebService(c *restful.Container) error { 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) + ReturnsError(http.StatusOK, "ok", workloadHealthResponse{}). + Writes(workloadHealthResponse{})).Produces(restful.MIME_JSON) // Get app health webservice.Route(webservice.GET("/namespaces/{namespace}/apps/{app}/health"). @@ -158,7 +180,8 @@ func addWebService(c *restful.Container) error { 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) + Returns(http.StatusOK, "ok", appHealthResponse{}). + Writes(appHealthResponse{})).Produces(restful.MIME_JSON) // Get service health webservice.Route(webservice.GET("/namespaces/{namespace}/services/{service}/health"). @@ -169,7 +192,8 @@ func addWebService(c *restful.Container) error { 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) + Returns(http.StatusOK, "ok", serviceHealthResponse{}). + Writes(serviceHealthResponse{})).Produces(restful.MIME_JSON) // Get service tracing webservice.Route(webservice.GET("/namespaces/{namespace}/services/{service}/traces"). @@ -182,9 +206,8 @@ func addWebService(c *restful.Container) error { Param(webservice.QueryParameter("end", "end of time range want to query, in unix timestamp")). Param(webservice.QueryParameter("limit", "maximum tracing entries returned at one query, default 10").DefaultValue("10")). Param(webservice.QueryParameter("loopback", "loopback of duration want to query, e.g. 30m/1h/2d")). - Param(webservice.QueryParameter("maxDuration", "maximum duration of tracing")). - Param(webservice.QueryParameter("minDuration", "minimum duration of tracing")). - Writes(errors.Error{}). + Param(webservice.QueryParameter("maxDuration", "maximum duration of a request")). + Param(webservice.QueryParameter("minDuration", "minimum duration of a request")). Consumes(restful.MIME_JSON). Produces(restful.MIME_JSON)) diff --git a/pkg/apis/servicemesh/metrics/v1alpha2/swagger-doc.go b/pkg/apis/servicemesh/metrics/v1alpha2/swagger-doc.go new file mode 100644 index 000000000..e8d3294d4 --- /dev/null +++ b/pkg/apis/servicemesh/metrics/v1alpha2/swagger-doc.go @@ -0,0 +1,54 @@ +package v1alpha2 + +import ( + "github.com/kiali/kiali/graph/cytoscape" + "github.com/kiali/kiali/models" + "github.com/kiali/kiali/prometheus" +) + +///////////////////// +// SWAGGER RESPONSES +///////////////////// + +// NoContent: the response is empty +type NoContent struct { + Status int32 `json:"status"` + Reason error `json:"reason"` +} + +// BadRequestError: the client request is incorrect +type BadRequestError struct { + Status int32 `json:"status"` + Reason error `json:"reason"` +} + +// NotFoundError is the error message that is generated when server could not find +// what was requested +type NotFoundError struct { + Status int32 `json:"status"` + Reason error `json:"reason"` +} + +type GraphResponse struct { + cytoscape.Config +} + +type serviceHealthResponse struct { + models.ServiceHealth +} + +type namespaceAppHealthResponse struct { + models.NamespaceAppHealth +} + +type workloadHealthResponse struct { + models.WorkloadHealth +} + +type appHealthResponse struct { + models.AppHealth +} + +type MetricsResponse struct { + prometheus.Metrics +}