soto-project / soto

Swift SDK for AWS that works on Linux, macOS and iOS
https://soto.codes
Apache License 2.0
871 stars 83 forks source link

I use aws-cli get eks token like "aws eks get-token --cluster-name xxx", but i can't find it this, so i missed or not exist. #652

Closed buhe closed 1 year ago

buhe commented 1 year ago

Is your feature request related to a problem? Please describe. I use aws-cli get eks token like "aws eks get-token --cluster-name xxx", but i can't find it this, so i missed or not exist. Thanks. this debug logs:

2023-01-07 11:43:38,354 - MainThread - awscli.clidriver - DEBUG - CLI version: aws-cli/2.9.12 Python/3.11.1 Darwin/22.1.0 source/arm64
2023-01-07 11:43:38,354 - MainThread - awscli.clidriver - DEBUG - Arguments entered to CLI: ['eks', 'get-token', '--cluster-name', 'dev-core', '--debug']
2023-01-07 11:43:38,389 - MainThread - botocore.hooks - DEBUG - Event building-command-table.main: calling handler <function add_s3 at 0x104ff3600>
2023-01-07 11:43:38,389 - MainThread - botocore.hooks - DEBUG - Event building-command-table.main: calling handler <function add_ddb at 0x104b83c40>
2023-01-07 11:43:38,389 - MainThread - botocore.hooks - DEBUG - Event building-command-table.main: calling handler <bound method BasicCommand.add_command of <class 'awscli.customizations.configure.configure.ConfigureCommand'>>
2023-01-07 11:43:38,389 - MainThread - botocore.hooks - DEBUG - Event building-command-table.main: calling handler <function change_name at 0x104b00900>
2023-01-07 11:43:38,389 - MainThread - botocore.hooks - DEBUG - Event building-command-table.main: calling handler <function change_name at 0x104b01f80>
2023-01-07 11:43:38,389 - MainThread - botocore.hooks - DEBUG - Event building-command-table.main: calling handler <function alias_opsworks_cm at 0x104ffb060>
2023-01-07 11:43:38,389 - MainThread - botocore.hooks - DEBUG - Event building-command-table.main: calling handler <function add_history_commands at 0x104bc3060>
2023-01-07 11:43:38,389 - MainThread - botocore.hooks - DEBUG - Event building-command-table.main: calling handler <bound method BasicCommand.add_command of <class 'awscli.customizations.devcommands.CLIDevCommand'>>
2023-01-07 11:43:38,389 - MainThread - botocore.hooks - DEBUG - Event building-command-table.main: calling handler <function add_waiters at 0x104ffa020>
2023-01-07 11:43:38,389 - MainThread - botocore.hooks - DEBUG - Event building-command-table.main: calling handler <bound method AliasSubCommandInjector.on_building_command_table of <awscli.alias.AliasSubCommandInjector object at 0x105211350>>
2023-01-07 11:43:38,389 - MainThread - botocore.loaders - DEBUG - Loading JSON file: /opt/homebrew/Cellar/awscli/2.9.12/libexec/lib/python3.11/site-packages/awscli/data/cli.json
2023-01-07 11:43:38,390 - MainThread - botocore.hooks - DEBUG - Event top-level-args-parsed: calling handler <function resolve_types at 0x104f32ca0>
2023-01-07 11:43:38,390 - MainThread - botocore.hooks - DEBUG - Event top-level-args-parsed: calling handler <function no_sign_request at 0x104f32fc0>
2023-01-07 11:43:38,390 - MainThread - botocore.hooks - DEBUG - Event top-level-args-parsed: calling handler <function resolve_verify_ssl at 0x104f32f20>
2023-01-07 11:43:38,390 - MainThread - botocore.hooks - DEBUG - Event top-level-args-parsed: calling handler <function resolve_cli_read_timeout at 0x104f33100>
2023-01-07 11:43:38,390 - MainThread - botocore.hooks - DEBUG - Event top-level-args-parsed: calling handler <function resolve_cli_connect_timeout at 0x104f33060>
2023-01-07 11:43:38,390 - MainThread - botocore.hooks - DEBUG - Event top-level-args-parsed: calling handler <built-in method update of dict object at 0x10520e640>
2023-01-07 11:43:38,390 - MainThread - awscli.clidriver - DEBUG - CLI version: aws-cli/2.9.12 Python/3.11.1 Darwin/22.1.0 source/arm64 prompt/off
2023-01-07 11:43:38,390 - MainThread - awscli.clidriver - DEBUG - Arguments entered to CLI: ['eks', 'get-token', '--cluster-name', 'dev-core', '--debug']
2023-01-07 11:43:38,390 - MainThread - botocore.hooks - DEBUG - Event session-initialized: calling handler <function add_timestamp_parser at 0x104ff80e0>
2023-01-07 11:43:38,390 - MainThread - botocore.hooks - DEBUG - Event session-initialized: calling handler <function register_uri_param_handler at 0x104651120>
2023-01-07 11:43:38,390 - MainThread - botocore.hooks - DEBUG - Event session-initialized: calling handler <function add_binary_formatter at 0x10507c540>
2023-01-07 11:43:38,390 - MainThread - botocore.hooks - DEBUG - Event session-initialized: calling handler <function no_pager_handler at 0x1046398a0>
2023-01-07 11:43:38,390 - MainThread - botocore.hooks - DEBUG - Event session-initialized: calling handler <function inject_assume_role_provider_cache at 0x10468b100>
2023-01-07 11:43:38,399 - MainThread - botocore.utils - DEBUG - IMDS ENDPOINT: http://169.254.169.254/
2023-01-07 11:43:38,404 - MainThread - botocore.hooks - DEBUG - Event session-initialized: calling handler <function attach_history_handler at 0x104bc2840>
2023-01-07 11:43:38,404 - MainThread - botocore.hooks - DEBUG - Event session-initialized: calling handler <function inject_json_file_cache at 0x104b6bce0>
2023-01-07 11:43:38,415 - MainThread - botocore.loaders - DEBUG - Loading JSON file: /opt/homebrew/Cellar/awscli/2.9.12/libexec/lib/python3.11/site-packages/awscli/botocore/data/eks/2017-11-01/service-2.json
2023-01-07 11:43:38,416 - MainThread - botocore.loaders - DEBUG - Loading JSON file: /opt/homebrew/Cellar/awscli/2.9.12/libexec/lib/python3.11/site-packages/awscli/botocore/data/eks/2017-11-01/service-2.sdk-extras.json
2023-01-07 11:43:38,417 - MainThread - botocore.hooks - DEBUG - Event building-command-table.eks: calling handler <function inject_commands at 0x104f16520>
2023-01-07 11:43:38,417 - MainThread - botocore.hooks - DEBUG - Event building-command-table.eks: calling handler <function add_waiters at 0x104ffa020>
2023-01-07 11:43:38,427 - MainThread - botocore.loaders - DEBUG - Loading JSON file: /opt/homebrew/Cellar/awscli/2.9.12/libexec/lib/python3.11/site-packages/awscli/botocore/data/eks/2017-11-01/waiters-2.json
2023-01-07 11:43:38,428 - MainThread - botocore.hooks - DEBUG - Event building-command-table.eks: calling handler <bound method AliasSubCommandInjector.on_building_command_table of <awscli.alias.AliasSubCommandInjector object at 0x105211350>>
2023-01-07 11:43:38,428 - MainThread - botocore.hooks - DEBUG - Event building-command-table.eks_get-token: calling handler <function add_waiters at 0x104ffa020>
2023-01-07 11:43:38,428 - MainThread - botocore.hooks - DEBUG - Event building-command-table.eks_get-token: calling handler <bound method AliasSubCommandInjector.on_building_command_table of <awscli.alias.AliasSubCommandInjector object at 0x105211350>>
2023-01-07 11:43:38,428 - MainThread - botocore.hooks - DEBUG - Event load-cli-arg.custom.get-token.cluster-name: calling handler <awscli.paramfile.URIArgumentHandler object at 0x105248e50>
2023-01-07 11:43:38,428 - MainThread - botocore.hooks - DEBUG - Event process-cli-arg.custom.get-token: calling handler <awscli.argprocess.ParamShorthandParser object at 0x10466f510>
2023-01-07 11:43:38,428 - MainThread - botocore.hooks - DEBUG - Event load-cli-arg.custom.get-token.role-arn: calling handler <awscli.paramfile.URIArgumentHandler object at 0x105248e50>
2023-01-07 11:43:38,428 - MainThread - botocore.hooks - DEBUG - Event load-cli-arg.custom.get-token.cluster-id: calling handler <awscli.paramfile.URIArgumentHandler object at 0x105248e50>
2023-01-07 11:43:38,428 - MainThread - botocore.credentials - DEBUG - Looking for credentials via: env
2023-01-07 11:43:38,428 - MainThread - botocore.credentials - DEBUG - Looking for credentials via: assume-role
2023-01-07 11:43:38,428 - MainThread - botocore.credentials - DEBUG - Looking for credentials via: assume-role-with-web-identity
2023-01-07 11:43:38,428 - MainThread - botocore.credentials - DEBUG - Looking for credentials via: sso
2023-01-07 11:43:38,428 - MainThread - botocore.credentials - DEBUG - Looking for credentials via: shared-credentials-file
2023-01-07 11:43:38,428 - MainThread - botocore.credentials - INFO - Found credentials in shared credentials file: ~/.aws/credentials
2023-01-07 11:43:38,429 - MainThread - botocore.loaders - DEBUG - Loading JSON file: /opt/homebrew/Cellar/awscli/2.9.12/libexec/lib/python3.11/site-packages/awscli/botocore/data/endpoints.json
2023-01-07 11:43:38,434 - MainThread - botocore.hooks - DEBUG - Event choose-service-name: calling handler <function handle_service_name_alias at 0x102e88720>
2023-01-07 11:43:38,434 - MainThread - botocore.loaders - DEBUG - Loading JSON file: /opt/homebrew/Cellar/awscli/2.9.12/libexec/lib/python3.11/site-packages/awscli/botocore/data/sts/2011-06-15/service-2.json
2023-01-07 11:43:38,445 - MainThread - botocore.loaders - DEBUG - Loading JSON file: /opt/homebrew/Cellar/awscli/2.9.12/libexec/lib/python3.11/site-packages/awscli/botocore/data/sts/2011-06-15/endpoint-rule-set-1.json
2023-01-07 11:43:38,446 - MainThread - botocore.loaders - DEBUG - Loading JSON file: /opt/homebrew/Cellar/awscli/2.9.12/libexec/lib/python3.11/site-packages/awscli/botocore/data/partitions.json
2023-01-07 11:43:38,446 - MainThread - botocore.hooks - DEBUG - Event creating-client-class.sts: calling handler <function add_generate_presigned_url at 0x102dc79c0>
2023-01-07 11:43:38,447 - MainThread - botocore.endpoint - DEBUG - Setting sts timeout as (60, 60)
2023-01-07 11:43:38,448 - MainThread - botocore.regions - DEBUG - Calling endpoint provider with parameters: {'Region': 'us-west-1', 'UseDualStack': False, 'UseFIPS': False, 'UseGlobalEndpoint': False}
2023-01-07 11:43:38,448 - MainThread - botocore.regions - DEBUG - Endpoint provider result: https://sts.us-west-1.amazonaws.com
2023-01-07 11:43:38,448 - MainThread - botocore.hooks - DEBUG - Event provide-client-params.sts.GetCallerIdentity: calling handler <bound method STSClientFactory._retrieve_k8s_aws_id of <awscli.customizations.eks.get_token.STSClientFactory object at 0x10531a050>>
2023-01-07 11:43:38,448 - MainThread - botocore.hooks - DEBUG - Event provide-client-params.sts.GetCallerIdentity: calling handler <function base64_decode_input_blobs at 0x10507c5e0>
2023-01-07 11:43:38,448 - MainThread - botocore.hooks - DEBUG - Event before-parameter-build.sts.GetCallerIdentity: calling handler <function generate_idempotent_uuid at 0x102e8aac0>
2023-01-07 11:43:38,448 - MainThread - botocore.hooks - DEBUG - Event choose-signer.sts.GetCallerIdentity: calling handler <function set_operation_specific_signer at 0x102e8a980>
2023-01-07 11:43:38,448 - MainThread - botocore.hooks - DEBUG - Event before-sign.sts.GetCallerIdentity: calling handler <bound method STSClientFactory._inject_k8s_aws_id_header of <awscli.customizations.eks.get_token.STSClientFactory object at 0x10531a050>>
2023-01-07 11:43:38,449 - MainThread - botocore.auth - DEBUG - Calculating signature using v4 auth.
2023-01-07 11:43:38,449 - MainThread - botocore.auth - DEBUG - CanonicalRequest:
GET
/
Action=GetCallerIdentity&Version=2011-06-15&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIATFIZFNSISE3OVGXB%2F20230107%2Fus-west-1%2Fsts%2Faws4_request&X-Amz-Date=20230107T034338Z&X-Amz-Expires=60&X-Amz-SignedHeaders=host%3Bx-k8s-aws-id
host:sts.us-west-1.amazonaws.com
x-k8s-aws-id:dev-core

