From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id 9DC4B72B3A for ; Tue, 13 Apr 2021 14:17:21 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 8FF1A2A6D3 for ; Tue, 13 Apr 2021 14:16:51 +0200 (CEST) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [212.186.127.180]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS id 010402A6A8 for ; Tue, 13 Apr 2021 14:16:49 +0200 (CEST) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id C056945A73 for ; Tue, 13 Apr 2021 14:16:48 +0200 (CEST) From: =?UTF-8?q?Fabian=20Gr=C3=BCnbichler?= To: pve-devel@lists.proxmox.com Date: Tue, 13 Apr 2021 14:16:25 +0200 Message-Id: <20210413121640.3602975-8-f.gruenbichler@proxmox.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210413121640.3602975-1-f.gruenbichler@proxmox.com> References: <20210413121640.3602975-1-f.gruenbichler@proxmox.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.027 Adjusted score from AWL reputation of From: address KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment RCVD_IN_DNSWL_MED -2.3 Sender listed at https://www.dnswl.org/, medium trust SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record URIBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [rrd.pm, cluster.pm, ipcc.pm, remoteconfig.pm, corosync.pm, sshinfo.pm, datacenterconfig.pm] Subject: [pve-devel] [PATCH cluster 1/4] remote.cfg: add new config file X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 13 Apr 2021 12:17:21 -0000 with two section/entry types: pve-cluster, referencing at least one node + an API token pve-node, containing the connection information (address + optional fingerprint) Signed-off-by: Fabian Grünbichler --- 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 c8e0d2d..3c28597 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 8e93221..40782d5 100644 --- a/data/src/status.c +++ b/data/src/status.c @@ -101,6 +101,7 @@ static memdb_change_t memdb_change_array[] = { { .path = "sdn/controllers.cfg" }, { .path = "sdn/.version" }, { .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 210ea85..0f636af 100644 --- a/data/PVE/Cluster.pm +++ b/data/PVE/Cluster.pm @@ -71,6 +71,7 @@ my $observed = { 'sdn/controllers.cfg' => 1, 'sdn/.version' => 1, 'virtual-guest/cpu-models.conf' => 1, + 'remote.cfg' => 1, }; sub prepare_observed_file_basedirs { 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