Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: retrieve Rackspace credentials from Keepass #9

Merged
merged 7 commits into from
May 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .config/cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"dockerhub",
"Hapag",
"Infracost",
"keepass",
"oidc",
"pytest",
"Repology",
Expand Down Expand Up @@ -35,6 +36,8 @@
"hmarr",
"ibiqlik",
"kayman",
"kdbx",
"kpscript",
"kskey",
"ludeeus",
"markdownlint",
Expand Down
19 changes: 17 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,33 @@ Main features:
- fetch new credentials only if old ones are expired or not present
- use AWS profiles via `aws configure`
- list all AWS accounts you are authorized to
- supports Keepass for storing the Rackspace username and API key

## Installation

The minimum requirements are the AWS CLI and [JQ](https://github.com/jqlang/jq). Install them first.

## KeePass support

Create a new entry in your KeePass database with the following fields:

- title: Rackspace
- username: your Rackspace username
- add a custom field with the name `api-key` and the value of your Rackspace API key

Set the path to your KeePass database in the environment variable `KEEPASS_FILE`.

```bash
export KEEPASS_FILE="$HOME/keepass.kdbx"
```

## Usage

Execute `aws_login` on the command line. The first time, the script creates a file in
`$HOME/config/rackspace-aws-login/aws_accounts.json` caching your accounts. Remove the file to reset the accounts.
`$HOME/.config/rackspace-aws-login/aws_accounts.txt` caching your accounts. Remove the file to reset the accounts.

In case the script retrieves the credentials from Rackspace, it asks for the Rackspace username and API key. Check your
Rackspace account to set up the API key.
Rackspace account to set up the API key. You can put both in a KeePass database and the script will fetch them from there.

```bash
# place this in your .bash_profile
Expand Down
93 changes: 60 additions & 33 deletions aws_login.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,30 +15,71 @@ function aws_login() {
mkdir -p "$config_dir"
fi

local temporary_rackspace_token
local rackspace_tennant_id
local rackspace_username
local rackspace_api_key

function get_aws_accounts_from_rackspace() {
local temporary_rackspace_token
local tennant_id
if [ -z "$temporary_rackspace_token" ]; then
get_rackspace_token_and_tenant
fi

temporary_rackspace_token=$1
tennant_id=$2
aws_accounts=$(curl --location 'https://accounts.api.manage.rackspace.com/v0/awsAccounts' \
--silent \
--header "X-Auth-Token: $temporary_rackspace_token" \
--header "X-Tenant-Id: $rackspace_tennant_id" | jq -r '.awsAccounts[] | .awsAccountNumber + "_" + .name' | sed 's/\r//' | sort)

echo "$aws_accounts" > "$config_dir/aws_accounts.txt"
}

if [ -f "$config_dir/aws_accounts.txt" ]; then
cat "$config_dir/aws_accounts.txt"
function get_rackspace_username_and_api_key() {
kpscript_executable=$(command -v kpscript)

if [ -z "$KEEPASS_FILE" ] || [ -z "$kpscript_executable" ]; then
# no Keepass in place --> ask the user
echo "Did not found your Keepass file or KPScript executable. Please enter your Rackspace credentials."

read -r -p 'Rackspace username: ' rackspace_username
read -r -sp 'Rackspace API key: ' rackspace_api_key

echo ""
else
aws_accounts=$(curl --location 'https://accounts.api.manage.rackspace.com/v0/awsAccounts' \
--silent \
--header "X-Auth-Token: $temporary_rackspace_token" \
--header "X-Tenant-Id: $tennant_id" | jq -r '.awsAccounts[] | .awsAccountNumber + "_" + .name' | sed 's/\r//' | sort)
# get credentials from Keepass
echo "Reading credentials from Keepass: $KEEPASS_FILE. Entry Rackspace (username + api-key field)."

echo "$aws_accounts" > "$config_dir/aws_accounts.txt"
echo "$aws_accounts"
read -r -sp 'Keepass Password: ' keepass_password
echo ""

rackspace_username=$($kpscript_executable -c:GetEntryString "${KEEPASS_FILE}" -Field:UserName -ref-Title:"Rackspace" -FailIfNoEntry -pw:"$keepass_password" | head -n1 )
rackspace_api_key=$($kpscript_executable -c:GetEntryString "${KEEPASS_FILE}" -Field:api-key -ref-Title:"Rackspace" -FailIfNoEntry -pw:"$keepass_password" | head -n1 )
fi
}

temporary_rackspace_token=$(jq -r '.access.token.id' <<<"$rackspace_token_json")
tennant_id=$(jq -r '.access.token.tenant.id' <<<"$rackspace_token_json")
function get_rackspace_token_and_tenant() {
get_rackspace_username_and_api_key

rackspace_token_json=$(curl --location 'https://identity.api.rackspacecloud.com/v2.0/tokens' \
--header 'Content-Type: application/json' \
--silent \
--data "{
\"auth\": {
\"RAX-KSKEY:apiKeyCredentials\": {
\"username\": \"$rackspace_username\",
\"apiKey\": \"$rackspace_api_key\"
}
}
}")

temporary_rackspace_token=$(jq -r '.access.token.id' <<<"$rackspace_token_json")
rackspace_tennant_id=$(jq -r '.access.token.tenant.id' <<<"$rackspace_token_json")
}

if [ ! -s "$config_dir/aws_accounts.txt" ]; then
get_aws_accounts_from_rackspace
fi

aws_accounts=$(get_aws_accounts_from_rackspace "$temporary_rackspace_token" "$tennant_id")
aws_accounts=$(cat "$config_dir/aws_accounts.txt")

PS3='Select the AWS account to connect to: '
select opt in $aws_accounts; do
Expand All @@ -51,28 +92,14 @@ function aws_login() {
aws sts get-caller-identity --profile "$aws_profile_name" >/dev/null 2>&1 || exit_state=$?

if [ $exit_state -ne 0 ]; then
read -r -p 'Rackspace username: ' username
read -r -sp 'Rackspace API key: ' api_key

# insert new line after last input
echo

rackspace_token_json=$(curl --location 'https://identity.api.rackspacecloud.com/v2.0/tokens' \
--header 'Content-Type: application/json' \
--silent \
--data "{
\"auth\": {
\"RAX-KSKEY:apiKeyCredentials\": {
\"username\": \"$username\",
\"apiKey\": \"$api_key\"
}
}
}")
if [ -z "$temporary_rackspace_token" ]; then
get_rackspace_token_and_tenant
fi

temp_credentials=$(curl --location --silent \
--request POST "https://accounts.api.manage.rackspace.com/v0/awsAccounts/$aws_account_no/credentials" \
--header "X-Auth-Token: $temporary_rackspace_token" \
--header "X-Tenant-Id: $tennant_id")
--header "X-Tenant-Id: $rackspace_tennant_id")

access_key=$(jq -r '.credential.accessKeyId' <<<"$temp_credentials")
secret_access_key=$(jq -r '.credential.secretAccessKey' <<<"$temp_credentials")
Expand Down