host;x-k8s-aws-id
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
2023-01-07 11:43:38,449 - MainThread - botocore.auth - DEBUG - StringToSign:
AWS4-HMAC-SHA256
20230107T034338Z
20230107/us-west-1/sts/aws4_request
4467956bdaa50ea77f058aa3f5903415a875ed089e2edc287c2dcee9c9a895af
2023-01-07 11:43:38,449 - MainThread - botocore.auth - DEBUG - Signature:
1453612ff17f472b110bc9764a060625b4fb93c933a7002648d89515abb02b43
{"kind": "ExecCredential", "apiVersion": "client.authentication.k8s.io/v1beta1", "spec": {}, "status": {"expirationTimestamp": "2023-01-07T03:57:38Z", "token": "k8s-aws-v1.aHR0cHM6Ly9zdHMudXMtd2VzdC0xLmFtYXpvbmF3cy5jb20vP0FjdGlvbj1HZXRDYWxsZXJJZGVudGl0eSZWZXJzaW9uPTIwMTEtMDYtMTUmWC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVEZJWkZOU0lTRTNPVkdYQiUyRjIwMjMwMTA3JTJGdXMtd2VzdC0xJTJGc3RzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyMzAxMDdUMDM0MzM4WiZYLUFtei1FeHBpcmVzPTYwJlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCUzQngtazhzLWF3cy1pZCZYLUFtei1TaWduYXR1cmU9MTQ1MzYxMmZmMTdmNDcyYjExMGJjOTc2NGEwNjA2MjViNGZiOTNjOTMzYTcwMDI2NDhkODk1MTVhYmIwMmI0Mw"}}
adam-fowler commented 1 year ago

