Skip to content

Commit

Permalink
feat: add Keeper support
Browse files Browse the repository at this point in the history
closes #649

Signed-off-by: Jack Chen <[email protected]>
  • Loading branch information
jackchenjc committed Mar 28, 2024
1 parent 84bbf53 commit 080e5c8
Show file tree
Hide file tree
Showing 8 changed files with 108 additions and 23 deletions.
2 changes: 2 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ updates:
directory: "/"
schedule:
interval: "daily"
ignore:
- dependency-name: "github.com/edgexfoundry/go-mod-core-contracts/v3"
3 changes: 2 additions & 1 deletion bootstrap/bootstrap.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/*******************************************************************************
* Copyright 2019 Dell Inc.
* Copyright 2023 Intel Corporation
* Copyright 2024 IOTech Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
Expand Down Expand Up @@ -125,7 +126,7 @@ func RunAndReturnWaitGroup(
// to the need for it to be used to get Access Token for the Configuration Provider and having to wait to
// initialize it until after the configuration is loaded from file.
configProcessor := config.NewProcessor(commonFlags, envVars, startupTimer, ctx, &wg, configUpdated, dic)
if err := configProcessor.Process(serviceKey, serviceType, configStem, serviceConfig, secretProvider); err != nil {
if err := configProcessor.Process(serviceKey, serviceType, configStem, serviceConfig, secretProvider, secret.NewJWTSecretProvider(secretProvider)); err != nil {
fatalError(err, lc)
}

Expand Down
80 changes: 70 additions & 10 deletions bootstrap/config/config.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/*******************************************************************************
* Copyright 2019 Dell Inc.
* Copyright 2023 Intel Corporation
* Copyright 2024 IOTech Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
Expand Down Expand Up @@ -47,7 +48,10 @@ import (
"github.com/edgexfoundry/go-mod-configuration/v3/configuration"
"github.com/edgexfoundry/go-mod-configuration/v3/pkg/types"

clientinterfaces "github.com/edgexfoundry/go-mod-core-contracts/v3/clients/interfaces"
"github.com/edgexfoundry/go-mod-core-contracts/v3/clients/logger"

"github.com/edgexfoundry/go-mod-messaging/v3/messaging"
)

const (
Expand All @@ -61,6 +65,8 @@ const (
deviceServicesKey = "device-services"

SecurityModeKey = "Mode"

configProviderTypeKeeper = "keeper"
)

var invalidRemoteHostsError = errors.New("-rsh/--remoteServiceHosts must contain 3 and only 3 comma seperated host names")
Expand Down Expand Up @@ -125,7 +131,8 @@ func (cp *Processor) Process(
serviceType string,
configStem string,
serviceConfig interfaces.Configuration,
secretProvider interfaces.SecretProviderExt) error {
secretProvider interfaces.SecretProviderExt,
jwtSecretProvider clientinterfaces.AuthenticationInjector) error {

cp.overwriteConfig = cp.flags.OverwriteConfig()
configProviderUrl := cp.flags.ConfigProviderUrl()
Expand All @@ -137,6 +144,8 @@ func (cp *Processor) Process(
return err
}

configProviderInfo.SetAuthInjector(jwtSecretProvider)

useProvider := configProviderInfo.UseProvider()

mode := &container.DevRemoteMode{
Expand Down Expand Up @@ -267,16 +276,16 @@ func (cp *Processor) Process(

// listen for changes on Writable
if useProvider {
cp.listenForPrivateChanges(serviceConfig, privateConfigClient, utils.BuildBaseKey(configStem, serviceKey))
cp.listenForPrivateChanges(serviceConfig, privateConfigClient, utils.BuildBaseKey(configStem, serviceKey), configProviderInfo.ServiceConfig().Type)
cp.lc.Infof("listening for private config changes")
cp.listenForCommonChanges(serviceConfig, cp.commonConfigClient, privateConfigClient, utils.BuildBaseKey(configStem, common.CoreCommonConfigServiceKey, allServicesKey))
cp.listenForCommonChanges(serviceConfig, cp.commonConfigClient, privateConfigClient, utils.BuildBaseKey(configStem, common.CoreCommonConfigServiceKey, allServicesKey), configProviderInfo.ServiceConfig().Type)
cp.lc.Infof("listening for all services common config changes")
if cp.appConfigClient != nil {
cp.listenForCommonChanges(serviceConfig, cp.appConfigClient, privateConfigClient, utils.BuildBaseKey(configStem, common.CoreCommonConfigServiceKey, appServicesKey))
cp.listenForCommonChanges(serviceConfig, cp.appConfigClient, privateConfigClient, utils.BuildBaseKey(configStem, common.CoreCommonConfigServiceKey, appServicesKey), configProviderInfo.ServiceConfig().Type)
cp.lc.Infof("listening for application service common config changes")
}
if cp.deviceConfigClient != nil {
cp.listenForCommonChanges(serviceConfig, cp.deviceConfigClient, privateConfigClient, utils.BuildBaseKey(configStem, common.CoreCommonConfigServiceKey, deviceServicesKey))
cp.listenForCommonChanges(serviceConfig, cp.deviceConfigClient, privateConfigClient, utils.BuildBaseKey(configStem, common.CoreCommonConfigServiceKey, deviceServicesKey), configProviderInfo.ServiceConfig().Type)
cp.lc.Infof("listening for device service common config changes")
}
}
Expand Down Expand Up @@ -660,7 +669,28 @@ func (cp *Processor) ListenForCustomConfigChanges(
updateStream := make(chan any)
defer close(updateStream)

configClient.WatchForChanges(updateStream, errorStream, configToWatch, sectionName)
var messageBus messaging.MessageClient
configProviderUrl := cp.flags.ConfigProviderUrl()
// check if the config provider type is keeper
if strings.HasPrefix(configProviderUrl, configProviderTypeKeeper) {
// there's no startupTimer for cp created by NewProcessorForCustomConfig
// add a new startupTimer here
if !cp.startupTimer.HasNotElapsed() {
cp.startupTimer = startup.NewStartUpTimer("")
}
for cp.startupTimer.HasNotElapsed() {
if msgClient := container.MessagingClientFrom(cp.dic.Get); msgClient != nil {
messageBus = msgClient
break
}
cp.startupTimer.SleepForInterval()
}
if messageBus == nil {
cp.lc.Error("unable to use MessageClient to watch for custom configuration changes")
return
}
}
go configClient.WatchForChanges(updateStream, errorStream, configToWatch, sectionName, messageBus)

isFirstUpdate := true

Expand Down Expand Up @@ -769,7 +799,7 @@ func GetConfigFileLocation(lc logger.LoggingClient, flags flags.Common) string {
// service's configuration writable sub-struct. It's assumed the log level is universally part of the
// writable struct and this function explicitly updates the loggingClient's log level when new configuration changes
// are received.
func (cp *Processor) listenForPrivateChanges(serviceConfig interfaces.Configuration, configClient configuration.Client, baseKey string) {
func (cp *Processor) listenForPrivateChanges(serviceConfig interfaces.Configuration, configClient configuration.Client, baseKey string, configProviderType string) {
lc := cp.lc
isFirstUpdate := true

Expand All @@ -783,7 +813,22 @@ func (cp *Processor) listenForPrivateChanges(serviceConfig interfaces.Configurat
updateStream := make(chan any)
defer close(updateStream)

go configClient.WatchForChanges(updateStream, errorStream, serviceConfig.EmptyWritablePtr(), writableKey)
// get the MessageClient to be used in Keeper WatchForChanges method
var messageBus messaging.MessageClient
if configProviderType == configProviderTypeKeeper {
for cp.startupTimer.HasNotElapsed() {
if msgClient := container.MessagingClientFrom(cp.dic.Get); msgClient != nil {
messageBus = msgClient
break
}
cp.startupTimer.SleepForInterval()
}
if messageBus == nil {
lc.Error("unable to use MessageClient to watch for configuration changes")
return
}
}
go configClient.WatchForChanges(updateStream, errorStream, serviceConfig.EmptyWritablePtr(), writableKey, messageBus)

for {
select {
Expand Down Expand Up @@ -826,7 +871,7 @@ func (cp *Processor) listenForPrivateChanges(serviceConfig interfaces.Configurat
// listenForCommonChanges leverages the Configuration Provider client's WatchForChanges() method to receive changes to and update the
// service's common configuration writable sub-struct.
func (cp *Processor) listenForCommonChanges(fullServiceConfig interfaces.Configuration, configClient configuration.Client,
privateConfigClient configuration.Client, baseKey string) {
privateConfigClient configuration.Client, baseKey string, configProviderType string) {
lc := cp.lc
isFirstUpdate := true
baseKey = utils.BuildBaseKey(baseKey, writableKey)
Expand All @@ -845,7 +890,22 @@ func (cp *Processor) listenForCommonChanges(fullServiceConfig interfaces.Configu
updateStream := make(chan any)
defer close(updateStream)

go commonConfigClient.WatchForChanges(updateStream, errorStream, fullServiceConfig.EmptyWritablePtr(), writableKey)
// get the MessageClient to be used in Keeper WatchForChanges method
var messageBus messaging.MessageClient
if configProviderType == configProviderTypeKeeper {
for cp.startupTimer.HasNotElapsed() {
if msgClient := container.MessagingClientFrom(cp.dic.Get); msgClient != nil {
messageBus = msgClient
break
}
cp.startupTimer.SleepForInterval()
}
if messageBus == nil {
lc.Error("unable to use MessageClient to watch for configuration changes")
return
}
}
go commonConfigClient.WatchForChanges(updateStream, errorStream, fullServiceConfig.EmptyWritablePtr(), writableKey, messageBus)

for {
select {
Expand Down
7 changes: 7 additions & 0 deletions bootstrap/config/provider.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*******************************************************************************
* Copyright 2020 Intel Corp.
* Copyright 2024 IOTech Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
Expand All @@ -15,6 +16,7 @@ package config

import (
"github.com/edgexfoundry/go-mod-configuration/v3/pkg/types"
"github.com/edgexfoundry/go-mod-core-contracts/v3/clients/interfaces"

"github.com/edgexfoundry/go-mod-bootstrap/v3/bootstrap/environment"
)
Expand Down Expand Up @@ -59,3 +61,8 @@ func (config *ProviderInfo) SetHost(host string) {
func (config *ProviderInfo) ServiceConfig() types.ServiceConfig {
return config.serviceConfig
}

// SetAuthInjector sets the Authentication Injector for the Configuration Provider
func (config *ProviderInfo) SetAuthInjector(authInjector interfaces.AuthenticationInjector) {
config.serviceConfig.AuthInjector = authInjector
}
3 changes: 3 additions & 0 deletions bootstrap/registration/registry.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/*******************************************************************************
* Copyright 2019 Dell Inc.
* Copyright 2020, 2023 Intel Inc.
* Copyright 2024 IOTech Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
Expand All @@ -20,6 +21,7 @@ import (
"errors"
"fmt"

"github.com/edgexfoundry/go-mod-bootstrap/v3/bootstrap/secret"
"github.com/edgexfoundry/go-mod-core-contracts/v3/clients/logger"
"github.com/edgexfoundry/go-mod-core-contracts/v3/common"

Expand Down Expand Up @@ -84,6 +86,7 @@ func createRegistryClient(
CheckInterval: bootstrapConfig.Service.HealthCheckInterval,
CheckRoute: common.ApiPingRoute,
GetAccessToken: getAccessToken,
AuthInjector: secret.NewJWTSecretProvider(secretProvider),
}

lc.Info(fmt.Sprintf("Using Registry (%s) from %s", registryConfig.Type, registryConfig.GetRegistryUrl()))
Expand Down
13 changes: 10 additions & 3 deletions bootstrap/secret/secure.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/*******************************************************************************
* Copyright 2018 Dell Inc.
* Copyright 2020-2023 Intel Corporation
* Copyright 2024 IOTech Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
Expand Down Expand Up @@ -41,6 +42,7 @@ import (

const (
TokenTypeConsul = "consul"
TokenTypeKeeper = "keeper"
AccessTokenAuthError = "HTTP response with status code 403"
//nolint: gosec
SecretsAuthError = "Received a '403' response"
Expand Down Expand Up @@ -249,9 +251,11 @@ func (p *SecureProvider) SecretsLastUpdated() time.Time {

// GetAccessToken returns the access token for the requested token type.
func (p *SecureProvider) GetAccessToken(tokenType string, serviceKey string) (string, error) {
p.securityConsulTokensRequested.Inc(1)
started := time.Now()
defer p.securityConsulTokenDuration.UpdateSince(started)
if tokenType == TokenTypeConsul {
p.securityConsulTokensRequested.Inc(1)
started := time.Now()
defer p.securityConsulTokenDuration.UpdateSince(started)
}

switch tokenType {
case TokenTypeConsul:
Expand All @@ -268,6 +272,9 @@ func (p *SecureProvider) GetAccessToken(tokenType string, serviceKey string) (st
}

return token, nil
case TokenTypeKeeper:
// return empty token for Keeper as we don't need a token to access to it in security mode
return "", nil

default:
return "", fmt.Errorf("invalid access token type '%s'", tokenType)
Expand Down
7 changes: 4 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ go 1.21

require (
github.com/eclipse/paho.mqtt.golang v1.4.3
github.com/edgexfoundry/go-mod-configuration/v3 v3.2.0-dev.3
github.com/edgexfoundry/go-mod-core-contracts/v3 v3.2.0-dev.13
github.com/edgexfoundry/go-mod-configuration/v3 v3.2.0-dev.4
github.com/edgexfoundry/go-mod-core-contracts/v3 v3.2.0-dev.15
github.com/edgexfoundry/go-mod-messaging/v3 v3.2.0-dev.15
github.com/edgexfoundry/go-mod-registry/v3 v3.2.0-dev.3
github.com/edgexfoundry/go-mod-registry/v3 v3.2.0-dev.4
github.com/edgexfoundry/go-mod-secrets/v3 v3.2.0-dev.5
github.com/google/uuid v1.6.0
github.com/hashicorp/go-multierror v1.1.1
Expand Down Expand Up @@ -106,6 +106,7 @@ require (
github.com/shirou/gopsutil/v3 v3.24.2 // indirect
github.com/shoenig/go-m1cpu v0.1.6 // indirect
github.com/speps/go-hashids v2.0.0+incompatible // indirect
github.com/spf13/cast v1.6.0 // indirect
github.com/spiffe/go-spiffe/v2 v2.1.7 // indirect
github.com/stretchr/objx v0.5.2 // indirect
github.com/tklauser/go-sysconf v0.3.12 // indirect
Expand Down
16 changes: 10 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -84,14 +84,14 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/eclipse/paho.mqtt.golang v1.4.3 h1:2kwcUGn8seMUfWndX0hGbvH8r7crgcJguQNCyp70xik=
github.com/eclipse/paho.mqtt.golang v1.4.3/go.mod h1:CSYvoAlsMkhYOXh/oKyxa8EcBci6dVkLCbo5tTC1RIE=
github.com/edgexfoundry/go-mod-configuration/v3 v3.2.0-dev.3 h1:FtK8jRqmeLXqonL5mH4ACvgymfKjtpcPoaClY/FsW8Y=
github.com/edgexfoundry/go-mod-configuration/v3 v3.2.0-dev.3/go.mod h1:gScVAJPTYrmLzcfBGlENxjLU30Fwl66DtdIAE+0eBOA=
github.com/edgexfoundry/go-mod-core-contracts/v3 v3.2.0-dev.13 h1:ezcC0Mwbrj/s/RJGhuhVlSR+I3XRVoZDCa8YYn5MNdk=
github.com/edgexfoundry/go-mod-core-contracts/v3 v3.2.0-dev.13/go.mod h1:osNZDpr2El77Z+CI0gg/rWwTYAVO+wpUkCfLJALatuI=
github.com/edgexfoundry/go-mod-configuration/v3 v3.2.0-dev.4 h1:MjlhyCo0TME3POp7tGxP+H0hoNilf+pbzcyK4kT8gnU=
github.com/edgexfoundry/go-mod-configuration/v3 v3.2.0-dev.4/go.mod h1:Im4AGMKgTnLaV4WVkogj/IBPnPnx2GRCra0SPiaZ9YQ=
github.com/edgexfoundry/go-mod-core-contracts/v3 v3.2.0-dev.15 h1:Gz44VbI7TEINEqRjUQJ0q5o4AYna2w+cX1l14RT3V6I=
github.com/edgexfoundry/go-mod-core-contracts/v3 v3.2.0-dev.15/go.mod h1:osNZDpr2El77Z+CI0gg/rWwTYAVO+wpUkCfLJALatuI=
github.com/edgexfoundry/go-mod-messaging/v3 v3.2.0-dev.15 h1:NA6b1XbXeg3tT15mzizWgoH9seaZuT1nAAmBoYkqIVk=
github.com/edgexfoundry/go-mod-messaging/v3 v3.2.0-dev.15/go.mod h1:/dSTjrwKRjYThVBFj9gpfylsrckIuaoabpaxhsFL3/s=
github.com/edgexfoundry/go-mod-registry/v3 v3.2.0-dev.3 h1:SL4s47SicMHIfxaj6liCl6Xu5me/EvIeG7MrCiX5Szk=
github.com/edgexfoundry/go-mod-registry/v3 v3.2.0-dev.3/go.mod h1:nVBWbEe1CDOWF2YXh50r4r/pW2Wh9qC12+pnuZImBdA=
github.com/edgexfoundry/go-mod-registry/v3 v3.2.0-dev.4 h1:mCS8sz9ytI2aAzZTcWQ3bQo4K+4UTfO5XvDyWFbRWMk=
github.com/edgexfoundry/go-mod-registry/v3 v3.2.0-dev.4/go.mod h1:PS08QGLYbXDF+RLWkT3R5VBocNF4XuP79thRLA8Tgss=
github.com/edgexfoundry/go-mod-secrets/v3 v3.2.0-dev.5 h1:RqNk0FOo5xu5Aqe0zq8ZpcELlKsbrsbJmIf/w+/1zsU=
github.com/edgexfoundry/go-mod-secrets/v3 v3.2.0-dev.5/go.mod h1:qlilWavlpjDqngArXuT1tIu77G6Zg/G5aPuqvRIRZfA=
github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
Expand All @@ -108,6 +108,8 @@ github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/fatih/color v1.14.1 h1:qfhVLaG5s+nCROl1zJsZRxFeYrHLqWroPOQ8BWiNb4w=
github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg=
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
Expand Down Expand Up @@ -520,6 +522,8 @@ github.com/speps/go-hashids v2.0.0+incompatible h1:kSfxGfESueJKTx0mpER9Y/1XHl+FV
github.com/speps/go-hashids v2.0.0+incompatible/go.mod h1:P7hqPzMdnZOfyIk+xrlG1QaSMw+gCBdHKsBDnhpaZvc=
github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0=
github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk=
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
Expand Down

0 comments on commit 080e5c8

Please sign in to comment.