Skip to content

Allow custom S3 domain #8

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

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
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
35 changes: 21 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,31 +1,38 @@
# s3-bash4

_s3-bash4_ is a small collection of _Bash_ scripts to do simple interaction with _Amazon S3_ using [_AWS Signature Version 4_](http://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html). The advantage of using _s3-bash4_ is that it's extremly lightweight and easy to use. No need to setup _Python_, _Java_, _Ruby_ and co.
_s3-bash4_ is a small collection of _Bash_ scripts to do simple interaction with _Amazon S3_ using [_AWS Signature Version 4_](http://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html). The advantage of using _s3-bash4_ is that it's extremely lightweight and easy to use. No need to setup _Python_, _Java_, _Ruby_ and co.

This is inspired by the discontinued [_s3-bash_](https://github.com/cosmin/s3-bash) from _cosmin_. I was in need of a _Bash_ version that supports the newer _AWS Signature Version 4_.

### Usage
# Get file from bucket:
s3-get -k {accesskey} -s /{path}/{secretid} -r {region} /{bucketname}/{filename} > {filename}
## Usage

# Upload file to bucket:
s3-put -k {accesskey} -s /{path}/{secretid} -r {region} -T /{path}/{filename} /{bucketname}/{filename}
```sh
# Get file from bucket:
s3-get -k {accesskey} -s /{path}/{secretid} -r {region} [-d {customdomain}] /{bucketname}/{filename} > {filename}

# Delete from bucket:
s3-delete -k {accesskey} -s /{path}/{secretid} -r {region} /{bucketname}/{filename}
# Upload file to bucket:
s3-put -k {accesskey} -s /{path}/{secretid} -r {region} [-d {customdomain}] -T /{path}/{filename} /{bucketname}/{filename}

### Environment Variables
# Delete from bucket:
s3-delete -k {accesskey} -s /{path}/{secretid} -r {region} [-d {customdomain}] /{bucketname}/{filename}
```

## Environment Variables

Variable | Description
---------------------- | -----------------------------------------------------------
`AWS_ACCESS_KEY_ID` | Default _AWS Access Key ID_
`AWS_SECRET_ACCESS_KEY`| Default _AWS Secret Access Key_
`AWS_DEFAULT_REGION` | Default _AWS S3 Region_
`S3_DEFAULT_DOMAIN` | Default _S3 custom domain_
`AWS_SECURITY_TOKEN` | Default _AWS Security Token for temporary credentials_

### Requirements
- _OpenSSL_
- _cUrl_
## Requirements

- _GNU Bash_
- _OpenSSL_
- _cUrl_

## License

### License
_Apache License Version 2.0_
This work is released under the _Apache License Version 2.0_
2 changes: 1 addition & 1 deletion STYLE_GUIDE
Original file line number Diff line number Diff line change
@@ -1 +1 @@
This project follows the following style guide: https://google-styleguide.googlecode.com/svn/trunk/shell.xml
This project follows the following style guide: https://google.github.io/styleguide/shellguide.html
54 changes: 32 additions & 22 deletions bin/s3-delete
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#
# Delete a file from S3
# (c) 2015 Chi Vinh Le <[email protected]>
# (c) 2024 Orange SA — author: [email protected]
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
Expand All @@ -17,12 +18,16 @@

set -euo pipefail

readonly PROJECT_PATH=$( cd $(dirname $0) ; cd ../; pwd -P )
readonly SCRIPT_NAME="$(basename $0)"
PROJECT_PATH=$( cd "$(dirname "$0")" ; cd ../; pwd -P )
readonly PROJECT_PATH
SCRIPT_NAME="$(basename "$0")"
readonly SCRIPT_NAME
# shellcheck disable=SC2034 # rule "METHOD appears unused"
readonly METHOD="DELETE"

# Includes
source ${PROJECT_PATH}/lib/s3-common.sh
# shellcheck source=../lib/s3-common.sh
source "${PROJECT_PATH}/lib/s3-common.sh"

##
# Print help and exit
Expand All @@ -33,21 +38,22 @@ source ${PROJECT_PATH}/lib/s3-common.sh
##
printUsageAndExitWith() {
printf "Usage:\n"
printf " ${SCRIPT_NAME} [-vi] [-k key] [-s file] [-r region] resource_path\n"
printf " ${SCRIPT_NAME} -h\n"
printf " %s [-vi] [-k key] [-s file] [-r region] [-d domain] resource_path\n" "${SCRIPT_NAME}"
printf " %s -h\n" "${SCRIPT_NAME}"
printf "Example:\n"
printf " ${SCRIPT_NAME} -k key -s secret -r eu-central-1 /bucket/file.ext\n"
printf " %s -k key -s secret -r eu-central-1 /bucket/file.ext\n" "${SCRIPT_NAME}"
printf "Options:\n"
printf " --debug\tEnable debugging mode\n"
printf " -h,--help\tPrint this help\n"
printf " -i,--insecure\tUse http instead of https\n"
printf " -k,--key\tAWS Access Key ID. Default to environment variable AWS_ACCESS_KEY_ID\n"
printf " -r,--region\tAWS S3 Region. Default to environment variable AWS_DEFAULT_REGION\n"
printf " -d,--domain\tS3 custom network domain. Default to environment variable S3_DEFAULT_DOMAIN or 'amazonaws.com'\n"
printf " -s,--secret\tFile containing AWS Secret Access Key. If not set, secret will be environment variable AWS_SECRET_ACCESS_KEY\n"
printf " -t,--token\tSecurity token for temporary credentials. If not set, token will be environment variable AWS_SECURITY_TOKEN\n"
printf " -v,--verbose\tVerbose output\n"
printf " --version\tShow version\n"
exit $1
exit "$1"
}

##
Expand All @@ -58,6 +64,7 @@ printUsageAndExitWith() {
# AWS_ACCESS_KEY_ID string
# AWS_SECRET_ACCESS_KEY string
# AWS_REGION string
# S3_DEFAULT_DOMAIN string
# AWS_SECURITY_TOKEN string
# RESOURCE_PATH string
# VERBOSE bool
Expand All @@ -67,6 +74,7 @@ printUsageAndExitWith() {
parseCommandLine() {
# Init globals
AWS_REGION=${AWS_DEFAULT_REGION:-""}
S3_DOMAIN=${S3_DEFAULT_DOMAIN:-""}
AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID:-""}
AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY:-""}
AWS_SECURITY_TOKEN=${AWS_SECURITY_TOKEN:-""}
Expand All @@ -77,57 +85,59 @@ parseCommandLine() {
# Parse options
local remaining=
local secretKeyFile=
while [[ $# > 0 ]]; do
while [[ $# -gt 0 ]]; do
local key="$1"
case ${key} in
--version) showVersionAndExit;;
--debug) DEBUG=true;;
-h|--help) printUsageAndExitWith 0;;
-v|--verbose) VERBOSE=true;;
-i|--insecure) INSECURE=true;;
-r|--region) assertArgument $@; AWS_REGION=$2; shift;;
-k|--key) assertArgument $@; AWS_ACCESS_KEY_ID=$2; shift;;
-s|--secret) assertArgument $@; secretKeyFile=$2; shift;;
-t|--token) assertArgument $@; AWS_SECURITY_TOKEN=$2; shift;;
-r|--region) assertArgument "$@"; AWS_REGION=$2; shift;;
-d|--domain) assertArgument "$@"; S3_DOMAIN=$2; shift;;
-k|--key) assertArgument "$@"; AWS_ACCESS_KEY_ID=$2; shift;;
-s|--secret) assertArgument "$@"; secretKeyFile=$2; shift;;
-t|--token) assertArgument "$@"; AWS_SECURITY_TOKEN=$2; shift;;
-*) err "Unknown option $1"
printUsageAndExitWith ${INVALID_USAGE_EXIT_CODE};;
printUsageAndExitWith "${INVALID_USAGE_EXIT_CODE}";;
*) remaining="${remaining} \"${key}\"";;
esac
shift
done

