mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-22 07:31:57 +00:00
Add parameters "backups.allowed_path" and "backups.allowed_disk" to config.
This commit is contained in:
parent
508fb6f54f
commit
71359433dd
@ -14,6 +14,34 @@ namespace ErrorCodes
|
|||||||
extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH;
|
extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
/// Checks multiple keys "key", "key[1]", "key[2]", and so on in the configuration
|
||||||
|
/// and find out if some of them have matching value.
|
||||||
|
bool findConfigKeyWithMatchingValue(const Poco::Util::AbstractConfiguration & config, const String & key, const std::function<bool(const String & value)> & match_function)
|
||||||
|
{
|
||||||
|
String current_key = key;
|
||||||
|
size_t counter = 0;
|
||||||
|
while (config.has(current_key))
|
||||||
|
{
|
||||||
|
if (match_function(config.getString(current_key)))
|
||||||
|
return true;
|
||||||
|
current_key = key + "[" + std::to_string(++counter) + "]";
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isDiskAllowed(const String & disk_name, const Poco::Util::AbstractConfiguration & config)
|
||||||
|
{
|
||||||
|
return findConfigKeyWithMatchingValue(config, "backups.allowed_disk", [&](const String & value) { return value == disk_name; });
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isPathAllowed(const String & path, const Poco::Util::AbstractConfiguration & config)
|
||||||
|
{
|
||||||
|
return findConfigKeyWithMatchingValue(config, "backups.allowed_path", [&](const String & value) { return path.starts_with(value); });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
BackupInDirectory::BackupInDirectory(
|
BackupInDirectory::BackupInDirectory(
|
||||||
const String & backup_name_,
|
const String & backup_name_,
|
||||||
@ -25,10 +53,12 @@ BackupInDirectory::BackupInDirectory(
|
|||||||
: BackupImpl(backup_name_, open_mode_, context_, base_backup_info_)
|
: BackupImpl(backup_name_, open_mode_, context_, base_backup_info_)
|
||||||
, disk(disk_), path(path_)
|
, disk(disk_), path(path_)
|
||||||
{
|
{
|
||||||
|
/// Path to backup must end with '/'
|
||||||
if (path.back() != '/')
|
if (path.back() != '/')
|
||||||
throw Exception(ErrorCodes::BAD_ARGUMENTS, "Backup {}: Path to backup must end with '/', but {} doesn't.", getName(), quoteString(path));
|
throw Exception(ErrorCodes::BAD_ARGUMENTS, "Backup {}: Path to backup must end with '/', but {} doesn't.", getName(), quoteString(path));
|
||||||
dir_path = fs::path(path).parent_path(); /// get path without terminating slash
|
dir_path = fs::path(path).parent_path(); /// get path without terminating slash
|
||||||
|
|
||||||
|
/// If `disk` is not specified, we create an internal instance of `DiskLocal` here.
|
||||||
if (!disk)
|
if (!disk)
|
||||||
{
|
{
|
||||||
auto fspath = fs::path{dir_path};
|
auto fspath = fs::path{dir_path};
|
||||||
@ -99,6 +129,9 @@ void registerBackupEngineFile(BackupFactory & factory)
|
|||||||
}
|
}
|
||||||
|
|
||||||
path = args[0].safeGet<String>();
|
path = args[0].safeGet<String>();
|
||||||
|
|
||||||
|
if (!isPathAllowed(path, params.context->getConfigRef()))
|
||||||
|
throw Exception(ErrorCodes::BAD_ARGUMENTS, "Path {} is not allowed for backups", path);
|
||||||
}
|
}
|
||||||
else if (engine_name == "Disk")
|
else if (engine_name == "Disk")
|
||||||
{
|
{
|
||||||
@ -108,9 +141,13 @@ void registerBackupEngineFile(BackupFactory & factory)
|
|||||||
"Backup engine 'Disk' requires 2 arguments (disk_name, path)",
|
"Backup engine 'Disk' requires 2 arguments (disk_name, path)",
|
||||||
ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
|
ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
String disk_name = args[0].safeGet<String>();
|
String disk_name = args[0].safeGet<String>();
|
||||||
disk = params.context->getDisk(disk_name);
|
disk = params.context->getDisk(disk_name);
|
||||||
path = args[1].safeGet<String>();
|
path = args[1].safeGet<String>();
|
||||||
|
|
||||||
|
if (!isDiskAllowed(disk_name, params.context->getConfigRef()))
|
||||||
|
throw Exception(ErrorCodes::BAD_ARGUMENTS, "Disk {} is not allowed for backups", disk_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::make_shared<BackupInDirectory>(backup_name, params.open_mode, disk, path, params.context, params.base_backup_info);
|
return std::make_shared<BackupInDirectory>(backup_name, params.open_mode, disk, path, params.context, params.base_backup_info);
|
||||||
|
@ -13,6 +13,7 @@ using DiskPtr = std::shared_ptr<IDisk>;
|
|||||||
class BackupInDirectory : public BackupImpl
|
class BackupInDirectory : public BackupImpl
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
/// `disk`_ is allowed to be nullptr and that means the `path_` is a path in the local filesystem.
|
||||||
BackupInDirectory(
|
BackupInDirectory(
|
||||||
const String & backup_name_,
|
const String & backup_name_,
|
||||||
OpenMode open_mode_,
|
OpenMode open_mode_,
|
||||||
|
@ -8,4 +8,8 @@
|
|||||||
</backups>
|
</backups>
|
||||||
</disks>
|
</disks>
|
||||||
</storage_configuration>
|
</storage_configuration>
|
||||||
|
<backups>
|
||||||
|
<allowed_disk>backups</allowed_disk>
|
||||||
|
<allowed_path>/backups/</allowed_path>
|
||||||
|
</backups>
|
||||||
</clickhouse>
|
</clickhouse>
|
||||||
|
Loading…
Reference in New Issue
Block a user