Skip to content

Commit fb858ec

Browse files
authored
Implement delta response for internal request and debug API (istio#48145)
* generate delta for interl request * debug interface as well * fix statusgen * fix lint
1 parent ce478be commit fb858ec

File tree

2 files changed

+81
-22
lines changed

2 files changed

+81
-22
lines changed

pilot/pkg/xds/debuggen.go

+64-22
Original file line numberDiff line numberDiff line change
@@ -83,31 +83,80 @@ func NewDebugGen(s *DiscoveryServer, systemNamespace string, debugMux *http.Serv
8383

8484
// Generate XDS debug responses according to the incoming debug request
8585
func (dg *DebugGen) Generate(proxy *model.Proxy, w *model.WatchedResource, req *model.PushRequest) (model.Resources, model.XdsLogDetails, error) {
86-
res := model.Resources{}
87-
var buffer bytes.Buffer
86+
if err := validateProxyAuthentication(proxy, w); err != nil {
87+
return nil, model.DefaultXdsLogDetails, err
88+
}
89+
90+
resourceName, err := parseAndValidateDebugRequest(proxy, w, dg)
91+
if err != nil {
92+
return nil, model.DefaultXdsLogDetails, err
93+
}
94+
95+
buffer := processDebugRequest(dg, resourceName)
96+
97+
res := model.Resources{&discovery.Resource{
98+
Name: resourceName,
99+
Resource: &anypb.Any{
100+
TypeUrl: v3.DebugType,
101+
Value: buffer.Bytes(),
102+
},
103+
}}
104+
return res, model.DefaultXdsLogDetails, nil
105+
}
106+
107+
// GenerateDeltas XDS debug responses according to the incoming debug request
108+
func (dg *DebugGen) GenerateDeltas(
109+
proxy *model.Proxy,
110+
req *model.PushRequest,
111+
w *model.WatchedResource,
112+
) (model.Resources, model.DeletedResources, model.XdsLogDetails, bool, error) {
113+
if err := validateProxyAuthentication(proxy, w); err != nil {
114+
return nil, nil, model.DefaultXdsLogDetails, true, err
115+
}
116+
117+
resourceName, err := parseAndValidateDebugRequest(proxy, w, dg)
118+
if err != nil {
119+
return nil, nil, model.DefaultXdsLogDetails, true, err
120+
}
121+
122+
buffer := processDebugRequest(dg, resourceName)
123+
124+
res := model.Resources{&discovery.Resource{
125+
Name: resourceName,
126+
Resource: &anypb.Any{
127+
TypeUrl: v3.DebugType,
128+
Value: buffer.Bytes(),
129+
},
130+
}}
131+
return res, nil, model.DefaultXdsLogDetails, true, nil
132+
}
133+
134+
func validateProxyAuthentication(proxy *model.Proxy, w *model.WatchedResource) error {
88135
if proxy.VerifiedIdentity == nil {
89136
log.Warnf("proxy %s is not authorized to receive debug. Ensure you are connecting over TLS port and are authenticated.", proxy.ID)
90-
return nil, model.DefaultXdsLogDetails, status.Error(codes.Unauthenticated, "authentication required")
91-
}
92-
if w.ResourceNames == nil {
93-
return res, model.DefaultXdsLogDetails, status.Error(codes.InvalidArgument, "debug type is required")
137+
return status.Error(codes.Unauthenticated, "authentication required")
94138
}
95-
if len(w.ResourceNames) != 1 {
96-
return res, model.DefaultXdsLogDetails, status.Error(codes.InvalidArgument, "only one debug request is allowed")
139+
if w.ResourceNames == nil || len(w.ResourceNames) != 1 {
140+
return status.Error(codes.InvalidArgument, "exactly one debug request is required")
97141
}
142+
return nil
143+
}
144+
145+
func parseAndValidateDebugRequest(proxy *model.Proxy, w *model.WatchedResource, dg *DebugGen) (string, error) {
98146
resourceName := w.ResourceNames[0]
99147
u, _ := url.Parse(resourceName)
100148
debugType := u.Path
101149
identity := proxy.VerifiedIdentity
102150
if identity.Namespace != dg.SystemNamespace {
103-
shouldAllow := false
104-
if _, ok := activeNamespaceDebuggers[debugType]; ok {
105-
shouldAllow = true
106-
}
107-
if !shouldAllow {
108-
return res, model.DefaultXdsLogDetails, status.Errorf(codes.PermissionDenied, "the debug info is not available for current identity: %q", identity)
151+
if _, ok := activeNamespaceDebuggers[debugType]; !ok {
152+
return "", status.Errorf(codes.PermissionDenied, "the debug info is not available for current identity: %q", identity)
109153
}
110154
}
155+
return resourceName, nil
156+
}
157+
158+
func processDebugRequest(dg *DebugGen, resourceName string) bytes.Buffer {
159+
var buffer bytes.Buffer
111160
debugURL := "/debug/" + resourceName
112161
hreq, _ := http.NewRequest(http.MethodGet, debugURL, nil)
113162
handler, _ := dg.DebugMux.Handler(hreq)
@@ -118,12 +167,5 @@ func (dg *DebugGen) Generate(proxy *model.Proxy, w *model.WatchedResource, req *
118167
buffer.Write(header)
119168
}
120169
buffer.Write(response.body.Bytes())
121-
res = append(res, &discovery.Resource{
122-
Name: resourceName,
123-
Resource: &anypb.Any{
124-
TypeUrl: v3.DebugType,
125-
Value: buffer.Bytes(),
126-
},
127-
})
128-
return res, model.DefaultXdsLogDetails, nil
170+
return buffer
129171
}

pilot/pkg/xds/statusgen.go

+17
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,23 @@ func NewStatusGen(s *DiscoveryServer) *StatusGen {
7070
// - NACKs
7171
// We can also expose ACKS.
7272
func (sg *StatusGen) Generate(proxy *model.Proxy, w *model.WatchedResource, req *model.PushRequest) (model.Resources, model.XdsLogDetails, error) {
73+
return sg.handleInternalRequest(proxy, w, req)
74+
}
75+
76+
// Generate delta XDS responses about internal events:
77+
// - connection status
78+
// - NACKs
79+
// We can also expose ACKS.
80+
func (sg *StatusGen) GenerateDeltas(
81+
proxy *model.Proxy,
82+
req *model.PushRequest,
83+
w *model.WatchedResource,
84+
) (model.Resources, model.DeletedResources, model.XdsLogDetails, bool, error) {
85+
res, detail, err := sg.handleInternalRequest(proxy, w, req)
86+
return res, nil, detail, true, err
87+
}
88+
89+
func (sg *StatusGen) handleInternalRequest(_ *model.Proxy, w *model.WatchedResource, _ *model.PushRequest) (model.Resources, model.XdsLogDetails, error) {
7390
res := model.Resources{}
7491

7592
switch w.TypeUrl {

0 commit comments

Comments
 (0)