Skip to content

Commit

Permalink
chore: configfetcher interface added
Browse files Browse the repository at this point in the history
Signed-off-by: Mattia Lavacca <[email protected]>
  • Loading branch information
mlavacca committed Jul 19, 2023
1 parent 3bddbf2 commit ba25db2
Show file tree
Hide file tree
Showing 7 changed files with 162 additions and 120 deletions.
87 changes: 87 additions & 0 deletions internal/dataplane/configfetcher/config_fetcher.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package configfetcher

import (
"context"
"errors"

"github.com/kong/deck/dump"
"github.com/kong/deck/utils"
"github.com/kong/go-kong/kong"
"github.com/kong/kubernetes-ingress-controller/v2/internal/adminapi"
"github.com/kong/kubernetes-ingress-controller/v2/internal/dataplane/kongstate"
"github.com/kong/kubernetes-ingress-controller/v2/internal/dataplane/sendconfig"
"github.com/sirupsen/logrus"
)

type LastValidConfigFetcher interface {
// TryFetchingValidConfigFromGateways tries to fetch a valid configuration from all gateways and persists it if found.
TryFetchingValidConfigFromGateways(ctx context.Context, logger logrus.FieldLogger, gatewayClients []*adminapi.Client) error

// LastValidConfig returns the last valid config and true if there's one available. Otherwise, second return value is false.
LastValidConfig() (*kongstate.KongState, bool)

// StoreLastValidConfig stores a given configuration as the last valid config. Should be used when the configuration was successfully accepted by a gateway.
StoreLastValidConfig(s *kongstate.KongState)
}

type DefaultKongLastGoodConfigFetcher struct {
config dump.Config
lastValidState *kongstate.KongState
}

func NewDefaultKongLastGoodConfigFetcher() *DefaultKongLastGoodConfigFetcher {
return &DefaultKongLastGoodConfigFetcher{
config: dump.Config{},
}
}

func (cf *DefaultKongLastGoodConfigFetcher) LastValidConfig() (*kongstate.KongState, bool) {
if cf.lastValidState != nil {
return cf.lastValidState, true
}
return nil, false
}

func (cf *DefaultKongLastGoodConfigFetcher) StoreLastValidConfig(s *kongstate.KongState) {
cf.lastValidState = s
}

func (cf *DefaultKongLastGoodConfigFetcher) TryFetchingValidConfigFromGateways(
ctx context.Context,
logger logrus.FieldLogger,
gatewayClients []*adminapi.Client,
) error {
logger.Debugf("fetching last good configuration from %d gateway clients", len(gatewayClients))

var goodKongState *kongstate.KongState
var errs error
for _, client := range gatewayClients {
rs, err := cf.getKongRawState(ctx, client.AdminAPIClient())
if err != nil {
errs = errors.Join(errs, err)
}
ks := KongRawStateToKongState(rs)
status, err := cf.getKongStatus(ctx, client.AdminAPIClient())
if err != nil {
errs = errors.Join(errs, err)
}
if status.ConfigurationHash != sendconfig.WellKnownInitialHash {
// Get the first good one as the one to be used.
goodKongState = ks
break
}
}
if goodKongState != nil {
cf.lastValidState = goodKongState
logger.Debug("last good configuration fetched from a Kong node")
}
return errs
}

func (cf *DefaultKongLastGoodConfigFetcher) getKongRawState(ctx context.Context, client *kong.Client) (*utils.KongRawState, error) {
return dump.Get(ctx, client, cf.config)
}

