mirror of https://github.com/linkerd/linkerd2.git
73 lines
1.7 KiB
Go
73 lines
1.7 KiB
Go
package tap
|
|
|
|
import (
|
|
"bufio"
|
|
"bytes"
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"net/url"
|
|
|
|
"github.com/golang/protobuf/proto"
|
|
"github.com/linkerd/linkerd2/pkg/k8s"
|
|
"github.com/linkerd/linkerd2/pkg/protohttp"
|
|
pb "github.com/linkerd/linkerd2/viz/metrics-api/gen/viz"
|
|
log "github.com/sirupsen/logrus"
|
|
)
|
|
|
|
const (
|
|
// ErrClosedResponseBody is returned when response body is closed in http2
|
|
ErrClosedResponseBody = "http2: response body closed"
|
|
)
|
|
|
|
// TapRbacURL is the link users should visit to remedy issues when attempting
|
|
// to tap resources with missing authorizations
|
|
const TapRbacURL = "https://linkerd.io/tap-rbac"
|
|
|
|
// Reader initiates a TapByResourceRequest and returns a buffered Reader.
|
|
// It is the caller's responsibility to call Close() on the io.ReadCloser.
|
|
func Reader(ctx context.Context, k8sAPI *k8s.KubernetesAPI, req *pb.TapByResourceRequest) (*bufio.Reader, io.ReadCloser, error) {
|
|
client, err := k8sAPI.NewClient()
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
reqBytes, err := proto.Marshal(req)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
url, err := url.Parse(k8sAPI.Host)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
url.Path = fmt.Sprintf("%s%s", url.Path, protohttp.TapReqToURL(req))
|
|
|
|
httpReq, err := http.NewRequest(
|
|
http.MethodPost,
|
|
url.String(),
|
|
bytes.NewReader(reqBytes),
|
|
)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
httpRsp, err := client.Do(httpReq.WithContext(ctx))
|
|
if err != nil {
|
|
log.Debugf("Error invoking [%s]: %v", url, err)
|
|
return nil, nil, err
|
|
}
|
|
|
|
log.Debugf("Response from [%s] had headers: %v", url, httpRsp.Header)
|
|
|
|
if err := protohttp.CheckIfResponseHasError(httpRsp); err != nil {
|
|
httpRsp.Body.Close()
|
|
return nil, nil, err
|
|
}
|
|
|
|
reader := bufio.NewReader(httpRsp.Body)
|
|
|
|
return reader, httpRsp.Body, nil
|
|
}
|