cachaca

package module
v0.0.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 9, 2023 License: MIT Imports: 26 Imported by: 0

README

Cachaça

codecov Go Reference

Cachaça (Portuguese pronunciation: kaˈʃasɐ) is a distilled spirit made from fermented sugarcane juice. Also known as pinga, caninha, and other names, it is the most popular spirit among distilled alcoholic beverages in Brazil. Outside Brazil, cachaça is used almost exclusively as an ingredient in tropical drinks, with the caipirinha being the most famous cocktail. In Brazil, caipirinha is often paired with the dish feijoada. (Source: Wikipedia).

Cachaca is an opinionated gRPC/gRPC-web/REST/HTTP server. The server is intended to handle the heavy lifting of server configuration and handling authorization with a pluggable interface.

  • gRPC, gRPC-web, REST and HTTP are multiplexed onto a single port
  • Authorizer middleware supports modular support for a variety of authorization types
    • mTLS authorizer supports client certificate based authorization
    • OAuth/OIDC authorizer supports interoperability with an IdP
  • Consistent logging by forcing all logs through a single zerolog logger

While being opinionated in the implementation, the intention is to stay as consistent and close to standards and best practices as possible.

Under the hood

Because cachaca is intended to simplify implementation of gRPC/gRPC-web/REST services it is based on a variety of libraries:

Initializing the server

A minimal example to run the server works is provided. As can be seen, the server object can be used directly in order to register HTTP and gRPC endpoints.

Please note that gRPC-web is simply a proxy to gRPC so there is no additional setup necessary.

Example:

server, _ := NewServer()
l, _ := net.Listen("tcp", fmt.Sprintf(":%d", 0))

server.GET("/ping", func(context *gin.Context) {
    context.String(http.StatusOK, "pong")
})

if err := server.Serve(l); err != nil {
	panic(err)
}

Using an authorizer

The authorizers can register themselves with the server and shall be passed to the server on initialization. The provided example uses the OIDC authorizer implementation - but the other implementations work similar.

Example:

// Prepare the OAuth/OIDC authorizer
provider, _ := rp.NewRelyingPartyOIDC("issuer", "clientId", "clientSecret", "http://localhost:8443/oidc/authorize", []string{"openid"})
signingKey := &jose.SigningKey{Algorithm: jose.HS256, Key: []byte(uuid.NewString())}

authorizer := oidc.NewAuthorizer(signingKey)
authorizer.RegisterRelyingParty("test", provider)

server, _ := NewServer(authorizer)
l, _ := net.Listen("tcp", ":8443")

if err := server.Serve(l); err != nil {
	panic(err)
}

Accessing the credentials from the environment

auth/auth.go exposes the auth.GetCredentials function which allows access to the credentials from the authorizer middleware from the *gin.Context variable in HTTP requests and context.Context variable in gRPC requests.

Each authorizer middleware ships with its own Credentials object which must be used to retrieve the credentials.

Example:

func (s *Service) CommonName(ctx context.Context, _ *CommonNameRequest) (*CommonNameResponse, error) {
	commonName, ok := auth.GetCredentials[string](ctx)
	if !ok {
		return nil, status.Error(codes.Unauthenticated, "no credentials found")
	}

	return &CommonNameResponse{CommonName: *commonName}, nil
}

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Option

type Option interface {
	Apply(*Server) error
}

func GRPCWebDisabled added in v0.0.4

func GRPCWebDisabled() Option

GRPCWebDisabled disables the grpc-web endpoint.

func InsecureHealth added in v0.0.4

func InsecureHealth() Option

InsecureHealth disables authentication on the health endpoint. Otherwise, the health endpoint will be protected by the authentication middleware and requires at least a valid token or certificate.

func WithEmbeddedMetricsEndpoint

func WithEmbeddedMetricsEndpoint() Option

WithEmbeddedMetricsEndpoint enables the prometheus metrics on the /metrics endpoint. Please note that when using a custom http handler this option will not be applied successfully.

func WithGinMiddleware added in v0.0.4

func WithGinMiddleware(middleware gin.HandlerFunc) Option

WithGinMiddleware adds a gin middleware to the server. This is necessary to achieve the correct ordering of middlewares as the ordering has a direct impact on the functionality of the middlewares.

func WithReadTimeout

func WithReadTimeout(timeout time.Duration) Option

WithReadTimeout sets the read timeout for the http server.

type Server

type Server struct {
	*gin.Engine
	TLSConfig       *tls.Config
	GrpcWebDisabled bool
	GrpcWeb         *grpcweb.WrappedGrpcServer
	Grpc            *grpc.Server
	HTTPHandler     http.Handler
	Server          *http.Server
	Healthcheck     *health.Server

	ReadTimeout    time.Duration
	InsecureHealth bool
	Authorizer     auth.Authorizer
}

Server is an opinionated server implementation multiplexing grpc, grpc-web and rest/http on a single port. It embeds gin.Engine and the grpc.ServiceRegistrar interface to directly interact with the server.

func NewServer

func NewServer(opts ...Option) (*Server, error)

NewServer creates a new instance of the server.

func (*Server) RegisterService

func (s *Server) RegisterService(desc *grpc.ServiceDesc, impl interface{})

RegisterService implements the grpc.ServiceRegistrar interface used to register services with the grpc server. ServiceRegistrar wraps a single method that supports service registration. It enables users to pass concrete types other than grpc.Server to the service registration methods exported by the IDL generated code.

func (*Server) Serve

func (s *Server) Serve(listener net.Listener) error

Serve starts the server on the given listener. It will automatically detect if the server is configured to use TLS.

func (*Server) ServeHTTP

func (s *Server) ServeHTTP(resp http.ResponseWriter, req *http.Request)

ServeHTTP implements the http.Handler interface used internally to route requests to the correct handler. This function handles the selection of the correct handler (grpc, grpc-web or http) based on the content-type header.

func (*Server) SetServingStatus

func (s *Server) SetServingStatus(service string, status healthgrpc.HealthCheckResponse_ServingStatus)

SetServingStatus is called when need to reset the serving status of a service or insert a new service entry into the statusMap.

Directories

Path Synopsis
nop
internal

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL