Signed-off-by: Fabian Grünbichler <f.gruenbich...@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 _______________________________________________ pve-devel mailing list pve-devel@pve.proxmox.com https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel