Repository: containous/maesh
Pull request #706 (2020-08-18 15:08:33)

Removes unnecessary traefik pkg dependencies
## What does this PR do?

This PR:

- Removes unnecessary traefik pkg dependencies.

### How to test it

* make test
* make test-integration


Patch:
diff --git a/cmd/cleanup/cleanup.go b/cmd/cleanup/cleanup.go
index e9eebf8..fdf1023 100644
--- a/cmd/cleanup/cleanup.go
+++ b/cmd/cleanup/cleanup.go
@@ -7,7 +7,7 @@ import (
 	"github.com/containous/maesh/cmd"
 	"github.com/containous/maesh/pkg/cleanup"
 	"github.com/containous/maesh/pkg/k8s"
-	"github.com/containous/traefik/v2/pkg/cli"
+	"github.com/traefik/paerser/cli"
 )
 
 // NewCmd builds a new Cleanup command.
diff --git a/cmd/configuration.go b/cmd/configuration.go
index f9da224..b05a502 100644
--- a/cmd/configuration.go
+++ b/cmd/configuration.go
@@ -2,9 +2,6 @@ package cmd
 
 import (
 	"os"
-	"time"
-
-	"github.com/containous/traefik/v2/pkg/config/static"
 )
 
 // MaeshConfiguration wraps the static configuration and extra parameters.
@@ -75,14 +72,6 @@ func NewPrepareConfiguration() *PrepareConfiguration {
 	}
 }
 
