Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: Rework Proxy Setup to use KongRoute struct for configuration #3228

Merged
merged 3 commits into from
Mar 5, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
23 changes: 15 additions & 8 deletions cmd/security-proxy-setup/res/configuration.toml
Original file line number Diff line number Diff line change
Expand Up @@ -54,38 +54,45 @@ RetryWaitPeriod = "1s"
[SecretStore.Authentication]
AuthType = "X-Vault-Token"

[Clients]
[Clients.CoreData]
[Routes]
[Routes.CoreData]
Name = "coredata"
jim-wang-intel marked this conversation as resolved.
Show resolved Hide resolved
Protocol = "http"
Host = "localhost"
Port = 48080

[Clients.Metadata]
[Routes.Metadata]
Name = "metadata"
Protocol = "http"
Host = "localhost"
Port = 48081

[Clients.Command]
[Routes.Command]
Name = "command"
Protocol = "http"
Host = "localhost"
Port = 48082

[Clients.Notifications]
[Routes.Notifications]
Name = "notifications"
Protocol = "http"
Host = "localhost"
Port = 48060

[Clients.Scheduler]
[Routes.Scheduler]
Name = "scheduler"
Protocol = "http"
Host = "localhost"
Port = 48085

[Clients.RulesEngine]
[Routes.RulesEngine]
Name = "rulesengine"
Protocol = "http"
Host = "localhost"
Port = 48075

[Clients.VirtualDevice]
[Routes.VirtualDevice]
Name = "virtualdevice"
Protocol = "http"
Host = "localhost"
Port = 49990
4 changes: 3 additions & 1 deletion internal/security/proxy/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import (
"net/url"

bootstrapConfig "github.com/edgexfoundry/go-mod-bootstrap/v2/config"

"github.com/edgexfoundry/edgex-go/internal/security/proxy/models"
)

