Commit f6e97287 authored by Pierre Smeyers's avatar Pierre Smeyers
Browse files

feat: add username & password APIs

parent 186f4bc6
Loading
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -83,7 +83,7 @@ test-health:
test-token-no-creds-fails:
  extends: .test-base
  script:
    - response_status=$(curl -s -o "resp.txt" -w "%{http_code}" "http://aws-auth-provider/ecr/token")
    - response_status=$(curl -s -o "resp.txt" -w "%{http_code}" "http://aws-auth-provider/ecr/auth/token")
    - cat resp.txt
    - assert_eq "401" $response_status

@@ -98,7 +98,7 @@ test-token-invalid-oidc-fails:
    AWS_JWT:
      aud: "$CI_SERVER_URL"
  script:
    - response_status=$(curl -s -o "resp.txt" -w "%{http_code}" "http://aws-auth-provider/ecr/token")
    - response_status=$(curl -s -o "resp.txt" -w "%{http_code}" "http://aws-auth-provider/ecr/auth/token")
    - cat resp.txt
    - assert_eq "500" $response_status

@@ -118,12 +118,12 @@ test-token-succeeds:
    AWS_JWT:
      aud: "$CI_SERVER_URL"
  script:
    - response_status=$(curl -s -o "resp.txt" -w "%{http_code}" "http://aws-auth-provider/ecr/token?env_ctx=TEST")
    - response_status=$(curl -s -o "resp.txt" -w "%{http_code}" "http://aws-auth-provider/ecr/auth/token?env_ctx=TEST")
    - |
      if [[ "$response_status" != 200 ]]
      then
        echo "Get ECR token failed ($response_status)"
        curl -s -v "http://aws-auth-provider/ecr/token?env_ctx=TEST"
        curl -s -v "http://aws-auth-provider/ecr/auth/token?env_ctx=TEST"
      fi
    - assert_eq "200" $response_status
    - ecr_token=$(cat resp.txt)
+30 −5
Original line number Diff line number Diff line
@@ -53,7 +53,7 @@ If you wish to use this authentication mode, please apply carefully the instruct

You may specialize those variables for the current `env_ctx`.

### API endpoint: GET ECR token
### `GET /ecr/auth/token`

This API retrieves an [ECR authorization token](https://docs.aws.amazon.com/AmazonECR/latest/APIReference/API_GetAuthorizationToken.html).

@@ -64,6 +64,30 @@ This API retrieves an [ECR authorization token](https://docs.aws.amazon.com/Amaz
| `region`   | AWS region to use                                             | no _(can be retrieved from env)_ |
| `env_ctx`  | the [environment context to consider](#the-notion-of-env_ctx) | no _(can be guessed)_ |

### `GET /ecr/auth/username`

This API retrieves the [ECR authorization token](https://docs.aws.amazon.com/AmazonECR/latest/APIReference/API_GetAuthorizationToken.html) username
(can be used in `docker login` command).

#### Query Parameters

| Name       | Description                                                   | Required              | 
|------------|---------------------------------------------------------------|-----------------------|
| `region`   | AWS region to use                                             | no _(can be retrieved from env)_ |
| `env_ctx`  | the [environment context to consider](#the-notion-of-env_ctx) | no _(can be guessed)_ |

### `GET /ecr/auth/password`

This API retrieves the [ECR authorization token](https://docs.aws.amazon.com/AmazonECR/latest/APIReference/API_GetAuthorizationToken.html) password
(can be used in `docker login` command).

#### Query Parameters

| Name       | Description                                                   | Required              | 
|------------|---------------------------------------------------------------|-----------------------|
| `region`   | AWS region to use                                             | no _(can be retrieved from env)_ |
| `env_ctx`  | the [environment context to consider](#the-notion-of-env_ctx) | no _(can be guessed)_ |

## Use in Gitlab CI

Finally, the Docker image can be used in your GitLab CI files as follows:
@@ -95,10 +119,11 @@ docker-build-step1:
    AWS_JWT:
      aud: "https://123456789012.dkr.ecr.$AWS_TEST1_REGION.amazonaws.com"
  before-script:
    # retrieve authorization token from ECR (in context 'TEST1')
    - ecr_token=$(curl -s -S -f "http://aws-auth-provider/ecr/token?env_ctx=TEST1")
    # retrieve authorization from ECR (in context 'TEST1')
    - ecr_auth_username=$(curl -s -S -f "http://aws-auth-provider/ecr/auth/username?env_ctx=TEST1")
    - ecr_auth_password=$(curl -s -S -f "http://aws-auth-provider/ecr/auth/password?env_ctx=TEST1")
    # login
    - echo "$ecr_token" | docker login --username AWS --password-stdin $ecr_registry
    - echo "$ecr_token" | docker login --username "$ecr_auth_username" --password-stdin "$ecr_auth_password"
    - docker info
  script:
    # build and push my image
+27 −2
Original line number Diff line number Diff line
import base64
import logging
import os
import re
@@ -136,9 +137,9 @@ async def request_validation_exception_handler(
    )


@app.get("/ecr/token", response_class=PlainTextResponse)
@app.get("/ecr/auth/token", response_class=PlainTextResponse)
@cache
def get_ecr_token(
def get_ecr_auth_token(
    env_ctx: str = Query(default=None, alias="env_ctx"),
    region: str = Query(default=None, alias="region"),
    role_arn: str = Query(default=None, alias="role_arn"),
@@ -148,3 +149,27 @@ def get_ecr_token(
    client = boto3.client("ecr")
    response = client.get_authorization_token()
    return response["authorizationData"][0]["authorizationToken"]


@app.get("/ecr/auth/username", response_class=PlainTextResponse)
def get_ecr_auth_username(
    env_ctx: str = Query(default=None, alias="env_ctx"),
    region: str = Query(default=None, alias="region"),
    role_arn: str = Query(default=None, alias="role_arn"),
) -> str:
    b64token = get_ecr_auth_token(env_ctx=env_ctx, region=region, role_arn=role_arn)
    # token is base64("<username>:<password>")
    user_password = base64.b64decode(b64token).decode("utf-8")
    return user_password.split(":")[0]


@app.get("/ecr/auth/password", response_class=PlainTextResponse)
def get_ecr_auth_password(
    env_ctx: str = Query(default=None, alias="env_ctx"),
    region: str = Query(default=None, alias="region"),
    role_arn: str = Query(default=None, alias="role_arn"),
) -> str:
    b64token = get_ecr_auth_token(env_ctx=env_ctx, region=region, role_arn=role_arn)
    # token is base64("<username>:<password>")
    user_password = base64.b64decode(b64token).decode("utf-8")
    return user_password.split(":")[1]
 No newline at end of file