-// ProxyConfiguration wraps the static configuration and extra parameters for proxy nodes.
-type ProxyConfiguration struct {
-	static.Configuration `export:"true"`
-	Endpoint             string        `description:"Load configuration from this endpoint." json:"endpoint" toml:"endpoint" yaml:"endpoint" export:"true"`
-	PollInterval         time.Duration `description:"Polling interval for endpoint." json:"pollInterval,omitempty" toml:"pollInterval,omitempty" yaml:"pollInterval,omitempty"`
-	PollTimeout          time.Duration `description:"Polling timeout for endpoint." json:"pollTimeout,omitempty" toml:"pollTimeout,omitempty" yaml:"pollTimeout,omitempty"`
-}
-
 // CleanupConfiguration holds the configuration for the cleanup command.
 type CleanupConfiguration struct {
 	ConfigFile string `description:"Configuration file to use. If specified all other flags are ignored." export:"true"`
diff --git a/cmd/loaders.go b/cmd/loaders.go
index bd982fa..a8747ae 100644
--- a/cmd/loaders.go
+++ b/cmd/loaders.go
@@ -6,12 +6,12 @@ import (
 	"os"
 	"strings"
 
-	"github.com/containous/traefik/v2/pkg/cli"
-	"github.com/containous/traefik/v2/pkg/config/env"
-	"github.com/containous/traefik/v2/pkg/config/file"
-	"github.com/containous/traefik/v2/pkg/config/flag"
-	"github.com/containous/traefik/v2/pkg/config/parser"
-	"github.com/containous/traefik/v2/pkg/log"
+	"github.com/sirupsen/logrus"
+	"github.com/traefik/paerser/cli"
+	"github.com/traefik/paerser/env"
+	"github.com/traefik/paerser/file"
+	"github.com/traefik/paerser/flag"
+	"github.com/traefik/paerser/parser"
 )
 
 const maeshPrefix = "MAESH_"
@@ -21,17 +21,19 @@ type EnvLoader struct{}
 
 // Load loads the command's configuration from the environment variables.
 func (e *EnvLoader) Load(_ []string, cmd *cli.Command) (bool, error) {
+	logger := logrus.StandardLogger()
+
 	vars := env.FindPrefixedEnvVars(os.Environ(), maeshPrefix, cmd.Configuration)
 	if len(vars) == 0 {
 		return false, nil
 	}
 
 	if err := env.Decode(vars, maeshPrefix, cmd.Configuration); err != nil {
-		log.WithoutContext().Debug("environment variables", strings.Join(vars, ", "))
+		logger.Debug("environment variables", strings.Join(vars, ", "))
 		return false, fmt.Errorf("failed to decode configuration from environment variables: %w ", err)
 	}
 
-	log.WithoutContext().Println("Configuration loaded from environment variables.")
+	logger.Println("Configuration loaded from environment variables.")
 
 	return true, nil
 }
@@ -41,6 +43,8 @@ type FileLoader struct{}
 
 // Load loads the command's configuration from a file either specified with the --configFile flag, or from default locations.
 func (f *FileLoader) Load(args []string, cmd *cli.Command) (bool, error) {
+	logger := logrus.StandardLogger()
+
 	ref, err := flag.Parse(args, cmd.Configuration)
 	if err != nil {
 		_ = cmd.PrintHelp(os.Stdout)
@@ -58,7 +62,6 @@ func (f *FileLoader) Load(args []string, cmd *cli.Command) (bool, error) {
 		return false, nil
 	}
 
-	logger := log.WithoutContext()
 	logger.Printf("Configuration loaded from file: %s", configFile)
 
 	content, _ := ioutil.ReadFile(configFile)
diff --git a/cmd/maesh/maesh.go b/cmd/maesh/maesh.go
index 6d09b6b..6db998f 100644
--- a/cmd/maesh/maesh.go
+++ b/cmd/maesh/maesh.go
@@ -17,8 +17,8 @@ import (
 	"github.com/containous/maesh/pkg/controller"
 	"github.com/containous/maesh/pkg/k8s"
 	preparepkg "github.com/containous/maesh/pkg/prepare"
-	"github.com/containous/traefik/v2/pkg/cli"
 	"github.com/sirupsen/logrus"
+	"github.com/traefik/paerser/cli"
 )
 
 const (
diff --git a/cmd/prepare/prepare.go b/cmd/prepare/prepare.go
index 70d60d3..81e349c 100644
--- a/cmd/prepare/prepare.go
+++ b/cmd/prepare/prepare.go
@@ -7,7 +7,7 @@ import (
 	"github.com/containous/maesh/cmd"
 	"github.com/containous/maesh/pkg/k8s"
 	"github.com/containous/maesh/pkg/prepare"
-	"github.com/containous/traefik/v2/pkg/cli"
+	"github.com/traefik/paerser/cli"
 )
 
 // NewCmd builds a new Prepare command.
diff --git a/cmd/version/version.go b/cmd/version/version.go
index 2544749..e580a4e 100644
--- a/cmd/version/version.go
+++ b/cmd/version/version.go
@@ -5,7 +5,7 @@ import (
 	"runtime"
 
 	"github.com/containous/maesh/pkg/version"
-	"github.com/containous/traefik/v2/pkg/cli"
+	"github.com/traefik/paerser/cli"
 )
 
 const versionFormat = `
diff --git a/go.mod b/go.mod
index 86d9c86..26afa83 100644
--- a/go.mod
+++ b/go.mod
@@ -13,7 +13,8 @@ require (
 	github.com/pmezard/go-difflib v1.0.0
 	github.com/servicemeshinterface/smi-sdk-go v0.4.1
 	github.com/sirupsen/logrus v1.6.0
-	github.com/stretchr/testify v1.5.1
+	github.com/stretchr/testify v1.6.1
+	github.com/traefik/paerser v0.1.0
 	github.com/vdemeester/shakers v0.1.0
 	k8s.io/api v0.18.6
 	k8s.io/apimachinery v0.18.6
diff --git a/go.sum b/go.sum
index 8b5247f..e5d7975 100644
--- a/go.sum
+++ b/go.sum
@@ -68,8 +68,12 @@ github.com/Masterminds/goutils v1.1.0 h1:zukEsf/1JZwCMgHiK3GZftabmxiCw4apj3a28RP
 github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
 github.com/Masterminds/semver v1.4.2 h1:WBLTQ37jOCzSLtXNdoo8bNM8876KhNqOKvrlGITgsTc=
 github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
+github.com/Masterminds/semver/v3 v3.1.0 h1:Y2lUDsFKVRSYGojLJ1yLxSXdMmMYTYls0rCvoqmMUQk=
+github.com/Masterminds/semver/v3 v3.1.0/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
 github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60=
 github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=
+github.com/Masterminds/sprig/v3 v3.1.0 h1:j7GpgZ7PdFqNsmncycTHsLmVPf5/3wJtlgW9TNDYD9Y=
+github.com/Masterminds/sprig/v3 v3.1.0/go.mod h1:ONGMf7UfYGAbMXCZmQLy8x3lCDIPrEZE/rU8pmrbihA=
 github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5 h1:ygIc8M6trr62pF5DucadTWGdEB4mEyvzi0e2nbcmcyA=
 github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
 github.com/Microsoft/hcsshim v0.8.7/go.mod h1:OHd7sQqRFrYd3RmSgbgji+ctCwkbq2wbEYNSzOYtcBQ=
@@ -410,11 +414,15 @@ github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
 github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
 github.com/huandu/xstrings v1.2.0 h1:yPeWdRnmynF7p+lLYz0H2tthW9lqhMJrQV/U7yy4wX0=
 github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4=
+github.com/huandu/xstrings v1.3.1 h1:4jgBlKK6tLKFvO8u5pmYjG91cqytmDCDvGh7ECVFfFs=
+github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
 github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
 github.com/iij/doapi v0.0.0-20190504054126-0bbf12d6d7df h1:MZf03xP9WdakyXhOWuAD5uPK3wHh96wCsqe3hCMKh8E=
 github.com/iij/doapi v0.0.0-20190504054126-0bbf12d6d7df/go.mod h1:QMZY7/J/KSQEhKWFeDesPjMj+wCHReeknARU3wqlyN4=
 github.com/imdario/mergo v0.3.5 h1:JboBksRwiiAJWvIYJVo46AfV+IAIKZpfrSzVKj42R4Q=
 github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
+github.com/imdario/mergo v0.3.8 h1:CGgOkSJeqMRmt0D9XLWExdT4m4F1vd3FV3VPt+0VxkQ=
+github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
 github.com/influxdata/influxdb1-client v0.0.0-20190809212627-fc22c7df067e h1:txQltCyjXAqVVSZDArPEhUTg35hKwVIuXwtQo7eAMNQ=
 github.com/influxdata/influxdb1-client v0.0.0-20190809212627-fc22c7df067e/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
 github.com/instana/go-sensor v1.5.1 h1:GLxYsYiDWD15RSXDHS70VvTVU/CbwUimWrK6/e4eBPQ=
@@ -650,6 +658,8 @@ github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9
 github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E=
 github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
 github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
+github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng=
+github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
 github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
 github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
 github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
@@ -663,6 +673,8 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV
 github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
 github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
 github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
+github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
+github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stvp/go-udp-testing v0.0.0-20191102171040-06b61409b154 h1:XGopsea1Dw7ecQ8JscCNQXDGYAKDiWjDeXnpN/+BY9g=
 github.com/stvp/go-udp-testing v0.0.0-20191102171040-06b61409b154/go.mod h1:7jxmlfBCDBXRzr0eAQJ48XC1hBu1np4CS5+cHEYfwpc=
 github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
@@ -672,6 +684,8 @@ github.com/tinylib/msgp v1.0.2 h1:DfdQrzQa7Yh2es9SuLkixqxuXS2SxsdYn0KbdrOGWD8=
 github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
 github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 h1:LnC5Kc/wtumK+WB441p7ynQJzVuNRJiqddSIE3IlSEQ=
 github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
+github.com/traefik/paerser v0.1.0 h1:B4v1tbvd8YnHsA7spwHKEWJoGrRP+2jYpIozsCMHhl0=
+github.com/traefik/paerser v0.1.0/go.mod h1:yYnAgdEC2wJH5CgG75qGWC8SsFDEapg09o9RrA6FfrE=
 github.com/transip/gotransip/v6 v6.0.2 h1:rOCMY607PYF+YvMHHtJt7eZRd0mx/uhyz6dsXWPmn+4=
 github.com/transip/gotransip/v6 v6.0.2/go.mod h1:pQZ36hWWRahCUXkFWlx9Hs711gLd8J4qdgLdRzmtY+g=
 github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
@@ -747,6 +761,8 @@ golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPh
 golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20200317142112-1b76d66859c6 h1:TjszyFsQsyZNHwdVdZ5m7bjmreu0znc2kRYsEml9/Ww=
 golang.org/x/crypto v0.0.0-20200317142112-1b76d66859c6/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20200414173820-0848c9571904 h1:bXoxMPcSLOq08zI3/c5dEBT6lE4eh+jOh886GHrn6V8=
+golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -1004,6 +1020,9 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
 gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
+gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ=
 gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
diff --git a/integration/try/try.go b/integration/try/try.go
index 722d1c7..7b429ac 100644
--- a/integration/try/try.go
+++ b/integration/try/try.go
@@ -14,7 +14,7 @@ import (
 
 	"github.com/cenkalti/backoff/v4"
 	"github.com/containous/maesh/pkg/k8s"
-	"github.com/containous/traefik/v2/pkg/safe"
+	"github.com/containous/maesh/pkg/safe"
 	"github.com/sirupsen/logrus"
 	appsv1 "k8s.io/api/apps/v1"
 	kubeerror "k8s.io/apimachinery/pkg/api/errors"
@@ -33,7 +33,7 @@ type timedAction func(timeout time.Duration, operation DoCondition) error
 // Try holds try configuration.
 type Try struct {
 	client k8s.Client
-	log    logrus.FieldLogger
+	logger logrus.FieldLogger
 }
 
 // NewTry creates a new try.
@@ -43,7 +43,7 @@ func NewTry(client k8s.Client) *Try {
 	log.SetOutput(os.Stdout)
 	log.SetLevel(logrus.DebugLevel)
 
-	return &Try{client: client, log: log}
+	return &Try{client: client, logger: log}
 }
 
 // WaitReadyDeployment wait until the deployment is ready.
@@ -152,7 +152,7 @@ func (t *Try) WaitPodIPAssigned(name string, namespace string, timeout time.Dura
 			return fmt.Errorf("unable get the pod %q in namespace %q: %v", name, namespace, err)
 		}
 
-		// If the pod IP is not empty, log and return.
+		// If the pod IP is not empty, logger and return.
 		if pod.Status.PodIP != "" {
 			// IP is assigned
 			fmt.Printf("Pod %q has IP: %s\n", name, pod.Status.PodIP)
@@ -187,7 +187,7 @@ func (t *Try) WaitCommandExecute(command string, argSlice []string, expected str
 			return fmt.Errorf("output %s does not contain %s", string(output), expected)
 		}
 
-		t.log.Debug(string(output))
+		t.logger.Debug(string(output))
 
 		return nil
 	}), ebo); err != nil {
diff --git a/pkg/api/api.go b/pkg/api/api.go
index 2140b60..4d3083b 100644
--- a/pkg/api/api.go
+++ b/pkg/api/api.go
@@ -10,9 +10,9 @@ import (
 
 	"github.com/containous/maesh/pkg/k8s"
 	"github.com/containous/maesh/pkg/provider"
+	"github.com/containous/maesh/pkg/safe"
 	"github.com/containous/maesh/pkg/topology"
 	"github.com/containous/traefik/v2/pkg/config/dynamic"
-	"github.com/containous/traefik/v2/pkg/safe"
 	"github.com/gorilla/mux"
 	"github.com/sirupsen/logrus"
 	kubeerror "k8s.io/apimachinery/pkg/api/errors"
diff --git a/pkg/dns/dns.go b/pkg/dns/dns.go
index 5a5aaed..7e9b9a4 100644
--- a/pkg/dns/dns.go
+++ b/pkg/dns/dns.go
@@ -9,7 +9,7 @@ import (
 	"time"
 
 	"github.com/cenkalti/backoff/v4"
-	"github.com/containous/traefik/v2/pkg/safe"
+	"github.com/containous/maesh/pkg/safe"
 	"github.com/google/uuid"
 	goversion "github.com/hashicorp/go-version"
 	"github.com/sirupsen/logrus"
diff --git a/pkg/k8s/client_mock.go b/pkg/k8s/client_mock.go
index d0b452c..da7702f 100644
--- a/pkg/k8s/client_mock.go
+++ b/pkg/k8s/client_mock.go
@@ -8,7 +8,6 @@ import (
 	"strings"
 	"testing"
 
-	"github.com/containous/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1"
 	access "github.com/servicemeshinterface/smi-sdk-go/pkg/apis/access/v1alpha2"
 	specs "github.com/servicemeshinterface/smi-sdk-go/pkg/apis/specs/v1alpha3"
 	split "github.com/servicemeshinterface/smi-sdk-go/pkg/apis/split/v1alpha3"
@@ -52,11 +51,6 @@ func init() {
 	if err != nil {
 		panic(err)
 	}
-
-	err = v1alpha1.AddToScheme(scheme.Scheme)
-	if err != nil {
-		panic(err)
-	}
 }
 
 // ClientMock holds mock client.
diff --git a/pkg/safe/recover.go b/pkg/safe/recover.go
new file mode 100644
index 0000000..7040cd0
--- /dev/null
+++ b/pkg/safe/recover.go
@@ -0,0 +1,27 @@
+package safe
+
+import (
+	"fmt"
+	"runtime/debug"
+
+	"github.com/cenkalti/backoff/v4"
+	"github.com/sirupsen/logrus"
+)
+
+// OperationWithRecover wrap a backoff operation in a Recover.
+func OperationWithRecover(operation backoff.Operation) backoff.Operation {
+	return func() (err error) {
+		defer func() {
+			if res := recover(); res != nil {
+				logger := logrus.StandardLogger()
+
+				logger.Errorf("Error in Go routine: %s", res)
+				logger.Errorf("Stack: %s", debug.Stack())
+
+				err = fmt.Errorf("panic in operation: %w", err)
+			}
+		}()
+
+		return operation()
+	}
+}
diff --git a/pkg/safe/safe.go b/pkg/safe/safe.go
new file mode 100644
index 0000000..d08e004
--- /dev/null
+++ b/pkg/safe/safe.go
@@ -0,0 +1,32 @@
+package safe
+
+import (
+	"sync"
+)
+
+// Safe contains a thread-safe value.
+type Safe struct {
+	value interface{}
+	lock  sync.RWMutex
+}
+
+// New create a new Safe instance given a value.
+func New(value interface{}) *Safe {
+	return &Safe{value: value}
+}
+
+// Get returns the value.
+func (s *Safe) Get() interface{} {
+	s.lock.RLock()
+	defer s.lock.RUnlock()
+
+	return s.value
+}
+
+// Set sets a new value.
+func (s *Safe) Set(value interface{}) {
+	s.lock.Lock()
+	defer s.lock.Unlock()
+
+	s.value = value
+}


Test patch:
diff --git a/integration/integration_test.go b/integration/integration_test.go
index d72f81c..617649d 100644
--- a/integration/integration_test.go
+++ b/integration/integration_test.go
@@ -24,8 +24,8 @@ import (
 	"github.com/cenkalti/backoff/v4"
 	"github.com/containous/maesh/integration/try"
 	"github.com/containous/maesh/pkg/k8s"
+	"github.com/containous/maesh/pkg/safe"
 	"github.com/containous/traefik/v2/pkg/config/dynamic"
-	"github.com/containous/traefik/v2/pkg/safe"
 	"github.com/go-check/check"
 	"github.com/pmezard/go-difflib/difflib"
 	access "github.com/servicemeshinterface/smi-sdk-go/pkg/apis/access/v1alpha2"
diff --git a/pkg/api/api_test.go b/pkg/api/api_test.go
index 5685fe6..832199d 100644
--- a/pkg/api/api_test.go
+++ b/pkg/api/api_test.go
@@ -9,7 +9,6 @@ import (
 	"testing"
 
 	"github.com/containous/maesh/pkg/k8s"
-	"github.com/containous/traefik/v2/pkg/testhelpers"
 	"github.com/gorilla/mux"
 	"github.com/sirupsen/logrus"
 	"github.com/stretchr/testify/assert"
@@ -72,7 +71,12 @@ func TestGetReadiness(t *testing.T) {
 			api.readiness.Set(test.readiness)
 
 			res := httptest.NewRecorder()
-			req := testhelpers.MustNewRequest(http.MethodGet, "/api/status/readiness", nil)
+
+			req, err := http.NewRequest(http.MethodGet, "/api/status/readiness", nil)
+			if err != nil {
+				require.NoError(t, err)
+				return
+			}
 
 			api.getReadiness(res, req)
 
@@ -94,7 +98,12 @@ func TestGetCurrentConfiguration(t *testing.T) {
 	api.configuration.Set("foo")
 
 	res := httptest.NewRecorder()
-	req := testhelpers.MustNewRequest(http.MethodGet, "/api/configuration/current", nil)
+
+	req, err := http.NewRequest(http.MethodGet, "/api/configuration/current", nil)
+	if err != nil {
+		require.NoError(t, err)
+		return
+	}
 
 	api.getCurrentConfiguration(res, req)
 
@@ -147,7 +156,12 @@ func TestGetMeshNodes(t *testing.T) {
 			require.NoError(t, err)
 
 			res := httptest.NewRecorder()
-			req := testhelpers.MustNewRequest(http.MethodGet, "/api/status/nodes", nil)
+
+			req, err := http.NewRequest(http.MethodGet, "/api/status/nodes", nil)
+			if err != nil {
+				require.NoError(t, err)
+				return
+			}
 
 			api.getMeshNodes(res, req)
 
@@ -198,9 +212,14 @@ func TestGetMeshNodeConfiguration(t *testing.T) {
 			require.NoError(t, err)
 
 			res := httptest.NewRecorder()
-			req := testhelpers.MustNewRequest(http.MethodGet, "/api/status/node/mesh-pod-1/configuration", nil)
 
-			//fake gorilla/mux vars
+			req, err := http.NewRequest(http.MethodGet, "/api/status/node/mesh-pod-1/configuration", nil)
+			if err != nil {
+				require.NoError(t, err)
+				return
+			}
+
+			// fake gorilla/mux vars
 			vars := map[string]string{
 				"node": "mesh-pod-1",
 			}
diff --git a/pkg/safe/recover_test.go b/pkg/safe/recover_test.go
new file mode 100644
index 0000000..a69a477
--- /dev/null
+++ b/pkg/safe/recover_test.go
@@ -0,0 +1,41 @@
+package safe
+
+import (
+	"fmt"
+	"testing"
+
+	"github.com/cenkalti/backoff/v4"
+)
+
+func TestOperationWithRecover(t *testing.T) {
+	operation := func() error {
+		return nil
+	}
+
+	err := backoff.Retry(OperationWithRecover(operation), &backoff.StopBackOff{})
+	if err != nil {
+		t.Fatalf("Error in OperationWithRecover: %s", err)
+	}
+}
+
+func TestOperationWithRecoverPanic(t *testing.T) {
+	operation := func() error {
+		panic("BOOM")
+	}
+
+	err := backoff.Retry(OperationWithRecover(operation), &backoff.StopBackOff{})
+	if err == nil {
+		t.Fatalf("Error in OperationWithRecover: %s", err)
+	}
+}
+
+func TestOperationWithRecoverError(t *testing.T) {
+	operation := func() error {
+		return fmt.Errorf("ERROR")
+	}
+
+	err := backoff.Retry(OperationWithRecover(operation), &backoff.StopBackOff{})
+	if err == nil {
+		t.Fatalf("Error in OperationWithRecover: %s", err)
+	}
+}
diff --git a/pkg/safe/safe_test.go b/pkg/safe/safe_test.go
new file mode 100644
index 0000000..1b858aa
--- /dev/null
+++ b/pkg/safe/safe_test.go
@@ -0,0 +1,29 @@
+package safe
+
+import "testing"
+
+func TestSafe(t *testing.T) {
+	const ts1, ts2 = "test1", "test2"
+
+	s := New(ts1)
+
+	result, ok := s.Get().(string)
+	if !ok {
+		t.Fatalf("Safe.Get() failed, got type '%T', expected string", s.Get())
+	}
+
+	if result != ts1 {
+		t.Errorf("Safe.Get() failed, got '%s', expected '%s'", result, ts1)
+	}
+
+	s.Set(ts2)
+
+	result, ok = s.Get().(string)
+	if !ok {
+		t.Fatalf("Safe.Get() after Safe.Set() failed, got type '%T', expected string", s.Get())
+	}
+
+	if result != ts2 {
+		t.Errorf("Safe.Get() after Safe.Set() failed, got '%s', expected '%s'", result, ts2)
+	}
+}