# Set the non-parameters back into the positional parameters ($1 $2 ..)
eval set -- ${remaining}
eval set -- "${remaining}"

# Read secret file if set
if ! [[ -z "${secretKeyFile}" ]]; then
if [[ -n "${secretKeyFile}" ]]; then
AWS_SECRET_ACCESS_KEY=$(processAWSSecretFile "${secretKeyFile}")
fi

# Parse arguments
if [[ $# != 1 ]]; then
if [[ $# -ne 1 ]]; then
err "You need to specify the resource path to download e.g. /bucket/file.ext"
printUsageAndExitWith ${INVALID_USAGE_EXIT_CODE}
printUsageAndExitWith "${INVALID_USAGE_EXIT_CODE}"
fi

assertResourcePath "$1"
RESOURCE_PATH="$1"

if [[ -z "${AWS_REGION}" ]]; then
err "AWS Region not specified"
printUsageAndExitWith ${INVALID_USAGE_EXIT_CODE}
printUsageAndExitWith "${INVALID_USAGE_EXIT_CODE}"
fi
if [[ -z "${AWS_ACCESS_KEY_ID}" ]]; then
err "AWS Access Key ID not specified"
printUsageAndExitWith ${INVALID_USAGE_EXIT_CODE}
printUsageAndExitWith "${INVALID_USAGE_EXIT_CODE}"
fi
if [[ -z "${AWS_SECRET_ACCESS_KEY}" ]]; then
err "AWS Secret Access Key not specified"
printUsageAndExitWith ${INVALID_USAGE_EXIT_CODE}
printUsageAndExitWith "${INVALID_USAGE_EXIT_CODE}"
fi

# Freeze globals
readonly AWS_REGION
readonly S3_DOMAIN
readonly AWS_ACCESS_KEY_ID
readonly AWS_SECRET_ACCESS_KEY
readonly RESOURCE_PATH
Expand All @@ -141,8 +151,8 @@ parseCommandLine() {
##
main() {
checkEnvironment
parseCommandLine $@
parseCommandLine "$@"
performRequest
}

main $@
main "$@"
54 changes: 32 additions & 22 deletions bin/s3-get
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#
# Download a file from S3
# (c) 2015 Chi Vinh Le <[email protected]>
# (c) 2024 Orange SA — author: [email protected]
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
Expand All @@ -17,12 +18,16 @@

set -euo pipefail

readonly PROJECT_PATH=$( cd $(dirname $0) ; cd ../; pwd -P )
readonly SCRIPT_NAME="$(basename $0)"
PROJECT_PATH=$( cd "$(dirname "$0")" ; cd ../; pwd -P )
readonly PROJECT_PATH
SCRIPT_NAME="$(basename "$0")"
readonly SCRIPT_NAME
# shellcheck disable=SC2034 # rule "METHOD appears unused"
readonly METHOD="GET"

# Includes
source ${PROJECT_PATH}/lib/s3-common.sh
# shellcheck source=../lib/s3-common.sh
source "${PROJECT_PATH}/lib/s3-common.sh"

##
# Print help and exit
Expand All @@ -33,21 +38,22 @@ source ${PROJECT_PATH}/lib/s3-common.sh
##
printUsageAndExitWith() {
printf "Usage:\n"
printf " ${SCRIPT_NAME} [-vi] [-k key] [-s file] [-r region] resource_path\n"
printf " ${SCRIPT_NAME} -h\n"
printf " %s [-vi] [-k key] [-s file] [-r region] [-d domain] resource_path\n" "${SCRIPT_NAME}"
printf " %s -h\n" "${SCRIPT_NAME}"
printf "Example:\n"
printf " ${SCRIPT_NAME} -k key -s secret -r eu-central-1 /bucket/file.ext\n"
printf " %s -k key -s secret -r eu-central-1 /bucket/file.ext\n" "${SCRIPT_NAME}"
printf "Options:\n"
printf " --debug\tEnable debugging mode\n"
printf " -h,--help\tPrint this help\n"
printf " -i,--insecure\tUse http instead of https\n"
printf " -k,--key\tAWS Access Key ID. Default to environment variable AWS_ACCESS_KEY_ID\n"
printf " -r,--region\tAWS S3 Region. Default to environment variable AWS_DEFAULT_REGION\n"
printf " -d,--domain\tS3 custom network domain. Default to environment variable S3_DEFAULT_DOMAIN or 'amazonaws.com'\n"
printf " -s,--secret\tFile containing AWS Secret Access Key. If not set, secret will be environment variable AWS_SECRET_ACCESS_KEY\n"
printf " -t,--token\tSecurity token for temporary credentials. If not set, token will be environment variable AWS_SECURITY_TOKEN\n"
printf " -v,--verbose\tVerbose output\n"
printf " --version\tShow version\n"
exit $1
exit "$1"
}

##
Expand All @@ -58,6 +64,7 @@ printUsageAndExitWith() {
# AWS_ACCESS_KEY_ID string
# AWS_SECRET_ACCESS_KEY string
# AWS_REGION string
# S3_DEFAULT_DOMAIN string
# AWS_SECURITY_TOKEN string
# RESOURCE_PATH string
# VERBOSE bool
Expand All @@ -67,6 +74,7 @@ printUsageAndExitWith() {
parseCommandLine() {
# Init globals
AWS_REGION=${AWS_DEFAULT_REGION:-""}
S3_DOMAIN=${S3_DEFAULT_DOMAIN:-""}
AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID:-""}
AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY:-""}
AWS_SECURITY_TOKEN=${AWS_SECURITY_TOKEN:-""}
Expand All @@ -77,57 +85,59 @@ parseCommandLine() {
# Parse options
local remaining=
local secretKeyFile=
while [[ $# > 0 ]]; do
while [[ $# -gt 0 ]]; do
local key="$1"
case ${key} in
--version) showVersionAndExit;;
--debug) DEBUG=true;;
-h|--help) printUsageAndExitWith 0;;
-v|--verbose) VERBOSE=true;;
-i|--insecure) INSECURE=true;;
-r|--region) assertArgument $@; AWS_REGION=$2; shift;;
-k|--key) assertArgument $@; AWS_ACCESS_KEY_ID=$2; shift;;
-s|--secret) assertArgument $@; secretKeyFile=$2; shift;;
-t|--token) assertArgument $@; AWS_SECURITY_TOKEN=$2; shift;;
-r|--region) assertArgument "$@"; AWS_REGION=$2; shift;;
-d|--domain) assertArgument "$@"; S3_DOMAIN=$2; shift;;
-k|--key) assertArgument "$@"; AWS_ACCESS_KEY_ID=$2; shift;;
-s|--secret) assertArgument "$@"; secretKeyFile=$2; shift;;
-t|--token) assertArgument "$@"; AWS_SECURITY_TOKEN=$2; shift;;
-*) err "Unknown option $1"
printUsageAndExitWith ${INVALID_USAGE_EXIT_CODE};;
printUsageAndExitWith "${INVALID_USAGE_EXIT_CODE}";;
*) remaining="${remaining} \"${key}\"";;
esac
shift
done