func (cf *DefaultKongLastGoodConfigFetcher) getKongStatus(ctx context.Context, client *kong.Client) (*kong.Status, error) {
return client.Status(ctx)
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package kongstate_test
package configfetcher_test

import (
"reflect"
Expand All @@ -10,6 +10,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/kong/kubernetes-ingress-controller/v2/internal/dataplane/configfetcher"
"github.com/kong/kubernetes-ingress-controller/v2/internal/dataplane/kongstate"
)

Expand Down Expand Up @@ -265,7 +266,7 @@ func TestKongRawStateToKongState(t *testing.T) {
} {
t.Run(tt.name, func(t *testing.T) {
tt := tt
state := kongstate.KongRawStateToKongState(&tt.kongRawState)
state := configfetcher.KongRawStateToKongState(&tt.kongRawState)
require.Equal(t, tt.expectedKongState, state)
})
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,41 +1,19 @@
package kongstate
package configfetcher

import (
"context"

"github.com/kong/deck/dump"
"github.com/kong/deck/utils"
"github.com/kong/go-kong/kong"
)

type KongLastGoodConfigFetcher interface {
// GetKongRawState fetches the configuration loaded in a Kong node.
GetKongRawState(ctx context.Context, client *kong.Client) (*utils.KongRawState, error)
// GetKongStatus fetches the status of a Kong node.
GetKongStatus(ctx context.Context, client *kong.Client) (*kong.Status, error)
}

type DefaultKongLastGoodConfigFetcher struct {
config dump.Config
}

func (g *DefaultKongLastGoodConfigFetcher) GetKongRawState(ctx context.Context, client *kong.Client) (*utils.KongRawState, error) {
return dump.Get(ctx, client, g.config)
}

func (g *DefaultKongLastGoodConfigFetcher) GetKongStatus(ctx context.Context, client *kong.Client) (*kong.Status, error) {
return client.Status(ctx)
}
"github.com/kong/kubernetes-ingress-controller/v2/internal/dataplane/kongstate"
)

func NewDefaultKongLastGoodConfigFetcher() *DefaultKongLastGoodConfigFetcher {
return &DefaultKongLastGoodConfigFetcher{
config: dump.Config{},
}
}
// -----------------------------------------------------------------------------
// KongRawState to KongState conversion functions
// -----------------------------------------------------------------------------

// KongRawStateToKongState converts a Deck kongRawState to a KIC KongState.
func KongRawStateToKongState(rawstate *utils.KongRawState) *KongState {
kongState := &KongState{}
func KongRawStateToKongState(rawstate *utils.KongRawState) *kongstate.KongState {
kongState := &kongstate.KongState{}

routes := make(map[string][]*kong.Route)
for _, r := range rawstate.Routes {
Expand Down Expand Up @@ -63,13 +41,13 @@ func KongRawStateToKongState(rawstate *utils.KongRawState) *KongState {
}

for i, s := range rawstate.Services {
kongState.Services = append(kongState.Services, Service{
kongState.Services = append(kongState.Services, kongstate.Service{
Service: sanitizeKongService(*s),
Routes: []Route{},
Routes: []kongstate.Route{},
Plugins: []kong.Plugin{},
})
for j, r := range routes[*s.ID] {
kongState.Services[i].Routes = append(kongState.Services[i].Routes, Route{
kongState.Services[i].Routes = append(kongState.Services[i].Routes, kongstate.Route{
Route: sanitizeKongRoute(*r),
Plugins: []kong.Plugin{},
})
Expand All @@ -81,7 +59,7 @@ func KongRawStateToKongState(rawstate *utils.KongRawState) *KongState {
}

for _, u := range rawstate.Upstreams {
newUpstream := Upstream{
newUpstream := kongstate.Upstream{
Upstream: *u,
}
if u.ID != nil {
Expand All @@ -94,15 +72,15 @@ func KongRawStateToKongState(rawstate *utils.KongRawState) *KongState {
kongState.Certificates = rawCertificatesToCertificates(rawstate.Certificates)

for i, consumer := range rawstate.Consumers {
kongState.Consumers = append(kongState.Consumers, Consumer{
kongState.Consumers = append(kongState.Consumers, kongstate.Consumer{
Consumer: sanitizeConsumer(*consumer),
})
for _, keyAuth := range rawstate.KeyAuths {
if keyAuth.Consumer != nil {
if *keyAuth.Consumer.ID == *consumer.ID {
sanitizeAuth(keyAuth)
kongState.Consumers[i].KeyAuths = append(kongState.Consumers[i].KeyAuths,
&KeyAuth{
&kongstate.KeyAuth{
KeyAuth: *keyAuth,
},
)
Expand All @@ -114,7 +92,7 @@ func KongRawStateToKongState(rawstate *utils.KongRawState) *KongState {
if *hmacAuth.Consumer.ID == *consumer.ID {
sanitizeAuth(hmacAuth)
kongState.Consumers[i].HMACAuths = append(kongState.Consumers[i].HMACAuths,
&HMACAuth{
&kongstate.HMACAuth{
HMACAuth: *hmacAuth,
},
)
Expand All @@ -126,7 +104,7 @@ func KongRawStateToKongState(rawstate *utils.KongRawState) *KongState {
if *jwtAuth.Consumer.ID == *consumer.ID {
sanitizeAuth(jwtAuth)
kongState.Consumers[i].JWTAuths = append(kongState.Consumers[i].JWTAuths,
&JWTAuth{
&kongstate.JWTAuth{
JWTAuth: *jwtAuth,
},
)
Expand All @@ -138,7 +116,7 @@ func KongRawStateToKongState(rawstate *utils.KongRawState) *KongState {
if *basicAuth.Consumer.ID == *consumer.ID {
sanitizeAuth(basicAuth)
kongState.Consumers[i].BasicAuths = append(kongState.Consumers[i].BasicAuths,
&BasicAuth{
&kongstate.BasicAuth{
BasicAuth: *basicAuth,
},
)
Expand All @@ -150,7 +128,7 @@ func KongRawStateToKongState(rawstate *utils.KongRawState) *KongState {
if *aclGroup.Consumer.ID == *consumer.ID {
sanitizeAuth(aclGroup)
kongState.Consumers[i].ACLGroups = append(kongState.Consumers[i].ACLGroups,
&ACLGroup{
&kongstate.ACLGroup{
ACLGroup: *aclGroup,
},
)
Expand All @@ -162,7 +140,7 @@ func KongRawStateToKongState(rawstate *utils.KongRawState) *KongState {
if *oauth2Cred.Consumer.ID == *consumer.ID {
sanitizeAuth(oauth2Cred)
kongState.Consumers[i].Oauth2Creds = append(kongState.Consumers[i].Oauth2Creds,
&Oauth2Credential{
&kongstate.Oauth2Credential{
Oauth2Credential: *oauth2Cred,
},
)
Expand All @@ -174,7 +152,7 @@ func KongRawStateToKongState(rawstate *utils.KongRawState) *KongState {
if *mTLSAuth.Consumer.ID == *consumer.ID {
sanitizeAuth(mTLSAuth)
kongState.Consumers[i].MTLSAuths = append(kongState.Consumers[i].MTLSAuths,
&MTLSAuth{
&kongstate.MTLSAuth{
MTLSAuth: *mTLSAuth,
},
)
Expand All @@ -186,10 +164,6 @@ func KongRawStateToKongState(rawstate *utils.KongRawState) *KongState {
return kongState
}

// -----------------------------------------------------------------------------
// KongRawState to KongState conversion functions
// -----------------------------------------------------------------------------

func rawPluginsToPlugins(plugins []*kong.Plugin) []kong.Plugin {
if len(plugins) == 0 {
return nil
Expand All @@ -202,26 +176,26 @@ func rawPluginsToPlugins(plugins []*kong.Plugin) []kong.Plugin {
return ps
}

func rawTargetsToTargets(targets []*kong.Target) []Target {
func rawTargetsToTargets(targets []*kong.Target) []kongstate.Target {
if len(targets) == 0 {
return nil
}
ts := []Target{}
ts := []kongstate.Target{}

for _, t := range targets {
ts = append(ts, Target{Target: *t})
ts = append(ts, kongstate.Target{Target: *t})
}
return ts
}

func rawCertificatesToCertificates(certificates []*kong.Certificate) []Certificate {
func rawCertificatesToCertificates(certificates []*kong.Certificate) []kongstate.Certificate {
if len(certificates) == 0 {
return nil
}
certs := []Certificate{}
certs := []kongstate.Certificate{}

for _, c := range certificates {
certs = append(certs, Certificate{
certs = append(certs, kongstate.Certificate{
Certificate: sanitizeCertificate(*c),
})
}
Expand Down Expand Up @@ -259,7 +233,7 @@ func sanitizeKongRoute(route kong.Route) kong.Route {
return route
}

func sanitizeUpstream(upstream Upstream) Upstream {
func sanitizeUpstream(upstream kongstate.Upstream) kongstate.Upstream {
upstream.Upstream.CreatedAt = nil
upstream.Upstream.ID = nil
for i := range upstream.Targets {
Expand Down
Loading

0 comments on commit ba25db2

Please sign in to comment.