-
Notifications
You must be signed in to change notification settings - Fork 125
/
models.go
155 lines (135 loc) · 4.6 KB
/
models.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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
// Copyright 2024 PingCAP, Inc. Licensed under Apache-2.0.
package endpoint
import (
"encoding/hex"
"fmt"
"strconv"
"github.com/pingcap/tidb-dashboard/util/client/httpclient"
"github.com/pingcap/tidb-dashboard/util/topo"
)
// APIDefinition defines what an API endpoints accepts.
// APIDefinition can be "resolved" to become a request when its parameter values are given via RequestPayload.
type APIDefinition struct {
ID string `json:"id"`
Component topo.Kind `json:"component"`
Path string `json:"path"`
Method string `json:"method"`
PathParams []APIParamDefinition `json:"path_params"` // e.g. /stats/dump/{db}/{table} -> db, table
QueryParams []APIParamDefinition `json:"query_params"` // e.g. /debug/pprof?seconds=1 -> seconds
BeforeSendRequest func(req *httpclient.LazyRequest) `json:"-"`
}
type APIParamResolveFn func(value string) ([]string, error)
// APIParamDefinition defines what an API endpoint parameter accepts and how it should look like in the UI.
// Usually this struct doesn't need to be manually constructed. Use APIParamXxx() helpers.
type APIParamDefinition struct {
Name string `json:"name"`
Required bool `json:"required"`
UIComponentKind string `json:"ui_kind"`
UIComponentProps interface{} `json:"ui_props"` // varies by different ui kinds
OnResolve APIParamResolveFn `json:"-"`
}
func (d *APIParamDefinition) Resolve(value string) ([]string, error) {
if d.OnResolve == nil {
return []string{value}, nil
}
return d.OnResolve(value)
}
// UIComponentTextProps is the type of UIComponentProps when UIComponentKind is "text".
type UIComponentTextProps struct {
Placeholder string `json:"placeholder"`
DefaultVal string `json:"default_val"`
}
func APIParamText(name string, required bool) APIParamDefinition {
return APIParamDefinition{
Name: name,
Required: required,
UIComponentKind: "text",
}
}
func APIParamInt(name string, required bool) APIParamDefinition {
return APIParamIntWithDefaultVal(name, required, "")
}
func APIParamIntWithDefaultVal(name string, required bool, defVal string) APIParamDefinition {
placeHolder := "(int)"
if defVal != "" {
placeHolder = fmt.Sprintf("(int, default: %s)", defVal)
}
return APIParamDefinition{
Name: name,
Required: required,
UIComponentKind: "text",
UIComponentProps: UIComponentTextProps{
Placeholder: placeHolder,
DefaultVal: defVal,
},
OnResolve: func(value string) ([]string, error) {
if _, err := strconv.Atoi(value); err != nil {
return nil, fmt.Errorf("'%s' is not a int", value)
}
return []string{value}, nil
},
}
}
func APIParamDBName(name string, required bool) APIParamDefinition {
return APIParamDefinition{
Name: name,
Required: required,
UIComponentKind: "db_dropdown",
}
}
func APIParamTableName(name string, required bool) APIParamDefinition {
return APIParamDefinition{
Name: name,
Required: required,
UIComponentKind: "table_dropdown",
}
}
func APIParamTableID(name string, required bool) APIParamDefinition {
return APIParamDefinition{
Name: name,
Required: required,
UIComponentKind: "table_id_dropdown",
}
}
// UIComponentDropdownProps is the type of UIComponentProps when UIComponentKind is "dropdown".
type UIComponentDropdownProps struct {
Items []EnumItemDefinition `json:"items"`
}
type EnumItemDefinition struct {
Value string `json:"value"`
DisplayAs string `json:"display_as"` // Optional
}
func APIParamEnum(name string, required bool, items []EnumItemDefinition) APIParamDefinition {
return APIParamDefinition{
Name: name,
Required: required,
UIComponentKind: "dropdown",
UIComponentProps: UIComponentDropdownProps{Items: items},
OnResolve: func(value string) ([]string, error) {
for _, item := range items {
if item.Value == value {
return []string{value}, nil
}
}
return nil, fmt.Errorf("'%s' is not a valid enum value", value)
},
}
}
// Below are some special API param kinds.
func APIParamPDKey(name string, required bool) APIParamDefinition {
return APIParamDefinition{
Name: name,
Required: required,
UIComponentKind: "text",
UIComponentProps: UIComponentTextProps{
Placeholder: "(hex key, e.g. 748000...)",
},
OnResolve: func(value string) ([]string, error) {
keyBinary, err := hex.DecodeString(value)
if err != nil {
return nil, fmt.Errorf("'%s' is not a valid hex key", value)
}
return []string{string(keyBinary)}, nil
},
}
}