Только для ключей и значений вы можете использовать мой маленький Perl-скрипт 'vault-backup', который также замораживает данные, используя правильные команды хранилища.
Обратите внимание, что это НЕ создает полную резервную копию вашегоСвод! Нет никаких методов, резервируемых, или любого другого (не подлежащего перечислению) материала вне секретов. Используется только для простых ключей и значений. Это также, вероятно, не может использоваться для многострочных или двоичных значений. Вы можете исправить скрипт, чтобы поддержать это, если хотите. ;)
#!/usr/bin/perl
#
# Usage: vault-backup [<PATH> [stdout]]
use Data::Dumper;
use Storable qw(freeze thaw);
# Set vault environment variables
# Always end with a " && " for the actual command
my $setenv =
"VAULT_ADDR=https://myvault.somewhere.com:8200 && ".
"VAULT_CA_PATH=/etc/yourcertificates/ && ";
my $path = $ARGV[0] || "secret/";
if ($path!~/\/$/) {
$path="$path/";
}
push @list, getData($path);
if ($ARGV[1] eq "stdout") {
print Dumper(\@list);
} else {
my $fn="vault-backup-frozen-".time().".dat";
open W,">$fn";
print W freeze(\@list);
close W;
print STDERR "Wrote data to $fn\n";
}
sub getData {
my $path=shift;
print STDERR "Starting getData($path)\n";
my @ret=();
my $command="$setenv vault kv list -tls-skip-verify $path | tail -n+3 ";
print STDERR "starting command: $command\n";
my @lines = `$command`;
chomp @lines;
foreach my $line (@lines) {
if ($line=~/\/$/) {
my @result = getData($path.$line);
if (scalar(@result)>0) {
# Find deeper results
push @ret, @result;
} else {
# empty final dir, no values
push @ret, { path => $path.$line };
}
} else {
# Found a key!
my $command="$setenv vault kv get -tls-skip-verify $path$line";
print STDERR "starting command: $command\n";
my $values = `$command`;
push @ret, {path=>$path.$line, value=>$values};
}
}
return @ret;
}
Для восстановления данных вы можете использовать скрипт ниже. Он обрабатывает только данные, он не влияет на метаданные.
#!/usr/bin/perl
# Usage: vault-restore <backup-filename>
use Data::Dumper;
use Storable qw(thaw);
my %all_entries;
# Set vault environment variables
# Always end with a " && " for the actual command
my $setenv =
"VAULT_ADDR=https://myothervault.somewhere.com:8200 && ".
"VAULT_CA_PATH=/etc/mycertificates/ && ";
# Read the data
my $fn = $ARGV[0] || die("I need a filename with the frozen data");
open F,"<$fn";
my @list = @{ thaw(join("",<F>)) };
close F;
print STDERR "Read ".scalar(@list)." entries.\n";
# Process the data
foreach my $entry (@list) {
print STDERR "\n# adding entry -> $entry->{path}\n";
addEntry($entry);
}
foreach my $path (keys %all_entries) {
my $keyvalues="";
foreach my $key (keys %{$all_entries{$path}}) {
my $value=$all_entries{$path}{$key};
$keyvalues.="'$key=$value' ";
}
print STDERR "vault kv put $path $keyvalues\n";
# `$command`;
}
sub addEntry {
my $entry=shift;
my $path = $entry->{'path'};
if ($entry->{'value'}) {
my $values = $entry->{value};
my @list=split("\n", $values);
my $metadata_engage=0;
my $data_engage=0;
foreach my $keyvalue (@list) {
if ($keyvalue=~/==== Metadata ====/) {
$metadata_engage=1;
$data_engage=0;
} elsif ($keyvalue=~/==== Data ====/) {
$metadata_engage=0;
$data_engage=1;
} elsif ($data_engage) {
my ($key,$value)=($keyvalue=~/^([^ ]+) +(.*)$/);
if ($key ne "Key" && $key ne "---") {
# print STDERR "key=$key ; value=$value\n";
$all_entries{$path}{$key}=$value;
} else {
# print STDERR "-- separator\n";
}
}
}
} else {
print STDERR "Found a final but empty path: $path\n";
}
}