Hi, I've had a quick look at this and there is no EKS.getToken(). From the debug output of awscli it looks like a custom call to STS.getCallerIdentity with extra headers and query parameters and is a GET instead of a POST. This will need some custom code to get it working properly. I'll see if I can construct something.

adam-fowler commented 1 year ago

Ok. So get-token doesn't even talk to AWS services. It just creates a pre-signed URL and then outputs it as base64 with a prefix. Here is the python code from aws-cli that does this

TOKEN_PREFIX = 'k8s-aws-v1.'
def get_token(self, k8s_aws_id):
        """Generate a presigned url token to pass to kubectl."""
        url = self._get_presigned_url(k8s_aws_id)
        token = TOKEN_PREFIX + base64.urlsafe_b64encode(
            url.encode('utf-8')
        ).decode('utf-8').rstrip('=')
        return token

You can create the presigned URL in Swift as follows

let url = try await Self.sts.signURL(
    url: URL(string: Self.sts.endpoint)!, 
    httpMethod: .GET, 
    headers: ["x-k8s-aws-id": "my-cluster-name"],
    expires: .seconds(60)
)
buhe commented 1 year ago

Thank you!! I will be try tomorrow Because I am in China..

buhe commented 1 year ago

Hi @adam-fowler I try, but signurl may miss something fix part, i use this code, token already incorrect. I print gen token vs aws-cli gen token