# Set the non-parameters back into the positional parameters ($1 $2 ..)
eval set -- ${remaining}
eval set -- "${remaining}"

# Read secret file if set
if ! [[ -z "${secretKeyFile}" ]]; then
if [[ -n "${secretKeyFile}" ]]; then
AWS_SECRET_ACCESS_KEY=$(processAWSSecretFile "${secretKeyFile}")
fi

# Parse arguments
if [[ $# != 1 ]]; then
if [[ $# -ne 1 ]]; then
err "You need to specify the resource path to download e.g. /bucket/file.ext"
printUsageAndExitWith ${INVALID_USAGE_EXIT_CODE}
printUsageAndExitWith "${INVALID_USAGE_EXIT_CODE}"
fi

assertResourcePath "$1"
RESOURCE_PATH="$1"

if [[ -z "${AWS_REGION}" ]]; then
err "AWS Region not specified"
printUsageAndExitWith ${INVALID_USAGE_EXIT_CODE}
printUsageAndExitWith "${INVALID_USAGE_EXIT_CODE}"
fi
if [[ -z "${AWS_ACCESS_KEY_ID}" ]]; then
err "AWS Access Key ID not specified"
printUsageAndExitWith ${INVALID_USAGE_EXIT_CODE}
printUsageAndExitWith "${INVALID_USAGE_EXIT_CODE}"
fi
if [[ -z "${AWS_SECRET_ACCESS_KEY}" ]]; then
err "AWS Secret Access Key not specified"
printUsageAndExitWith ${INVALID_USAGE_EXIT_CODE}
printUsageAndExitWith "${INVALID_USAGE_EXIT_CODE}"
fi

# Freeze globals
readonly AWS_REGION
readonly S3_DOMAIN
readonly AWS_ACCESS_KEY_ID
readonly AWS_SECRET_ACCESS_KEY
readonly RESOURCE_PATH
Expand All @@ -141,8 +151,8 @@ parseCommandLine() {
##
main() {
checkEnvironment
parseCommandLine $@
parseCommandLine "$@"
performRequest
}

main $@
main "$@"
Loading