...
1
4 package rpc
5
6 import (
7 "flag"
8 "fmt"
9 "golang.conradwood.net/apis/auth"
10 ge "golang.conradwood.net/apis/goeasyops"
11 "golang.conradwood.net/go-easyops/common"
12 "golang.conradwood.net/go-easyops/prometheus"
13
14 "golang.org/x/net/context"
15 "time"
16 )
17
18 const (
19 LOCALCONTEXTNAME = "GOEASYOPS_LOCALCTX"
20 LOCALCONTEXTNAMEV2 = "GOEASYOPS_LOCALCTX_V2"
21
22 DEFAULT_TIMEOUT_SECS = 10
23 )
24
25 var (
26 moan_about_no_auth = flag.Bool("ge_debug_print_old_signatures", false, "if true print services which are calling this module with old-style signatures")
27 userSourceMetric = prometheus.NewCounterVec(
28 prometheus.CounterOpts{
29 Name: "grpc_requests_user_source",
30 Help: "V=1 UNIT=ops DESC=RPC requests with users, split by source",
31 },
32 []string{"servicename", "method", "source"},
33 )
34 )
35
36 func init() {
37 prometheus.MustRegister(userSourceMetric)
38 }
39
40
41
42 type CallState struct {
43
44 Debug bool
45 Started time.Time
46 ServiceName string
47 MethodName string
48 CallingMethodID uint64
49 Context context.Context
50 MyServiceID uint64
51 userCounted bool
52
53 v2 LocalCallState
54 isV2 bool
55 signedUser *auth.SignedUser
56 signedService *auth.SignedUser
57 }
58
59
60 func (c *CallState) SetV2(lcs LocalCallState) {
61 c.v2 = lcs
62 c.isV2 = true
63 }
64 func (c *CallState) IsV2() bool {
65 return c.isV2
66 }
67 func EnableDebug(ctx context.Context) {
68 cs := CallStateFromContext(ctx)
69 if cs == nil {
70 return
71 }
72 cs.Debug = true
73 }
74
75 func (cs *CallState) RequestID() string {
76 if cs.IsV2() {
77 return cs.v2.RequestID()
78 }
79 panic("obsolete codepath")
80 }
81
82 func (cs *CallState) SignedUser() *auth.SignedUser {
83 return cs.signedUser
84
85 }
86 func (cs *CallState) SignedService() *auth.SignedUser {
87 return cs.signedService
88 }
89
90
91 func (cs *CallState) User() *auth.User {
92 if cs == nil {
93 return nil
94 }
95 if cs.IsV2() {
96 return cs.v2.User()
97 }
98 panic("obsolete codepath")
99 }
100
101 func (cs *CallState) userbysource(src string) {
102 if cs.userCounted {
103 return
104 }
105 if *moan_about_no_auth && src != "signedv2" && src != "none" {
106 sn := "undef"
107 s := cs.CallerService()
108 if s != nil {
109 sn = fmt.Sprintf("%s/%s", s.ID, s.Email)
110 }
111 fmt.Printf("[go-easyops] service %s called us with old style signature \"%s\"\n", sn, src)
112 }
113 l := prometheus.Labels{"servicename": cs.ServiceName, "method": cs.MethodName, "source": src}
114 userSourceMetric.With(l).Inc()
115 }
116
117
118 func (cs *CallState) CallerService() *auth.User {
119 if cs == nil {
120 return nil
121 }
122 if cs.IsV2() {
123 return cs.v2.CallingService()
124 }
125 panic("obsolete codepath")
126 }
127 func (cs *CallState) TargetString() string {
128 if cs == nil {
129 return ""
130 }
131 return fmt.Sprintf("%s.%s", cs.ServiceName, cs.MethodName)
132 }
133 func (cs *CallState) CallerString() string {
134 if cs == nil {
135 return ""
136 }
137 u := common.VerifySignedUser(cs.SignedUser())
138 if u == nil {
139 return ""
140 }
141 return u.Abbrev
142
143 }
144
145
146 func (cs *CallState) DebugPrintContext() {
147 if cs == nil || !cs.Debug {
148 return
149 }
150 cs.PrintContext()
151 }
152 func (cs *CallState) RoutingTags() *ge.CTXRoutingTags {
153 if cs == nil {
154 return nil
155 }
156 if cs.IsV2() {
157 return cs.v2.RoutingTags()
158 }
159 panic("obsolete codepath")
160 }
161 func (cs *CallState) PrintContext() {
162 if cs == nil {
163 fmt.Printf("[go-easyops] Context has no Callstate\n")
164 return
165 }
166 fmt.Printf("[go-easyops] printing old style context (%v)", cs.v2)
167
191 }
192 func desc(u *auth.User) string {
193 if u == nil {
194 return "NONE"
195 }
196 return fmt.Sprintf("%s[%s]", u.ID, u.Email)
197 }
198 func (cs *CallState) DISMetadataValue() string {
199 return ""
200 }
201 func CallStateFromContext(ctx context.Context) *CallState {
202 if ctx == nil {
203 return nil
204 }
205 lcv := ctx.Value(LOCALCONTEXTNAME)
206 if lcv == nil {
207 return nil
208 }
209 return lcv.(*CallState)
210 }
211
212
213
214
215
216
217 func (cs *CallState) UpdateContextFromResponse() error {
218 return cs.UpdateContextFromResponseWithTimeout(time.Duration(10) * time.Second)
219 }
220 func (cs *CallState) UpdateContextFromResponseWithTimeout(t time.Duration) error {
221 panic("obsolete codepath")
222 }
223
224 func ContextWithCallState(ctx context.Context) (context.Context, *CallState) {
225 cs := &CallState{}
226 nc := context.WithValue(ctx, LOCALCONTEXTNAME, cs)
227 return nc, cs
228 }
229 func (cs *CallState) SignedSession() *auth.SignedSession {
230 if cs.IsV2() {
231 return cs.v2.SignedSession()
232 }
233 panic("obsolete codepath")
234 }
235
View as plain text