mirror of
https://github.com/versity/versitygw.git
synced 2026-01-09 21:07:21 +00:00
Merge pull request #794 from versity/test_cmdline_xml_retrieval
Test cmdline xml retrieval
This commit is contained in:
2
.github/workflows/docker-bats.yaml
vendored
2
.github/workflows/docker-bats.yaml
vendored
@@ -25,4 +25,4 @@ jobs:
|
||||
run: sudo apt-get install -y docker-compose
|
||||
|
||||
- name: Run Docker Container
|
||||
run: docker-compose -f docker-compose-bats.yml up posix_backend
|
||||
run: docker-compose -f docker-compose-bats.yml up --exit-code-from posix_backend posix_backend
|
||||
|
||||
15
.github/workflows/system.yml
vendored
15
.github/workflows/system.yml
vendored
@@ -85,6 +85,17 @@ jobs:
|
||||
RECREATE_BUCKETS: "true"
|
||||
PORT: 7076
|
||||
BACKEND: "s3"
|
||||
- set: 8
|
||||
LOCAL_FOLDER: /tmp/gw8
|
||||
BUCKET_ONE_NAME: versity-gwtest-bucket-one-7
|
||||
BUCKET_TWO_NAME: versity-gwtest-bucket-two-7
|
||||
IAM_TYPE: folder
|
||||
USERS_FOLDER: /tmp/iam8
|
||||
AWS_ENDPOINT_URL: https://127.0.0.1:7077
|
||||
RUN_SET: "rest"
|
||||
RECREATE_BUCKETS: "true"
|
||||
PORT: 7077
|
||||
BACKEND: "posix"
|
||||
steps:
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@v4
|
||||
@@ -115,6 +126,10 @@ jobs:
|
||||
curl https://dl.min.io/client/mc/release/linux-amd64/mc --create-dirs -o /usr/local/bin/mc
|
||||
chmod 755 /usr/local/bin/mc
|
||||
|
||||
- name: Install xmllint (for rest)
|
||||
run: |
|
||||
sudo apt-get install libxml2-utils
|
||||
|
||||
- name: Build and run, posix backend
|
||||
env:
|
||||
LOCAL_FOLDER: ${{ matrix.LOCAL_FOLDER }}
|
||||
|
||||
@@ -19,6 +19,7 @@ RUN apt-get update && \
|
||||
s3cmd \
|
||||
jq \
|
||||
bc \
|
||||
libxml2-utils \
|
||||
ca-certificates && \
|
||||
update-ca-certificates && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
@@ -26,4 +26,4 @@ PASSWORD_ONE=HIJKLMN
|
||||
USERNAME_TWO=HIJKLMN
|
||||
PASSWORD_TWO=OPQRSTU
|
||||
TEST_FILE_FOLDER=$PWD/versity-gwtest-files
|
||||
REMOVE_TEST_FILE_FOLDER=false
|
||||
REMOVE_TEST_FILE_FOLDER=true
|
||||
|
||||
@@ -24,4 +24,5 @@ PASSWORD_ONE=HIJKLMN
|
||||
USERNAME_TWO=HIJKLMN
|
||||
PASSWORD_TWO=OPQRSTU
|
||||
TEST_FILE_FOLDER=$PWD/versity-gwtest-files
|
||||
RECREATE_BUCKETS=true
|
||||
RECREATE_BUCKETS=true
|
||||
REMOVE_TEST_FILE_FOLDER=true
|
||||
@@ -31,6 +31,8 @@ list_buckets() {
|
||||
buckets=$(s3cmd "${S3CMD_OPTS[@]}" --no-check-certificate ls s3:// 2>&1) || exit_code=$?
|
||||
elif [[ $1 == 'mc' ]]; then
|
||||
buckets=$(mc --insecure ls "$MC_ALIAS" 2>&1) || exit_code=$?
|
||||
elif [[ $1 == 'rest' ]]; then
|
||||
list_buckets_rest || exit_code=$?
|
||||
else
|
||||
echo "list buckets command not implemented for '$1'"
|
||||
return 1
|
||||
@@ -40,7 +42,7 @@ list_buckets() {
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [[ $1 == 's3api' ]] || [[ $1 == 'aws' ]]; then
|
||||
if [[ $1 == 's3api' ]] || [[ $1 == 'aws' ]] || [[ $1 == 'rest' ]]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
@@ -113,3 +115,32 @@ list_buckets_s3api() {
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
list_buckets_rest() {
|
||||
generate_hash_for_payload ""
|
||||
|
||||
current_date_time=$(date -u +"%Y%m%dT%H%M%SZ")
|
||||
# shellcheck disable=SC2154
|
||||
canonical_request="GET
|
||||
/
|
||||
|
||||
host:${AWS_ENDPOINT_URL#*//}
|
||||
x-amz-content-sha256:$payload_hash
|
||||
x-amz-date:$current_date_time
|
||||
|
||||
host;x-amz-content-sha256;x-amz-date
|
||||
$payload_hash"
|
||||
|
||||
if ! generate_sts_string "$current_date_time" "$canonical_request"; then
|
||||
log 2 "error generating sts string"
|
||||
return 1
|
||||
fi
|
||||
|
||||
get_signature
|
||||
# shellcheck disable=SC2034,SC2154
|
||||
reply=$(curl -ks "$AWS_ENDPOINT_URL" \
|
||||
-H "Authorization: AWS4-HMAC-SHA256 Credential=$AWS_ACCESS_KEY_ID/$ymd/$AWS_REGION/s3/aws4_request,SignedHeaders=host;x-amz-content-sha256;x-amz-date,Signature=$signature" \
|
||||
-H "x-amz-content-sha256: $payload_hash" \
|
||||
-H "x-amz-date: $current_date_time" 2>&1)
|
||||
parse_bucket_list
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
source ./tests/util_list_objects.sh
|
||||
|
||||
# Copyright 2024 Versity Software
|
||||
# This file is licensed under the Apache License, Version 2.0
|
||||
# (the "License"); you may not use this file except in compliance
|
||||
@@ -35,6 +37,9 @@ list_objects() {
|
||||
output=$(s3cmd "${S3CMD_OPTS[@]}" --no-check-certificate ls s3://"$2" 2>&1) || result=$?
|
||||
elif [[ $1 == 'mc' ]]; then
|
||||
output=$(mc --insecure ls "$MC_ALIAS"/"$2" 2>&1) || result=$?
|
||||
elif [[ $1 == 'rest' ]]; then
|
||||
list_objects_rest "$2" || result=$?
|
||||
return $result
|
||||
else
|
||||
fail "invalid command type $1"
|
||||
return 1
|
||||
@@ -126,3 +131,41 @@ list_objects_with_prefix() {
|
||||
export objects
|
||||
return 0
|
||||
}
|
||||
|
||||
list_objects_rest() {
|
||||
if [ $# -ne 1 ]; then
|
||||
log 2 "'list_objects_rest' requires bucket name"
|
||||
return 1
|
||||
fi
|
||||
|
||||
generate_hash_for_payload ""
|
||||
|
||||
current_date_time=$(date -u +"%Y%m%dT%H%M%SZ")
|
||||
aws_endpoint_url_address=${AWS_ENDPOINT_URL#*//}
|
||||
header=$(echo "$AWS_ENDPOINT_URL" | awk -F: '{print $1}')
|
||||
# shellcheck disable=SC2154
|
||||
canonical_request="GET
|
||||
/$1
|
||||
|
||||
host:$aws_endpoint_url_address
|
||||
x-amz-content-sha256:$payload_hash
|
||||
x-amz-date:$current_date_time
|
||||
|
||||
host;x-amz-content-sha256;x-amz-date
|
||||
$payload_hash"
|
||||
|
||||
log 5 "canonical request: $canonical_request"
|
||||
|
||||
if ! generate_sts_string "$current_date_time" "$canonical_request"; then
|
||||
log 2 "error generating sts string"
|
||||
return 1
|
||||
fi
|
||||
get_signature
|
||||
# shellcheck disable=SC2154
|
||||
reply=$(curl -ks "$header://$aws_endpoint_url_address/$1" \
|
||||
-H "Authorization: AWS4-HMAC-SHA256 Credential=$AWS_ACCESS_KEY_ID/$ymd/$AWS_REGION/s3/aws4_request,SignedHeaders=host;x-amz-content-sha256;x-amz-date,Signature=$signature" \
|
||||
-H "x-amz-content-sha256: $payload_hash" \
|
||||
-H "x-amz-date: $current_date_time" 2>&1)
|
||||
log 5 "reply: $reply"
|
||||
parse_objects_list_rest
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ show_help() {
|
||||
echo " s3 Run tests with s3 cli"
|
||||
echo " s3cmd Run tests with s3cmd utility"
|
||||
echo " mc Run tests with mc utility"
|
||||
echo " rest Run tests with rest cli"
|
||||
echo " aws-user Run user tests with aws cli"
|
||||
}
|
||||
|
||||
@@ -33,7 +34,7 @@ handle_param() {
|
||||
show_help
|
||||
exit 0
|
||||
;;
|
||||
s3|s3api|aws|s3cmd|mc|aws-user)
|
||||
s3|s3api|aws|s3cmd|mc|aws-user|rest)
|
||||
set_command_type "$1"
|
||||
;;
|
||||
*) # Handle unrecognized options or positional arguments
|
||||
@@ -85,6 +86,10 @@ case $command_type in
|
||||
echo "Running mc tests ..."
|
||||
"$HOME"/bin/bats ./tests/test_mc.sh || exit_code=$?
|
||||
;;
|
||||
rest)
|
||||
echo "Running rest tests ..."
|
||||
"$HOME"/bin/bats ./tests/test_rest.sh || exit_code=$?
|
||||
;;
|
||||
aws-user)
|
||||
echo "Running aws user tests ..."
|
||||
"$HOME"/bin/bats ./tests/test_user_aws.sh || exit_code=$?
|
||||
|
||||
@@ -31,4 +31,7 @@ fi
|
||||
if ! ./tests/run.sh mc; then
|
||||
exit 1
|
||||
fi
|
||||
if ! ./tests/run.sh rest; then
|
||||
exit 1
|
||||
fi
|
||||
exit 0
|
||||
|
||||
@@ -63,6 +63,12 @@ setup() {
|
||||
# bats teardown function
|
||||
teardown() {
|
||||
# shellcheck disable=SC2154
|
||||
if ! delete_bucket_or_contents_if_exists "$BUCKET_ONE_NAME"; then
|
||||
log 3 "error deleting bucket $BUCKET_ONE_NAME or contents"
|
||||
fi
|
||||
if ! delete_bucket_or_contents_if_exists "$BUCKET_TWO_NAME"; then
|
||||
log 3 "error deleting bucket $BUCKET_TWO_NAME or contents"
|
||||
fi
|
||||
if [ "$REMOVE_TEST_FILE_FOLDER" == "true" ]; then
|
||||
log 6 "removing test file folder"
|
||||
if ! error=$(rm -rf "${TEST_FILE_FOLDER:?}" 2>&1); then
|
||||
|
||||
@@ -17,6 +17,12 @@
|
||||
source ./tests/commands/delete_objects.sh
|
||||
source ./tests/commands/list_objects_v2.sh
|
||||
source ./tests/commands/list_parts.sh
|
||||
source ./tests/util_get_bucket_acl.sh
|
||||
source ./tests/util_get_object_attributes.sh
|
||||
source ./tests/util_get_object_retention.sh
|
||||
source ./tests/util_head_object.sh
|
||||
source ./tests/util_legal_hold.sh
|
||||
source ./tests/util_list_objects.sh
|
||||
|
||||
test_abort_multipart_upload_aws_root() {
|
||||
local bucket_file="bucket-file"
|
||||
@@ -30,31 +36,29 @@ test_abort_multipart_upload_aws_root() {
|
||||
run setup_bucket "aws" "$BUCKET_ONE_NAME"
|
||||
assert_success
|
||||
|
||||
run_then_abort_multipart_upload "$BUCKET_ONE_NAME" "$bucket_file" "$TEST_FILE_FOLDER"/"$bucket_file" 4 || fail "abort failed"
|
||||
run run_then_abort_multipart_upload "$BUCKET_ONE_NAME" "$bucket_file" "$TEST_FILE_FOLDER"/"$bucket_file" 4
|
||||
assert_success
|
||||
|
||||
if object_exists "aws" "$BUCKET_ONE_NAME" "$bucket_file"; then
|
||||
fail "Upload file exists after abort"
|
||||
fi
|
||||
|
||||
delete_bucket_or_contents "aws" "$BUCKET_ONE_NAME"
|
||||
delete_test_files $bucket_file
|
||||
run object_exists "aws" "$BUCKET_ONE_NAME" "$bucket_file"
|
||||
assert_failure 1
|
||||
}
|
||||
|
||||
test_complete_multipart_upload_aws_root() {
|
||||
local bucket_file="bucket-file"
|
||||
run create_test_files "$bucket_file"
|
||||
assert_success
|
||||
dd if=/dev/urandom of="$TEST_FILE_FOLDER/$bucket_file" bs=5M count=1 || fail "error creating test file"
|
||||
|
||||
run dd if=/dev/urandom of="$TEST_FILE_FOLDER/$bucket_file" bs=5M count=1
|
||||
assert_success
|
||||
|
||||
run setup_bucket "aws" "$BUCKET_ONE_NAME"
|
||||
assert_success
|
||||
|
||||
multipart_upload "$BUCKET_ONE_NAME" "$bucket_file" "$TEST_FILE_FOLDER"/"$bucket_file" 4 || fail "error performing multipart upload"
|
||||
run multipart_upload "$BUCKET_ONE_NAME" "$bucket_file" "$TEST_FILE_FOLDER"/"$bucket_file" 4
|
||||
assert_success
|
||||
|
||||
download_and_compare_file "s3api" "$TEST_FILE_FOLDER/$bucket_file" "$BUCKET_ONE_NAME" "$bucket_file" "$TEST_FILE_FOLDER/$bucket_file-copy" || fail "error downloading and comparing file"
|
||||
|
||||
delete_bucket_or_contents "aws" "$BUCKET_ONE_NAME"
|
||||
delete_test_files $bucket_file
|
||||
run download_and_compare_file "s3api" "$TEST_FILE_FOLDER/$bucket_file" "$BUCKET_ONE_NAME" "$bucket_file" "$TEST_FILE_FOLDER/$bucket_file-copy"
|
||||
assert_success
|
||||
}
|
||||
|
||||
test_create_multipart_upload_properties_aws_root() {
|
||||
@@ -67,7 +71,6 @@ test_create_multipart_upload_properties_aws_root() {
|
||||
local expected_retention_mode="GOVERNANCE"
|
||||
local expected_tag_key="TestTag"
|
||||
local expected_tag_val="TestTagVal"
|
||||
local five_seconds_later
|
||||
|
||||
os_name="$(uname)"
|
||||
if [[ "$os_name" == "Darwin" ]]; then
|
||||
@@ -80,64 +83,42 @@ test_create_multipart_upload_properties_aws_root() {
|
||||
|
||||
run create_test_files "$bucket_file"
|
||||
assert_success
|
||||
dd if=/dev/urandom of="$TEST_FILE_FOLDER/$bucket_file" bs=5M count=1 || fail "error creating test file"
|
||||
|
||||
run dd if=/dev/urandom of="$TEST_FILE_FOLDER/$bucket_file" bs=5M count=1
|
||||
assert_success
|
||||
|
||||
run delete_bucket_or_contents_if_exists "s3api" "$BUCKET_ONE_NAME"
|
||||
assert_success
|
||||
# in static bucket config, bucket will still exist
|
||||
bucket_exists "s3api" "$BUCKET_ONE_NAME" || local exists_result=$?
|
||||
[[ $exists_result -ne 2 ]] || fail "error checking for bucket existence"
|
||||
if [[ $exists_result -eq 1 ]]; then
|
||||
if ! bucket_exists "s3api" "$BUCKET_ONE_NAME"; then
|
||||
run create_bucket_object_lock_enabled "$BUCKET_ONE_NAME"
|
||||
assert_success
|
||||
fi
|
||||
get_object_lock_configuration "$BUCKET_ONE_NAME" || fail "error getting log config"
|
||||
# shellcheck disable=SC2154
|
||||
log 5 "LOG CONFIG: $log_config"
|
||||
|
||||
log 5 "LATER: $later"
|
||||
multipart_upload_with_params "$BUCKET_ONE_NAME" "$bucket_file" "$TEST_FILE_FOLDER"/"$bucket_file" 4 \
|
||||
run multipart_upload_with_params "$BUCKET_ONE_NAME" "$bucket_file" "$TEST_FILE_FOLDER"/"$bucket_file" 4 \
|
||||
"$expected_content_type" \
|
||||
"{\"$expected_meta_key\": \"$expected_meta_val\"}" \
|
||||
"$expected_hold_status" \
|
||||
"$expected_retention_mode" \
|
||||
"$later" \
|
||||
"$expected_tag_key=$expected_tag_val" || fail "error performing multipart upload"
|
||||
assert_success
|
||||
|
||||
head_object "s3api" "$BUCKET_ONE_NAME" "$bucket_file" || fail "error getting metadata"
|
||||
# shellcheck disable=SC2154
|
||||
raw_metadata=$(echo "$metadata" | grep -v "InsecureRequestWarning")
|
||||
log 5 "raw metadata: $raw_metadata"
|
||||
run get_and_verify_metadata "$bucket_file" "$expected_content_type" "$expected_meta_key" "$expected_meta_val" \
|
||||
"$expected_hold_status" "$expected_retention_mode" "$later"
|
||||
assert_success
|
||||
|
||||
content_type=$(echo "$raw_metadata" | jq -r ".ContentType")
|
||||
[[ $content_type == "$expected_content_type" ]] || fail "content type mismatch ($content_type, $expected_content_type)"
|
||||
meta_val=$(echo "$raw_metadata" | jq -r ".Metadata.$expected_meta_key")
|
||||
[[ $meta_val == "$expected_meta_val" ]] || fail "metadata val mismatch ($meta_val, $expected_meta_val)"
|
||||
hold_status=$(echo "$raw_metadata" | jq -r ".ObjectLockLegalHoldStatus")
|
||||
[[ $hold_status == "$expected_hold_status" ]] || fail "hold status mismatch ($hold_status, $expected_hold_status)"
|
||||
retention_mode=$(echo "$raw_metadata" | jq -r ".ObjectLockMode")
|
||||
[[ $retention_mode == "$expected_retention_mode" ]] || fail "retention mode mismatch ($retention_mode, $expected_retention_mode)"
|
||||
retain_until_date=$(echo "$raw_metadata" | jq -r ".ObjectLockRetainUntilDate")
|
||||
[[ $retain_until_date == "$later"* ]] || fail "retention date mismatch ($retain_until_date, $five_seconds_later)"
|
||||
run get_and_check_bucket_tags "$BUCKET_ONE_NAME" "$expected_tag_key" "$expected_tag_val"
|
||||
assert_success
|
||||
|
||||
get_object_tagging "aws" "$BUCKET_ONE_NAME" "$bucket_file" || fail "error getting tagging"
|
||||
# shellcheck disable=SC2154
|
||||
log 5 "tags: $tags"
|
||||
tag_key=$(echo "$tags" | jq -r ".TagSet[0].Key")
|
||||
[[ $tag_key == "$expected_tag_key" ]] || fail "tag mismatch ($tag_key, $expected_tag_key)"
|
||||
tag_val=$(echo "$tags" | jq -r ".TagSet[0].Value")
|
||||
[[ $tag_val == "$expected_tag_val" ]] || fail "tag mismatch ($tag_val, $expected_tag_val)"
|
||||
run put_object_legal_hold "$BUCKET_ONE_NAME" "$bucket_file" "OFF"
|
||||
assert_success
|
||||
|
||||
put_object_legal_hold "$BUCKET_ONE_NAME" "$bucket_file" "OFF" || fail "error disabling legal hold"
|
||||
head_object "s3api" "$BUCKET_ONE_NAME" "$bucket_file" || fail "error getting metadata"
|
||||
run get_and_check_legal_hold "s3api" "$BUCKET_ONE_NAME" "$bucket_file" "OFF"
|
||||
assert_success
|
||||
|
||||
get_object "s3api" "$BUCKET_ONE_NAME" "$bucket_file" "$TEST_FILE_FOLDER/$bucket_file-copy" || fail "error getting object"
|
||||
compare_files "$TEST_FILE_FOLDER/$bucket_file" "$TEST_FILE_FOLDER/$bucket_file-copy" || fail "files not equal"
|
||||
|
||||
sleep 15
|
||||
|
||||
delete_bucket_or_contents "aws" "$BUCKET_ONE_NAME"
|
||||
delete_test_files $bucket_file
|
||||
run download_and_compare_file "s3api" "$TEST_FILE_FOLDER/$bucket_file" "$BUCKET_ONE_NAME" "$bucket_file" "$TEST_FILE_FOLDER/$bucket_file-copy" || fail "error getting object"
|
||||
assert_success
|
||||
}
|
||||
|
||||
test_delete_objects_aws_root() {
|
||||
@@ -150,18 +131,20 @@ test_delete_objects_aws_root() {
|
||||
run setup_bucket "s3api" "$BUCKET_ONE_NAME"
|
||||
assert_success
|
||||
|
||||
put_object "s3api" "$TEST_FILE_FOLDER"/"$object_one" "$BUCKET_ONE_NAME" "$object_one" || fail "error adding object one"
|
||||
put_object "s3api" "$TEST_FILE_FOLDER"/"$object_two" "$BUCKET_ONE_NAME" "$object_two" || fail "error adding object two"
|
||||
run put_object "s3api" "$TEST_FILE_FOLDER"/"$object_one" "$BUCKET_ONE_NAME" "$object_one"
|
||||
assert_success
|
||||
|
||||
delete_objects "$BUCKET_ONE_NAME" "$object_one" "$object_two" || fail "error deleting objects"
|
||||
run put_object "s3api" "$TEST_FILE_FOLDER"/"$object_two" "$BUCKET_ONE_NAME" "$object_two"
|
||||
assert_success
|
||||
|
||||
object_exists "s3api" "$BUCKET_ONE_NAME" "$object_one" || local object_one_exists_result=$?
|
||||
[[ $object_one_exists_result -eq 1 ]] || fail "object $object_one not deleted"
|
||||
object_exists "s3api" "$BUCKET_ONE_NAME" "$object_two" || local object_two_exists_result=$?
|
||||
[[ $object_two_exists_result -eq 1 ]] || fail "object $object_two not deleted"
|
||||
run delete_objects "$BUCKET_ONE_NAME" "$object_one" "$object_two"
|
||||
assert_success
|
||||
|
||||
delete_bucket_or_contents "s3api" "$BUCKET_ONE_NAME"
|
||||
delete_test_files "$object_one" "$object_two"
|
||||
run object_exists "s3api" "$BUCKET_ONE_NAME" "$object_one"
|
||||
assert_failure 1
|
||||
|
||||
run object_exists "s3api" "$BUCKET_ONE_NAME" "$object_two"
|
||||
assert_failure 1
|
||||
}
|
||||
|
||||
test_get_bucket_acl_aws_root() {
|
||||
@@ -172,14 +155,8 @@ test_get_bucket_acl_aws_root() {
|
||||
run setup_bucket "aws" "$BUCKET_ONE_NAME"
|
||||
assert_success
|
||||
|
||||
get_bucket_acl "s3api" "$BUCKET_ONE_NAME" || fail "error retreving ACL"
|
||||
|
||||
# shellcheck disable=SC2154
|
||||
log 5 "ACL: $acl"
|
||||
id=$(echo "$acl" | grep -v "InsecureRequestWarning" | jq -r '.Owner.ID')
|
||||
[[ $id == "$AWS_ACCESS_KEY_ID" ]] || fail "Acl mismatch"
|
||||
|
||||
delete_bucket_or_contents "aws" "$BUCKET_ONE_NAME"
|
||||
run get_bucket_acl_and_check_owner "s3api" "$BUCKET_ONE_NAME"
|
||||
assert_success
|
||||
}
|
||||
|
||||
test_get_object_full_range_aws_root() {
|
||||
@@ -192,9 +169,13 @@ test_get_object_full_range_aws_root() {
|
||||
run setup_bucket "s3api" "$BUCKET_ONE_NAME"
|
||||
assert_success
|
||||
|
||||
put_object "s3api" "$TEST_FILE_FOLDER/$bucket_file" "$BUCKET_ONE_NAME" "$bucket_file" || fail "error putting object"
|
||||
get_object_with_range "$BUCKET_ONE_NAME" "$bucket_file" "bytes=9-15" "$TEST_FILE_FOLDER/$bucket_file-range" || fail "error getting range"
|
||||
[[ "$(cat "$TEST_FILE_FOLDER/$bucket_file-range")" == "9" ]] || fail "byte range not copied properly"
|
||||
run put_object "s3api" "$TEST_FILE_FOLDER/$bucket_file" "$BUCKET_ONE_NAME" "$bucket_file"
|
||||
assert_success
|
||||
|
||||
run get_object_with_range "$BUCKET_ONE_NAME" "$bucket_file" "bytes=9-15" "$TEST_FILE_FOLDER/$bucket_file-range"
|
||||
assert_success
|
||||
|
||||
assert [ "$(cat "$TEST_FILE_FOLDER/$bucket_file-range")" == "9" ]
|
||||
}
|
||||
|
||||
test_get_object_invalid_range_aws_root() {
|
||||
@@ -205,9 +186,11 @@ test_get_object_invalid_range_aws_root() {
|
||||
run setup_bucket "s3api" "$BUCKET_ONE_NAME"
|
||||
assert_success
|
||||
|
||||
put_object "s3api" "$TEST_FILE_FOLDER/$bucket_file" "$BUCKET_ONE_NAME" "$bucket_file" || fail "error putting object"
|
||||
get_object_with_range "$BUCKET_ONE_NAME" "$bucket_file" "bytes=0-0" "$TEST_FILE_FOLDER/$bucket_file-range" || local get_result=$?
|
||||
[[ $get_result -ne 0 ]] || fail "Get object with zero range returned no error"
|
||||
run put_object "s3api" "$TEST_FILE_FOLDER/$bucket_file" "$BUCKET_ONE_NAME" "$bucket_file"
|
||||
assert_success
|
||||
|
||||
run get_object_with_range "$BUCKET_ONE_NAME" "$bucket_file" "bytes=0-0" "$TEST_FILE_FOLDER/$bucket_file-range"
|
||||
assert_failure
|
||||
}
|
||||
|
||||
test_put_object_aws_root() {
|
||||
@@ -227,10 +210,6 @@ test_put_object_aws_root() {
|
||||
|
||||
run download_and_compare_file "s3api" "$TEST_FILE_FOLDER/$bucket_file" "$BUCKET_ONE_NAME" "$bucket_file" "$TEST_FILE_FOLDER/${bucket_file}_copy"
|
||||
assert_success
|
||||
|
||||
delete_bucket_or_contents "aws" "$BUCKET_ONE_NAME"
|
||||
delete_bucket_or_contents "aws" "$BUCKET_TWO_NAME"
|
||||
delete_test_files "$bucket_file"
|
||||
}
|
||||
|
||||
test_create_bucket_invalid_name_aws_root() {
|
||||
@@ -238,11 +217,8 @@ test_create_bucket_invalid_name_aws_root() {
|
||||
return
|
||||
fi
|
||||
|
||||
create_bucket_invalid_name "aws" || local create_result=$?
|
||||
[[ $create_result -eq 0 ]] || fail "Invalid name test failed"
|
||||
|
||||
# shellcheck disable=SC2154
|
||||
[[ "$bucket_create_error" == *"Invalid bucket name "* ]] || fail "unexpected error: $bucket_create_error"
|
||||
run create_and_check_bucket_invalid_name "aws"
|
||||
assert_success
|
||||
}
|
||||
|
||||
test_get_object_attributes_aws_root() {
|
||||
@@ -253,17 +229,11 @@ test_get_object_attributes_aws_root() {
|
||||
run setup_bucket "s3api" "$BUCKET_ONE_NAME"
|
||||
assert_success
|
||||
|
||||
put_object "s3api" "$TEST_FILE_FOLDER/$bucket_file" "$BUCKET_ONE_NAME" "$bucket_file" || fail "failed to add object to bucket"
|
||||
get_object_attributes "$BUCKET_ONE_NAME" "$bucket_file" || failed "failed to get object attributes"
|
||||
# shellcheck disable=SC2154
|
||||
has_object_size=$(echo "$attributes" | jq 'has("ObjectSize")' 2>&1) || fail "error checking for ObjectSize parameters: $has_object_size"
|
||||
if [[ $has_object_size == "true" ]]; then
|
||||
object_size=$(echo "$attributes" | jq -r ".ObjectSize")
|
||||
[[ $object_size == 10 ]] || fail "Incorrect object size: $object_size"
|
||||
else
|
||||
fail "ObjectSize parameter missing: $attributes"
|
||||
fi
|
||||
delete_bucket_or_contents "s3api" "$BUCKET_ONE_NAME"
|
||||
run put_object "s3api" "$TEST_FILE_FOLDER/$bucket_file" "$BUCKET_ONE_NAME" "$bucket_file"
|
||||
assert_success
|
||||
|
||||
run get_and_check_object_size "$BUCKET_ONE_NAME" "$bucket_file" 10
|
||||
assert_success
|
||||
}
|
||||
|
||||
test_get_put_object_legal_hold_aws_root() {
|
||||
@@ -276,37 +246,34 @@ test_get_put_object_legal_hold_aws_root() {
|
||||
username=$USERNAME_ONE
|
||||
password=$PASSWORD_ONE
|
||||
|
||||
legal_hold_retention_setup "$username" "$password" "$bucket_file"
|
||||
run legal_hold_retention_setup "$username" "$password" "$bucket_file"
|
||||
assert_success
|
||||
|
||||
get_object_lock_configuration "$BUCKET_ONE_NAME" || fail "error getting lock configuration"
|
||||
# shellcheck disable=SC2154
|
||||
log 5 "$lock_config"
|
||||
enabled=$(echo "$lock_config" | jq -r ".ObjectLockConfiguration.ObjectLockEnabled")
|
||||
[[ $enabled == "Enabled" ]] || fail "ObjectLockEnabled should be 'Enabled', is '$enabled'"
|
||||
run get_check_object_lock_config_enabled "$BUCKET_ONE_NAME"
|
||||
assert_success
|
||||
|
||||
put_object_legal_hold "$BUCKET_ONE_NAME" "$bucket_file" "ON" || fail "error putting legal hold on object"
|
||||
get_object_legal_hold "$BUCKET_ONE_NAME" "$bucket_file" || fail "error getting object legal hold status"
|
||||
# shellcheck disable=SC2154
|
||||
log 5 "$legal_hold"
|
||||
hold_status=$(echo "$legal_hold" | grep -v "InsecureRequestWarning" | jq -r ".LegalHold.Status" 2>&1) || fail "error obtaining hold status: $hold_status"
|
||||
[[ $hold_status == "ON" ]] || fail "Status should be 'ON', is '$hold_status'"
|
||||
run put_object_legal_hold "$BUCKET_ONE_NAME" "$bucket_file" "ON"
|
||||
assert_success
|
||||
|
||||
run get_and_check_legal_hold "s3api" "$BUCKET_ONE_NAME" "$bucket_file" "ON"
|
||||
assert_success
|
||||
|
||||
echo "fdkljafajkfs" > "$TEST_FILE_FOLDER/$bucket_file"
|
||||
if put_object_with_user "s3api" "$TEST_FILE_FOLDER/$bucket_file" "$BUCKET_ONE_NAME" "$bucket_file" "$username" "$password"; then
|
||||
fail "able to overwrite object with hold"
|
||||
fi
|
||||
run put_object_with_user "s3api" "$TEST_FILE_FOLDER/$bucket_file" "$BUCKET_ONE_NAME" "$bucket_file" "$username" "$password"
|
||||
assert_failure 1
|
||||
# shellcheck disable=SC2154
|
||||
#[[ $put_object_error == *"Object is WORM protected and cannot be overwritten"* ]] || fail "unexpected error message: $put_object_error"
|
||||
|
||||
if delete_object_with_user "s3api" "$BUCKET_ONE_NAME" "$bucket_file" "$username" "$password"; then
|
||||
fail "able to delete object with hold"
|
||||
fi
|
||||
run delete_object_with_user "s3api" "$BUCKET_ONE_NAME" "$bucket_file" "$username" "$password"
|
||||
assert_failure 1
|
||||
# shellcheck disable=SC2154
|
||||
[[ $delete_object_error == *"Object is WORM protected and cannot be overwritten"* ]] || fail "unexpected error message: $delete_object_error"
|
||||
put_object_legal_hold "$BUCKET_ONE_NAME" "$bucket_file" "OFF" || fail "error removing legal hold on object"
|
||||
delete_object_with_user "s3api" "$BUCKET_ONE_NAME" "$bucket_file" "$username" "$password" || fail "error deleting object after removing legal hold"
|
||||
assert_output --partial "Object is WORM protected and cannot be overwritten"
|
||||
|
||||
delete_bucket_recursive "s3api" "$BUCKET_ONE_NAME"
|
||||
run put_object_legal_hold "$BUCKET_ONE_NAME" "$bucket_file" "OFF"
|
||||
assert_success
|
||||
|
||||
run delete_object_with_user "s3api" "$BUCKET_ONE_NAME" "$bucket_file" "$username" "$password"
|
||||
assert_success
|
||||
}
|
||||
|
||||
test_get_put_object_retention_aws_root() {
|
||||
@@ -319,12 +286,11 @@ test_get_put_object_retention_aws_root() {
|
||||
skip
|
||||
fi
|
||||
|
||||
legal_hold_retention_setup "$username" "$secret_key" "$bucket_file"
|
||||
run legal_hold_retention_setup "$username" "$secret_key" "$bucket_file"
|
||||
assert_success
|
||||
|
||||
get_object_lock_configuration "$BUCKET_ONE_NAME" || fail "error getting lock configuration"
|
||||
log 5 "$lock_config"
|
||||
enabled=$(echo "$lock_config" | jq -r ".ObjectLockConfiguration.ObjectLockEnabled")
|
||||
[[ $enabled == "Enabled" ]] || fail "ObjectLockEnabled should be 'Enabled', is '$enabled'"
|
||||
run get_check_object_lock_config_enabled "$BUCKET_ONE_NAME"
|
||||
assert_success
|
||||
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
retention_date=$(TZ="UTC" date -v+5S +"%Y-%m-%dT%H:%M:%S")
|
||||
@@ -332,30 +298,23 @@ test_get_put_object_retention_aws_root() {
|
||||
retention_date=$(TZ="UTC" date -d "+5 seconds" +"%Y-%m-%dT%H:%M:%S")
|
||||
fi
|
||||
log 5 "retention date: $retention_date"
|
||||
put_object_retention "$BUCKET_ONE_NAME" "$bucket_file" "GOVERNANCE" "$retention_date" || fail "failed to add object retention"
|
||||
get_object_retention "$BUCKET_ONE_NAME" "$bucket_file" || fail "failed to get object retention"
|
||||
log 5 "$retention"
|
||||
retention=$(echo "$retention" | grep -v "InsecureRequestWarning")
|
||||
mode=$(echo "$retention" | jq -r ".Retention.Mode")
|
||||
retain_until_date=$(echo "$retention" | jq -r ".Retention.RetainUntilDate")
|
||||
[[ $mode == "GOVERNANCE" ]] || fail "retention mode should be governance, is $mode"
|
||||
[[ $retain_until_date == "$retention_date"* ]] || fail "retain until date should be $retention_date, is $retain_until_date"
|
||||
|
||||
run put_object_retention "$BUCKET_ONE_NAME" "$bucket_file" "GOVERNANCE" "$retention_date"
|
||||
assert_success
|
||||
|
||||
run get_check_object_retention "$BUCKET_ONE_NAME" "$bucket_file" "$retention_date"
|
||||
assert_success
|
||||
|
||||
echo "fdkljafajkfs" > "$TEST_FILE_FOLDER/$bucket_file"
|
||||
put_object_with_user "s3api" "$TEST_FILE_FOLDER/$bucket_file" "$BUCKET_ONE_NAME" "$bucket_file" "$username" "$secret_key" || local put_result=$?
|
||||
[[ $put_result -ne 0 ]] || fail "able to overwrite object with hold"
|
||||
run put_object_with_user "s3api" "$TEST_FILE_FOLDER/$bucket_file" "$BUCKET_ONE_NAME" "$bucket_file" "$username" "$secret_key"
|
||||
assert_failure 1
|
||||
# shellcheck disable=SC2154
|
||||
[[ $put_object_error == *"Object is WORM protected and cannot be overwritten"* ]] || fail "unexpected error message: $error"
|
||||
assert_output --partial "Object is WORM protected and cannot be overwritten"
|
||||
|
||||
delete_object_with_user "s3api" "$BUCKET_ONE_NAME" "$bucket_file" "$username" "$secret_key" || local delete_result=$?
|
||||
[[ $delete_result -ne 0 ]] || fail "able to delete object with hold"
|
||||
[[ $delete_object_error == *"Object is WORM protected and cannot be overwritten"* ]] || fail "unexpected error message: $error"
|
||||
|
||||
sleep 5
|
||||
|
||||
delete_object "s3api" "$BUCKET_ONE_NAME" "$bucket_file" || fail "error deleting object"
|
||||
delete_bucket_or_contents "s3api" "$BUCKET_ONE_NAME"
|
||||
delete_test_files "$bucket_file"
|
||||
run delete_object_with_user "s3api" "$BUCKET_ONE_NAME" "$bucket_file" "$username" "$secret_key"
|
||||
assert_failure 1
|
||||
# shellcheck disable=SC2154
|
||||
assert_output --partial "Object is WORM protected and cannot be overwritten"
|
||||
}
|
||||
|
||||
test_retention_bypass_aws_root() {
|
||||
@@ -368,12 +327,11 @@ test_retention_bypass_aws_root() {
|
||||
secret_key=$PASSWORD_ONE
|
||||
policy_file="policy_file"
|
||||
|
||||
legal_hold_retention_setup "$username" "$secret_key" "$bucket_file"
|
||||
run legal_hold_retention_setup "$username" "$secret_key" "$bucket_file"
|
||||
assert_success
|
||||
|
||||
get_object_lock_configuration "$BUCKET_ONE_NAME" || fail "error getting lock configuration"
|
||||
log 5 "$lock_config"
|
||||
enabled=$(echo "$lock_config" | jq -r ".ObjectLockConfiguration.ObjectLockEnabled")
|
||||
[[ $enabled == "Enabled" ]] || fail "ObjectLockEnabled should be 'Enabled', is '$enabled'"
|
||||
run get_check_object_lock_config_enabled "$BUCKET_ONE_NAME"
|
||||
assert_success
|
||||
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
retention_date=$(TZ="UTC" date -v+30S +"%Y-%m-%dT%H:%M:%S")
|
||||
@@ -381,28 +339,22 @@ test_retention_bypass_aws_root() {
|
||||
retention_date=$(TZ="UTC" date -d "+30 seconds" +"%Y-%m-%dT%H:%M:%S")
|
||||
fi
|
||||
log 5 "retention date: $retention_date"
|
||||
put_object_retention "$BUCKET_ONE_NAME" "$bucket_file" "GOVERNANCE" "$retention_date" || fail "failed to add object retention"
|
||||
if delete_object_with_user "s3api" "$BUCKET_ONE_NAME" "$bucket_file"; then
|
||||
log 2 "able to delete object despite retention"
|
||||
return 1
|
||||
fi
|
||||
cat <<EOF > "$TEST_FILE_FOLDER/$policy_file"
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Principal": "$username",
|
||||
"Action": ["s3:BypassGovernanceRetention","s3:DeleteObject"],
|
||||
"Resource": "arn:aws:s3:::$BUCKET_ONE_NAME/*"
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
put_bucket_policy "s3api" "$BUCKET_ONE_NAME" "$TEST_FILE_FOLDER/$policy_file" || fail "error putting bucket policy"
|
||||
delete_object_bypass_retention "$BUCKET_ONE_NAME" "$bucket_file" "$username" "$secret_key" || fail "error deleting object and bypassing retention"
|
||||
delete_bucket_or_contents "s3api" "$BUCKET_ONE_NAME"
|
||||
delete_test_files "$bucket_file" "$policy_file"
|
||||
|
||||
run put_object_retention "$BUCKET_ONE_NAME" "$bucket_file" "GOVERNANCE" "$retention_date"
|
||||
assert_success
|
||||
|
||||
run delete_object_with_user "s3api" "$BUCKET_ONE_NAME" "$bucket_file"
|
||||
assert_failure 1
|
||||
|
||||
run setup_policy_with_single_statement "$TEST_FILE_FOLDER/$policy_file" "2012-10-17" "Allow" "$username" \
|
||||
"[\"s3:BypassGovernanceRetention\",\"s3:DeleteObject\"]" "arn:aws:s3:::$BUCKET_ONE_NAME/*"
|
||||
assert_success
|
||||
|
||||
run put_bucket_policy "s3api" "$BUCKET_ONE_NAME" "$TEST_FILE_FOLDER/$policy_file"
|
||||
assert_success
|
||||
|
||||
run delete_object_bypass_retention "$BUCKET_ONE_NAME" "$bucket_file" "$username" "$secret_key"
|
||||
assert_success
|
||||
}
|
||||
|
||||
legal_hold_retention_setup() {
|
||||
@@ -411,24 +363,23 @@ legal_hold_retention_setup() {
|
||||
run delete_bucket_or_contents_if_exists "s3api" "$BUCKET_ONE_NAME"
|
||||
assert_success
|
||||
|
||||
setup_user "$1" "$2" "user" || fail "error creating user if nonexistent"
|
||||
run setup_user "$1" "$2" "user"
|
||||
assert_success
|
||||
|
||||
run create_test_file "$3"
|
||||
assert_success
|
||||
|
||||
#create_bucket "s3api" "$BUCKET_ONE_NAME" || fail "error creating bucket"
|
||||
if [[ $RECREATE_BUCKETS == "true" ]]; then
|
||||
create_bucket_object_lock_enabled "$BUCKET_ONE_NAME" || fail "error creating bucket"
|
||||
run create_bucket_object_lock_enabled "$BUCKET_ONE_NAME"
|
||||
assert_success
|
||||
fi
|
||||
change_bucket_owner "$AWS_ACCESS_KEY_ID" "$AWS_SECRET_ACCESS_KEY" "$BUCKET_ONE_NAME" "$1" || fail "error changing bucket ownership"
|
||||
get_bucket_policy "s3api" "$BUCKET_ONE_NAME" || fail "error getting bucket policy"
|
||||
# shellcheck disable=SC2154
|
||||
log 5 "POLICY: $bucket_policy"
|
||||
get_bucket_owner "$BUCKET_ONE_NAME"
|
||||
# shellcheck disable=SC2154
|
||||
log 5 "owner: $bucket_owner"
|
||||
#put_bucket_ownership_controls "$BUCKET_ONE_NAME" "BucketOwnerPreferred" || fail "error putting bucket ownership controls"
|
||||
put_object_with_user "s3api" "$TEST_FILE_FOLDER/$3" "$BUCKET_ONE_NAME" "$3" "$1" "$2" || fail "failed to add object to bucket"
|
||||
|
||||
run change_bucket_owner "$AWS_ACCESS_KEY_ID" "$AWS_SECRET_ACCESS_KEY" "$BUCKET_ONE_NAME" "$1"
|
||||
assert_success
|
||||
|
||||
run put_object_with_user "s3api" "$TEST_FILE_FOLDER/$3" "$BUCKET_ONE_NAME" "$3" "$1" "$2"
|
||||
assert_success
|
||||
}
|
||||
|
||||
test_s3api_list_objects_v1_aws_root() {
|
||||
@@ -441,95 +392,50 @@ test_s3api_list_objects_v1_aws_root() {
|
||||
run setup_bucket "aws" "$BUCKET_ONE_NAME"
|
||||
assert_success
|
||||
|
||||
put_object "s3api" "$TEST_FILE_FOLDER"/"$object_one" "$BUCKET_ONE_NAME" "$object_one" || local copy_result_one=$?
|
||||
[[ $copy_result_one -eq 0 ]] || fail "Failed to add object $object_one"
|
||||
put_object "s3api" "$TEST_FILE_FOLDER"/"$object_two" "$BUCKET_ONE_NAME" "$object_two" || local copy_result_two=$?
|
||||
[[ $copy_result_two -eq 0 ]] || fail "Failed to add object $object_two"
|
||||
run put_object "s3api" "$TEST_FILE_FOLDER"/"$object_one" "$BUCKET_ONE_NAME" "$object_one"
|
||||
assert_success
|
||||
|
||||
list_objects_s3api_v1 "$BUCKET_ONE_NAME"
|
||||
# shellcheck disable=SC2154
|
||||
key_one=$(echo "$objects" | jq -r '.Contents[0].Key')
|
||||
[[ $key_one == "$object_one" ]] || fail "Object one mismatch ($key_one, $object_one)"
|
||||
size_one=$(echo "$objects" | jq -r '.Contents[0].Size')
|
||||
[[ $size_one -eq 10 ]] || fail "Object one size mismatch ($size_one, 0)"
|
||||
key_two=$(echo "$objects" | jq -r '.Contents[1].Key')
|
||||
[[ $key_two == "$object_two" ]] || fail "Object two mismatch ($key_two, $object_two)"
|
||||
size_two=$(echo "$objects" | jq '.Contents[1].Size')
|
||||
[[ $size_two -eq 10 ]] || fail "Object two size mismatch ($size_two, 10)"
|
||||
run put_object "s3api" "$TEST_FILE_FOLDER"/"$object_two" "$BUCKET_ONE_NAME" "$object_two"
|
||||
assert_success
|
||||
|
||||
delete_bucket_or_contents "aws" "$BUCKET_ONE_NAME"
|
||||
delete_test_files "$object_one" "$object_two"
|
||||
run list_check_objects_v1 "$BUCKET_ONE_NAME" "$object_one" 10 "$object_two" 10
|
||||
assert_success
|
||||
}
|
||||
|
||||
test_s3api_list_objects_v2_aws_root() {
|
||||
local object_one="test-file-one"
|
||||
local object_two="test-file-two"
|
||||
|
||||
run create_test_files "$object_one" "$object_two"
|
||||
assert_success
|
||||
|
||||
run setup_bucket "aws" "$BUCKET_ONE_NAME"
|
||||
assert_success
|
||||
|
||||
put_object "s3api" "$TEST_FILE_FOLDER"/"$object_one" "$BUCKET_ONE_NAME" "$object_one" || local copy_object_one=$?
|
||||
[[ $copy_object_one -eq 0 ]] || fail "Failed to add object $object_one"
|
||||
put_object "s3api" "$TEST_FILE_FOLDER"/"$object_two" "$BUCKET_ONE_NAME" "$object_two" || local copy_object_two=$?
|
||||
[[ $copy_object_two -eq 0 ]] || fail "Failed to add object $object_two"
|
||||
run put_object "s3api" "$TEST_FILE_FOLDER"/"$object_one" "$BUCKET_ONE_NAME" "$object_one"
|
||||
assert_success
|
||||
|
||||
list_objects_v2 "$BUCKET_ONE_NAME" || fail "error listing objects (v2)"
|
||||
key_one=$(echo "$objects" | jq -r '.Contents[0].Key')
|
||||
[[ $key_one == "$object_one" ]] || fail "Object one mismatch ($key_one, $object_one)"
|
||||
size_one=$(echo "$objects" | jq -r '.Contents[0].Size')
|
||||
[[ $size_one -eq 10 ]] || fail "Object one size mismatch ($size_one, 10)"
|
||||
key_two=$(echo "$objects" | jq -r '.Contents[1].Key')
|
||||
[[ $key_two == "$object_two" ]] || fail "Object two mismatch ($key_two, $object_two)"
|
||||
size_two=$(echo "$objects" | jq -r '.Contents[1].Size')
|
||||
[[ $size_two -eq 10 ]] || fail "Object two size mismatch ($size_two, 10)"
|
||||
run put_object "s3api" "$TEST_FILE_FOLDER"/"$object_two" "$BUCKET_ONE_NAME" "$object_two"
|
||||
assert_success
|
||||
|
||||
delete_bucket_or_contents "aws" "$BUCKET_ONE_NAME"
|
||||
delete_test_files "$object_one" "$object_two"
|
||||
run list_check_objects_v2 "$BUCKET_ONE_NAME" "$object_one" 10 "$object_two" 10
|
||||
assert_success
|
||||
}
|
||||
|
||||
test_multipart_upload_list_parts_aws_root() {
|
||||
local bucket_file="bucket-file"
|
||||
|
||||
run create_test_file "$bucket_file"
|
||||
run create_test_file "$bucket_file" 0
|
||||
assert_success
|
||||
run dd if=/dev/urandom of="$TEST_FILE_FOLDER/$bucket_file" bs=5M count=1
|
||||
assert_success
|
||||
dd if=/dev/urandom of="$TEST_FILE_FOLDER/$bucket_file" bs=5M count=1 || fail "error filling test file"
|
||||
|
||||
run setup_bucket "aws" "$BUCKET_ONE_NAME"
|
||||
assert_success
|
||||
|
||||
start_multipart_upload_and_list_parts "$BUCKET_ONE_NAME" "$bucket_file" "$TEST_FILE_FOLDER"/"$bucket_file" 4 || fail "listing multipart upload parts failed"
|
||||
run start_multipart_upload_list_check_parts "$BUCKET_ONE_NAME" "$bucket_file" "$TEST_FILE_FOLDER"/"$bucket_file"
|
||||
assert_success
|
||||
|
||||
declare -a parts_map
|
||||
# shellcheck disable=SC2154
|
||||
log 5 "parts: $parts"
|
||||
for i in {0..3}; do
|
||||
local part_number
|
||||
local etag
|
||||
# shellcheck disable=SC2154
|
||||
part=$(echo "$parts" | grep -v "InsecureRequestWarning" | jq -r ".[$i]" 2>&1) || fail "error getting part: $part"
|
||||
part_number=$(echo "$part" | jq ".PartNumber" 2>&1) || fail "error parsing part number: $part_number"
|
||||
[[ $part_number != "" ]] || fail "error: blank part number"
|
||||
|
||||
etag=$(echo "$part" | jq ".ETag" 2>&1) || fail "error parsing etag: $etag"
|
||||
[[ $etag != "" ]] || fail "error: blank etag"
|
||||
# shellcheck disable=SC2004
|
||||
parts_map[$part_number]=$etag
|
||||
done
|
||||
[[ ${#parts_map[@]} -ne 0 ]] || fail "error loading multipart upload parts to check"
|
||||
|
||||
for i in {0..3}; do
|
||||
local part_number
|
||||
local etag
|
||||
# shellcheck disable=SC2154
|
||||
listed_part=$(echo "$listed_parts" | grep -v "InsecureRequestWarning" | jq -r ".Parts[$i]" 2>&1) || fail "error parsing listed part: $listed_part"
|
||||
part_number=$(echo "$listed_part" | jq ".PartNumber" 2>&1) || fail "error parsing listed part number: $part_number"
|
||||
etag=$(echo "$listed_part" | jq ".ETag" 2>&1) || fail "error getting listed etag: $etag"
|
||||
[[ ${parts_map[$part_number]} == "$etag" ]] || fail "error: etags don't match (part number: $part_number, etags ${parts_map[$part_number]},$etag)"
|
||||
done
|
||||
|
||||
run_then_abort_multipart_upload "$BUCKET_ONE_NAME" "$bucket_file" "$TEST_FILE_FOLDER/$bucket_file" 4
|
||||
delete_bucket_or_contents "aws" "$BUCKET_ONE_NAME"
|
||||
delete_test_files $bucket_file
|
||||
run run_then_abort_multipart_upload "$BUCKET_ONE_NAME" "$bucket_file" "$TEST_FILE_FOLDER/$bucket_file" 4
|
||||
assert_success
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
source ./tests/test_common.sh
|
||||
source ./tests/setup.sh
|
||||
source ./tests/util_bucket_create.sh
|
||||
source ./tests/util_create_bucket.sh
|
||||
source ./tests/commands/delete_bucket_policy.sh
|
||||
source ./tests/commands/get_bucket_policy.sh
|
||||
source ./tests/commands/put_bucket_policy.sh
|
||||
|
||||
33
tests/test_rest.sh
Executable file
33
tests/test_rest.sh
Executable file
@@ -0,0 +1,33 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
source ./tests/commands/list_buckets.sh
|
||||
source ./tests/commands/put_object.sh
|
||||
source ./tests/logger.sh
|
||||
source ./tests/setup.sh
|
||||
source ./tests/util.sh
|
||||
source ./tests/util_rest.sh
|
||||
source ./tests/util_list_buckets.sh
|
||||
source ./tests/util_list_objects.sh
|
||||
|
||||
@test "test_rest_list_objects" {
|
||||
run setup_bucket "s3api" "$BUCKET_ONE_NAME"
|
||||
assert_success
|
||||
|
||||
test_file="test_file"
|
||||
run create_test_files "$test_file"
|
||||
assert_success
|
||||
|
||||
run put_object "s3api" "$TEST_FILE_FOLDER/$test_file" "$BUCKET_ONE_NAME" "$test_file"
|
||||
assert_success
|
||||
|
||||
run list_check_objects_rest "$BUCKET_ONE_NAME"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "test_authorization_list_buckets" {
|
||||
run setup_bucket "s3api" "$BUCKET_ONE_NAME"
|
||||
assert_success
|
||||
|
||||
run list_check_buckets_rest
|
||||
assert_success
|
||||
}
|
||||
@@ -20,7 +20,7 @@ load ./bats-assert/load
|
||||
source ./tests/setup.sh
|
||||
source ./tests/util.sh
|
||||
source ./tests/util_aws.sh
|
||||
source ./tests/util_bucket_create.sh
|
||||
source ./tests/util_create_bucket.sh
|
||||
source ./tests/util_file.sh
|
||||
source ./tests/util_lock_config.sh
|
||||
source ./tests/util_users.sh
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
source ./tests/setup.sh
|
||||
source ./tests/test_common.sh
|
||||
source ./tests/util.sh
|
||||
source ./tests/util_bucket_create.sh
|
||||
source ./tests/util_create_bucket.sh
|
||||
source ./tests/util_users.sh
|
||||
source ./tests/commands/delete_bucket_policy.sh
|
||||
source ./tests/commands/get_bucket_policy.sh
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
source ./tests/setup.sh
|
||||
source ./tests/util_users.sh
|
||||
source ./tests/util.sh
|
||||
source ./tests/util_bucket_create.sh
|
||||
source ./tests/util_create_bucket.sh
|
||||
source ./tests/commands/list_buckets.sh
|
||||
|
||||
test_admin_user() {
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
source ./tests/util_bucket_create.sh
|
||||
source ./tests/util_create_bucket.sh
|
||||
source ./tests/util_mc.sh
|
||||
source ./tests/logger.sh
|
||||
source ./tests/commands/abort_multipart_upload.sh
|
||||
|
||||
@@ -41,3 +41,21 @@ create_bucket_invalid_name() {
|
||||
fi
|
||||
export bucket_create_error
|
||||
}
|
||||
|
||||
create_and_check_bucket_invalid_name() {
|
||||
if [ $# -ne 1 ]; then
|
||||
log 2 "'create_and_check_bucket_invalid_name' requires client"
|
||||
return 1
|
||||
fi
|
||||
if ! create_bucket_invalid_name "$1"; then
|
||||
log 2 "error creating bucket with invalid name"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# shellcheck disable=SC2154
|
||||
if [[ "$bucket_create_error" != *"Invalid bucket name "* ]]; then
|
||||
log 2 "unexpected error: $bucket_create_error"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
31
tests/util_get_bucket_acl.sh
Normal file
31
tests/util_get_bucket_acl.sh
Normal file
@@ -0,0 +1,31 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright 2024 Versity Software
|
||||
# This file is 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 the License at
|
||||
#
|
||||
# http:#www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
get_bucket_acl_and_check_owner() {
|
||||
if [ $# -ne 2 ]; then
|
||||
log 2 "'get_acl_and_check_owner' requires client, bucket name"
|
||||
return 1
|
||||
fi
|
||||
if ! get_bucket_acl "$1" "$2"; then
|
||||
log 2 "error getting bucket acl"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# shellcheck disable=SC2154
|
||||
log 5 "ACL: $acl"
|
||||
id=$(echo "$acl" | jq -r '.Owner.ID')
|
||||
[[ $id == "$AWS_ACCESS_KEY_ID" ]] || fail "Acl mismatch"
|
||||
}
|
||||
44
tests/util_get_object_attributes.sh
Normal file
44
tests/util_get_object_attributes.sh
Normal file
@@ -0,0 +1,44 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright 2024 Versity Software
|
||||
# This file is 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 the License at
|
||||
#
|
||||
# http:#www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
get_and_check_object_size() {
|
||||
if [ $# -ne 3 ]; then
|
||||
log 2 "'get_and_check_object_size' requires bucket, key, object size"
|
||||
return 1
|
||||
fi
|
||||
if ! get_object_attributes "$1" "$2"; then
|
||||
log 2 "failed to get object attributes"
|
||||
return 1
|
||||
fi
|
||||
# shellcheck disable=SC2154
|
||||
if ! has_object_size=$(echo "$attributes" | jq 'has("ObjectSize")' 2>&1); then
|
||||
log 2 "error checking for ObjectSize parameters: $has_object_size"
|
||||
return 1
|
||||
fi
|
||||
if [[ $has_object_size != "true" ]]; then
|
||||
log 2 "ObjectSize parameter missing: $attributes"
|
||||
return 1
|
||||
fi
|
||||
if ! object_size=$(echo "$attributes" | jq -r ".ObjectSize" 2>&1); then
|
||||
log 2 "error getting object size: $object_size"
|
||||
return 1
|
||||
fi
|
||||
if [[ $object_size != "$3" ]]; then
|
||||
log 2 "Incorrect object size: $object_size"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
46
tests/util_get_object_retention.sh
Normal file
46
tests/util_get_object_retention.sh
Normal file
@@ -0,0 +1,46 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright 2024 Versity Software
|
||||
# This file is 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 the License at
|
||||
#
|
||||
# http:#www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
get_check_object_retention() {
|
||||
if [ $# -ne 3 ]; then
|
||||
log 2 "'get_check_object_retention' requires bucket, file, expected retention date"
|
||||
return 1
|
||||
fi
|
||||
# shellcheck disable=SC2154
|
||||
if ! get_object_retention "$BUCKET_ONE_NAME" "$bucket_file"; then
|
||||
log 2 "failed to get object retention"
|
||||
return 1
|
||||
fi
|
||||
log 5 "RETENTION: $retention"
|
||||
retention=$(echo "$retention" | grep -v "InsecureRequestWarning")
|
||||
if ! mode=$(echo "$retention" | jq -r ".Retention.Mode" 2>&1); then
|
||||
log 2 "error getting retention mode: $mode"
|
||||
return 1
|
||||
fi
|
||||
if ! retain_until_date=$(echo "$retention" | jq -r ".Retention.RetainUntilDate" 2>&1); then
|
||||
log 2 "error getting retain until date: $retain_until_date"
|
||||
return 1
|
||||
fi
|
||||
if [[ $mode != "GOVERNANCE" ]]; then
|
||||
log 2 "retention mode should be governance, is $mode"
|
||||
return 1
|
||||
fi
|
||||
if [[ $retain_until_date != "$3"* ]]; then
|
||||
log 2 "retain until date should be $3, is $retain_until_date"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
72
tests/util_head_object.sh
Normal file
72
tests/util_head_object.sh
Normal file
@@ -0,0 +1,72 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright 2024 Versity Software
|
||||
# This file is 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 the License at
|
||||
#
|
||||
# http:#www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
get_and_verify_metadata() {
|
||||
if [ $# -ne 7 ]; then
|
||||
log 2 "'get_and_verify_metadata' requires bucket file, expected content type,
|
||||
expected metadata key, expected metadata val, expected hold status, expected retention mode, expected retention date"
|
||||
return 1
|
||||
fi
|
||||
if ! head_object "s3api" "$BUCKET_ONE_NAME" "$1"; then
|
||||
log 2 "error retrieving metadata"
|
||||
return 1
|
||||
fi
|
||||
# shellcheck disable=SC2154
|
||||
raw_metadata=$(echo "$metadata" | grep -v "InsecureRequestWarning")
|
||||
log 5 "raw metadata: $raw_metadata"
|
||||
|
||||
if ! content_type=$(echo "$raw_metadata" | jq -r ".ContentType" 2>&1); then
|
||||
log 2 "error retrieving content type: $content_type"
|
||||
return 1
|
||||
fi
|
||||
if [[ $content_type != "$2" ]]; then
|
||||
log 2 "content type mismatch ($content_type, $2)"
|
||||
return 1
|
||||
fi
|
||||
if ! meta_val=$(echo "$raw_metadata" | jq -r ".Metadata.$3" 2>&1); then
|
||||
log 2 "error retrieving metadata val: $meta_val"
|
||||
return 1
|
||||
fi
|
||||
if [[ $meta_val != "$4" ]]; then
|
||||
log 2 "metadata val mismatch ($meta_val, $4)"
|
||||
return 1
|
||||
fi
|
||||
if ! hold_status=$(echo "$raw_metadata" | jq -r ".ObjectLockLegalHoldStatus" 2>&1); then
|
||||
log 2 "error retrieving hold status: $hold_status"
|
||||
return 1
|
||||
fi
|
||||
if [[ $hold_status != "$5" ]]; then
|
||||
log 2 "hold status mismatch ($hold_status, $5)"
|
||||
return 1
|
||||
fi
|
||||
if ! retention_mode=$(echo "$raw_metadata" | jq -r ".ObjectLockMode" 2>&1); then
|
||||
log 2 "error retrieving retention mode: $retention_mode"
|
||||
return 1
|
||||
fi
|
||||
if [[ $retention_mode != "$6" ]]; then
|
||||
log 2 "retention mode mismatch ($retention_mode, $6)"
|
||||
return 1
|
||||
fi
|
||||
if ! retain_until_date=$(echo "$raw_metadata" | jq -r ".ObjectLockRetainUntilDate" 2>&1); then
|
||||
log 2 "error retrieving retain until date: $retain_until_date"
|
||||
return 1
|
||||
fi
|
||||
if [[ $retain_until_date != "$7"* ]]; then
|
||||
log 2"retention date mismatch ($retain_until_date, $7)"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
38
tests/util_legal_hold.sh
Normal file
38
tests/util_legal_hold.sh
Normal file
@@ -0,0 +1,38 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright 2024 Versity Software
|
||||
# This file is 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 the License at
|
||||
#
|
||||
# http:#www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
get_and_check_legal_hold() {
|
||||
if [ $# -ne 4 ]; then
|
||||
log 2 "'get_and_check_legal_hold' requires client, bucket, key, expected status"
|
||||
return 1
|
||||
fi
|
||||
if ! head_object "$1" "$2" "$3"; then
|
||||
log 2 "error getting object metadata"
|
||||
return 1
|
||||
fi
|
||||
# shellcheck disable=SC2154
|
||||
raw_metadata=$(echo "$metadata" | grep -v "InsecureRequestWarning")
|
||||
log 5 "raw metadata: $raw_metadata"
|
||||
if ! hold_status=$(echo "$raw_metadata" | jq -r ".ObjectLockLegalHoldStatus" 2>&1); then
|
||||
log 2 "error retrieving hold status: $hold_status"
|
||||
return 1
|
||||
fi
|
||||
if [[ "$hold_status" != "$4" ]]; then
|
||||
log 2 "hold status mismatch ($hold_status, $4)"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
36
tests/util_list_buckets.sh
Normal file
36
tests/util_list_buckets.sh
Normal file
@@ -0,0 +1,36 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright 2024 Versity Software
|
||||
# This file is 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 the License at
|
||||
#
|
||||
# http:#www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
list_check_buckets_rest() {
|
||||
if ! list_buckets "rest"; then
|
||||
log 2 "error listing buckets"
|
||||
return 1
|
||||
fi
|
||||
bucket_found=false
|
||||
# shellcheck disable=SC2154
|
||||
for bucket in "${bucket_array[@]}"; do
|
||||
log 5 "bucket: $bucket"
|
||||
if [[ $bucket == "$BUCKET_ONE_NAME" ]]; then
|
||||
bucket_found=true
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [[ $bucket_found == "false" ]]; then
|
||||
log 2 "bucket not found"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
121
tests/util_list_objects.sh
Normal file
121
tests/util_list_objects.sh
Normal file
@@ -0,0 +1,121 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
source ./tests/commands/list_objects_v2.sh
|
||||
|
||||
# Copyright 2024 Versity Software
|
||||
# This file is 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 the License at
|
||||
#
|
||||
# http:#www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
parse_objects_list_rest() {
|
||||
# shellcheck disable=SC2154
|
||||
object_list=$(echo "$reply" | xmllint --xpath '//*[local-name()="Key"]/text()' -)
|
||||
object_array=()
|
||||
while read -r object; do
|
||||
object_array+=("$object")
|
||||
done <<< "$object_list"
|
||||
log 5 "object array: ${object_array[*]}"
|
||||
}
|
||||
|
||||
list_check_objects_v1() {
|
||||
if [ $# -ne 5 ]; then
|
||||
log 2 "'list_check_objects_v1' requires bucket, expected key one, expected size one, expected key two, expected size two"
|
||||
return 1
|
||||
fi
|
||||
if ! list_objects_s3api_v1 "$1"; then
|
||||
log 2 "error listing objects (s3api, v1)"
|
||||
return 1
|
||||
fi
|
||||
if ! check_listed_objects "$2" "$3" "$4" "$5"; then
|
||||
log 2 "error checking listed objects"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
check_listed_objects() {
|
||||
if [ $# -ne 4 ]; then
|
||||
log 2 "'check_listed_objects' requires expected key one, expected size one, expected key two, expected size two"
|
||||
return 1
|
||||
fi
|
||||
# shellcheck disable=SC2154
|
||||
if ! key_one=$(echo "$objects" | jq -r '.Contents[0].Key' 2>&1); then
|
||||
log 2 "error obtaining key one: $key_one"
|
||||
return 1
|
||||
fi
|
||||
if [[ $key_one != "$1" ]]; then
|
||||
log 2 "Object one mismatch ($key_one, $1)"
|
||||
return 1
|
||||
fi
|
||||
if ! size_one=$(echo "$objects" | jq -r '.Contents[0].Size' 2>&1); then
|
||||
log 2 "error obtaining size one: $size_one"
|
||||
return 1
|
||||
fi
|
||||
if [[ $size_one -ne "$2" ]]; then
|
||||
log 2 "Object one size mismatch ($size_one, $2)"
|
||||
return 1
|
||||
fi
|
||||
if ! key_two=$(echo "$objects" | jq -r '.Contents[1].Key' 2>&1); then
|
||||
log 2 "error obtaining key two: $key_two"
|
||||
return 1
|
||||
fi
|
||||
if [[ $key_two != "$3" ]]; then
|
||||
log 2 "Object two mismatch ($key_two, $3)"
|
||||
return 1
|
||||
fi
|
||||
if ! size_two=$(echo "$objects" | jq '.Contents[1].Size' 2>&1); then
|
||||
log 2 "error obtaining size two: $size_two"
|
||||
return 1
|
||||
fi
|
||||
if [[ $size_two -ne "$4" ]]; then
|
||||
log 2 "Object two size mismatch ($size_two, $4)"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
list_check_objects_v2() {
|
||||
if [ $# -ne 5 ]; then
|
||||
log 2 "'list_check_objects_v1' requires bucket, expected key one, expected size one, expected key two, expected size two"
|
||||
return 1
|
||||
fi
|
||||
if ! list_objects_v2 "$1"; then
|
||||
log 2 "error listing objects (s3api, v1)"
|
||||
return 1
|
||||
fi
|
||||
if ! check_listed_objects "$2" "$3" "$4" "$5"; then
|
||||
log 2 "error checking listed objects"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
list_check_objects_rest() {
|
||||
if [ $# -ne 1 ]; then
|
||||
log 2 "'list_check_objects_rest' requires bucket name"
|
||||
return 1
|
||||
fi
|
||||
list_objects "rest" "$1"
|
||||
object_found=false
|
||||
# shellcheck disable=SC2154
|
||||
for object in "${object_array[@]}"; do
|
||||
log 5 "object: $object"
|
||||
if [[ $object == "$test_file" ]]; then
|
||||
object_found=true
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [[ $object_found == "false" ]]; then
|
||||
log 2 "object not found"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
@@ -61,4 +61,26 @@ get_and_check_object_lock_config() {
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
get_check_object_lock_config_enabled() {
|
||||
if [ $# -ne 1 ]; then
|
||||
log 2 "'get_check_object_lock_config_enabled' requires bucket name"
|
||||
return 1
|
||||
fi
|
||||
if ! get_object_lock_configuration "$1"; then
|
||||
log 2 "error getting lock configuration"
|
||||
return 1
|
||||
fi
|
||||
# shellcheck disable=SC2154
|
||||
log 5 "Lock config: $lock_config"
|
||||
if ! enabled=$(echo "$lock_config" | jq -r ".ObjectLockConfiguration.ObjectLockEnabled" 2>&1); then
|
||||
log 2 "error parsing enabled value: $enabled"
|
||||
return 1
|
||||
fi
|
||||
if [[ $enabled != "Enabled" ]]; then
|
||||
log 2 "ObjectLockEnabled should be 'Enabled', is '$enabled'"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
@@ -46,3 +46,94 @@ create_upload_and_test_parts_listing() {
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
start_multipart_upload_list_check_parts() {
|
||||
if [ $# -ne 3 ]; then
|
||||
log 2 "'start_multipart_upload_and_list_parts' requires bucket, key, original source"
|
||||
return 1
|
||||
fi
|
||||
if ! start_multipart_upload_and_list_parts "$1" "$2" "$3" 4; then
|
||||
log 2 "error starting upload"
|
||||
return 1
|
||||
fi
|
||||
|
||||
declare -a parts_map
|
||||
# shellcheck disable=SC2154
|
||||
log 5 "parts: $parts"
|
||||
for i in {0..3}; do
|
||||
if ! parse_parts_and_etags "$i"; then
|
||||
log 2 "error parsing part $i"
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
if [[ ${#parts_map[@]} -eq 0 ]]; then
|
||||
log 2 "error loading multipart upload parts to check"
|
||||
return 1
|
||||
fi
|
||||
|
||||
for i in {0..3}; do
|
||||
if ! compare_parts_to_listed_parts "$i"; then
|
||||
log 2 "error comparing parts to listed parts"
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
return 0
|
||||
}
|
||||
|
||||
parse_parts_and_etags() {
|
||||
if [ $# -ne 1 ]; then
|
||||
log 2 "'parse_parts_and_etags' requires part id"
|
||||
return 1
|
||||
fi
|
||||
local part_number
|
||||
local etag
|
||||
# shellcheck disable=SC2154
|
||||
if ! part=$(echo "$parts" | grep -v "InsecureRequestWarning" | jq -r ".[$i]" 2>&1); then
|
||||
log 2 "error getting part: $part"
|
||||
return 1
|
||||
fi
|
||||
if ! part_number=$(echo "$part" | jq ".PartNumber" 2>&1); then
|
||||
log 2 "error parsing part number: $part_number"
|
||||
return 1
|
||||
fi
|
||||
if [[ $part_number == "" ]]; then
|
||||
log 2 "error: blank part number"
|
||||
return 1
|
||||
fi
|
||||
if ! etag=$(echo "$part" | jq ".ETag" 2>&1); then
|
||||
log 2 "error parsing etag: $etag"
|
||||
return 1
|
||||
fi
|
||||
if [[ $etag == "" ]]; then
|
||||
log 2 "error: blank etag"
|
||||
return 1
|
||||
fi
|
||||
# shellcheck disable=SC2004
|
||||
parts_map[$part_number]=$etag
|
||||
}
|
||||
|
||||
compare_parts_to_listed_parts() {
|
||||
if [ $# -ne 1 ]; then
|
||||
log 2 "'compare_parts_to_listed_parts' requires part number"
|
||||
return 1
|
||||
fi
|
||||
local part_number
|
||||
local etag
|
||||
# shellcheck disable=SC2154
|
||||
if ! listed_part=$(echo "$listed_parts" | grep -v "InsecureRequestWarning" | jq -r ".Parts[$i]" 2>&1); then
|
||||
log 2 "error parsing listed part: $listed_part"
|
||||
return 1
|
||||
fi
|
||||
if ! part_number=$(echo "$listed_part" | jq ".PartNumber" 2>&1); then
|
||||
log 2 "error parsing listed part number: $part_number"
|
||||
return 1
|
||||
fi
|
||||
if ! etag=$(echo "$listed_part" | jq ".ETag" 2>&1); then
|
||||
log 2 "error getting listed etag: $etag"
|
||||
return 1
|
||||
fi
|
||||
if [[ ${parts_map[$part_number]} != "$etag" ]]; then
|
||||
log 2 "error: etags don't match (part number: $part_number, etags ${parts_map[$part_number]},$etag)"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -44,7 +44,10 @@ check_for_empty_policy() {
|
||||
|
||||
get_modified_principal() {
|
||||
log 6 "get_modified_principal"
|
||||
assert [ $# -eq 1 ]
|
||||
if [ $# -ne 1 ]; then
|
||||
log 2 "'get_modified_principal' requires principal"
|
||||
return 1
|
||||
fi
|
||||
local first_char="${1:0:1}"
|
||||
if [ "$first_char" != '{' ] && [ "$first_char" != '[' ] && [ "$first_char" != '"' ]; then
|
||||
# shellcheck disable=SC2089
|
||||
@@ -52,16 +55,40 @@ get_modified_principal() {
|
||||
else
|
||||
modified_principal=$1
|
||||
fi
|
||||
export modified_principal
|
||||
}
|
||||
|
||||
get_modified_action() {
|
||||
log 6 "get_modified_action"
|
||||
if [ $# -ne 1 ]; then
|
||||
log 2 "'get_modified_action' requires action"
|
||||
return 1
|
||||
fi
|
||||
local first_char="${1:0:1}"
|
||||
if [ "$first_char" != '{' ] && [ "$first_char" != '[' ] && [ "$first_char" != '"' ]; then
|
||||
# shellcheck disable=SC2089
|
||||
modified_action="\"$1\""
|
||||
else
|
||||
modified_action=$1
|
||||
fi
|
||||
}
|
||||
|
||||
# params: file, version, effect, principal, action, resource
|
||||
# fail on error
|
||||
setup_policy_with_single_statement() {
|
||||
log 6 "setup_policy_with_single_statement"
|
||||
assert [ $# -eq 6 ]
|
||||
if [ $# -ne 6 ]; then
|
||||
log 2 "'setup_policy_with_single_statement' requires policy file, version, effect, principal, action, resource"
|
||||
return 1
|
||||
fi
|
||||
log 5 "policy file: $1"
|
||||
get_modified_principal "$4"
|
||||
if ! get_modified_principal "$4"; then
|
||||
log 2 "error getting modified principal"
|
||||
return 1
|
||||
fi
|
||||
if ! get_modified_action "$5"; then
|
||||
log 2 "error getting modified action"
|
||||
return 1
|
||||
fi
|
||||
bash -c "cat <<EOF > $1
|
||||
{
|
||||
\"Version\": \"$2\",
|
||||
@@ -69,7 +96,7 @@ setup_policy_with_single_statement() {
|
||||
{
|
||||
\"Effect\": \"$3\",
|
||||
\"Principal\": $modified_principal,
|
||||
\"Action\": \"$5\",
|
||||
\"Action\": $modified_action,
|
||||
\"Resource\": \"$6\"
|
||||
}
|
||||
]
|
||||
@@ -81,15 +108,24 @@ EOF"
|
||||
}
|
||||
|
||||
# params: file, version, two sets: effect, principal, action, resource
|
||||
# fail on error
|
||||
# return 0 on success, 1 on error
|
||||
setup_policy_with_double_statement() {
|
||||
log 6 "setup_policy_with_double_statement"
|
||||
assert [ $# -eq 10 ]
|
||||
get_modified_principal "$4"
|
||||
if [ $# -ne 10 ]; then
|
||||
log 2 "invalid number of parameters"
|
||||
return 1
|
||||
fi
|
||||
if ! get_modified_principal "$4"; then
|
||||
log 2 "error getting first modified principal"
|
||||
return 1
|
||||
fi
|
||||
principal_one=$modified_principal
|
||||
get_modified_principal "$8"
|
||||
if ! get_modified_principal "$8"; then
|
||||
log 2 "error getting second modified principal"
|
||||
return 1
|
||||
fi
|
||||
principal_two=$modified_principal
|
||||
run bash -c "cat <<EOF > $1
|
||||
bash -c "cat <<EOF > $1
|
||||
{
|
||||
\"Version\": \"$2\",
|
||||
\"Statement\": [
|
||||
@@ -109,6 +145,5 @@ setup_policy_with_double_statement() {
|
||||
}
|
||||
EOF"
|
||||
# shellcheck disable=SC2154
|
||||
assert_success "failed to set up policy: $output"
|
||||
log 5 "policy data: $(cat "$1")"
|
||||
}
|
||||
145
tests/util_rest.sh
Normal file
145
tests/util_rest.sh
Normal file
@@ -0,0 +1,145 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
parse_bucket_list() {
|
||||
# shellcheck disable=SC2154
|
||||
bucket_list=$(echo "$reply" | xmllint --xpath '//*[local-name()="Bucket"]/*[local-name()="Name"]/text()' -)
|
||||
bucket_array=()
|
||||
while read -r bucket; do
|
||||
bucket_array+=("$bucket")
|
||||
done <<< "$bucket_list"
|
||||
log 5 "bucket array: ${bucket_array[*]}"
|
||||
}
|
||||
|
||||
parse_object_list() {
|
||||
object_list=$(echo "$reply" | xmllint --xpath '//*[local-name()="Bucket"]/*[local-name()="Name"]/text()' -)
|
||||
object_array=()
|
||||
while read -r object; do
|
||||
object_array+=("$object")
|
||||
done <<< "$object_list"
|
||||
log 5 "object array: ${object_array[*]}"
|
||||
}
|
||||
|
||||
get_signature() {
|
||||
date_key=$(echo -n "$ymd" | openssl dgst -sha256 -mac HMAC -macopt key:"AWS4${AWS_SECRET_ACCESS_KEY}" | awk '{print $2}')
|
||||
date_region_key=$(echo -n "$AWS_REGION" | openssl dgst -sha256 -mac HMAC -macopt hexkey:"$date_key" | awk '{print $2}')
|
||||
date_region_service_key=$(echo -n "s3" | openssl dgst -sha256 -mac HMAC -macopt hexkey:"$date_region_key" | awk '{print $2}')
|
||||
signing_key=$(echo -n "aws4_request" | openssl dgst -sha256 -mac HMAC -macopt hexkey:"$date_region_service_key" | awk '{print $2}')
|
||||
# shellcheck disable=SC2034
|
||||
signature=$(echo -n "$sts_data" | openssl dgst -sha256 \
|
||||
-mac HMAC \
|
||||
-macopt hexkey:"$signing_key" | awk '{print $2}')
|
||||
}
|
||||
|
||||
hmac_sha256() {
|
||||
key="$1"
|
||||
data="$2"
|
||||
#echo "key: $1"
|
||||
echo -n "$data" | openssl dgst -sha256 -mac HMAC -macopt "$key" | sed 's/^.* //'
|
||||
}
|
||||
|
||||
send_rest_command_no_payload_no_bucket() {
|
||||
generate_hash_for_payload ""
|
||||
get_creq_string
|
||||
}
|
||||
|
||||
send_rest_command_no_payload() {
|
||||
if [ $# -ne 1 ]; then
|
||||
log 2 "'send_rest_command_no_payload' requires payload"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
generate_hash_for_payload() {
|
||||
if [ $# -ne 1 ]; then
|
||||
log 2 "'generate_hash_for_payload' requires payload string"
|
||||
return 1
|
||||
fi
|
||||
payload_hash="$(echo -n "$1" | sha256sum | awk '{print $1}')"
|
||||
}
|
||||
|
||||
get_creq_string_list_buckets() {
|
||||
|
||||
current_date_time=$(date -u +"%Y%m%dT%H%M%SZ")
|
||||
canonical_request="GET
|
||||
/
|
||||
|
||||
host:${AWS_ENDPOINT_URL#*//}
|
||||
x-amz-content-sha256:$payload_hash
|
||||
x-amz-date:$current_date_time
|
||||
|
||||
host;x-amz-content-sha256;x-amz-date
|
||||
$payload_hash"
|
||||
}
|
||||
|
||||
generate_creq_file() {
|
||||
if [ $# -ne 3 ]; then
|
||||
log 2 "'generate_creq_file' command requires bucket name, creq file name, hash"
|
||||
return 1
|
||||
fi
|
||||
current_time=$(date -u +"%Y%m%dT%H%M%SZ")
|
||||
cat <<EOF > "$2"
|
||||
GET
|
||||
/
|
||||
|
||||
host:$1.s3.amazonaws.com
|
||||
x-amz-content-sha256:$3
|
||||
x-amz-date:$current_time
|
||||
|
||||
host;x-amz-content-sha256;x-amz-date
|
||||
$3
|
||||
EOF
|
||||
|
||||
canonical_request="GET
|
||||
/
|
||||
|
||||
host:$1.s3.amazonaws.com
|
||||
x-amz-content-sha256:$3
|
||||
x-amz-date:$current_time
|
||||
|
||||
host;x-amz-content-sha256;x-amz-date
|
||||
$3"
|
||||
echo "canonical: $canonical_request"
|
||||
|
||||
echo "TEST CREQ"
|
||||
cat test.creq
|
||||
}
|
||||
|
||||
generate_sts_string() {
|
||||
if [ $# -ne 2 ]; then
|
||||
log 2 "'generate_sts_string' requires current date and time, canonical request string"
|
||||
return 1
|
||||
fi
|
||||
|
||||
ymd=$(echo "$1" | cut -c1-8)
|
||||
creq_hash="$(echo -n "$2" | openssl dgst -sha256 | awk '{print $2}')"
|
||||
sts_data="AWS4-HMAC-SHA256
|
||||
$1
|
||||
$ymd/$AWS_REGION/s3/aws4_request
|
||||
$creq_hash"
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
generate_sts_file() {
|
||||
if [ $# -ne 3 ]; then
|
||||
log 2 "'generate_sts_file' requires date, hash, file name"
|
||||
return 1
|
||||
fi
|
||||
ymd=$(echo "$current_time" | cut -c1-8)
|
||||
creq_hash="$(echo -n "$canonical_request" | openssl dgst -sha256 | awk '{print $2}')"
|
||||
echo "creq hash: $creq_hash"
|
||||
cat <<EOF > "$3"
|
||||
AWS4-HMAC-SHA256
|
||||
$1
|
||||
$ymd/us-west-2/s3/aws4_request
|
||||
$creq_hash
|
||||
EOF
|
||||
sts_data="AWS4-HMAC-SHA256
|
||||
$1
|
||||
$ymd/us-west-2/s3/aws4_request
|
||||
$creq_hash"
|
||||
|
||||
echo "TEST STS"
|
||||
cat test.sts
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user