code

k8s-aws-v1.aHR0cHM6Ly9zdHMudXMtd2VzdC0xLmFtYXpvbmF3cy5jb20/WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVEZJWkZOU0lTRTNPVkdYQiUyRjIwMjMwMTA4JTJGdXMtd2VzdC0xJTJGc3RzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyMzAxMDhUMDMwNzE2WiZYLUFtei1FeHBpcmVzPTYwJlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCUzQngtazhzLWF3cy1pZCZYLUFtei1TaWduYXR1cmU9NjgxNzdmOWFkMTU1ZDIzZjk4Y2IyNjg0MjhhODFhYzIyOGQ2ZTdiYTMzODVhNTk0YjgzYjI0YzAzZTM3MWJmYQ

aws-cli

k8s-aws-v1.aHR0cHM6Ly9zdHMudXMtd2VzdC0xLmFtYXpvbmF3cy5jb20vP0FjdGlvbj1HZXRDYWxsZXJJZGVudGl0eSZWZXJzaW9uPTIwMTEtMDYtMTUmWC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVEZJWkZOU0lTRTNPVkdYQiUyRjIwMjMwMTA4JTJGdXMtd2VzdC0xJTJGc3RzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyMzAxMDhUMDMyMTM3WiZYLUFtei1FeHBpcmVzPTYwJlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCUzQngtazhzLWF3cy1pZCZYLUFtei1TaWduYXR1cmU9ODFiZGU2N2ViNzdmZjUzYWFiMmQwYzA4YTk3ZjRiNDI3MDZmYjQyZmI3YmFlM2NjZmVmY2NiYjM5ODNjMzgxZA
let url = try! sts.signURL(
            url: URL(string: sts.endpoint)!,
            httpMethod: .GET,
            headers: ["x-k8s-aws-id": clusterName],
            expires: .seconds(60)
        ).wait()
        print("signed: \(url.absoluteString)")
        var token = MyAWSClient.TOKEN_PREFIX + url.absoluteString.data(using: .utf8)!.base64EncodedString()
        token.remove(at: token.index(before: token.endIndex))
        token.remove(at: token.index(before: token.endIndex))

