Files
scylladb/utils/gcp/object_storage.hh
Calle Wilund 4a5b547a86 utils::gcp::object_storage: Add client for GCP object storage
Adds a minial client for GCP object storage operations:

* Create buckets
* Delete buckets
* List bucket content
* Copy/move bucket content
* Delete bucket content
* Upload bucket content
* Download bucket content
2025-09-01 18:03:44 +00:00

149 lines
4.9 KiB
C++

/*
* Copyright (C) 2025-present ScyllaDB
*/
/*
* SPDX-License-Identifier: LicenseRef-ScyllaDB-Source-Available-1.0
*/
#pragma once
#include <variant>
#include <string>
#include <chrono>
#include <seastar/core/future.hh>
#include <seastar/core/iostream.hh>
#include <seastar/net/tls.hh>
#include "utils/rjson.hh"
#include "utils/chunked_vector.hh"
namespace utils::gcp {
struct google_credentials;
}
namespace utils::gcp::storage {
/**
* List info on a named object in a bucket
*/
struct object_info {
std::string name;
std::string content_type;
uint64_t size;
uint64_t generation;
// TODO: what info do we need?
};
/**
* Minimal GCP object storage client
*/
class client {
class impl;
class object_data_sink;
class object_data_source;
shared_ptr<impl> _impl;
public:
static const std::string DEFAULT_ENDPOINT;
client(client&&);
/**
* @endpoint - typically https://storage.googleapis.com.
* @credentials - google credentials for accessing the bucket(s). Can be nullopt, but only really useful for mockup testing.
* @certs - TLS certs (truststore). Optional TLS parameters for connecting to endpoint. Normally not required (default is
* using system trust iff endpoint is a https url)
*/
client(std::string_view endpoint, std::optional<google_credentials> credentials, shared_ptr<seastar::tls::certificate_credentials> certs={});
~client();
/**
* Creates a named bucket in project and region, using storage_class
*/
future<> create_bucket(std::string_view project, std::string_view bucket, std::string_view region = {}, std::string_view storage_class = {});
/**
* Creates a named bucket in project, using provided metadata json
* See https://cloud.google.com/storage/docs/creating-buckets
*/
future<> create_bucket(std::string_view project, rjson::value meta);
/**
* Deletes a bucket. Note: bucket must be empty.
*/
future<> delete_bucket(std::string_view bucket);
/**
* List objects in bucket. Optionally applies the @prefix as filter
*/
future<utils::chunked_vector<object_info>> list_objects(std::string_view bucket, std::string_view prefix = {});
/**
* Deletes a named object from bucket
*/
future<> delete_object(std::string_view bucket, std::string_view object_name);
/**
* Renames a named object in bucket
*/
future<> rename_object(std::string_view bucket, std::string_view object_name, std::string_view new_name);
/**
* Moves a named object from one bucket to a different one using new name
*/
future<> rename_object(std::string_view bucket, std::string_view object_name, std::string_view new_bucket, std::string_view new_name);
/**
* Copies a named object to @new_name
*/
future<> copy_object(std::string_view bucket, std::string_view object_name, std::string_view to_name);
/**
* Copies a named object to @new_bucket and @new_name
*/
future<> copy_object(std::string_view bucket, std::string_view object_name, std::string_view new_bucket, std::string_view to_name);
/**
* Creates a data_sink for uploading data to a given name in bucket.
*
* @name - name of object to create/overwrite
* @metadata - optional metadata to set in the created object.
*
* Note: this will overwrite any existing object of the same name.
*/
seastar::data_sink create_upload_sink(std::string_view bucket, std::string_view object_name, rjson::value metadata = {}) const;
/**
* Creates a data_source for reading from a named object.
*/
seastar::data_source create_download_source(std::string_view bucket, std::string_view object_name) const;
/**
* Destroys resources. Must be called before releasing object
*/
future<> close();
};
class storage_error : public std::runtime_error {
int _status;
public:
storage_error(const std::string&);
storage_error(int status, const std::string&);
// TODO: make http::status_type non-nested type, and forward declarable
int status() const {
return _status;
}
};
class permission_error : public storage_error {
public:
using mybase = storage_error;
using mybase::mybase;
};
class failed_operation : public storage_error {
public:
using mybase = storage_error;
using mybase::mybase;
};
class failed_upload_error : public failed_operation {
public:
using mybase = failed_operation;
using mybase::mybase;
};
}