Skip to content

Commit

Permalink
httpheader extension: Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
disq committed Dec 10, 2021
1 parent 08ed4f5 commit 709f76e
Show file tree
Hide file tree
Showing 7 changed files with 480 additions and 0 deletions.
8 changes: 8 additions & 0 deletions extension/httpheaderextension/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# HTTP Header Extension

Exposes incoming HTTP headers as fields in the Auth context using [configauth](https://github.com/open-telemetry/opentelemetry-collector/tree/main/config/configauth).

# Credits

- [oidcauthextension](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/extension/oidcauthextension)
- [Issue #4400](https://github.com/open-telemetry/opentelemetry-collector/issues/4440)
30 changes: 30 additions & 0 deletions extension/httpheaderextension/authdata.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package httpheaderextension

import "go.opentelemetry.io/collector/client"

var _ client.AuthData = (*authData)(nil)

type authData struct {
headers map[string][]string
}

func (a *authData) GetAttribute(name string) interface{} {
v, ok := a.headers[name]
if !ok {
return nil
}
if len(v) == 0 {
return ""
}
return v[len(v)-1] // return last
}

func (a *authData) GetAttributeNames() []string {
list := make([]string, len(a.headers))
i := 0
for k := range a.headers {
list[i] = k
i++
}
return list
}
8 changes: 8 additions & 0 deletions extension/httpheaderextension/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package httpheaderextension

import "go.opentelemetry.io/collector/config"

// Config has the configuration for the HTTP Header extension.
type Config struct {
config.ExtensionSettings `mapstructure:",squash"` // squash ensures fields are correctly decoded in embedded struct
}
68 changes: 68 additions & 0 deletions extension/httpheaderextension/extension.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package httpheaderextension

import (
"context"
"net/http"

"go.opentelemetry.io/collector/client"
"go.opentelemetry.io/collector/component"
"go.opentelemetry.io/collector/config/configauth"
"go.uber.org/zap"
"google.golang.org/grpc"
)

type httpheaderExtension struct {
cfg *Config
unaryInterceptor configauth.GRPCUnaryInterceptorFunc
streamInterceptor configauth.GRPCStreamInterceptorFunc
httpInterceptor configauth.HTTPInterceptorFunc

logger *zap.Logger
}

var (
_ configauth.ServerAuthenticator = (*httpheaderExtension)(nil)
)

func newExtension(cfg *Config, logger *zap.Logger) (*httpheaderExtension, error) {
return &httpheaderExtension{
cfg: cfg,
logger: logger,
unaryInterceptor: configauth.DefaultGRPCUnaryServerInterceptor,
streamInterceptor: configauth.DefaultGRPCStreamServerInterceptor,
httpInterceptor: configauth.DefaultHTTPInterceptor,
}, nil
}

func (e *httpheaderExtension) Start(_ context.Context, _ component.Host) error {
return nil
}

// Shutdown is invoked during service shutdown.
func (e *httpheaderExtension) Shutdown(context.Context) error {
return nil
}

// Authenticate checks whether the given context contains valid auth data. Successfully authenticated calls will always return a nil error and a context with the auth data.
func (e *httpheaderExtension) Authenticate(ctx context.Context, headers map[string][]string) (context.Context, error) {
cl := client.FromContext(ctx)
cl.Auth = &authData{
headers: headers,
}
return client.NewContext(ctx, cl), nil
}

// GRPCUnaryServerInterceptor is a helper method to provide a gRPC-compatible UnaryInterceptor, typically calling the authenticator's Authenticate method.
func (e *httpheaderExtension) GRPCUnaryServerInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
return e.unaryInterceptor(ctx, req, info, handler, e.Authenticate)
}

// GRPCStreamServerInterceptor is a helper method to provide a gRPC-compatible StreamInterceptor, typically calling the authenticator's Authenticate method.
func (e *httpheaderExtension) GRPCStreamServerInterceptor(srv interface{}, str grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
return e.streamInterceptor(srv, str, info, handler, e.Authenticate)
}

// GRPCStreamServerInterceptor is a helper method to provide a gRPC-compatible StreamInterceptor, typically calling the authenticator's Authenticate method.
func (e *httpheaderExtension) HTTPInterceptor(next http.Handler) http.Handler {
return e.httpInterceptor(next, e.Authenticate)
}
32 changes: 32 additions & 0 deletions extension/httpheaderextension/factory.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package httpheaderextension

import (
"context"

"go.opentelemetry.io/collector/component"
"go.opentelemetry.io/collector/config"
"go.opentelemetry.io/collector/extension/extensionhelper"
)

const (
// The value of extension "type" in configuration.
typeStr = "httpheader"
)

// NewFactory creates a factory for the OIDC Authenticator extension.
func NewFactory() component.ExtensionFactory {
return extensionhelper.NewFactory(
typeStr,
createDefaultConfig,
createExtension)
}

func createDefaultConfig() config.Extension {
return &Config{
ExtensionSettings: config.NewExtensionSettings(config.NewComponentID(typeStr)),
}
}

func createExtension(_ context.Context, set component.ExtensionCreateSettings, cfg config.Extension) (component.Extension, error) {
return newExtension(cfg.(*Config), set.Logger)
}
32 changes: 32 additions & 0 deletions extension/httpheaderextension/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
module github.com/open-telemetry/opentelemetry-collector-contrib/extension/httpheaderextension

go 1.17

require (
go.opentelemetry.io/collector v0.41.1-0.20211210184707-4dcb3388a168
go.uber.org/zap v1.19.1
google.golang.org/grpc v1.42.0
)

require (
github.com/fsnotify/fsnotify v1.4.9 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/knadh/koanf v1.3.2 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/mapstructure v1.4.2 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/spf13/cast v1.4.1 // indirect
go.opentelemetry.io/collector/model v0.40.0 // indirect
go.opentelemetry.io/otel v1.2.0 // indirect
go.opentelemetry.io/otel/metric v0.25.0 // indirect
go.opentelemetry.io/otel/trace v1.2.0 // indirect
go.uber.org/atomic v1.9.0 // indirect
go.uber.org/multierr v1.7.0 // indirect
golang.org/x/net v0.0.0-20210614182718-04defd469f4e // indirect
golang.org/x/sys v0.0.0-20211013075003-97ac67df715c // indirect
golang.org/x/text v0.3.6 // indirect
google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08 // indirect
google.golang.org/protobuf v1.27.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
)
Loading

0 comments on commit 709f76e

Please sign in to comment.