-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
split out basic discovery code (#23)
* split out basic discovery code * added tests * merged with master * changelog * moved changelog * code gen * locked version of imports
- Loading branch information
Showing
19 changed files
with
1,001 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
changelog: | ||
- type: NEW_FEATURE | ||
description: | | ||
Add functions to build temporary ClientConfig from different cloud provider cluster resources | ||
issueLink: https://github.com/solo-io/skv2/issues/25 | ||
resolvesIssue: false |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
package discovery | ||
|
||
import ( | ||
"context" | ||
"encoding/base64" | ||
|
||
"github.com/aws/aws-sdk-go/aws" | ||
"github.com/aws/aws-sdk-go/service/eks" | ||
"github.com/solo-io/skv2/pkg/multicluster/discovery/cloud" | ||
"github.com/solo-io/skv2/pkg/multicluster/kubeconfig" | ||
"k8s.io/client-go/tools/clientcmd" | ||
clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | ||
) | ||
|
||
func NewEksConfigBuilder(eksClient cloud.EksClient) EksConfigBuilder { | ||
return &awsClusterConfigBuilder{ | ||
eksClient: eksClient, | ||
} | ||
} | ||
|
||
type awsClusterConfigBuilder struct { | ||
eksClient cloud.EksClient | ||
} | ||
|
||
func (a *awsClusterConfigBuilder) ConfigForCluster(ctx context.Context, cluster *eks.Cluster) (clientcmd.ClientConfig, error) { | ||
tok, err := a.eksClient.Token(ctx, aws.StringValue(cluster.Name)) | ||
if err != nil { | ||
return nil, err | ||
} | ||
ca, err := base64.StdEncoding.DecodeString(aws.StringValue(cluster.CertificateAuthority.Data)) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
cfg := kubeconfig.BuildRemoteCfg( | ||
&clientcmdapi.Cluster{ | ||
Server: aws.StringValue(cluster.Endpoint), | ||
CertificateAuthorityData: ca, | ||
}, | ||
&clientcmdapi.Context{ | ||
Cluster: aws.StringValue(cluster.Name), | ||
}, | ||
aws.StringValue(cluster.Name), | ||
tok.Token, | ||
) | ||
|
||
return clientcmd.NewDefaultClientConfig(cfg, &clientcmd.ConfigOverrides{}), nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
package discovery_test | ||
|
||
import ( | ||
"context" | ||
"encoding/base64" | ||
|
||
"github.com/aws/aws-sdk-go/aws" | ||
"github.com/aws/aws-sdk-go/service/eks" | ||
"github.com/golang/mock/gomock" | ||
. "github.com/onsi/ginkgo" | ||
. "github.com/onsi/gomega" | ||
"github.com/rotisserie/eris" | ||
"github.com/solo-io/go-utils/testutils" | ||
"github.com/solo-io/skv2/pkg/multicluster/discovery" | ||
mock_cloud "github.com/solo-io/skv2/pkg/multicluster/discovery/cloud/mocks" | ||
"github.com/solo-io/skv2/pkg/multicluster/kubeconfig" | ||
clientcmdapi "k8s.io/client-go/tools/clientcmd/api" | ||
"sigs.k8s.io/aws-iam-authenticator/pkg/token" | ||
) | ||
|
||
var _ = Describe("Aws", func() { | ||
var ( | ||
ctx context.Context | ||
ctrl *gomock.Controller | ||
|
||
eksClient *mock_cloud.MockEksClient | ||
|
||
testErr = eris.New("hello") | ||
) | ||
|
||
BeforeEach(func() { | ||
ctrl, ctx = gomock.WithContext(context.TODO(), GinkgoT()) | ||
|
||
eksClient = mock_cloud.NewMockEksClient(ctrl) | ||
}) | ||
|
||
It("will fail if token cannot be found", func() { | ||
configBuilder := discovery.NewEksConfigBuilder(eksClient) | ||
|
||
cluster := &eks.Cluster{ | ||
Name: aws.String("cluster-name"), | ||
} | ||
eksClient.EXPECT(). | ||
Token(ctx, aws.StringValue(cluster.Name)). | ||
Return(token.Token{}, testErr) | ||
|
||
_, err := configBuilder.ConfigForCluster(ctx, cluster) | ||
Expect(err).To(HaveOccurred()) | ||
Expect(err).To(testutils.HaveInErrorChain(testErr)) | ||
}) | ||
|
||
It("will Create ClientConfig if token can be found", func() { | ||
configBuilder := discovery.NewEksConfigBuilder(eksClient) | ||
caData := []byte("fake-ca-data") | ||
tok := token.Token{Token: "new-token-who-dis"} | ||
cluster := &eks.Cluster{ | ||
Name: aws.String("cluster-name"), | ||
CertificateAuthority: &eks.Certificate{ | ||
Data: aws.String(base64.StdEncoding.EncodeToString(caData)), | ||
}, | ||
Endpoint: aws.String("fake-endpoint"), | ||
} | ||
eksClient.EXPECT(). | ||
Token(ctx, aws.StringValue(cluster.Name)). | ||
Return(tok, nil) | ||
|
||
cfg, err := configBuilder.ConfigForCluster(ctx, cluster) | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
ca, err := base64.StdEncoding.DecodeString(aws.StringValue(cluster.CertificateAuthority.Data)) | ||
Expect(err).NotTo(HaveOccurred()) | ||
newCfg := kubeconfig.BuildRemoteCfg( | ||
&clientcmdapi.Cluster{ | ||
Server: aws.StringValue(cluster.Endpoint), | ||
CertificateAuthorityData: ca, | ||
}, | ||
&clientcmdapi.Context{ | ||
Cluster: aws.StringValue(cluster.Name), | ||
}, | ||
aws.StringValue(cluster.Name), | ||
tok.Token, | ||
) | ||
|
||
rawCfg, err := cfg.RawConfig() | ||
Expect(err).NotTo(HaveOccurred()) | ||
Expect(rawCfg).To(Equal(newCfg)) | ||
|
||
}) | ||
|
||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
package cloud | ||
|
||
import ( | ||
"context" | ||
|
||
"github.com/aws/aws-sdk-go/aws" | ||
"github.com/aws/aws-sdk-go/aws/credentials" | ||
"github.com/aws/aws-sdk-go/aws/session" | ||
"github.com/aws/aws-sdk-go/service/eks" | ||
"sigs.k8s.io/aws-iam-authenticator/pkg/token" | ||
) | ||
|
||
func NewEksClient(region string, creds *credentials.Credentials) (EksClient, error) { | ||
sess, err := session.NewSession(&aws.Config{ | ||
Region: aws.String(region), | ||
Credentials: creds, | ||
}) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return &awsClient{ | ||
sess: sess, | ||
}, nil | ||
} | ||
|
||
type awsClient struct { | ||
sess *session.Session | ||
} | ||
|
||
func (a *awsClient) Session() *session.Session { | ||
return a.sess | ||
} | ||
|
||
func (a *awsClient) DescribeCluster(ctx context.Context, name string) (*eks.Cluster, error) { | ||
eksSvc := eks.New(a.sess) | ||
input := &eks.DescribeClusterInput{ | ||
Name: aws.String(name), | ||
} | ||
resp, err := eksSvc.DescribeClusterWithContext(ctx, input) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return resp.Cluster, nil | ||
} | ||
|
||
func (a *awsClient) ListClusters(ctx context.Context, input *eks.ListClustersInput) (*eks.ListClustersOutput, error) { | ||
eksSvc := eks.New(a.sess) | ||
return eksSvc.ListClustersWithContext(ctx, input) | ||
} | ||
|
||
func (a *awsClient) Token(ctx context.Context, name string) (token.Token, error) { | ||
gen, err := token.NewGenerator(true, false) | ||
if err != nil { | ||
return token.Token{}, err | ||
} | ||
opts := &token.GetTokenOptions{ | ||
ClusterID: name, | ||
Session: a.sess, | ||
} | ||
tok, err := gen.GetWithOptions(opts) | ||
if err != nil { | ||
return token.Token{}, err | ||
} | ||
return tok, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package cloud | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
|
||
container "cloud.google.com/go/container/apiv1" | ||
"golang.org/x/oauth2" | ||
"golang.org/x/oauth2/google" | ||
"google.golang.org/api/option" | ||
containerpb "google.golang.org/genproto/googleapis/container/v1" | ||
) | ||
|
||
func NewGkeClient(ctx context.Context, projectId string) (GkeClient, error) { | ||
creds, err := google.FindDefaultCredentials(ctx, container.DefaultAuthScopes()...) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return &gkeClient{ | ||
creds: creds, | ||
projectId: projectId, | ||
}, nil | ||
} | ||
|
||
type gkeClient struct { | ||
projectId string | ||
creds *google.Credentials | ||
} | ||
|
||
func (g *gkeClient) Token(ctx context.Context) (*oauth2.Token, error) { | ||
return g.creds.TokenSource.Token() | ||
} | ||
|
||
func (g *gkeClient) ListClusters(ctx context.Context) ([]*containerpb.Cluster, error) { | ||
client, err := container.NewClusterManagerClient(ctx, option.WithCredentials(g.creds)) | ||
if err != nil { | ||
return nil, err | ||
} | ||
resp, err := client.ListClusters(ctx, &containerpb.ListClustersRequest{ | ||
Parent: fmt.Sprintf("projects/%s/locations/-", g.projectId), | ||
}) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return resp.GetClusters(), nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package cloud | ||
|
||
import ( | ||
"context" | ||
|
||
"github.com/aws/aws-sdk-go/service/eks" | ||
"golang.org/x/oauth2" | ||
containerpb "google.golang.org/genproto/googleapis/container/v1" | ||
"sigs.k8s.io/aws-iam-authenticator/pkg/token" | ||
) | ||
|
||
//go:generate mockgen -source ./interfaces.go -destination ./mocks/mock_interfaces.go | ||
|
||
type EksClient interface { | ||
DescribeCluster(ctx context.Context, name string) (*eks.Cluster, error) | ||
ListClusters(ctx context.Context, input *eks.ListClustersInput) (*eks.ListClustersOutput, error) | ||
Token(ctx context.Context, name string) (token.Token, error) | ||
} | ||
|
||
type GkeClient interface { | ||
Token(ctx context.Context) (*oauth2.Token, error) | ||
ListClusters(ctx context.Context) ([]*containerpb.Cluster, error) | ||
} |
Oops, something went wrong.