[pve-devel] [PATCH cluster 1/2] remote.cfg: add new config file
Fabian Grünbichler
f.gruenbichler at proxmox.com
Fri Mar 6 11:20:24 CET 2020
Signed-off-by: Fabian Grünbichler <f.gruenbichler at proxmox.com>
---
the secret 'token' could of course also be split out to a second file,
or just masked when returned via the API
data/PVE/Makefile | 2 +-
data/src/status.c | 1 +
data/PVE/Cluster.pm | 1 +
data/PVE/RemoteConfig.pm | 226 +++++++++++++++++++++++++++++
debian/libpve-cluster-perl.install | 1 +
5 files changed, 230 insertions(+), 1 deletion(-)
create mode 100644 data/PVE/RemoteConfig.pm
diff --git a/data/PVE/Makefile b/data/PVE/Makefile
index 8ee4900..78a2b02 100644
--- a/data/PVE/Makefile
+++ b/data/PVE/Makefile
@@ -11,7 +11,7 @@ PVE_VENDORARCH=${DESTDIR}/${PERL_VENDORARCH}/auto/PVE/IPCC
PERL_DOC_INC_DIRS:=..
SUBDIRS=Cluster CLI API2
-SOURCES=IPCC.pm Cluster.pm Corosync.pm RRD.pm DataCenterConfig.pm SSHInfo.pm
+SOURCES=IPCC.pm Cluster.pm Corosync.pm RRD.pm DataCenterConfig.pm SSHInfo.pm RemoteConfig.pm
all:
diff --git a/data/src/status.c b/data/src/status.c
index 5e0cebe..9200ad2 100644
--- a/data/src/status.c
+++ b/data/src/status.c
@@ -102,6 +102,7 @@ static memdb_change_t memdb_change_array[] = {
{ .path = "sdn/controllers.cfg" },
{ .path = "sdn/controllers.cfg.new" },
{ .path = "virtual-guest/cpu-models.conf" },
+ { .path = "remote.cfg" },
};
static GMutex mutex;
diff --git a/data/PVE/Cluster.pm b/data/PVE/Cluster.pm
index 068d626..78dc703 100644
--- a/data/PVE/Cluster.pm
+++ b/data/PVE/Cluster.pm
@@ -71,6 +71,7 @@ my $observed = {
'sdn/controllers.cfg' => 1,
'sdn/controllers.cfg.new' => 1,
'virtual-guest/cpu-models.conf' => 1,
+ 'remote.cfg' => 1,
};
sub base_dir {
diff --git a/data/PVE/RemoteConfig.pm b/data/PVE/RemoteConfig.pm
new file mode 100644
index 0000000..23274de
--- /dev/null
+++ b/data/PVE/RemoteConfig.pm
@@ -0,0 +1,226 @@
+package PVE::RemoteConfig;
+
+use strict;
+use warnings;
+
+use PVE::Cluster qw(cfs_register_file cfs_read_file cfs_write_file cfs_lock_file);
+use PVE::JSONSchema qw(get_standard_option);
+use PVE::Tools;
+
+use PVE::SectionConfig;
+
+use base qw(PVE::SectionConfig);
+
+my $remote_cfg_filename = 'remote.cfg';
+
+cfs_register_file($remote_cfg_filename,
+ sub { __PACKAGE__->parse_config(@_); },
+ sub { __PACKAGE__->write_config(@_); });
+
+my $defaultData = {
+ propertyList => {
+ type => { description => "Remote type." },
+ id => get_standard_option('pve-node', {
+ description => "Remote identifier.",
+ }),
+ comment => {
+ description => "Description.",
+ type => 'string',
+ optional => 1,
+ maxLength => 4096,
+ },
+ },
+};
+
+sub private {
+ return $defaultData;
+}
+
+sub parse_section_header {
+ my ($class, $line) = @_;
+
+ if ($line =~ m/^(\S+):\s*(\S+)\s*$/) {
+ my ($type, $id) = (lc($1), lc($2));
+ my $errmsg = undef; # set if you want to skip whole section
+ eval { PVE::JSONSchema::pve_verify_node_name($id); };
+ $errmsg = $@ if $@;
+ my $config = {};
+ return ($type, $id, $errmsg, $config);
+ }
+ return undef;
+}
+
+sub decode_value {
+ my ($class, $type, $key, $value) = @_;
+
+ my $def = $defaultData->{plugindata}->{$type};
+
+ if ($key eq 'nodes') {
+ my $res = {};
+
+ foreach my $node (PVE::Tools::split_list($value)) {
+ if (PVE::JSONSchema::pve_verify_node_name($node)) {
+ $res->{$node} = 1;
+ }
+ }
+
+ return $res;
+ }
+
+ return $value;
+}
+
+sub encode_value {
+ my ($class, $type, $key, $value) = @_;
+
+ if ($key eq 'nodes') {
+ return join(',', keys(%$value));
+ }
+
+ return $value;
+}
+
+sub parse_config {
+ my ($class, $filename, $raw) = @_;
+
+ my $cfg = $class->SUPER::parse_config($filename, $raw);
+
+ foreach my $id (sort keys %{$cfg->{ids}}) {
+ my $data = $cfg->{ids}->{$id};
+
+ if ($data->{type} eq 'cluster') {
+ my $nodes = $data->{nodes};
+ foreach my $node (keys %$nodes) {
+ my $node_data = $cfg->{ids}->{$node};
+ if (!defined($node_data)) {
+ warn "Ignoring undefined remote node '$node' in remote cluster '$id'!\n";
+ delete $nodes->{$node};
+ }
+ }
+ }
+
+ $data->{comment} = PVE::Tools::decode_text($data->{comment})
+ if defined($data->{comment});
+ }
+
+ return $cfg;
+}
+
+sub write_config {
+ my ($class, $filename, $cfg) = @_;
+
+ my $target_hash = {};
+
+ foreach my $id (keys %{$cfg->{ids}}) {
+ my $data = $cfg->{ids}->{$id};
+
+ if ($data->{type} eq 'cluster') {
+ my $nodes = $data->{nodes};
+ foreach my $node (keys %$nodes) {
+ my $node_data = $cfg->{ids}->{$node};
+ if (!defined($node_data)) {
+ warn "Ignoring undefined remote node '$node' in remote cluster '$id'!\n";
+ delete $nodes->{$node};
+ }
+ }
+ }
+
+ $data->{comment} = PVE::Tools::encode_text($data->{comment})
+ if defined($data->{comment});
+ }
+
+ return $class->SUPER::write_config($filename, $cfg);
+}
+
+sub new {
+ my ($type) = @_;
+
+ my $class = ref($type) || $type;
+
+ my $cfg = cfs_read_file($remote_cfg_filename);
+
+ return bless $cfg, $class;
+}
+
+sub write {
+ my ($cfg) = @_;
+
+ cfs_write_file($remote_cfg_filename, $cfg);
+}
+
+sub lock {
+ my ($code, $errmsg) = @_;
+
+ cfs_lock_file($remote_cfg_filename, undef, $code);
+ my $err = $@;
+ if ($err) {
+ $errmsg ? die "$errmsg: $err" : die $err;
+ }
+}
+
+package PVE::RemoteConfig::Cluster;
+
+use PVE::RemoteConfig;
+use base qw(PVE::RemoteConfig);
+
+sub type {
+ return 'pvecluster';
+}
+
+sub properties {
+ return {
+ nodes => {
+ description => "Cluster nodes.",
+ type => 'string', format => 'pve-node-list',
+ },
+ token => {
+ description => "PVE API Token",
+ type => 'string',
+ },
+ };
+}
+
+sub options {
+ return {
+ nodes => { optional => 0 },
+ comment => { optional => 1 },
+ token => { optional => 1 },
+ };
+}
+
+package PVE::RemoteConfig::Node;
+
+use PVE::JSONSchema qw(get_standard_option);
+
+use PVE::RemoteConfig;
+use base qw(PVE::RemoteConfig);
+
+sub type {
+ return 'pvenode';
+}
+
+sub properties {
+ return {
+ endpoint => {
+ description => "Remote IP/FQDN.",
+ type => 'string',
+ },
+ fingerprint => get_standard_option('fingerprint-sha256'),
+ };
+}
+
+sub options {
+ return {
+ endpoint => { optional => 0 },
+ fingerprint => { optional => 1 },
+ token => { optional => 1 },
+ comment => { optional => 1 },
+ };
+}
+
+
+PVE::RemoteConfig::Cluster->register();
+PVE::RemoteConfig::Node->register();
+PVE::RemoteConfig->init();
+
+1;
diff --git a/debian/libpve-cluster-perl.install b/debian/libpve-cluster-perl.install
index 51223f9..0610384 100644
--- a/debian/libpve-cluster-perl.install
+++ b/debian/libpve-cluster-perl.install
@@ -1,5 +1,6 @@
usr/share/man/man5/datacenter.cfg.5
usr/share/perl5/PVE/Corosync.pm
usr/share/perl5/PVE/DataCenterConfig.pm
+usr/share/perl5/PVE/RemoteConfig.pm
usr/share/perl5/PVE/RRD.pm
usr/share/perl5/PVE/SSHInfo.pm
--
2.20.1
More information about the pve-devel
mailing list