1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package debug
17
18 import (
19 "context"
20 "fmt"
21 "strings"
22
23 "github.com/hasura/go-graphql-client"
24
25 "github.com/chaos-mesh/chaos-mesh/api/v1alpha1"
26 "github.com/chaos-mesh/chaos-mesh/pkg/chaosctl/common"
27 ctrlclient "github.com/chaos-mesh/chaos-mesh/pkg/ctrl/client"
28 )
29
30 type httpDebugger struct {
31 client *ctrlclient.CtrlClient
32 }
33
34 func HTTPDebug(client *ctrlclient.CtrlClient) Debugger {
35 return &httpDebugger{
36 client: client,
37 }
38 }
39
40 func (d *httpDebugger) Collect(ctx context.Context, namespace, chaosName string) ([]*common.ChaosResult, error) {
41 var results []*common.ChaosResult
42
43 var name *graphql.String
44 if chaosName != "" {
45 n := graphql.String(chaosName)
46 name = &n
47 }
48
49 var query struct {
50 Namespace []struct {
51 HTTPChaos []struct {
52 Name string
53 Podhttp []struct {
54 Namespace string
55 Name string
56 Spec *v1alpha1.PodHttpChaosSpec
57 Pod struct {
58 Iptables []string
59 Processes []struct {
60 Pid string
61 Command string
62 Fds []struct {
63 Fd, Target string
64 }
65 }
66 }
67 }
68 } `graphql:"httpchaos(name: $name)"`
69 } `graphql:"namespace(ns: $namespace)"`
70 }
71
72 variables := map[string]interface{}{
73 "namespace": graphql.String(namespace),
74 "name": name,
75 }
76
77 err := d.client.QueryClient.Query(ctx, &query, variables)
78 if err != nil {
79 return nil, err
80 }
81
82 if len(query.Namespace) == 0 {
83 return results, nil
84 }
85
86 for _, httpChaos := range query.Namespace[0].HTTPChaos {
87 result := &common.ChaosResult{
88 Name: string(httpChaos.Name),
89 }
90
91 for _, podhttpchaos := range httpChaos.Podhttp {
92 podResult := common.PodResult{
93 Name: string(podhttpchaos.Name),
94 }
95
96 podResult.Items = append(podResult.Items, common.ItemResult{Name: "iptables list", Value: strings.Join(podhttpchaos.Pod.Iptables, "\n")})
97 for _, process := range podhttpchaos.Pod.Processes {
98 var fds []string
99 for _, fd := range process.Fds {
100 fds = append(fds, fmt.Sprintf("%s -> %s", fd.Fd, fd.Target))
101 }
102 podResult.Items = append(podResult.Items, common.ItemResult{
103 Name: fmt.Sprintf("file descriptors of PID: %s, COMMAND: %s", process.Pid, process.Command),
104 Value: strings.Join(fds, "\n"),
105 })
106 }
107 output, err := common.MarshalChaos(podhttpchaos.Spec)
108 if err != nil {
109 return nil, err
110 }
111 podResult.Items = append(podResult.Items, common.ItemResult{Name: "podhttpchaos", Value: output})
112 result.Pods = append(result.Pods, podResult)
113 }
114
115 results = append(results, result)
116 }
117 return results, nil
118 }
119
120 func (d *httpDebugger) List(ctx context.Context, namespace string) ([]string, error) {
121 var query struct {
122 Namespace []struct {
123 HTTPChaos []struct {
124 Name string
125 } `graphql:"httpchaos"`
126 } `graphql:"namespace(ns: $namespace)"`
127 }
128
129 variables := map[string]interface{}{
130 "namespace": graphql.String(namespace),
131 }
132
133 err := d.client.QueryClient.Query(ctx, &query, variables)
134 if err != nil {
135 return nil, err
136 }
137
138 if len(query.Namespace) == 0 {
139 return nil, nil
140 }
141
142 var names []string
143 for _, httpChaos := range query.Namespace[0].HTTPChaos {
144 names = append(names, string(httpChaos.Name))
145 }
146 return names, nil
147 }
148