mirror of
https://github.com/weaveworks/scope.git
synced 2026-03-03 02:00:43 +00:00
Bump github.com/weaveworks/common
This commit is contained in:
6
vendor/github.com/weaveworks/common/errors/error.go
generated
vendored
Normal file
6
vendor/github.com/weaveworks/common/errors/error.go
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
package errors
|
||||
|
||||
// Error see https://dave.cheney.net/2016/04/07/constant-errors.
|
||||
type Error string
|
||||
|
||||
func (e Error) Error() string { return string(e) }
|
||||
19
vendor/github.com/weaveworks/common/httpgrpc/httpgrpc.go
generated
vendored
19
vendor/github.com/weaveworks/common/httpgrpc/httpgrpc.go
generated
vendored
@@ -65,18 +65,27 @@ type Client struct {
|
||||
conn *grpc.ClientConn
|
||||
}
|
||||
|
||||
// NewClient makes a new Client, given a kubernetes service address. Expects
|
||||
// an address of the form <service>.<namespace>:<port>
|
||||
func NewClient(address string) (*Client, error) {
|
||||
// ParseKubernetesAddress splits up an address of the form <service>(.<namespace>):<port>
|
||||
// into its consistuent parts. Namespace will be "default" if missing.
|
||||
func ParseKubernetesAddress(address string) (service, namespace, port string, err error) {
|
||||
host, port, err := net.SplitHostPort(address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return "", "", "", err
|
||||
}
|
||||
parts := strings.SplitN(host, ".", 2)
|
||||
service, namespace := parts[0], "default"
|
||||
service, namespace = parts[0], "default"
|
||||
if len(parts) == 2 {
|
||||
namespace = parts[1]
|
||||
}
|
||||
return service, namespace, port, nil
|
||||
}
|
||||
|
||||
// NewClient makes a new Client, given a kubernetes service address.
|
||||
func NewClient(address string) (*Client, error) {
|
||||
service, namespace, port, err := ParseKubernetesAddress(address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Client{
|
||||
service: service,
|
||||
namespace: namespace,
|
||||
|
||||
2
vendor/github.com/weaveworks/common/instrument/instrument.go
generated
vendored
2
vendor/github.com/weaveworks/common/instrument/instrument.go
generated
vendored
@@ -22,7 +22,7 @@ func ErrorCode(err error) string {
|
||||
// "500". It will also emit an OpenTracing span if you have a global tracer configured.
|
||||
//
|
||||
// If you want more complicated logic for translating errors into statuses,
|
||||
// use 'TimeRequestStatus'.
|
||||
// use 'TimeRequestHistogramStatus'.
|
||||
func TimeRequestHistogram(ctx context.Context, method string, metric *prometheus.HistogramVec, f func(context.Context) error) error {
|
||||
return TimeRequestHistogramStatus(ctx, method, metric, ErrorCode, f)
|
||||
}
|
||||
|
||||
42
vendor/github.com/weaveworks/common/middleware/grpc_auth.go
generated
vendored
42
vendor/github.com/weaveworks/common/middleware/grpc_auth.go
generated
vendored
@@ -1,58 +1,28 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/metadata"
|
||||
|
||||
"github.com/weaveworks/common/user"
|
||||
)
|
||||
|
||||
// ClientUserHeaderInterceptor propagates the user ID from the context to gRPC metadata, which eventually ends up as a HTTP2 header.
|
||||
func ClientUserHeaderInterceptor(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
|
||||
userID, err := user.GetID(ctx)
|
||||
ctx, err := user.InjectIntoGRPCRequest(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
md, ok := metadata.FromContext(ctx)
|
||||
if !ok {
|
||||
md = metadata.New(map[string]string{})
|
||||
}
|
||||
|
||||
newCtx := ctx
|
||||
if userIDs, ok := md[user.LowerOrgIDHeaderName]; ok {
|
||||
switch len(userIDs) {
|
||||
case 1:
|
||||
if userIDs[0] != userID {
|
||||
return fmt.Errorf("wrong user ID found")
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("multiple user IDs found")
|
||||
}
|
||||
} else {
|
||||
md = md.Copy()
|
||||
md[user.LowerOrgIDHeaderName] = []string{userID}
|
||||
newCtx = metadata.NewContext(ctx, md)
|
||||
}
|
||||
|
||||
return invoker(newCtx, method, req, reply, cc, opts...)
|
||||
return invoker(ctx, method, req, reply, cc, opts...)
|
||||
}
|
||||
|
||||
// ServerUserHeaderInterceptor propagates the user ID from the gRPC metadata back to our context.
|
||||
func ServerUserHeaderInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
|
||||
md, ok := metadata.FromContext(ctx)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("no metadata")
|
||||
_, ctx, err := user.ExtractFromGRPCRequest(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
userIDs, ok := md[user.LowerOrgIDHeaderName]
|
||||
if !ok || len(userIDs) != 1 {
|
||||
return nil, fmt.Errorf("no user id")
|
||||
}
|
||||
|
||||
newCtx := user.WithID(ctx, userIDs[0])
|
||||
return handler(newCtx, req)
|
||||
return handler(ctx, req)
|
||||
}
|
||||
|
||||
18
vendor/github.com/weaveworks/common/middleware/grpc_logging.go
generated
vendored
18
vendor/github.com/weaveworks/common/middleware/grpc_logging.go
generated
vendored
@@ -11,15 +11,13 @@ import (
|
||||
const gRPC = "gRPC"
|
||||
|
||||
// ServerLoggingInterceptor logs gRPC requests, errors and latency.
|
||||
func ServerLoggingInterceptor(logSuccess bool) grpc.UnaryServerInterceptor {
|
||||
return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
|
||||
begin := time.Now()
|
||||
resp, err := handler(ctx, req)
|
||||
if err != nil {
|
||||
log.Errorf("%s %s (%v) %s", gRPC, info.FullMethod, err, time.Since(begin))
|
||||
} else if logSuccess {
|
||||
log.Infof("%s %s (success) %s", gRPC, info.FullMethod, time.Since(begin))
|
||||
}
|
||||
return resp, err
|
||||
var ServerLoggingInterceptor = func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
|
||||
begin := time.Now()
|
||||
resp, err := handler(ctx, req)
|
||||
if err != nil {
|
||||
log.Warnf("%s %s (%v) %s", gRPC, info.FullMethod, err, time.Since(begin))
|
||||
} else {
|
||||
log.Debugf("%s %s (success) %s", gRPC, info.FullMethod, time.Since(begin))
|
||||
}
|
||||
return resp, err
|
||||
}
|
||||
|
||||
19
vendor/github.com/weaveworks/common/middleware/http_auth.go
generated
vendored
Normal file
19
vendor/github.com/weaveworks/common/middleware/http_auth.go
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/weaveworks/common/user"
|
||||
)
|
||||
|
||||
// AuthenticateUser propagates the user ID from HTTP headers back to the request's context.
|
||||
var AuthenticateUser = Func(func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
_, ctx, err := user.ExtractFromHTTPRequest(r)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
next.ServeHTTP(w, r.WithContext(ctx))
|
||||
})
|
||||
})
|
||||
2
vendor/github.com/weaveworks/common/middleware/instrument.go
generated
vendored
2
vendor/github.com/weaveworks/common/middleware/instrument.go
generated
vendored
@@ -67,7 +67,7 @@ func (i Instrument) getRouteName(r *http.Request) string {
|
||||
if name := routeMatch.Route.GetName(); name != "" {
|
||||
return name
|
||||
}
|
||||
if tmpl, err := routeMatch.Route.GetPathTemplate(); err != nil {
|
||||
if tmpl, err := routeMatch.Route.GetPathTemplate(); err == nil {
|
||||
return MakeLabelValue(tmpl)
|
||||
}
|
||||
}
|
||||
|
||||
18
vendor/github.com/weaveworks/common/middleware/logging.go
generated
vendored
18
vendor/github.com/weaveworks/common/middleware/logging.go
generated
vendored
@@ -13,7 +13,6 @@ import (
|
||||
|
||||
// Log middleware logs http requests
|
||||
type Log struct {
|
||||
LogSuccess bool // LogSuccess true -> log successful queries; false -> only log failed queries
|
||||
LogRequestHeaders bool // LogRequestHeaders true -> dump http headers at debug log level
|
||||
}
|
||||
|
||||
@@ -33,24 +32,17 @@ func (l Log) Wrap(next http.Handler) http.Handler {
|
||||
}
|
||||
i := &interceptor{ResponseWriter: w, statusCode: http.StatusOK}
|
||||
next.ServeHTTP(i, r)
|
||||
if l.LogSuccess || !(100 <= i.statusCode && i.statusCode < 400) {
|
||||
log.Infof("%s %s (%d) %s", r.Method, uri, i.statusCode, time.Since(begin))
|
||||
if 100 <= i.statusCode && i.statusCode < 400 {
|
||||
log.Debugf("%s %s (%d) %s", r.Method, uri, i.statusCode, time.Since(begin))
|
||||
} else {
|
||||
log.Warnf("%s %s (%d) %s", r.Method, uri, i.statusCode, time.Since(begin))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Logging middleware logs each HTTP request method, path, response code and
|
||||
// duration for all HTTP requests.
|
||||
var Logging = Log{
|
||||
LogSuccess: true,
|
||||
LogRequestHeaders: false,
|
||||
}
|
||||
|
||||
// LogFailed middleware logs each HTTP request method, path, response code and
|
||||
// duration for non-2xx HTTP requests.
|
||||
var LogFailed = Log{
|
||||
LogSuccess: false,
|
||||
}
|
||||
var Logging = Log{}
|
||||
|
||||
// interceptor implements WriteHeader to intercept status codes. WriteHeader
|
||||
// may not be called on success, so initialize statusCode with the status you
|
||||
|
||||
172
vendor/github.com/weaveworks/common/server/server.go
generated
vendored
Normal file
172
vendor/github.com/weaveworks/common/server/server.go
generated
vendored
Normal file
@@ -0,0 +1,172 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
_ "net/http/pprof" // anonymous import to get the pprof handler registered
|
||||
"time"
|
||||
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc"
|
||||
"github.com/mwitkow/go-grpc-middleware"
|
||||
"github.com/opentracing-contrib/go-stdlib/nethttp"
|
||||
"github.com/opentracing/opentracing-go"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"golang.org/x/net/context"
|
||||
"google.golang.org/grpc"
|
||||
|
||||
"github.com/weaveworks-experiments/loki/pkg/client"
|
||||
"github.com/weaveworks/common/httpgrpc"
|
||||
"github.com/weaveworks/common/middleware"
|
||||
"github.com/weaveworks/common/signals"
|
||||
)
|
||||
|
||||
func init() {
|
||||
tracer, err := loki.NewTracer()
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("Failed to create tracer: %v", err))
|
||||
} else {
|
||||
opentracing.InitGlobalTracer(tracer)
|
||||
}
|
||||
}
|
||||
|
||||
// Config for a Server
|
||||
type Config struct {
|
||||
MetricsNamespace string
|
||||
HTTPListenPort int
|
||||
GRPCListenPort int
|
||||
|
||||
ServerGracefulShutdownTimeout time.Duration
|
||||
HTTPServerReadTimeout time.Duration
|
||||
HTTPServerWriteTimeout time.Duration
|
||||
HTTPServerIdleTimeout time.Duration
|
||||
|
||||
GRPCMiddleware []grpc.UnaryServerInterceptor
|
||||
HTTPMiddleware []middleware.Interface
|
||||
}
|
||||
|
||||
// RegisterFlags adds the flags required to config this to the given FlagSet
|
||||
func (cfg *Config) RegisterFlags(f *flag.FlagSet) {
|
||||
f.IntVar(&cfg.HTTPListenPort, "server.http-listen-port", 80, "HTTP server listen port.")
|
||||
f.IntVar(&cfg.GRPCListenPort, "server.grpc-listen-port", 9095, "gRPC server listen port.")
|
||||
f.DurationVar(&cfg.ServerGracefulShutdownTimeout, "server.graceful-shutdown-timeout", 5*time.Second, "Timeout for graceful shutdowns")
|
||||
f.DurationVar(&cfg.HTTPServerReadTimeout, "server.http-read-timeout", 5*time.Second, "Read timeout for HTTP server")
|
||||
f.DurationVar(&cfg.HTTPServerWriteTimeout, "server.http-write-timeout", 5*time.Second, "Write timeout for HTTP server")
|
||||
f.DurationVar(&cfg.HTTPServerIdleTimeout, "server.http-idle-timeout", 120*time.Second, "Idle timeout for HTTP server")
|
||||
}
|
||||
|
||||
// Server wraps a HTTP and gRPC server, and some common initialization.
|
||||
//
|
||||
// Servers will be automatically instrumented for Prometheus metrics
|
||||
// and Loki tracing. HTTP over gRPC
|
||||
type Server struct {
|
||||
cfg Config
|
||||
handler *signals.Handler
|
||||
httpListener net.Listener
|
||||
grpcListener net.Listener
|
||||
httpServer *http.Server
|
||||
|
||||
HTTP *mux.Router
|
||||
GRPC *grpc.Server
|
||||
}
|
||||
|
||||
// New makes a new Server
|
||||
func New(cfg Config) (*Server, error) {
|
||||
// Setup listeners first, so we can fail early if the port is in use.
|
||||
httpListener, err := net.Listen("tcp", fmt.Sprintf(":%d", cfg.HTTPListenPort))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
grpcListener, err := net.Listen("tcp", fmt.Sprintf(":%d", cfg.GRPCListenPort))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Prometheus histograms for requests.
|
||||
requestDuration := prometheus.NewHistogramVec(prometheus.HistogramOpts{
|
||||
Namespace: cfg.MetricsNamespace,
|
||||
Name: "request_duration_seconds",
|
||||
Help: "Time (in seconds) spent serving HTTP requests.",
|
||||
Buckets: prometheus.DefBuckets,
|
||||
}, []string{"method", "route", "status_code", "ws"})
|
||||
prometheus.MustRegister(requestDuration)
|
||||
|
||||
// Setup gRPC server
|
||||
grpcMiddleware := []grpc.UnaryServerInterceptor{
|
||||
middleware.ServerLoggingInterceptor,
|
||||
middleware.ServerInstrumentInterceptor(requestDuration),
|
||||
otgrpc.OpenTracingServerInterceptor(opentracing.GlobalTracer()),
|
||||
}
|
||||
grpcMiddleware = append(grpcMiddleware, cfg.GRPCMiddleware...)
|
||||
grpcServer := grpc.NewServer(
|
||||
grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer(
|
||||
grpcMiddleware...,
|
||||
)),
|
||||
)
|
||||
|
||||
// Setup HTTP server
|
||||
router := mux.NewRouter()
|
||||
router.Handle("/metrics", prometheus.Handler())
|
||||
router.Handle("/traces", loki.Handler())
|
||||
router.PathPrefix("/debug/pprof").Handler(http.DefaultServeMux)
|
||||
httpMiddleware := []middleware.Interface{
|
||||
middleware.Log{},
|
||||
middleware.Instrument{
|
||||
Duration: requestDuration,
|
||||
RouteMatcher: router,
|
||||
},
|
||||
middleware.Func(func(handler http.Handler) http.Handler {
|
||||
return nethttp.Middleware(opentracing.GlobalTracer(), handler)
|
||||
}),
|
||||
}
|
||||
httpMiddleware = append(httpMiddleware, cfg.HTTPMiddleware...)
|
||||
httpServer := &http.Server{
|
||||
ReadTimeout: cfg.HTTPServerReadTimeout,
|
||||
WriteTimeout: cfg.HTTPServerWriteTimeout,
|
||||
IdleTimeout: cfg.HTTPServerIdleTimeout,
|
||||
Handler: middleware.Merge(httpMiddleware...).Wrap(router),
|
||||
}
|
||||
|
||||
return &Server{
|
||||
cfg: cfg,
|
||||
httpListener: httpListener,
|
||||
grpcListener: grpcListener,
|
||||
httpServer: httpServer,
|
||||
handler: signals.NewHandler(log.StandardLogger()),
|
||||
|
||||
HTTP: router,
|
||||
GRPC: grpcServer,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Run the server; blocks until SIGTERM is received.
|
||||
func (s *Server) Run() {
|
||||
go s.httpServer.Serve(s.httpListener)
|
||||
|
||||
// Setup gRPC server
|
||||
// for HTTP over gRPC, ensure we don't double-count the middleware
|
||||
httpgrpc.RegisterHTTPServer(s.GRPC, httpgrpc.NewServer(s.HTTP))
|
||||
go s.GRPC.Serve(s.grpcListener)
|
||||
defer s.GRPC.GracefulStop()
|
||||
|
||||
// Wait for a signal
|
||||
s.handler.Loop()
|
||||
}
|
||||
|
||||
// Stop unblocks Run().
|
||||
func (s *Server) Stop() {
|
||||
s.handler.Stop()
|
||||
}
|
||||
|
||||
// Shutdown the server, gracefully. Should be defered after New().
|
||||
func (s *Server) Shutdown() {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), s.cfg.ServerGracefulShutdownTimeout)
|
||||
defer cancel() // releases resources if httpServer.Churdown completes before timeout elapses
|
||||
|
||||
s.httpServer.Shutdown(ctx)
|
||||
s.GRPC.Stop()
|
||||
}
|
||||
60
vendor/github.com/weaveworks/common/signals/signals.go
generated
vendored
60
vendor/github.com/weaveworks/common/signals/signals.go
generated
vendored
@@ -18,24 +18,58 @@ type Logger interface {
|
||||
Infof(format string, args ...interface{})
|
||||
}
|
||||
|
||||
// SignalHandlerLoop blocks until it receives a SIGINT, SIGTERM or SIGQUIT.
|
||||
// For SIGINT and SIGTERM, it exits; for SIGQUIT is print a goroutine stack
|
||||
// dump.
|
||||
func SignalHandlerLoop(log Logger, ss ...SignalReceiver) {
|
||||
// Handler handles signals, can be interrupted.
|
||||
// On SIGINT or SIGTERM it will exit, on SIGQUIT it
|
||||
// will dump goroutine stacks to the Logger.
|
||||
type Handler struct {
|
||||
log Logger
|
||||
receivers []SignalReceiver
|
||||
quit chan struct{}
|
||||
}
|
||||
|
||||
// NewHandler makes a new Handler.
|
||||
func NewHandler(log Logger, receivers ...SignalReceiver) *Handler {
|
||||
return &Handler{
|
||||
log: log,
|
||||
receivers: receivers,
|
||||
quit: make(chan struct{}),
|
||||
}
|
||||
}
|
||||
|
||||
// Stop the handler
|
||||
func (h *Handler) Stop() {
|
||||
close(h.quit)
|
||||
}
|
||||
|
||||
// Loop handles signals.
|
||||
func (h *Handler) Loop() {
|
||||
sigs := make(chan os.Signal, 1)
|
||||
signal.Notify(sigs, syscall.SIGINT, syscall.SIGQUIT, syscall.SIGTERM)
|
||||
buf := make([]byte, 1<<20)
|
||||
for {
|
||||
switch <-sigs {
|
||||
case syscall.SIGINT, syscall.SIGTERM:
|
||||
log.Infof("=== received SIGINT/SIGTERM ===\n*** exiting")
|
||||
for _, subsystem := range ss {
|
||||
subsystem.Stop()
|
||||
}
|
||||
select {
|
||||
case <-h.quit:
|
||||
h.log.Infof("=== Handler.Stop()'d ===")
|
||||
return
|
||||
case syscall.SIGQUIT:
|
||||
stacklen := runtime.Stack(buf, true)
|
||||
log.Infof("=== received SIGQUIT ===\n*** goroutine dump...\n%s\n*** end", buf[:stacklen])
|
||||
case sig := <-sigs:
|
||||
switch sig {
|
||||
case syscall.SIGINT, syscall.SIGTERM:
|
||||
h.log.Infof("=== received SIGINT/SIGTERM ===\n*** exiting")
|
||||
for _, subsystem := range h.receivers {
|
||||
subsystem.Stop()
|
||||
}
|
||||
return
|
||||
case syscall.SIGQUIT:
|
||||
stacklen := runtime.Stack(buf, true)
|
||||
h.log.Infof("=== received SIGQUIT ===\n*** goroutine dump...\n%s\n*** end", buf[:stacklen])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// SignalHandlerLoop blocks until it receives a SIGINT, SIGTERM or SIGQUIT.
|
||||
// For SIGINT and SIGTERM, it exits; for SIGQUIT is print a goroutine stack
|
||||
// dump.
|
||||
func SignalHandlerLoop(log Logger, ss ...SignalReceiver) {
|
||||
NewHandler(log, ss...).Loop()
|
||||
}
|
||||
|
||||
20
vendor/github.com/weaveworks/common/test/exec/exec.go
generated
vendored
20
vendor/github.com/weaveworks/common/test/exec/exec.go
generated
vendored
@@ -10,11 +10,6 @@ import (
|
||||
|
||||
type mockCmd struct {
|
||||
io.ReadCloser
|
||||
quit chan struct{}
|
||||
}
|
||||
|
||||
type blockingReader struct {
|
||||
quit chan struct{}
|
||||
}
|
||||
|
||||
// NewMockCmdString creates a new mock Cmd which has s on its stdout pipe
|
||||
@@ -27,7 +22,6 @@ func NewMockCmdString(s string) exec.Cmd {
|
||||
bytes.NewBufferString(s),
|
||||
ioutil.NopCloser(nil),
|
||||
},
|
||||
quit: make(chan struct{}),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +29,6 @@ func NewMockCmdString(s string) exec.Cmd {
|
||||
func NewMockCmd(rc io.ReadCloser) exec.Cmd {
|
||||
return &mockCmd{
|
||||
ReadCloser: rc,
|
||||
quit: make(chan struct{}),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,11 +45,10 @@ func (c *mockCmd) StdoutPipe() (io.ReadCloser, error) {
|
||||
}
|
||||
|
||||
func (c *mockCmd) StderrPipe() (io.ReadCloser, error) {
|
||||
return &blockingReader{c.quit}, nil
|
||||
return ioutil.NopCloser(bytes.NewReader(nil)), nil
|
||||
}
|
||||
|
||||
func (c *mockCmd) Kill() error {
|
||||
close(c.quit)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -69,13 +61,3 @@ func (c *mockCmd) Run() error {
|
||||
}
|
||||
|
||||
func (c *mockCmd) SetEnv([]string) {}
|
||||
|
||||
func (b *blockingReader) Read(p []byte) (n int, err error) {
|
||||
<-b.quit
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func (b *blockingReader) Close() error {
|
||||
<-b.quit
|
||||
return nil
|
||||
}
|
||||
|
||||
51
vendor/github.com/weaveworks/common/user/grpc.go
generated
vendored
Normal file
51
vendor/github.com/weaveworks/common/user/grpc.go
generated
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"golang.org/x/net/context"
|
||||
"google.golang.org/grpc/metadata"
|
||||
)
|
||||
|
||||
// ExtractFromGRPCRequest extracts the user ID from the request metadata and returns
|
||||
// the user ID and a context with the user ID injected.
|
||||
func ExtractFromGRPCRequest(ctx context.Context) (string, context.Context, error) {
|
||||
md, ok := metadata.FromContext(ctx)
|
||||
if !ok {
|
||||
return "", ctx, ErrNoUserID
|
||||
}
|
||||
|
||||
userIDs, ok := md[lowerOrgIDHeaderName]
|
||||
if !ok || len(userIDs) != 1 {
|
||||
return "", ctx, ErrNoUserID
|
||||
}
|
||||
|
||||
return userIDs[0], Inject(ctx, userIDs[0]), nil
|
||||
}
|
||||
|
||||
// InjectIntoGRPCRequest injects the userID from the context into the request metadata.
|
||||
func InjectIntoGRPCRequest(ctx context.Context) (context.Context, error) {
|
||||
userID, err := Extract(ctx)
|
||||
if err != nil {
|
||||
return ctx, err
|
||||
}
|
||||
|
||||
md, ok := metadata.FromContext(ctx)
|
||||
if !ok {
|
||||
md = metadata.New(map[string]string{})
|
||||
}
|
||||
newCtx := ctx
|
||||
if userIDs, ok := md[lowerOrgIDHeaderName]; ok {
|
||||
if len(userIDs) == 1 {
|
||||
if userIDs[0] != userID {
|
||||
return ctx, ErrDifferentIDPresent
|
||||
}
|
||||
} else {
|
||||
return ctx, ErrTooManyUserIDs
|
||||
}
|
||||
} else {
|
||||
md = md.Copy()
|
||||
md[lowerOrgIDHeaderName] = []string{userID}
|
||||
newCtx = metadata.NewContext(ctx, md)
|
||||
}
|
||||
|
||||
return newCtx, nil
|
||||
}
|
||||
31
vendor/github.com/weaveworks/common/user/http.go
generated
vendored
Normal file
31
vendor/github.com/weaveworks/common/user/http.go
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
// ExtractFromHTTPRequest extracts the user ID from the request headers and returns
|
||||
// the user ID and a context with the user ID embbedded.
|
||||
func ExtractFromHTTPRequest(r *http.Request) (string, context.Context, error) {
|
||||
userID := r.Header.Get(orgIDHeaderName)
|
||||
if userID == "" {
|
||||
return "", r.Context(), ErrNoUserID
|
||||
}
|
||||
return userID, Inject(r.Context(), userID), nil
|
||||
}
|
||||
|
||||
// InjectIntoHTTPRequest injects the userID from the context into the request headers.
|
||||
func InjectIntoHTTPRequest(ctx context.Context, r *http.Request) error {
|
||||
userID, err := Extract(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
existingID := r.Header.Get(orgIDHeaderName)
|
||||
if existingID != "" && existingID != userID {
|
||||
return ErrDifferentIDPresent
|
||||
}
|
||||
r.Header.Set(orgIDHeaderName, userID)
|
||||
return nil
|
||||
}
|
||||
39
vendor/github.com/weaveworks/common/user/id.go
generated
vendored
39
vendor/github.com/weaveworks/common/user/id.go
generated
vendored
@@ -1,32 +1,41 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"github.com/weaveworks/common/errors"
|
||||
)
|
||||
|
||||
// UserIDContextKey is the key used in contexts to find the userid
|
||||
type contextKey int
|
||||
|
||||
const userIDContextKey contextKey = 0
|
||||
const (
|
||||
// UserIDContextKey is the key used in contexts to find the userid
|
||||
userIDContextKey contextKey = 0
|
||||
|
||||
// OrgIDHeaderName is a legacy from scope as a service.
|
||||
const OrgIDHeaderName = "X-Scope-OrgID"
|
||||
// orgIDHeaderName is a legacy from scope as a service.
|
||||
orgIDHeaderName = "X-Scope-OrgID"
|
||||
|
||||
// LowerOrgIDHeaderName as gRPC / HTTP2.0 headers are lowercased.
|
||||
const LowerOrgIDHeaderName = "x-scope-orgid"
|
||||
// LowerOrgIDHeaderName as gRPC / HTTP2.0 headers are lowercased.
|
||||
lowerOrgIDHeaderName = "x-scope-orgid"
|
||||
)
|
||||
|
||||
// GetID returns the user
|
||||
func GetID(ctx context.Context) (string, error) {
|
||||
userid, ok := ctx.Value(userIDContextKey).(string)
|
||||
// Errors that we return
|
||||
const (
|
||||
ErrNoUserID = errors.Error("no user id")
|
||||
ErrDifferentIDPresent = errors.Error("different user ID already present")
|
||||
ErrTooManyUserIDs = errors.Error("multiple user IDs present")
|
||||
)
|
||||
|
||||
// Extract gets the user ID from the context
|
||||
func Extract(ctx context.Context) (string, error) {
|
||||
userID, ok := ctx.Value(userIDContextKey).(string)
|
||||
if !ok {
|
||||
return "", fmt.Errorf("no user id")
|
||||
return "", ErrNoUserID
|
||||
}
|
||||
return userid, nil
|
||||
return userID, nil
|
||||
}
|
||||
|
||||
// WithID returns a derived context containing the user ID.
|
||||
func WithID(ctx context.Context, userID string) context.Context {
|
||||
// Inject returns a derived context containing the user ID.
|
||||
func Inject(ctx context.Context, userID string) context.Context {
|
||||
return context.WithValue(ctx, interface{}(userIDContextKey), userID)
|
||||
}
|
||||
|
||||
2
vendor/manifest
vendored
2
vendor/manifest
vendored
@@ -1414,7 +1414,7 @@
|
||||
"importpath": "github.com/weaveworks/common",
|
||||
"repository": "https://github.com/weaveworks/common",
|
||||
"vcs": "git",
|
||||
"revision": "8da456c848efd2a13ffb5a3f9f4507c52c3f52e1",
|
||||
"revision": "f94043b3da140c7a735b1f2f286d72d19014b200",
|
||||
"branch": "master",
|
||||
"notests": true
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user