Skip to content

Commit b042df2

Browse files
committed
replace platformiam library with custom opensource implementation
1 parent f2fbed3 commit b042df2

File tree

4 files changed

+79
-53
lines changed

4 files changed

+79
-53
lines changed

auth/tokens.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package auth
2+
3+
import (
4+
"fmt"
5+
"net/http"
6+
"os"
7+
"path"
8+
9+
"golang.org/x/oauth2"
10+
"k8s.io/client-go/transport"
11+
)
12+
13+
const (
14+
DefaultCredentialsDir = "/meta/credentials"
15+
CredentialsDirEnvar = "CREDENTIALS_DIR"
16+
)
17+
18+
type platformCredentialsTokenSource struct {
19+
tokenName string
20+
credentialsDir string
21+
}
22+
23+
func NewPlatformCredentialsTokenSource(tokenName string, credentialsDir string) *platformCredentialsTokenSource {
24+
return &platformCredentialsTokenSource{
25+
tokenName: tokenName,
26+
credentialsDir: credentialsDir,
27+
}
28+
}
29+
30+
func (s *platformCredentialsTokenSource) Token() (*oauth2.Token, error) {
31+
filePath := path.Join(s.credentialsDir, fmt.Sprintf("%s-token-secret", s.tokenName))
32+
contents, err := os.ReadFile(filePath)
33+
if err != nil {
34+
return nil, err
35+
}
36+
return &oauth2.Token{AccessToken: string(contents)}, nil
37+
}
38+
39+
type tokenInjector struct {
40+
tokenSource oauth2.TokenSource
41+
next http.RoundTripper
42+
}
43+
44+
func TokenInjector(tokenSource oauth2.TokenSource) transport.WrapperFunc {
45+
return func(rt http.RoundTripper) http.RoundTripper {
46+
return &tokenInjector{
47+
tokenSource: tokenSource,
48+
next: rt,
49+
}
50+
}
51+
}
52+
53+
func (i *tokenInjector) RoundTrip(request *http.Request) (*http.Response, error) {
54+
token, err := i.tokenSource.Token()
55+
if err != nil {
56+
return nil, err
57+
}
58+
59+
request.Header.Set("Authorization", "Bearer "+token.AccessToken)
60+
return i.next.RoundTrip(request)
61+
}

