-
Notifications
You must be signed in to change notification settings - Fork 474
/
graph.go
101 lines (89 loc) · 3.46 KB
/
graph.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
package handlers
// Graph.go provides handlers for graph request endpoints. The handlers access vendor-specific
// telemetry (default istio) and return vendor-specific configuration (default cytoscape). The
// configuration format depends on the vendor but is typically JSON and provides what is necessary
// to allow the vendor's tool to render the graph.
//
// The algorithm is two-phased:
// Phase One: Generate a TrafficMap using the requested TelemetryVendor. This typically queries
// Prometheus, Istio and Kubernetes.
//
// Phase Two: Provide the TrafficMap to the requested ConfigVendor which returns the vendor-specific
// configuration returned to the caller.
//
// The current Handlers:
// GraphNamespaces: Generate a graph for one or more requested namespaces.
// GraphNode: Generate a graph for a specific node, detailing the immediate incoming and outgoing traffic.
//
// The handlers accept the following query parameters (see notes below)
// appenders: Comma-separated list of TelemetryVendor-specific appenders to run. (default: all)
// configVendor: default: cytoscape
// duration: time.Duration indicating desired query range duration, (default: 10m)
// graphType: Determines how to present the telemetry data. app | service | versionedApp | workload (default: workload)
// boxBy: If supported by vendor, visually box by a specified node attribute (default: none)
// namespaces: Comma-separated list of namespace names to use in the graph. Will override namespace path param
// queryTime: Unix time (seconds) for query such that range is queryTime-duration..queryTime (default now)
// TelemetryVendor: default: istio
//
// Note: some handlers may ignore some query parameters.
// Note: vendors may support additional, vendor-specific query parameters.
//
import (
"fmt"
"net/http"
"runtime/debug"
"github.com/kiali/kiali/graph"
"github.com/kiali/kiali/graph/api"
"github.com/kiali/kiali/log"
)
// GraphNamespaces is a REST http.HandlerFunc handling graph generation for 1 or more namespaces
func GraphNamespaces(w http.ResponseWriter, r *http.Request) {
defer handlePanic(w)
o := graph.NewOptions(r)
business, err := getBusiness(r)
graph.CheckError(err)
code, payload := api.GraphNamespaces(r.Context(), business, o)
respond(w, code, payload)
}
// GraphNode is a REST http.HandlerFunc handling node-detail graph config generation.
func GraphNode(w http.ResponseWriter, r *http.Request) {
defer handlePanic(w)
o := graph.NewOptions(r)
business, err := getBusiness(r)
graph.CheckError(err)
code, payload := api.GraphNode(r.Context(), business, o)
respond(w, code, payload)
}
func handlePanic(w http.ResponseWriter) {
code := http.StatusInternalServerError
if r := recover(); r != nil {
var message string
switch err := r.(type) {
case string:
message = err
case error:
message = err.Error()
case func() string:
message = err()
case graph.Response:
message = err.Message
code = err.Code
default:
message = fmt.Sprintf("%v", r)
}
if code == http.StatusInternalServerError {
stack := debug.Stack()
log.Errorf("%s: %s", message, stack)
RespondWithDetailedError(w, code, message, string(stack))
return
}
RespondWithError(w, code, message)
}
}
func respond(w http.ResponseWriter, code int, payload interface{}) {
if code == http.StatusOK {
RespondWithJSONIndent(w, code, payload)
return
}
RespondWithError(w, code, payload.(string))
}