diff --git a/cmd/cli/proxy.go b/cmd/cli/proxy.go index 31ebcaa..07a826c 100644 --- a/cmd/cli/proxy.go +++ b/cmd/cli/proxy.go @@ -47,7 +47,7 @@ func StartProxy( for _, endpoints := range config.ProxyGateway.EnpointsProxy { - h.ProxyGateway(endpoints, key, securityType) + h.ProxyGateway(endpoints, engine, key, securityType) } if config.ProxySSL.Enable { diff --git a/go.mod b/go.mod old mode 100755 new mode 100644 index a14ee1c..2d41cc6 --- a/go.mod +++ b/go.mod @@ -9,5 +9,5 @@ require ( github.com/gorilla/mux v1.8.0 github.com/prometheus/client_golang v1.11.0 github.com/spf13/viper v1.8.1 - go.uber.org/zap v1.17.0 + go.uber.org/zap v1.19.0 ) diff --git a/go.sum b/go.sum index 91d1f85..80a0265 100644 --- a/go.sum +++ b/go.sum @@ -53,6 +53,8 @@ github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hC github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -371,10 +373,13 @@ go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0= +go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/zap v1.17.0 h1:MTjgFu6ZLKvY6Pvaqk97GlxNBuMpV4Hy/3P6tRGlI2U= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= +go.uber.org/zap v1.19.0 h1:mZQZefskPPCMIBCSEH0v2/iUqqLrYtaeqwD6FUGUnFE= +go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -409,6 +414,7 @@ golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRu golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= @@ -572,6 +578,7 @@ golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190927191325-030b2cf1153e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -607,6 +614,7 @@ golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.2 h1:kRBLX7v7Af8W7Gdbbc908OJcdgtK8bOz9Uaj8/F1ACA= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/internal/proxy/README.md b/internal/proxy/README.md index f0b2201..da3ac9b 100644 --- a/internal/proxy/README.md +++ b/internal/proxy/README.md @@ -11,8 +11,5 @@ ReverseProxy is an HTTP Handler that takes an incoming request and sends it to a TODO ----- -- add tls custom or let`s encrypt integration -- add first unit testings - add observability loggin, metric, tracing -- add Load balancer Round Robbin algoritm - add rate limit cache badgerdb and redis \ No newline at end of file diff --git a/internal/proxy/domain/proxy.go b/internal/proxy/domain/proxy.go index 3600634..887dcb7 100644 --- a/internal/proxy/domain/proxy.go +++ b/internal/proxy/domain/proxy.go @@ -17,5 +17,5 @@ type Endpoint struct { // ProxyRepository interface type ProxyRepository interface { SaveKEY(string, string, string) error - GetKEY(string) (string, error) + GetKEY(string, string) (string, error) } diff --git a/internal/proxy/domain/repositoryDB.go b/internal/proxy/domain/repositoryDB.go index d19f559..fddebe0 100644 --- a/internal/proxy/domain/repositoryDB.go +++ b/internal/proxy/domain/repositoryDB.go @@ -1,10 +1,12 @@ package proxy import ( + "context" "fmt" "os" badger "github.com/dgraph-io/badger/v3" + "github.com/go-redis/redis/v8" "github.com/kenriortega/ngonx/pkg/errors" "github.com/kenriortega/ngonx/pkg/logger" ) @@ -12,6 +14,7 @@ import ( // ProxyRepositoryStorage struct repository storage type ProxyRepositoryStorage struct { clientBadger *badger.DB + clientRdb *redis.Client } // NewProxyRepository return a new ProxyRepositoryStorage @@ -22,6 +25,8 @@ func NewProxyRepository(clients ...interface{}) ProxyRepositoryStorage { switch c := c.(type) { case *badger.DB: proxyRepositoryDB.clientBadger = c + case *redis.Client: + proxyRepositoryDB.clientRdb = c } } return proxyRepositoryDB @@ -45,6 +50,11 @@ func (r ProxyRepositoryStorage) SaveKEY(engine, key, apikey string) error { } return nil + case "redis": + if _, err := r.clientRdb.HSet(context.TODO(), key, apikey).Result(); err != nil { + logger.LogError(err.Error()) + } + // r.clientRdb.Expire(context.TODO(), key, 24*time.Hour) case "local": f, err := os.Create("./apikey") @@ -69,24 +79,33 @@ func (r ProxyRepositoryStorage) SaveKEY(engine, key, apikey string) error { } // GetKEY get key from the database -func (r ProxyRepositoryStorage) GetKEY(key string) (string, error) { +func (r ProxyRepositoryStorage) GetKEY(engine, key string) (string, error) { var apikey string - fmt.Println(key) - if err := r.clientBadger.View(func(txn *badger.Txn) error { - item, err := txn.Get([]byte(key)) - if err != nil { - return errors.ErrGetkeyTX - } - if err := item.Value(func(value []byte) error { - apikey = string(value) + + switch engine { + case "badger": + if err := r.clientBadger.View(func(txn *badger.Txn) error { + item, err := txn.Get([]byte(key)) + if err != nil { + return errors.ErrGetkeyTX + } + if err := item.Value(func(value []byte) error { + apikey = string(value) + return nil + }); err != nil { + return errors.ErrGetkeyValue + } + return nil }); err != nil { - return errors.ErrGetkeyValue + return "", errors.ErrGetkeyView } - - return nil - }); err != nil { - return "", errors.ErrGetkeyView + case "redis": + value, err := r.clientRdb.Get(context.TODO(), key).Result() + if err == redis.Nil || err != nil { + return "", err + } + apikey = value } return apikey, nil diff --git a/internal/proxy/handlers/proxy.go b/internal/proxy/handlers/proxy.go index ae6713c..7d60f4c 100644 --- a/internal/proxy/handlers/proxy.go +++ b/internal/proxy/handlers/proxy.go @@ -47,7 +47,7 @@ func (ph *ProxyHandler) SaveSecretKEY(engine, key, apikey string) { } // ProxyGateway handler for management all request -func (ph *ProxyHandler) ProxyGateway(endpoints domain.ProxyEndpoint, key, securityType string) { +func (ph *ProxyHandler) ProxyGateway(endpoints domain.ProxyEndpoint, engine, key, securityType string) { for _, endpoint := range endpoints.Endpoints { target, err := url.Parse( @@ -69,7 +69,7 @@ func (ph *ProxyHandler) ProxyGateway(endpoints domain.ProxyEndpoint, key, securi err := checkJWTSecretKeyFromRequest(req, key) proxy.ModifyResponse = modifyResponse(err) case "apikey": - err := checkAPIKEYSecretKeyFromRequest(req, ph, key) + err := checkAPIKEYSecretKeyFromRequest(req, ph, engine, key) proxy.ModifyResponse = modifyResponse(err) } @@ -154,8 +154,8 @@ func checkJWTSecretKeyFromRequest(req *http.Request, key string) error { } // checkAPIKEYSecretKeyFromRequest check apikey from request -func checkAPIKEYSecretKeyFromRequest(req *http.Request, ph *ProxyHandler, key string) error { - apikey, err := ph.Service.GetKEY(key) +func checkAPIKEYSecretKeyFromRequest(req *http.Request, ph *ProxyHandler, engine, key string) error { + apikey, err := ph.Service.GetKEY(engine, key) header := req.Header.Get("X-API-KEY") // pass to constants if err != nil { logger.LogError(errors.ErrGetkeyView.Error()) diff --git a/internal/proxy/services/proxy.go b/internal/proxy/services/proxy.go index add0c50..4237ac9 100644 --- a/internal/proxy/services/proxy.go +++ b/internal/proxy/services/proxy.go @@ -7,7 +7,7 @@ import ( // ProxyService interface service for proxy repository funcionalities type ProxyService interface { SaveSecretKEY(string, string, string) error - GetKEY(string) (string, error) + GetKEY(string, string) (string, error) } // DefaultProxyService struct for management proxy repository @@ -31,8 +31,8 @@ func (s DefaultProxyService) SaveSecretKEY(engine, key, apikey string) (string, } // GetKEY get key -func (s DefaultProxyService) GetKEY(key string) (string, error) { - result, err := s.repo.GetKEY(key) +func (s DefaultProxyService) GetKEY(engine, key string) (string, error) { + result, err := s.repo.GetKEY(engine, key) if err != nil { return "failed", err } diff --git a/internal/proxy/services/proxy_test.go b/internal/proxy/services/proxy_test.go index f53b87d..c954291 100644 --- a/internal/proxy/services/proxy_test.go +++ b/internal/proxy/services/proxy_test.go @@ -21,7 +21,7 @@ func Test_SaveSecretKEY(t *testing.T) { func Test_GetKEY(t *testing.T) { clientBadger := badgerdb.GetBadgerDB(false) proxyRepository = domain.NewProxyRepository(clientBadger) - result, err := proxyRepository.GetKEY("key") + result, err := proxyRepository.GetKEY("badger", "key") if err != nil { t.Error("Error to created key") } diff --git a/ngonx.yaml b/ngonx.yaml index 4b4605c..d7a73c3 100644 --- a/ngonx.yaml +++ b/ngonx.yaml @@ -17,7 +17,7 @@ proxy: crt_file: ./ssl/cert.pem key_file: ./ssl/key.pem cache_proxy: - engine: badger # local|badgerDB|redis + engine: badger # badgerDB|redis key: secretKey security: type: apikey # apikey|jwt|none diff --git a/pkg/redisdb/client.go b/pkg/redisdb/client.go index 9ade65e..c0d506a 100644 --- a/pkg/redisdb/client.go +++ b/pkg/redisdb/client.go @@ -2,7 +2,6 @@ package redisdb import ( "context" - "os" "time" "github.com/kenriortega/ngonx/pkg/logger" @@ -10,11 +9,11 @@ import ( "github.com/go-redis/redis/v8" ) -func GetRedisDbClient() *redis.Client { +func GetRedisDbClient(redisUri, redisPass string) *redis.Client { clientInstance := redis.NewClient(&redis.Options{ - Addr: os.Getenv("REDIS_URI"), // use default Addr - Password: os.Getenv("REDIS_PASS"), // no password set + Addr: redisUri, // use default Addr + Password: redisPass, // no password set DB: 0, DialTimeout: 60 * time.Second, ReadTimeout: 60 * time.Second,