go.mod

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,8 @@ require (
1717
github.com/pkg/errors v0.9.1
1818
github.com/prometheus/client_golang v1.20.4
1919
github.com/sirupsen/logrus v1.9.3
20-
github.com/stretchr/testify v1.11.1
21-
github.com/zalando-build/credentials-loader v0.0.0-20251013185331-dad2c8c72ce9
22-
golang.org/x/oauth2 v0.32.0
20+
github.com/stretchr/testify v1.10.0
21+
golang.org/x/oauth2 v0.27.0
2322
k8s.io/api v0.33.5
2423
k8s.io/apimachinery v0.33.5
2524
k8s.io/client-go v0.33.5
@@ -53,7 +52,6 @@ require (
5352
github.com/go-playground/locales v0.14.1 // indirect
5453
github.com/go-playground/universal-translator v0.18.1 // indirect
5554
github.com/gogo/protobuf v1.3.2 // indirect
56-
github.com/golang-jwt/jwt/v5 v5.3.0 // indirect
5755
github.com/google/gnostic-models v0.6.9 // indirect
5856
github.com/google/go-cmp v0.7.0 // indirect
5957
github.com/jmespath/go-jmespath v0.4.0 // indirect

go.sum

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,6 @@ github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1v
7979
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
8080
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
8181
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
82-
github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo=
83-
github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
8482
github.com/google/gnostic-models v0.6.9 h1:MU/8wDLif2qCXZmzncUQ/BOfxWfthHi63KqpoNbWqVw=
8583
github.com/google/gnostic-models v0.6.9/go.mod h1:CiWsm0s6BSQd1hRn8/QmxqB6BesYcbSZxsz9b0KuDBw=
8684
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
@@ -158,16 +156,14 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
158156
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
159157
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
160158
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
161-
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
162-
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
159+
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
160+
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
163161
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
164162
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
165163
github.com/xhit/go-str2duration/v2 v2.1.0 h1:lxklc02Drh6ynqX+DdPyp5pCKLUQpRT8bp8Ydu2Bstc=
166164
github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU=
167165
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
168166
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
169-
github.com/zalando-build/credentials-loader v0.0.0-20251013185331-dad2c8c72ce9 h1:MeB2BcFDoyl9wbX3ABSHGiDytRhe1Bvq9sko2QWEXr8=
170-
github.com/zalando-build/credentials-loader v0.0.0-20251013185331-dad2c8c72ce9/go.mod h1:iPUMtmKVg7nrQD6qlq54mULsaybwIopouDLLgWIKsVY=
171167
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
172168
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
173169
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
@@ -181,8 +177,8 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLL
181177
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
182178
golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
183179
golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
184-
golang.org/x/oauth2 v0.32.0 h1:jsCblLleRMDrxMN29H3z/k1KliIvpLgCkE6R8FXXNgY=
185-
golang.org/x/oauth2 v0.32.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
180+
golang.org/x/oauth2 v0.27.0 h1:da9Vo7/tDv5RH/7nZDz1eMGS/q1Vv1N/7FCrBhI9I3M=
181+
golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
186182
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
187183
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
188184
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=

main.go

Lines changed: 12 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,15 @@ import (
1313
"github.com/aws/aws-sdk-go-v2/config"
1414
"github.com/prometheus/client_golang/prometheus/promhttp"
1515
log "github.com/sirupsen/logrus"
16+
"github.com/szuecs/kube-static-egress-controller/auth"
1617
"github.com/szuecs/kube-static-egress-controller/controller"
1718
"github.com/szuecs/kube-static-egress-controller/kube"
1819
"github.com/szuecs/kube-static-egress-controller/provider"
1920
"github.com/szuecs/kube-static-egress-controller/provider/aws"
2021
"github.com/szuecs/kube-static-egress-controller/provider/noop"
21-
"github.com/zalando-build/credentials-loader/platformiam"
22-
"golang.org/x/oauth2"
2322
v1 "k8s.io/api/core/v1"
2423
"k8s.io/client-go/kubernetes"
25-
"k8s.io/client-go/rest"
2624
"k8s.io/client-go/tools/clientcmd"
27-
"k8s.io/client-go/transport"
2825
)
2926

3027
const (
@@ -59,6 +56,9 @@ type Config struct {
5956
Namespace string
6057
ResyncInterval time.Duration
6158
Address string
59+
// required by Platform credentials
60+
UsePlatformCredentials bool
61+
CredentialsDir string
6262
}
6363

6464
var defaultConfig = &Config{
@@ -124,6 +124,8 @@ Example:
124124
// Flags related to Kubernetes
125125
app.Flag("master", "The Kubernetes API server to connect to (default: auto-detect)").Default(defaultConfig.Master).StringVar(&cfg.Master)
126126
app.Flag("kubeconfig", "Retrieve target cluster configuration from a Kubernetes configuration file (default: auto-detect)").Default(defaultConfig.KubeConfig).StringVar(&cfg.KubeConfig)
127+
app.Flag("use-platform-credentials", "Use Platform credentials (default: disabled)").BoolVar(&cfg.UsePlatformCredentials)
128+
app.Flag("credentials-dir", "Directory where the Platform credentials are stored").Default(auth.DefaultCredentialsDir).Envar(auth.CredentialsDirEnvar).StringVar(&cfg.CredentialsDir)
127129
app.Flag("provider", "Provider implementing static egress <noop|aws> (default: auto-detect)").Default(defaultConfig.Provider).StringVar(&cfg.Provider)
128130
app.Flag("cluster-id", "Cluster ID used define ownership of Egress stack.").StringVar(&cfg.ClusterID)
129131
app.Flag("cluster-id-tag-prefix", "Prefix for the Cluster ID tag set on the Egress stack.").Default(defaultConfig.ClusterIDTagPrefix).StringVar(&cfg.ClusterIDTagPrefix)
@@ -173,7 +175,7 @@ func main() {
173175
}
174176

175177
configsChan := make(chan provider.EgressConfig)
176-
cmWatcher, err := kube.NewConfigMapWatcher(newKubeClient(), cfg.Namespace, "egress=static", configsChan)
178+
cmWatcher, err := kube.NewConfigMapWatcher(newKubeClient(cfg), cfg.Namespace, "egress=static", configsChan)
177179
if err != nil {
178180
log.Fatalf("Failed to setup ConfigMap watcher: %v", err)
179181
}
@@ -192,7 +194,7 @@ func main() {
192194
}
193195

194196
// newKubeClient returns a new Kubernetes client with the default config.
195-
func newKubeClient() kubernetes.Interface {
197+
func newKubeClient(cfg *Config) kubernetes.Interface {
196198
var kubeconfig string
197199
if _, err := os.Stat(clientcmd.RecommendedHomeFile); err == nil {
198200
kubeconfig = clientcmd.RecommendedHomeFile
@@ -203,12 +205,11 @@ func newKubeClient() kubernetes.Interface {
203205
log.Fatalf("build config failed: %v", err)
204206
}
205207

206-
platformIAMTokenSource := platformiam.NewTokenSource("kube-static-egress-controller", DefaultCredentialsDir)
207-
208-
platformIAMRestConfig := rest.AnonymousClientConfig(config)
209-
platformIAMRestConfig.Wrap(TokenInjector(platformIAMTokenSource))
208+
if cfg.UsePlatformCredentials {
209+
config.Wrap(auth.TokenInjector(auth.NewPlatformCredentialsTokenSource(name, cfg.CredentialsDir)))
210+
}
210211

211-
client, err := kubernetes.NewForConfig(platformIAMRestConfig)
212+
client, err := kubernetes.NewForConfig(config)
212213
if err != nil {
213214
log.Fatalf("initialize kubernetes client failed: %v", err)
214215
}
@@ -247,33 +248,3 @@ func serve(ctx context.Context, address string, handler http.Handler) {
247248
}
248249
}
249250
}
250-
251-
const (
252-
DefaultCredentialsDir = "/meta/credentials"
253-
254-
// CredentialsDirEnvar = "CREDENTIALS_DIR"
255-
)
256-
257-
type kubeTokenInjector struct {
258-
tokenSource oauth2.TokenSource
259-
next http.RoundTripper
260-
}
261-
262-
func TokenInjector(tokenSource oauth2.TokenSource) transport.WrapperFunc {
263-
return func(rt http.RoundTripper) http.RoundTripper {
264-
return &kubeTokenInjector{
265-
tokenSource: tokenSource,
266-
next: rt,
267-
}
268-
}
269-
}
270-
271-
func (i *kubeTokenInjector) RoundTrip(request *http.Request) (*http.Response, error) {
272-
token, err := i.tokenSource.Token()
273-
if err != nil {
274-
return nil, err
275-
}
276-
277-
request.Header.Set("Authorization", "Bearer "+token.AccessToken)
278-
return i.next.RoundTrip(request)
279-
}

0 commit comments

Comments
 (0)