Skip to content

Commit

Permalink
feat: support Auth provider to directly connect to GCP
Browse files Browse the repository at this point in the history
  • Loading branch information
crgisch authored and claudio.gisch committed May 2, 2022
1 parent b7eb3b4 commit 8842151
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 42 deletions.
4 changes: 4 additions & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"github.com/spf13/pflag"
"github.com/spf13/viper"
corev1 "k8s.io/api/core/v1"
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
)

const (
Expand Down Expand Up @@ -59,6 +60,9 @@ type ClusterConfig struct {
Address string `json:"address"`
Token string `json:"token"`
TokenFile string `json:"tokenFile"`
CA string `json:"ca"`

AuthProvider *clientcmdapi.AuthProviderConfig `json:"authProvider"`
}

var rpaasConfig struct {
Expand Down
59 changes: 42 additions & 17 deletions internal/web/target/multi-cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package target

import (
"context"
"encoding/base64"
"errors"
"io/ioutil"
"net/http"
"sync"
Expand All @@ -11,6 +13,7 @@ import (
"github.com/tsuru/rpaas-operator/internal/pkg/rpaas"
"github.com/tsuru/rpaas-operator/pkg/observability"
extensionsruntime "github.com/tsuru/rpaas-operator/pkg/runtime"
_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
"k8s.io/client-go/rest"
sigsk8sclient "sigs.k8s.io/controller-runtime/pkg/client"
)
Expand Down Expand Up @@ -83,15 +86,10 @@ func (m *multiClusterFactory) Manager(ctx context.Context, headers http.Header)
span.SetTag("pool.name", poolName)
}

bearerToken, err := m.getToken(clusterName)
kubernetesRestConfig, err := m.getKubeConfig(clusterName, address)
if err != nil {
return nil, err
}
kubernetesRestConfig := &rest.Config{
Host: address,
BearerToken: bearerToken,
WrapTransport: observability.OpentracingTransport,
}
k8sClient, err := sigsk8sclient.New(kubernetesRestConfig, sigsk8sclient.Options{Scheme: extensionsruntime.NewScheme()})
if err != nil {
return nil, err
Expand All @@ -109,28 +107,55 @@ func (m *multiClusterFactory) Manager(ctx context.Context, headers http.Header)
return manager, nil
}

func (m *multiClusterFactory) getToken(clusterName string) (string, error) {
var defaultCluster *config.ClusterConfig = nil
func (m *multiClusterFactory) getKubeConfig(name, address string) (*rest.Config, error) {
selectedCluster := config.ClusterConfig{}

for _, cluster := range m.clusters {
if cluster.Default || cluster.Name == clusterName {
defaultCluster = &cluster
if cluster.Default {
selectedCluster = cluster
}
if cluster.Name == name {
selectedCluster = cluster
break
}
}

if defaultCluster == nil {
return "", nil
if selectedCluster.Name == "" {
return nil, errors.New("cluster not found")
}

if selectedCluster.Address != "" {
address = selectedCluster.Address
}

restConfig := &rest.Config{
Host: address,
BearerToken: selectedCluster.Token,
WrapTransport: observability.OpentracingTransport,
}

if selectedCluster.AuthProvider != nil {
restConfig.AuthProvider = selectedCluster.AuthProvider
}

if defaultCluster.Token != "" {
return defaultCluster.Token, nil
if selectedCluster.CA != "" {
caData, err := base64.StdEncoding.DecodeString(selectedCluster.CA)
if err != nil {
return nil, err
}
restConfig.TLSClientConfig.CAData = caData
}

if defaultCluster.TokenFile != "" {
return m.readTokenFile(defaultCluster.TokenFile)
if selectedCluster.TokenFile != "" {
var err error
restConfig.BearerToken, err = m.readTokenFile(selectedCluster.TokenFile)
if err != nil {
return nil, err
}
}

return "", nil
return restConfig, nil

}

func (m *multiClusterFactory) readTokenFile(tokenFile string) (string, error) {
Expand Down
35 changes: 10 additions & 25 deletions internal/web/target/multi-cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,6 @@ import (

var ctx = context.Background()

func TestMultiClusterToken(t *testing.T) {
target := NewMultiClustersFactory([]config.ClusterConfig{
{
Name: "my-cluster",
Token: "my-token",
},
})

multiClusterTarget := target.(*multiClusterFactory)
token, err := multiClusterTarget.getToken("my-cluster")

assert.NoError(t, err)
assert.Equal(t, token, "my-token")
}

func TestMultiClusterTokenFile(t *testing.T) {
tmpfile, err := ioutil.TempFile("", "example")
require.NoError(t, err)
Expand All @@ -45,16 +30,16 @@ func TestMultiClusterTokenFile(t *testing.T) {
defer os.Remove(tmpfile.Name())

multiClusterTarget := target.(*multiClusterFactory)
token, err := multiClusterTarget.getToken("my-cluster")
restConfig, err := multiClusterTarget.getKubeConfig("my-cluster", "")

assert.NoError(t, err)
assert.Equal(t, token, "token-from-file")
assert.Equal(t, "token-from-file", restConfig.BearerToken)

os.Remove(tmpfile.Name())
token, err = multiClusterTarget.getToken("my-cluster")
restConfig, err = multiClusterTarget.getKubeConfig("my-cluster", "")

assert.NoError(t, err)
assert.Equal(t, token, "token-from-file")
assert.Equal(t, "token-from-file", restConfig.BearerToken)
}

func TestMultiClusterNoToken(t *testing.T) {
Expand All @@ -73,10 +58,10 @@ func TestMultiClusterNoToken(t *testing.T) {
defer os.Remove(tmpfile.Name())

multiClusterTarget := target.(*multiClusterFactory)
token, err := multiClusterTarget.getToken("my-wrong-cluster")
_, err = multiClusterTarget.getKubeConfig("my-wrong-cluster", "")

assert.NoError(t, err)
assert.Equal(t, token, "")
require.Error(t, err)
assert.Equal(t, "cluster not found", err.Error())
}

func TestMultiClusterDefaultToken(t *testing.T) {
Expand All @@ -90,10 +75,10 @@ func TestMultiClusterDefaultToken(t *testing.T) {
})

multiClusterTarget := target.(*multiClusterFactory)
token, err := multiClusterTarget.getToken("my-other-cluster")
restConfig, err := multiClusterTarget.getKubeConfig("my-other-cluster", "")

assert.NoError(t, err)
assert.Equal(t, token, "my-token")
assert.Equal(t, "my-token", restConfig.BearerToken)
}

func TestMultiClusterNoHeaders(t *testing.T) {
Expand All @@ -108,5 +93,5 @@ func TestMultiClusterNoHeaders(t *testing.T) {
rpaasManager, err := target.Manager(ctx, http.Header{})

assert.Nil(t, rpaasManager)
assert.Equal(t, err, ErrNoClusterProvided)
assert.Equal(t, ErrNoClusterProvided, err)
}

0 comments on commit 8842151

Please sign in to comment.