Skip to content
This repository has been archived by the owner on May 18, 2024. It is now read-only.

Public sync #4

Merged
merged 59 commits into from
Jan 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
2881af3
add mTLS config for backend clients
dhontecillas Jul 10, 2023
4b8ded2
fix: issue in test found by deep source
dhontecillas Jul 10, 2023
16de1b3
fix: flaky test for mTLS
dhontecillas Jul 10, 2023
91f0b03
use newTransport function for custom configured default transport
dhontecillas Jul 11, 2023
de13d55
fix: typo in config name
dhontecillas Jul 13, 2023
e052c58
initialize the ClientTLS if required
kpacha Sep 13, 2023
54ff0a4
pass the global ctx to the handler plugins
kpacha Sep 13, 2023
482e6ba
allow multiple unsafe backends
kpacha Sep 14, 2023
5157a29
inject the req cloner and avoid the extra if per backend and request
kpacha Sep 15, 2023
31953b3
Do not replace the default gin value if there's no remote_ip_headers …
taik0 Sep 25, 2023
005d77b
Do not replace the default gin value if there's no trusted_proxies to…
taik0 Sep 25, 2023
9f8cb9c
fix broken links in documentation
dhontecillas Sep 27, 2023
ef0793c
remove panic from uri clean host
dhontecillas Sep 28, 2023
8afdf3a
Merge pull request #686 from luraproject/remote_ip_headers
taik0 Sep 28, 2023
5e477e1
Add new plugin HTTP Request Executor which accepts a context to be ab…
taik0 Sep 28, 2023
e045d0a
Merge pull request #687 from luraproject/fix_documentation_links
taik0 Sep 28, 2023
7636fc0
Merge pull request #682 from luraproject/fix_panic_client_tls
taik0 Sep 28, 2023
d92cf28
change panics in middlewares for log errors when wrong number of prox…
dhontecillas Sep 28, 2023
62d6450
explain why proxy/merging.go still has panics
dhontecillas Sep 28, 2023
1c01d40
fix regex "\w" includes "\d"
dhontecillas Sep 28, 2023
e2fb809
fix regex "\w" includes "_"
dhontecillas Sep 28, 2023
691640c
Merge pull request #683 from luraproject/plugin_ctx
kpacha Sep 28, 2023
960961a
require 2 unsafe backends in order to clone the request
kpacha Sep 28, 2023
7f3754d
fix integration tests running on IPv6
kpacha Sep 28, 2023
16dfe43
complete the fix
kpacha Sep 28, 2023
a77c39b
return when an error is returned
kpacha Sep 28, 2023
965dacf
Merge pull request #689 from luraproject/multiple_unsafe_req
kpacha Sep 28, 2023
ae13206
remove loggers created "in situ" to remove panics
dhontecillas Sep 29, 2023
69027ca
fix: change Error for Fatal where there was a panic
dhontecillas Sep 29, 2023
36e08a4
fix: formating issue %s -> %d
dhontecillas Sep 29, 2023
8362d2b
fix: add returns after log.Fatal and change existing panic
dhontecillas Sep 29, 2023
69ca25e
Merge pull request #688 from luraproject/avoid_panics
kpacha Sep 29, 2023
19ef64c
add backend level query strings filtering
dhontecillas Oct 1, 2023
a02df2b
Merge pull request #676 from luraproject/add_backend_mtls
taik0 Oct 4, 2023
ed8dc3d
add tests for block all and allow all query strings at backend level …
dhontecillas Oct 4, 2023
8f8a142
Merge pull request #690 from luraproject/backend_level_query_strings
kpacha Oct 4, 2023
1c2ae1f
upgrade some x pkgs
kpacha Oct 10, 2023
bfa00c0
Merge pull request #692 from luraproject/upgrade_x_net
kpacha Oct 11, 2023
ca40f6c
remove call to force initialization in gin that was not happening in …
dhontecillas Oct 17, 2023
8fc9527
Merge pull request #693 from luraproject/remove_temporal_gin_fix
kpacha Oct 17, 2023
c9d8011
Allow to configure the listen address of the service (defaults to 0.0…
taik0 Oct 23, 2023
12cc82f
Update config hash test.
taik0 Oct 23, 2023
5bd1c4c
Use JoinHostPort to generate the listen address.
taik0 Oct 24, 2023
16d335c
Rename listen_address to listen_ip.
taik0 Oct 24, 2023
20a22f6
Merge pull request #695 from luraproject/listen_address
kpacha Oct 26, 2023
c864b6c
Move support for h2c from gin router init to http server
anivanovic Oct 19, 2023
c2b430d
Add test.
anivanovic Oct 20, 2023
f6dc72d
Addressed review comments.
anivanovic Oct 24, 2023
b777b7f
Fix tests.
anivanovic Oct 25, 2023
c9838bd
Update config hash in test
anivanovic Oct 26, 2023
4d07104
Merge pull request #694 from anivanovic/antonije/fix_h2c_support
dhontecillas Oct 26, 2023
328e33d
improve client certs for mtls config structure
dhontecillas Oct 30, 2023
63204b0
apply deepsource suggestion
dhontecillas Oct 30, 2023
6ca4f01
Merge pull request #696 from luraproject/improve_client_tls_config
kpacha Oct 31, 2023
396a97c
Fix for parsing use_h2c config
anivanovic Nov 9, 2023
e9eccd1
Merge pull request #698 from anivanovic/antonije/fix_parsing_h2c_config
taik0 Nov 16, 2023
cb05abe
fix missing use_h2c from parser to ocnfig
dhontecillas Nov 17, 2023
c0dd026
Merge pull request #699 from luraproject/fix_missing_h2c_in_parser_to…
taik0 Nov 20, 2023
7cc0da8
public main merge
jayanth-tatina-groww Jan 9, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ the change with the owners before investing a lot of time coding. The process
could be:

1. Open an issue explaining the improvment or fix you want to add
2. [Fork the project](https://github.com/luraproject/lura/fork_select)
2. [Fork the project](https://github.com/luraproject/lura/fork)
3. Code it in your fork
4. Submit a [pull request](https://help.github.com/articles/creating-a-pull-request) referencing the issue

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/3151/badge)
![Docker Pulls](https://img.shields.io/docker/pulls/devopsfaith/krakend.svg)
[![Slack Widget](https://img.shields.io/badge/join-us%20on%20slack-gray.svg?longCache=true&logo=slack&colorB=red)](https://gophers.slack.com/messages/lura)
[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fluraproject%2Flura.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2Fluraproject%2Flura?ref=badge_shield)
[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fluraproject%2Flura.svg?type=shield&issueType=license)](https://app.fossa.com/projects/git%2Bgithub.com%2Fluraproject%2Flura?ref=badge_shield&issueType=license)


An open framework to assemble ultra performance API Gateways with middlewares; formerly known as _KrakenD framework_, and core service of the [KrakenD API Gateway](http://www.krakend.io).
Expand Down Expand Up @@ -124,4 +124,4 @@ Enjoy Lura!


## License
[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fluraproject%2Flura.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2Fluraproject%2Flura?ref=badge_large)
[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fluraproject%2Flura.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2Fluraproject%2Flura?ref=badge_large)
82 changes: 65 additions & 17 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"encoding/json"
"errors"
"fmt"
"net"
"net/http"
"net/textproto"
"regexp"
Expand Down Expand Up @@ -56,6 +57,8 @@ type ServiceConfig struct {
Host []string `mapstructure:"host"`
// port to bind the lura service
Port int `mapstructure:"port"`
// address to listen
Address string `mapstructure:"listen_ip"`
// version code of the configuration
Version int `mapstructure:"version"`
// OutputEncoding defines the default encoding strategy to use for the endpoint responses
Expand Down Expand Up @@ -157,10 +160,13 @@ type ServiceConfig struct {
// the router layer
TLS *TLS `mapstructure:"tls"`

// UseH2C enables h2c support.
UseH2C bool `mapstructure:"use_h2c"`

// run lura in debug mode
Debug bool `mapstructure:"debug_endpoint"`
Echo bool `mapstructure:"echo_endpoint"`
uriParser URIParser
uriParser SafeURIParser

// SequentialStart flags if the agents should be started sequentially
// before starting the router
Expand Down Expand Up @@ -272,6 +278,8 @@ type Backend struct {
ExtraConfig ExtraConfig `mapstructure:"extra_config"`
// HeadersToPass defines the list of headers to pass to this backend
HeadersToPass []string `mapstructure:"input_headers"`
// QueryStringsToPass has the list of query string params to be sent to the backend
QueryStringsToPass []string `mapstructure:"input_query_strings"`
}

// Plugin contains the config required by the plugin module
Expand All @@ -297,13 +305,21 @@ type TLS struct {

// ClientTLS defines the configuration params for an HTTP Client
type ClientTLS struct {
AllowInsecureConnections bool `mapstructure:"allow_insecure_connections"`
CaCerts []string `mapstructure:"ca_certs"`
DisableSystemCaPool bool `mapstructure:"disable_system_ca_pool"`
MinVersion string `mapstructure:"min_version"`
MaxVersion string `mapstructure:"max_version"`
CurvePreferences []uint16 `mapstructure:"curve_preferences"`
CipherSuites []uint16 `mapstructure:"cipher_suites"`
AllowInsecureConnections bool `mapstructure:"allow_insecure_connections"`
CaCerts []string `mapstructure:"ca_certs"`
DisableSystemCaPool bool `mapstructure:"disable_system_ca_pool"`
MinVersion string `mapstructure:"min_version"`
MaxVersion string `mapstructure:"max_version"`
CurvePreferences []uint16 `mapstructure:"curve_preferences"`
CipherSuites []uint16 `mapstructure:"cipher_suites"`
ClientCerts []ClientTLSCert `mapstructure:"client_certs"`
}

// ClientTLSCert holds a certificate with its private key to be
// used for mTLS against the backend services
type ClientTLSCert struct {
Certificate string `mapstructure:"certificate"`
PrivateKey string `mapstructure:"private_key"`
}

// ExtraConfig is a type to store extra configurations for customized behaviours
Expand Down Expand Up @@ -361,7 +377,7 @@ func (s *ServiceConfig) Hash() (string, error) {
// Init also sanitizes the values, applies the default ones whenever necessary and
// normalizes all the things.
func (s *ServiceConfig) Init() error {
s.uriParser = NewURIParser()
s.uriParser = NewSafeURIParser()

if s.Version != ConfigVersion {
return &UnsupportedVersionError{
Expand All @@ -370,9 +386,13 @@ func (s *ServiceConfig) Init() error {
}
}

s.initGlobalParams()
if err := s.initGlobalParams(); err != nil {
return err
}

s.initAsyncAgents()
if err := s.initAsyncAgents(); err != nil {
return err
}

return s.initEndpoints()
}
Expand All @@ -393,19 +413,31 @@ func (s *ServiceConfig) Normalize() {
}
}

func (s *ServiceConfig) initGlobalParams() {
func (s *ServiceConfig) initGlobalParams() error {
if s.Port == 0 {
s.Port = defaultPort
}

if s.Address != "" {
if !validateAddress(s.Address) {
return fmt.Errorf("invalid ip address %s", s.Address)
}
}

if s.MaxIdleConnsPerHost == 0 {
s.MaxIdleConnsPerHost = DefaultMaxIdleConnsPerHost
}
if s.Timeout == 0 {
s.Timeout = DefaultTimeout
}

s.Host = s.uriParser.CleanHosts(s.Host)
var err error
s.Host, err = s.uriParser.SafeCleanHosts(s.Host)
if err != nil {
return err
}
s.ExtraConfig.sanitize()
return nil
}

func (s *ServiceConfig) initAsyncAgents() error {
Expand All @@ -418,7 +450,11 @@ func (s *ServiceConfig) initAsyncAgents() error {
if len(b.Host) == 0 {
b.Host = s.Host
} else if !b.HostSanitizationDisabled {
b.Host = s.uriParser.CleanHosts(b.Host)
var err error
b.Host, err = s.uriParser.SafeCleanHosts(b.Host)
if err != nil {
return err
}
}
if b.Method == "" {
b.Method = http.MethodGet
Expand Down Expand Up @@ -461,7 +497,9 @@ func (s *ServiceConfig) initEndpoints() error {
e.ExtraConfig.sanitize()

for j, b := range e.Backend {
s.initBackendDefaults(i, j)
if err := s.initBackendDefaults(i, j); err != nil {
return err
}

if err := s.initBackendURLMappings(i, j, inputSet); err != nil {
return err
Expand Down Expand Up @@ -525,13 +563,17 @@ func (s *ServiceConfig) initAsyncAgentDefaults(e int) {
}
}

func (s *ServiceConfig) initBackendDefaults(e, b int) {
func (s *ServiceConfig) initBackendDefaults(e, b int) error {
endpoint := s.Endpoints[e]
backend := endpoint.Backend[b]
if len(backend.Host) == 0 {
backend.Host = s.Host
} else if !backend.HostSanitizationDisabled {
backend.Host = s.uriParser.CleanHosts(backend.Host)
var err error
backend.Host, err = s.uriParser.SafeCleanHosts(backend.Host)
if err != nil {
return err
}
}
if backend.Method == "" {
backend.Method = endpoint.Method
Expand All @@ -549,6 +591,7 @@ func (s *ServiceConfig) initBackendDefaults(e, b int) {
if backend.SDScheme == "" {
backend.SDScheme = "http"
}
return nil
}

func (s *ServiceConfig) initBackendURLMappings(e, b int, inputParams map[string]interface{}) error {
Expand Down Expand Up @@ -743,3 +786,8 @@ func SetSequentialParamsPattern(pattern string) error {
sequentialParamsPattern = re
return nil
}

func validateAddress(address string) bool {
ip := net.ParseIP(address)
return ip != nil
}
25 changes: 15 additions & 10 deletions config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
package config

import (
"errors"
"fmt"
"strings"
"testing"
Expand Down Expand Up @@ -61,7 +62,7 @@ func TestConfig_initBackendURLMappings_ok(t *testing.T) {

backend := Backend{}
endpoint := EndpointConfig{Backend: []*Backend{&backend}}
subject := ServiceConfig{Endpoints: []*EndpointConfig{&endpoint}, uriParser: NewURIParser()}
subject := ServiceConfig{Endpoints: []*EndpointConfig{&endpoint}, uriParser: NewSafeURIParser()}

inputSet := map[string]interface{}{
"tupu": nil,
Expand Down Expand Up @@ -89,7 +90,7 @@ func TestConfig_initBackendURLMappings_tooManyOutput(t *testing.T) {
Endpoint: "/some/{tupu}",
Backend: []*Backend{&backend},
}
subject := ServiceConfig{Endpoints: []*EndpointConfig{&endpoint}, uriParser: NewURIParser()}
subject := ServiceConfig{Endpoints: []*EndpointConfig{&endpoint}, uriParser: NewSafeURIParser()}

inputSet := map[string]interface{}{
"tupu": nil,
Expand All @@ -106,7 +107,7 @@ func TestConfig_initBackendURLMappings_tooManyOutput(t *testing.T) {
func TestConfig_initBackendURLMappings_undefinedOutput(t *testing.T) {
backend := Backend{URLPattern: "supu/{tupu_56}/{supu-5t6}?a={foo}&b={foo}"}
endpoint := EndpointConfig{Endpoint: "/", Method: "GET", Backend: []*Backend{&backend}}
subject := ServiceConfig{Endpoints: []*EndpointConfig{&endpoint}, uriParser: NewURIParser()}
subject := ServiceConfig{Endpoints: []*EndpointConfig{&endpoint}, uriParser: NewSafeURIParser()}

inputSet := map[string]interface{}{
"tupu": nil,
Expand Down Expand Up @@ -210,7 +211,7 @@ func TestConfig_init(t *testing.T) {
t.Error(err.Error())
}

if hash != "0O1SlXMLFZwKikXa02ymwM301C8q0P4ekbb5PzsBbxM=" {
if hash != "GdZTJtCn9ZHj3iBR1ZxmZL65HjbTCU8HhbDG8YWudAo=" {
t.Errorf("unexpected hash: %s", hash)
}
}
Expand Down Expand Up @@ -261,11 +262,6 @@ func TestConfig_initKOMultipleBackendsForNoopEncoder(t *testing.T) {
}

func TestConfig_initKOInvalidHost(t *testing.T) {
defer func() {
if r := recover(); r == nil {
t.Errorf("The init process did not panic with an invalid host!")
}
}()
subject := ServiceConfig{
Version: ConfigVersion,
Host: []string{"http://127.0.0.1:8080http://127.0.0.1:8080"},
Expand All @@ -278,7 +274,16 @@ func TestConfig_initKOInvalidHost(t *testing.T) {
},
}

subject.Init()
err := subject.Init()
if err == nil {
t.Errorf("expected to fail with invalid host")
return
}

if !errors.Is(err, errInvalidHost) {
t.Errorf("expected 'errInvalidHost' got: %s", err.Error())
return
}
}

func TestConfig_initKOInvalidDebugPattern(t *testing.T) {
Expand Down
30 changes: 23 additions & 7 deletions config/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ type parseableServiceConfig struct {
CacheTTL string `json:"cache_ttl"`
Host []string `json:"host"`
Port int `json:"port"`
Address string `json:"listen_ip"`
Version int `json:"version"`
ExtraConfig *ExtraConfig `json:"extra_config,omitempty"`
ReadTimeout string `json:"read_timeout"`
Expand All @@ -162,6 +163,7 @@ type parseableServiceConfig struct {
Plugin *Plugin `json:"plugin,omitempty"`
TLS *parseableTLS `json:"tls,omitempty"`
ClientTLS *parseableClientTLS `json:"client_tls,omitempty"`
UseH2C bool `json:"use_h2c,omitempty"`
}

func (p *parseableServiceConfig) normalize() ServiceConfig {
Expand All @@ -171,6 +173,7 @@ func (p *parseableServiceConfig) normalize() ServiceConfig {
CacheTTL: parseDuration(p.CacheTTL),
Host: p.Host,
Port: p.Port,
Address: p.Address,
Version: p.Version,
Debug: p.Debug,
Echo: p.Echo,
Expand All @@ -191,6 +194,7 @@ func (p *parseableServiceConfig) normalize() ServiceConfig {
DialerKeepAlive: parseDuration(p.DialerKeepAlive),
OutputEncoding: p.OutputEncoding,
Plugin: p.Plugin,
UseH2C: p.UseH2C,
}
if p.TLS != nil {
cfg.TLS = &TLS{
Expand All @@ -216,6 +220,10 @@ func (p *parseableServiceConfig) normalize() ServiceConfig {
MaxVersion: p.ClientTLS.MaxVersion,
CurvePreferences: p.ClientTLS.CurvePreferences,
CipherSuites: p.ClientTLS.CipherSuites,
ClientCerts: make([]ClientTLSCert, 0, len(p.ClientTLS.ClientCerts)),
}
for _, cc := range p.ClientTLS.ClientCerts {
cfg.ClientTLS.ClientCerts = append(cfg.ClientTLS.ClientCerts, ClientTLSCert(cc))
}
}
if p.ExtraConfig != nil {
Expand Down Expand Up @@ -249,13 +257,19 @@ type parseableTLS struct {
}

type parseableClientTLS struct {
AllowInsecureConnections bool `json:"allow_insecure_connections"`
CaCerts []string `json:"ca_certs"`
DisableSystemCaPool bool `json:"disable_system_ca_pool"`
MinVersion string `json:"min_version"`
MaxVersion string `json:"max_version"`
CurvePreferences []uint16 `json:"curve_preferences"`
CipherSuites []uint16 `json:"cipher_suites"`
AllowInsecureConnections bool `json:"allow_insecure_connections"`
CaCerts []string `json:"ca_certs"`
DisableSystemCaPool bool `json:"disable_system_ca_pool"`
MinVersion string `json:"min_version"`
MaxVersion string `json:"max_version"`
CurvePreferences []uint16 `json:"curve_preferences"`
CipherSuites []uint16 `json:"cipher_suites"`
ClientCerts []parseableClientTLSCert `json:"client_certs"`
}

type parseableClientTLSCert struct {
Certificate string `json:"certificate"`
PrivateKey string `json:"private_key"`
}

type parseableEndpointConfig struct {
Expand Down Expand Up @@ -354,6 +368,7 @@ type parseableBackend struct {
SD string `json:"sd"`
HeadersToPass []string `json:"input_headers"`
SDScheme string `json:"sd_scheme"`
QueryStringsToPass []string `json:"input_query_strings"`
}

func (p *parseableBackend) normalize() *Backend {
Expand All @@ -372,6 +387,7 @@ func (p *parseableBackend) normalize() *Backend {
AllowList: p.AllowList,
DenyList: p.DenyList,
HeadersToPass: p.HeadersToPass,
QueryStringsToPass: p.QueryStringsToPass,
}
if b.SDScheme == "" {
b.SDScheme = "http"
Expand Down
Loading
Loading