Skip to content

Commit

Permalink
Merge pull request #27 from szuecs/refactor-controller
Browse files Browse the repository at this point in the history
Refactor watch and provider logic
  • Loading branch information
mikkeloscar authored Jun 28, 2019
2 parents 289dd13 + e920bc1 commit 2ddc79f
Show file tree
Hide file tree
Showing 12 changed files with 896 additions and 710 deletions.
12 changes: 5 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,11 @@ namespace to limit the usage to a given namespace.

## How it works

1. list configmap by label selector to get a current list
1. enter watch configmap by label selector goroutine to react on updates
1. enter merge goroutine to build a sorted, uniqued list of target networks
1. enter provider goroutine that calls provider implementations of
Create(), Update(), Delete() to apply the rules specified by the user
base. Apply steps will only be executed from this goroutine if a
change was detected.
1. watch configmap by label selector and send an event with the Egress
configuration to the controller loop.
2. Store a cache of all Egress configurations observed in the cluster.
3. Pass the stored cache to the provider to ensure the configuration is
applied.

## Example

Expand Down
62 changes: 62 additions & 0 deletions controller/controller.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package controller

import (
"context"
"time"

log "github.com/sirupsen/logrus"
"github.com/szuecs/kube-static-egress-controller/provider"
)

// EgressController is the controller for creating Egress configuration via a
// provider.
type EgressController struct {
interval time.Duration
configsChan <-chan provider.EgressConfig
configsCache map[provider.Resource]map[string]struct{}
provider provider.Provider
}

// NewEgressController initializes a new EgressController.
func NewEgressController(prov provider.Provider, configsChan <-chan provider.EgressConfig, interval time.Duration) *EgressController {
return &EgressController{
interval: interval,
configsChan: configsChan,
provider: prov,
configsCache: make(map[provider.Resource]map[string]struct{}),
}
}

// Run runs the EgressController main loop.
func (c *EgressController) Run(ctx context.Context) {
log.Info("Running controller")
interval := c.interval
for {
select {
case <-time.After(interval):
err := c.provider.Ensure(c.configsCache)
if err != nil {
log.Errorf("Failed to ensure configuration: %v", err)
continue
}
interval = c.interval
case config := <-c.configsChan:
if len(config.IPAddresses) == 0 {
delete(c.configsCache, config.Resource)
} else {
log.Infof("Observed IP Addresses %v for %v", config.IPAddresses, config.Resource)
c.configsCache[config.Resource] = config.IPAddresses
}

err := c.provider.Ensure(c.configsCache)
if err != nil {
log.Errorf("Failed to ensure configuration: %v", err)
continue
}
interval = c.interval
case <-ctx.Done():
log.Info("Terminating controller loop.")
return
}
}
}
51 changes: 51 additions & 0 deletions controller/controller_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package controller

import (
"context"
"testing"

"github.com/stretchr/testify/require"
"github.com/szuecs/kube-static-egress-controller/provider"
"github.com/szuecs/kube-static-egress-controller/provider/noop"
)

func TestControllerRun(t *testing.T) {
prov := noop.NewNoopProvider()
configsChan := make(chan provider.EgressConfig)
controller := NewEgressController(prov, configsChan, 0)

// test adding the an egress config.
ctx, cancel := context.WithCancel(context.Background())
go controller.Run(ctx)

configsChan <- provider.EgressConfig{
Resource: provider.Resource{
Name: "a",
Namespace: "x",
},
IPAddresses: map[string]struct{}{
"10.0.0.1": struct{}{},
},
}

cancel()
require.Len(t, controller.configsCache, 1)
require.Contains(t, controller.configsCache, provider.Resource{
Name: "a",
Namespace: "x",
})

// test removing the config
ctx, cancel = context.WithCancel(context.Background())
go controller.Run(ctx)

configsChan <- provider.EgressConfig{
Resource: provider.Resource{
Name: "a",
Namespace: "x",
},
}

cancel()
require.Len(t, controller.configsCache, 0)
}
49 changes: 22 additions & 27 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,58 +3,53 @@ module github.com/szuecs/kube-static-egress-controller
go 1.12

