-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 4f3d2a4
Showing
6 changed files
with
277 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
on: | ||
release: | ||
types: [created] | ||
|
||
jobs: | ||
releases-matrix: | ||
name: Release Go Binary | ||
runs-on: ubuntu-latest | ||
strategy: | ||
matrix: | ||
goos: [linux, darwin] | ||
goarch: [amd64, arm64] | ||
steps: | ||
- uses: actions/checkout@v3 | ||
- uses: wangyoucao577/[email protected] | ||
with: | ||
github_token: ${{ secrets.GITHUB_TOKEN }} | ||
goos: ${{ matrix.goos }} | ||
goarch: ${{ matrix.goarch }} | ||
goversion: 1.19 | ||
ldflags: "-s -w" | ||
extra_files: LICENSE README.md | ||
compress_assets: auto |
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,21 @@ | ||
MIT License | ||
|
||
Copyright (c) 2022 Jake Scaltreto | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
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,34 @@ | ||
# eks-auth | ||
Standalone program to fetch authentication tokens for AWS EKS Clusters | ||
|
||
## Description | ||
|
||
This is a standalone program to fetch authentication tokens for AWS EKS Clusters. It functions in much the same way as `aws eks get-token` and supports similar arguments. | ||
|
||
Under the hood it uses the AWS Go SDK v2 and will respect certain environment variables such as `AWS_REGION`, `AWS_PROFILE`, and other variables related to authentication. | ||
|
||
This is primarily useful for using tools such as [Atlantis](https://www.runatlantis.io/). When running terraform with pre-generated plans (such as in Atlantis), using `exec` for authentication is preferred over fetching a token with the `aws_eks_cluster_auth` data source since the latter will only fetch a short-lived token during the `plan` phase, which may be expired by the time the `apply` is executed. | ||
|
||
This was created as a ligher-weight alternative to installing the AWS cli, along with a Python interpreter, in an Atlantis Docker image when the only feature of the CLI being used is EKS authentication. | ||
|
||
## Terraform example | ||
|
||
Here is an example of how to initialize the `kubernetes` [Terraform provider](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs) using this program. The `eks-auth` binary must be accessible in the `$PATH` where terraform is run (such as `/usr/bin` in an Atlantis Docker image). | ||
|
||
```hcl | ||
data "aws_eks_cluster" "cluster" { | ||
name = "my-cluster" | ||
} | ||
provider "kubernetes" { | ||
host = data.aws_eks_cluster.cluster.endpoint | ||
cluster_ca_certificate = data.aws_eks_cluster.cluster.certificate_autority[0].data | ||
exec { | ||
api_version = "client.authentication.k8s.io/v1beta1" | ||
args = ["--cluster-name", data.aws_eks_cluster.cluster.id] | ||
command = "eks-auth" | ||
} | ||
} | ||
``` | ||
|
||
Other providers, such as [Helm](https://registry.terraform.io/providers/hashicorp/helm/latest/docs) similarly support exec authentication. |
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,145 @@ | ||
/* | ||
MIT License | ||
Copyright (c) 2022 Jake Scaltreto | ||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. | ||
*/ | ||
|
||
package main | ||
|
||
import ( | ||
"context" | ||
"flag" | ||
"fmt" | ||
"log" | ||
|
||
"encoding/base64" | ||
"encoding/json" | ||
|
||
"github.com/aws/aws-sdk-go-v2/aws" | ||
"github.com/aws/aws-sdk-go-v2/config" | ||
"github.com/aws/aws-sdk-go-v2/credentials/stscreds" | ||
"github.com/aws/aws-sdk-go-v2/service/sts" | ||
"github.com/aws/smithy-go/middleware" | ||
smithyhttp "github.com/aws/smithy-go/transport/http" | ||
) | ||
|
||
const ( | ||
K8S_AWS_ID_HEADER = "x-k8s-aws-id" | ||
TOKEN_PREFIX = "k8s-aws-v1." | ||
|
||
KIND = "ExecCredential" | ||
API_VERSION = "client.authentication.k8s.io/v1beta1" | ||
|
||
EXPIRE_PARAM = "X-Amz-Expires" | ||
EXPIRE_PARAM_VALUE = "60" | ||
) | ||
|
||
type ExecCredential struct { | ||
ApiVersion string `json:"apiVersion"` | ||
Kind string `json:"kind"` | ||
Status map[string]string `json:"status"` | ||
} | ||
|
||
func main() { | ||
ctx := context.Background() | ||
|
||
var clusterName, roleArn string | ||
flag.StringVar(&clusterName, "cluster-name", "", "Name of the EKS cluster") | ||
flag.StringVar(&roleArn, "role-arn", "", "Assume this role for credentials") | ||
flag.Parse() | ||
|
||
if clusterName == "" { | ||
panic("cluster-name is required!") | ||
} | ||
|
||
cfg, err := config.LoadDefaultConfig(ctx) | ||
if err != nil { | ||
log.Fatalf("Failed to load AWS config %v", err) | ||
} | ||
|
||
client := sts.NewFromConfig(cfg) | ||
|
||
if roleArn != "" { | ||
creds := stscreds.NewAssumeRoleProvider(client, roleArn) | ||
cfg.Credentials = aws.NewCredentialsCache(creds) | ||
client = sts.NewFromConfig(cfg) | ||
} | ||
|
||
token, err := getToken(ctx, client, clusterName) | ||
if err != nil { | ||
log.Fatalf("Failed to fetch STS token: %v", err) | ||
} | ||
|
||
auth, err := getExecAuth(token) | ||
if err != nil { | ||
log.Fatalf("Failed to generate ExecCredential: %v", err) | ||
} | ||
|
||
fmt.Println(auth) | ||
} | ||
|
||
func getExecAuth(token string) (string, error) { | ||
execAuth := ExecCredential{ | ||
ApiVersion: API_VERSION, | ||
Kind: KIND, | ||
Status: map[string]string{"token": token}, | ||
} | ||
encoded, err := json.Marshal(execAuth) | ||
return string(encoded), err | ||
} | ||
|
||
func getToken(ctx context.Context, client *sts.Client, clusterName string) (string, error) { | ||
presignSts := sts.NewPresignClient(client) | ||
req, err := presignSts.PresignGetCallerIdentity( | ||
ctx, | ||
&sts.GetCallerIdentityInput{}, | ||
func(pso *sts.PresignOptions) { | ||
pso.ClientOptions = append(pso.ClientOptions, sts.WithAPIOptions( | ||
addEksHeader(clusterName), | ||
)) | ||
}, | ||
) | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
return TOKEN_PREFIX + base64.URLEncoding. | ||
WithPadding(base64.NoPadding). | ||
EncodeToString([]byte(req.URL)), nil | ||
} | ||
|
||
func addEksHeader(cluster string) func(*middleware.Stack) error { | ||
return func(stack *middleware.Stack) error { | ||
return stack.Build.Add(middleware.BuildMiddlewareFunc("AddEKSId", func( | ||
ctx context.Context, in middleware.BuildInput, next middleware.BuildHandler, | ||
) (middleware.BuildOutput, middleware.Metadata, error) { | ||
switch req := in.Request.(type) { | ||
case *smithyhttp.Request: | ||
query := req.URL.Query() | ||
query.Add(EXPIRE_PARAM, EXPIRE_PARAM_VALUE) | ||
req.URL.RawQuery = query.Encode() | ||
|
||
req.Header.Add(K8S_AWS_ID_HEADER, cluster) | ||
} | ||
return next.HandleBuild(ctx, in) | ||
}), middleware.Before) | ||
} | ||
} |
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,21 @@ | ||
module github.com/jscaltreto/eks-auth | ||
|
||
go 1.19 | ||
|
||
require ( | ||
github.com/aws/aws-sdk-go-v2 v1.17.1 | ||
github.com/aws/aws-sdk-go-v2/config v1.18.0 | ||
github.com/aws/aws-sdk-go-v2/credentials v1.13.0 | ||
github.com/aws/aws-sdk-go-v2/service/sts v1.17.2 | ||
github.com/aws/smithy-go v1.13.4 | ||
) | ||
|
||
require ( | ||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.19 // indirect | ||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.25 // indirect | ||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.19 // indirect | ||
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.26 // indirect | ||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.19 // indirect | ||
github.com/aws/aws-sdk-go-v2/service/sso v1.11.25 // indirect | ||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.13.8 // indirect | ||
) |
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,33 @@ | ||
github.com/aws/aws-sdk-go-v2 v1.17.1 h1:02c72fDJr87N8RAC2s3Qu0YuvMRZKNZJ9F+lAehCazk= | ||
github.com/aws/aws-sdk-go-v2 v1.17.1/go.mod h1:JLnGeGONAyi2lWXI1p0PCIOIy333JMVK1U7Hf0aRFLw= | ||
github.com/aws/aws-sdk-go-v2/config v1.18.0 h1:ULASZmfhKR/QE9UeZ7mzYjUzsnIydy/K1YMT6uH1KC0= | ||
github.com/aws/aws-sdk-go-v2/config v1.18.0/go.mod h1:H13DRX9Nv5tAcQvPABrE3dm5XnLp1RC7fVSM3OWiLvA= | ||
github.com/aws/aws-sdk-go-v2/credentials v1.13.0 h1:W5f73j1qurASap+jdScUo4aGzSXxaC7wq1i7CiwhvU8= | ||
github.com/aws/aws-sdk-go-v2/credentials v1.13.0/go.mod h1:prZpUfBu1KZLBLVX482Sq4DpDXGugAre08TPEc21GUg= | ||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.19 h1:E3PXZSI3F2bzyj6XxUXdTIfvp425HHhwKsFvmzBwHgs= | ||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.19/go.mod h1:VihW95zQpeKQWVPGkwT+2+WJNQV8UXFfMTWdU6VErL8= | ||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.25 h1:nBO/RFxeq/IS5G9Of+ZrgucRciie2qpLy++3UGZ+q2E= | ||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.25/go.mod h1:Zb29PYkf42vVYQY6pvSyJCJcFHlPIiY+YKdPtwnvMkY= | ||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.19 h1:oRHDrwCTVT8ZXi4sr9Ld+EXk7N/KGssOr2ygNeojEhw= | ||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.19/go.mod h1:6Q0546uHDp421okhmmGfbxzq2hBqbXFNpi4k+Q1JnQA= | ||
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.26 h1:Mza+vlnZr+fPKFKRq/lKGVvM6B/8ZZmNdEopOwSQLms= | ||
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.26/go.mod h1:Y2OJ+P+MC1u1VKnavT+PshiEuGPyh/7DqxoDNij4/bg= | ||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.19 h1:GE25AWCdNUPh9AOJzI9KIJnja7IwUc1WyUqz/JTyJ/I= | ||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.19/go.mod h1:02CP6iuYP+IVnBX5HULVdSAku/85eHB2Y9EsFhrkEwU= | ||
github.com/aws/aws-sdk-go-v2/service/sso v1.11.25 h1:GFZitO48N/7EsFDt8fMa5iYdmWqkUDDB3Eje6z3kbG0= | ||
github.com/aws/aws-sdk-go-v2/service/sso v1.11.25/go.mod h1:IARHuzTXmj1C0KS35vboR0FeJ89OkEy1M9mWbK2ifCI= | ||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.13.8 h1:jcw6kKZrtNfBPJkaHrscDOZoe5gvi9wjudnxvozYFJo= | ||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.13.8/go.mod h1:er2JHN+kBY6FcMfcBBKNGCT3CarImmdFzishsqBmSRI= | ||
github.com/aws/aws-sdk-go-v2/service/sts v1.17.2 h1:tpwEMRdMf2UsplengAOnmSIRdvAxf75oUFR+blBr92I= | ||
github.com/aws/aws-sdk-go-v2/service/sts v1.17.2/go.mod h1:bXcN3koeVYiJcdDU89n3kCYILob7Y34AeLopUbZgLT4= | ||
github.com/aws/smithy-go v1.13.4 h1:/RN2z1txIJWeXeOkzX+Hk/4Uuvv7dWtCjbmVJcrskyk= | ||
github.com/aws/smithy-go v1.13.4/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= | ||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= | ||
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= | ||
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= | ||
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= | ||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= |