type ConfigurationStruct struct {
Expand All @@ -31,7 +33,7 @@ type ConfigurationStruct struct {
KongAuth KongAuthInfo
KongACL KongAclInfo
SecretStore bootstrapConfig.SecretStoreInfo
Clients map[string]bootstrapConfig.ClientInfo
Routes map[string]models.KongService
}

type KongUrlInfo struct {
Expand Down
4 changes: 2 additions & 2 deletions internal/security/proxy/container/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
package container

import (
"github.com/edgexfoundry/edgex-go/internal/security/proxy/config"

"github.com/edgexfoundry/go-mod-bootstrap/v2/di"

"github.com/edgexfoundry/edgex-go/internal/security/proxy/config"
)

// ConfigurationName contains the name of the config.ConfigurationStruct implementation in the DIC.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
*
* @author: Tingyu Zeng, Dell
*******************************************************************************/
package proxy
package models

type KongService struct {
Name string `url:"name,omitempty"`
Expand Down
77 changes: 36 additions & 41 deletions internal/security/proxy/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ import (
"strconv"
"strings"

"github.com/edgexfoundry/edgex-go/internal/security/proxy/config"

"github.com/edgexfoundry/edgex-go/internal"
"github.com/edgexfoundry/edgex-go/internal/security/proxy/config"
"github.com/edgexfoundry/edgex-go/internal/security/proxy/models"

"github.com/edgexfoundry/go-mod-core-contracts/v2/clients"
"github.com/edgexfoundry/go-mod-core-contracts/v2/clients/logger"
Expand Down Expand Up @@ -62,7 +62,7 @@ type Service struct {
loggingClient logger.LoggingClient
configuration *config.ConfigurationStruct
additionalRoutes string
routes map[string]*KongRoute
routes map[string]*models.KongRoute
}

func NewService(
Expand All @@ -75,7 +75,7 @@ func NewService(
loggingClient: lc,
configuration: configuration,
additionalRoutes: strings.TrimSpace(os.Getenv(AddProxyRoutesEnv)),
routes: make(map[string]*KongRoute),
routes: make(map[string]*models.KongRoute),
}
}

Expand Down Expand Up @@ -136,27 +136,21 @@ func (s *Service) Init() error {
s.additionalRoutes, parseErr.Error()))
}

mergedClients := s.mergeRoutesWith(addRoutesFromEnv)
mergedRoutes := s.mergeRoutesWith(addRoutesFromEnv)

for clientName, client := range mergedClients {
serviceParams := &KongService{
Name: strings.ToLower(clientName),
Host: client.Host,
Port: client.Port,
Protocol: client.Protocol,
}
for _, route := range mergedRoutes {

err := s.initKongService(serviceParams)
err := s.initKongService(&route)
if err != nil {
return err
}

routeParams := &KongRoute{
Paths: []string{"/" + strings.ToLower(clientName)},
Name: strings.ToLower(clientName),
routeParams := &models.KongRoute{
Paths: []string{"/" + strings.ToLower(route.Name)},
Name: strings.ToLower(route.Name),
}

err = s.initKongRoutes(routeParams, strings.ToLower(clientName))
err = s.initKongRoutes(routeParams, strings.ToLower(route.Name))
if err != nil {
return err
}
Expand All @@ -177,20 +171,20 @@ func (s *Service) Init() error {
}

// parseAdditionalProxyRoutes is to parse out the value of env AddProxyRoutesEnv
// into key / value pairs of map [string]bootstrapConfig.ClientInfo
// where key is service name, and value is the service ClientInfo
// into key / value pairs of map [string]KongService
// where key is service name, and value is the service
// the env should contain the list of comma separated entries with the format of
// Name.URL to be considered well-formed
// Name is used as the key of service name
// URL should be well-formed as protocol://hostName:portNumber
// and is parsed into bootstrapConfig.ClientInfo structure if valid
// and is parsed into KongService structure if valid
// returns error if not valid
func (s *Service) parseAdditionalProxyRoutes() (map[string]bootstrapConfig.ClientInfo, error) {
emptyMap := make(map[string]bootstrapConfig.ClientInfo)
func (s *Service) parseAdditionalProxyRoutes() (map[string]models.KongService, error) {
emptyMap := make(map[string]models.KongService)

routesFromEnv := strings.Split(s.additionalRoutes, ",")

additionalClientMap := make(map[string]bootstrapConfig.ClientInfo)
additionalRouteMap := make(map[string]models.KongService)
for _, rt := range routesFromEnv {
route := strings.TrimSpace(rt)
// ignore the empty route
Expand Down Expand Up @@ -232,50 +226,51 @@ func (s *Service) parseAdditionalProxyRoutes() (map[string]bootstrapConfig.Clien
"invalid port, expecting integer as port number for additional kong route %s: %s", port, err.Error())
}

clientInfo := bootstrapConfig.ClientInfo{
routeInfo := models.KongService{
Name: serviceName,
Protocol: url.Scheme,
Host: hostName,
Port: portNum,
}

additionalClientMap[serviceName] = clientInfo
additionalRouteMap[serviceName] = routeInfo
}

return additionalClientMap, nil
return additionalRouteMap, nil
}

func (s *Service) mergeRoutesWith(additional map[string]bootstrapConfig.ClientInfo) map[string]bootstrapConfig.ClientInfo {
func (s *Service) mergeRoutesWith(additional map[string]models.KongService) map[string]models.KongService {
// merging ignores the duplicate keys with the current internal map

if len(additional) == 0 {
return s.configuration.Clients
return s.configuration.Routes
}

if len(s.configuration.Clients) == 0 {
if len(s.configuration.Routes) == 0 {
return additional
}

merged := make(map[string]bootstrapConfig.ClientInfo)
for serviceName, client := range s.configuration.Clients {
merged[serviceName] = client
merged := make(map[string]models.KongService)
for serviceName, route := range s.configuration.Routes {
merged[serviceName] = route
}

for serviceName, client := range additional {
for serviceName, route := range additional {
_, exists := merged[serviceName]
if exists {
s.loggingClient.Warn(fmt.Sprintf(
"attempting to add additional service name %s that already exists in the config. "+
"Ignoring additional", serviceName))
continue
}
merged[serviceName] = client
merged[serviceName] = route
}

return merged
}

func (s *Service) postCert(cp bootstrapConfig.CertKeyPair) *CertError {
body := &CertInfo{
body := &models.CertInfo{
Cert: cp.Cert,
Key: cp.Key,
Snis: s.configuration.SNIS,
Expand Down Expand Up @@ -322,7 +317,7 @@ func (s *Service) postCert(cp bootstrapConfig.CertKeyPair) *CertError {
return nil
}

func (s *Service) initKongService(service *KongService) error {
func (s *Service) initKongService(service *models.KongService) error {
formVals := url.Values{
"name": {service.Name},
"host": {service.Host},
Expand Down Expand Up @@ -360,7 +355,7 @@ func (s *Service) initKongService(service *KongService) error {
return nil
}

func (s *Service) initKongRoutes(r *KongRoute, name string) error {
func (s *Service) initKongRoutes(r *models.KongRoute, name string) error {
data, err := json.Marshal(r)
if err != nil {
s.loggingClient.Error(err.Error())
Expand Down Expand Up @@ -398,7 +393,7 @@ func (s *Service) initKongRoutes(r *KongRoute, name string) error {
}

func (s *Service) initACL(name string, whitelist string) error {
aclParams := &KongACLPlugin{
aclParams := &models.KongACLPlugin{
Name: name,
WhiteList: whitelist,
}
Expand Down Expand Up @@ -483,7 +478,7 @@ func (s *Service) initJWTAuth() error {
}

func (s *Service) initOAuth2(ttl int) error {
oauth2Params := &KongOAuth2Plugin{
oauth2Params := &models.KongOAuth2Plugin{
Name: "oauth2",
Scope: OAuth2Scopes,
MandatoryScope: "true",
Expand Down Expand Up @@ -529,8 +524,8 @@ func (s *Service) initOAuth2(ttl int) error {
return nil
}

func (s *Service) getSvcIDs(path string) (DataCollect, error) {
collection := DataCollect{}
func (s *Service) getSvcIDs(path string) (models.DataCollect, error) {
collection := models.DataCollect{}

tokens := []string{s.configuration.KongURL.GetProxyBaseURL(), path}
req, err := http.NewRequest(http.MethodGet, strings.Join(tokens, "/"), nil)
Expand Down
6 changes: 4 additions & 2 deletions internal/security/proxy/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import (
"testing"

"github.com/edgexfoundry/edgex-go/internal/security/proxy/config"
"github.com/edgexfoundry/edgex-go/internal/security/proxy/models"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

Expand Down Expand Up @@ -325,7 +327,7 @@ func TestInitKongService(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tk := &KongService{tt.serviceId, "test", 80, "http"}
tk := &models.KongService{tt.serviceId, "test", 80, "http"}
svc := NewService(&http.Client{}, logger.MockLogger{}, &tt.config)
err = svc.initKongService(tk)

Expand Down Expand Up @@ -384,7 +386,7 @@ func TestInitKongRoutes(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
svc := NewService(&http.Client{}, logger.MockLogger{}, &tt.config)
err = svc.initKongRoutes(&KongRoute{}, tt.path)
err = svc.initKongRoutes(&models.KongRoute{}, tt.path)
if err != nil && !tt.expectError {
t.Error(err)
}
Expand Down
47 changes: 27 additions & 20 deletions internal/security/proxy/testdata/configuration.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,38 +47,45 @@ TokenPath = "res/resp-init.json"
CACertPath = "res/EdgeXFoundryCA/EdgeXFoundryCA.pem"
SNIS = ["edgex-kong"]

[Clients]
[Clients.CoreData]
[Routes]
[Routes.CoreData]
Name = "coredata"
Protocol = "http"
Host = "edgex-core-data"
Host = "localhost"
Port = 48080

[Clients.Metadata]

[Routes.Metadata]
Name = "metadata"
Protocol = "http"
Host = "edgex-core-metadata"
Host = "localhost"
Port = 48081

[Clients.Command]

[Routes.Command]
Name = "command"
Protocol = "http"
Host = "edgex-core-command"
Host = "localhost"
Port = 48082

[Clients.Notifications]

[Routes.Notifications]
Name = "notifications"
Protocol = "http"
Host = "edgex-support-notifications"
Host = "localhost"
Port = 48060

[Clients.Scheduler]
Protocol = 'http'
Host = 'edgex-support-scheduler'
[Routes.Scheduler]
Name = "scheduler"
Protocol = "http"
Host = "localhost"
Port = 48085

[Clients.Rulesengine]
[Routes.RulesEngine]
Name = "rules"
Protocol = "http"
Host = "edgex-support-rulesengine"
Host = "localhost"
Port = 48075

[Clients.Virtualdevice]

[Routes.VirtualDevice]
Name = "ds-virtual"
Protocol = "http"
Host = "edgex-device-virtual"
Host = "localhost"
Port = 49990