So, any idea. thanks.

buhe commented 1 year ago
signed: https://sts.us-west-1.amazonaws.com?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIATFIZFNSISE3OVGXB%2F20230108%2Fus-west-1%2Fsts%2Faws4_request&X-Amz-Date=20230108T032024Z&X-Amz-Expires=60&X-Amz-SignedHeaders=host%3Bx-k8s-aws-id&X-Amz-Signature=09e203e2db953ca526c39545f6e763c2ef083eea352fbc10d2c6122f16c28078
buhe commented 1 year ago
https://sts.us-west-1.amazonaws.com/?Action=GetCallerIdentity&Version=2011-06-15&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIATFIZFNSISE3OVGXB%2F20230108%2Fus-west-1%2Fsts%2Faws4_request&X-Amz-Date=20230108T041100Z&X-Amz-Expires=60&X-Amz-SignedHeaders=host%3Bx-k8s-aws-id&X-Amz-Signature=839eddff93e520580770281c28f2e5ada9f67afde4900f32b246e86b332aeb4

This is aws-cli url. More "Action=GetCallerIdentity&Version=2011-06-15"

buhe commented 1 year ago

Amazing! finally version.thank you!

let url = try! sts.signURL(
            url: URL(string: sts.endpoint+"/?Action=GetCallerIdentity&Version=2011-06-15")!,
            httpMethod: .GET,
            headers: ["x-k8s-aws-id": clusterName],
            expires: .seconds(60)
        ).wait()
        print("signed: \(url.absoluteString)")
        var token = MyAWSClient.TOKEN_PREFIX + Base64FS.encodeString(str: url.absoluteString)
        token.remove(at: token.index(before: token.endIndex))
        token.remove(at: token.index(before: token.endIndex))