require (
github.com/PuerkitoBio/purell v1.0.0 // indirect
github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2 // indirect
github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38 // indirect
github.com/alecthomas/colour v0.0.0-20160524082231-60882d9e2721 // indirect
github.com/alecthomas/repr v0.0.0-20181024024818-d37bc2a10ba1 // indirect
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc // indirect
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf // indirect
github.com/aws/aws-sdk-go v1.19.41
github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a // indirect
github.com/cenkalti/backoff v1.1.0
github.com/crewjam/go-cloudformation v0.0.0-20170426160047-d3183a4759da
github.com/docker/distribution v2.7.1+incompatible // indirect
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633 // indirect
github.com/emicklei/go-restful-swagger12 v0.0.0-20170208215640-dcef7f557305 // indirect
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680 // indirect
github.com/go-openapi/analysis v0.0.0-20160815203709-b44dc874b601 // indirect
github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1 // indirect
github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9 // indirect
github.com/go-openapi/loads v0.0.0-20160704185440-18441dfa706d // indirect
github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501 // indirect
github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87 // indirect
github.com/gogo/protobuf v0.0.0-20170330071051-c0656edd0d9e // indirect
github.com/golang/glog v0.0.0-20141105023935-44145f04b68c // indirect
github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367 // indirect
github.com/howeyc/gopass v0.0.0-20170109162249-bf9dde6d0d2c // indirect
github.com/imdario/mergo v0.0.0-20141206190957-6633656539c1 // indirect
github.com/juju/ratelimit v0.0.0-20170523012141-5b9ff8664717 // indirect
github.com/gogo/protobuf v0.0.0-20171007142547-342cbe0a0415 // indirect
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903 // indirect
github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf // indirect
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d // indirect
github.com/hashicorp/golang-lru v0.5.1 // indirect
github.com/imdario/mergo v0.3.5 // indirect
github.com/json-iterator/go v0.0.0-20180701071628-ab8a2e0c74be // indirect
github.com/kr/pretty v0.1.0 // indirect
github.com/linki/instrumented_http v0.2.0
github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a // indirect
github.com/mattn/go-isatty v0.0.7 // indirect
github.com/matttproud/golang_protobuf_extensions v0.0.0-20150406173934-fc2b8d3a73c4 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.1 // indirect
github.com/onsi/ginkgo v1.8.0 // indirect
github.com/onsi/gomega v1.5.0 // indirect
github.com/opencontainers/go-digest v1.0.0-rc1 // indirect
github.com/pkg/errors v0.8.0
github.com/prometheus/client_golang v0.8.0 // indirect
github.com/prometheus/client_model v0.0.0-20170216185247-6f3806018612 // indirect
github.com/prometheus/common v0.0.0-20170220103846-49fee292b27b // indirect
github.com/prometheus/procfs v0.0.0-20150928173926-454a56f35412 // indirect
github.com/sergi/go-diff v1.0.0 // indirect
github.com/sirupsen/logrus v1.0.3
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff // indirect
github.com/stretchr/testify v1.3.0 // indirect
github.com/ugorji/go v0.0.0-20170107133203-ded73eae5db7 // indirect
github.com/spf13/pflag v1.0.1 // indirect
github.com/stretchr/testify v1.3.0
golang.org/x/crypto v0.0.0-20161006174701-d172538b2cfc // indirect
golang.org/x/net v0.0.0-20190206173232-65e2d4e15006 // indirect
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 // indirect
golang.org/x/sys v0.0.0-20190312061237-fead79001313 // indirect
golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db // indirect
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 // indirect
gopkg.in/airbrake/gobrake.v2 v2.0.9 // indirect
gopkg.in/alecthomas/kingpin.v2 v2.2.5
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2 // indirect
gopkg.in/inf.v0 v0.9.0 // indirect
gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0 // indirect
k8s.io/apimachinery v0.0.0-20170728134514-1fd2e63a9a37
k8s.io/client-go v4.0.0+incompatible
k8s.io/api v0.0.0-20190313235455-40a48860b5ab
k8s.io/apimachinery v0.0.0-20190313205120-d7deff9243b1
k8s.io/client-go v11.0.0+incompatible
k8s.io/klog v0.3.2 // indirect
k8s.io/utils v0.0.0-20190529001817-6999998975a7 // indirect
sigs.k8s.io/yaml v1.1.0 // indirect
)
Loading

0 comments on commit 2ddc79f

Please sign in to comment.