feat(aws): s3 snapshot error handling (#2002)

* feat(s3): support bucket only dir

* feat(s3): improve error handling

* chore: update helio
This commit is contained in:
Andy Dunstall 2023-10-10 13:03:46 +01:00 committed by GitHub
parent b1bd2103d7
commit f008965527
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 23 additions and 3 deletions

2
helio

@ -1 +1 @@
Subproject commit 0950c8fd612bba442caffdabd86d67a32246d461 Subproject commit 2d447ea39da78d0ec0003e812c306f2846e8e727

View File

@ -35,8 +35,9 @@ std::optional<std::pair<std::string, std::string>> GetBucketPath(std::string_vie
std::string_view clean = absl::StripPrefix(path, kS3Prefix); std::string_view clean = absl::StripPrefix(path, kS3Prefix);
size_t pos = clean.find('/'); size_t pos = clean.find('/');
if (pos == std::string_view::npos) if (pos == std::string_view::npos) {
return std::nullopt; return std::make_pair(std::string(clean), "");
}
std::string bucket_name{clean.substr(0, pos)}; std::string bucket_name{clean.substr(0, pos)};
std::string obj_path{clean.substr(pos + 1)}; std::string obj_path{clean.substr(pos + 1)};
@ -183,6 +184,7 @@ AwsS3SnapshotStorage::AwsS3SnapshotStorage(const std::string& endpoint, bool ec2
// S3ClientConfiguration may request configuration and credentials from // S3ClientConfiguration may request configuration and credentials from
// EC2 metadata so must be run in a proactor thread. // EC2 metadata so must be run in a proactor thread.
Aws::S3::S3ClientConfiguration s3_conf{}; Aws::S3::S3ClientConfiguration s3_conf{};
LOG(INFO) << "Creating AWS S3 client; region=" << s3_conf.region << "; endpoint=" << endpoint;
if (!sign_payload) { if (!sign_payload) {
s3_conf.payloadSigningPolicy = Aws::Client::AWSAuthV4Signer::PayloadSigningPolicy::ForceNever; s3_conf.payloadSigningPolicy = Aws::Client::AWSAuthV4Signer::PayloadSigningPolicy::ForceNever;
} }
@ -342,6 +344,24 @@ io::Result<std::vector<std::string>, GenericError> AwsS3SnapshotStorage::ListObj
for (const auto& object : outcome.GetResult().GetContents()) { for (const auto& object : outcome.GetResult().GetContents()) {
keys.push_back(object.GetKey()); keys.push_back(object.GetKey());
} }
} else if (outcome.GetError().GetExceptionName() == "PermanentRedirect") {
return nonstd::make_unexpected(
GenericError{"Failed list objects in S3 bucket: Permanent redirect; Ensure your "
"configured AWS region matches the S3 bucket region"});
} else if (outcome.GetError().GetErrorType() == Aws::S3::S3Errors::NO_SUCH_BUCKET) {
return nonstd::make_unexpected(GenericError{
"Failed list objects in S3 bucket: Bucket not found: " + std::string(bucket_name)});
} else if (outcome.GetError().GetErrorType() == Aws::S3::S3Errors::INVALID_ACCESS_KEY_ID) {
return nonstd::make_unexpected(
GenericError{"Failed list objects in S3 bucket: Invalid access key ID"});
} else if (outcome.GetError().GetErrorType() == Aws::S3::S3Errors::SIGNATURE_DOES_NOT_MATCH) {
return nonstd::make_unexpected(
GenericError{"Failed list objects in S3 bucket: Invalid signature; Check your AWS "
"credentials are correct"});
} else if (outcome.GetError().GetExceptionName() == "InvalidToken") {
return nonstd::make_unexpected(
GenericError{"Failed list objects in S3 bucket: Invalid token; Check your AWS "
"credentials are correct"});
} else { } else {
return nonstd::make_unexpected(GenericError{"Failed list objects in S3 bucket: " + return nonstd::make_unexpected(GenericError{"Failed list objects in S3 bucket: " +
outcome.GetError().GetExceptionName()}); outcome.GetError().GetExceptionName()});