With this configuration it is possible to use many different plugins with different providers and users.
Signed-off-by: Wolfgang Link <w.l...@proxmox.com> --- PVE/API2/ACMEPlugin.pm | 149 +++++++++++++++++++++++++++++++++++++++++ PVE/API2/Cluster.pm | 6 ++ PVE/API2/Makefile | 1 + PVE/CLI/pvenode.pm | 22 ++++++ debian/control | 2 + 5 files changed, 180 insertions(+) create mode 100644 PVE/API2/ACMEPlugin.pm diff --git a/PVE/API2/ACMEPlugin.pm b/PVE/API2/ACMEPlugin.pm new file mode 100644 index 00000000..df570e6a --- /dev/null +++ b/PVE/API2/ACMEPlugin.pm @@ -0,0 +1,149 @@ +package PVE::API2::ACMEPlugin; + +use strict; +use warnings; + +use PVE::ACME::Challenge; +use PVE::ACME::DNSChallenge; +use PVE::ACME::StandAlone; +use PVE::Tools qw(extract_param); +use PVE::Cluster qw(cfs_read_file cfs_write_file cfs_register_file); +use MIME::Base64; + +use base qw(PVE::RESTHandler); + +my $FILENAME = "priv/acme/plugins.cfg"; + +cfs_register_file ($FILENAME, + sub { PVE::ACME::Challenge->parse_config(@_); }, + sub { PVE::ACME::Challenge->write_config(@_); }); + +PVE::ACME::DNSChallenge->register(); +PVE::ACME::StandAlone->register(); +PVE::ACME::Challenge->init(); + +__PACKAGE__->register_method({ + name => 'get_plugin_config', + path => 'plugin', + method => 'GET', + description => "Get ACME DNS plugin configurations.", + permissions => { + check => ['perm', '/', [ 'Sys.Modily' ]], + }, + protected => 1, + parameters => { + additionalProperties => 0, + properties => { + }, + }, + returns => { + type => 'object', + }, + code => sub { + + return load_config(); + }}); + +my $encode_data_field = sub { + my ($data) = @_; + + my $encoded_data; + while ($data) { + $data =~ /^([a-zA-Z]\w*=)([\w.,-]*)(,([a-zA-Z]\w*=.*))?$/; + $encoded_data .= $1; + $encoded_data .= MIME::Base64::encode_base64($2, ''); + $encoded_data .= "," if $4; + $data = $4 ? $4 : undef; + } + return $encoded_data; +}; + +my $update_config = sub { + my ($id, $op, $type, $param) = @_; + + my $conf = load_config(); + + if ( $op eq "add" ) { + die "Section with ID: $id already exists\n" + if defined($conf->{ids}->{$id}); + $conf->{ids}->{$id}->{type} = $type; + } elsif ($op eq "del") { + delete $conf->{ids}->{$id}; + } + + foreach my $opt (keys %$param) { + my $value = $param->{$opt}; + if ($opt eq 'data'){ + $value = &$encode_data_field($value); + } + $conf->{ids}->{$id}->{$opt} = $value; + } + + PVE::Cluster::cfs_write_file($FILENAME, $conf); +}; + +__PACKAGE__->register_method({ + name => 'add_plugin', + path => 'plugin', + method => 'POST', + description => "Add ACME DNS plugin configuration.", + permissions => { + check => ['perm', '/', [ 'Sys.Modify' ]], + }, + protected => 1, + parameters => PVE::ACME::Challenge->createSchema(), + returns => { type => "null" }, + code => sub { + my ($param) = @_; + + my $id = extract_param($param, 'id'); + my $type = extract_param($param, 'type'); + + PVE::Cluster::cfs_lock_file($FILENAME, undef, $update_config, $id, "add", $type, $param); + + return undef; + }}); + +__PACKAGE__->register_method({ + name => 'delete_plugin', + path => 'plugin', + method => 'DELETE', + description => "Delete ACME DNS plugin configuration.", + permissions => { + check => ['perm', '/', [ 'Sys.Modify' ]], + }, + protected => 1, + parameters => { + additionalProperties => 0, + properties => { + id => { + description => "Plugin configuration name", + type => 'string', + }, + }, + }, + returns => { type => "null" }, + code => sub { + my ($param) = @_; + + my $id = extract_param($param, 'id'); + + PVE::Cluster::cfs_lock_file($FILENAME, undef, $update_config, $id, "del", undef, $param ); + + return undef; + }}); + +sub load_config { + + my $raw = eval { cfs_read_file($FILENAME); }; + return !$raw ? {} : $raw; +} + +sub write_conf { + my ($conf) = @_; + + my $raw = PVE::ACME::Challenge->write_config($FILENAME, $conf); + + cfs_write_file($FILENAME, $raw); +} +1; diff --git a/PVE/API2/Cluster.pm b/PVE/API2/Cluster.pm index c802d440..0810da0a 100644 --- a/PVE/API2/Cluster.pm +++ b/PVE/API2/Cluster.pm @@ -21,6 +21,7 @@ use PVE::Storage; use PVE::Tools qw(extract_param); use PVE::API2::ACMEAccount; +use PVE::API2::ACMEPlugin; use PVE::API2::Backup; use PVE::API2::Cluster::Ceph; use PVE::API2::ClusterConfig; @@ -66,6 +67,11 @@ __PACKAGE__->register_method ({ path => 'acme', }); +__PACKAGE__->register_method ({ + subclass => "PVE::API2::ACMEPlugin", + path => 'acmeplugin', +}); + __PACKAGE__->register_method ({ subclass => "PVE::API2::Cluster::Ceph", path => 'ceph', diff --git a/PVE/API2/Makefile b/PVE/API2/Makefile index 8554efa1..28ecc070 100644 --- a/PVE/API2/Makefile +++ b/PVE/API2/Makefile @@ -19,6 +19,7 @@ PERLSOURCE = \ Certificates.pm \ ACME.pm \ ACMEAccount.pm \ + ACMEPlugin.pm \ NodeConfig.pm \ Scan.pm \ Hardware.pm \ diff --git a/PVE/CLI/pvenode.pm b/PVE/CLI/pvenode.pm index fd3cf52d..ba01b7a4 100644 --- a/PVE/CLI/pvenode.pm +++ b/PVE/CLI/pvenode.pm @@ -5,6 +5,7 @@ use warnings; use PVE::API2::ACME; use PVE::API2::ACMEAccount; +use PVE::API2::ACMEPlugin; use PVE::API2::Certificates; use PVE::API2::NodeConfig; use PVE::API2::Nodes; @@ -207,6 +208,27 @@ our $cmddef = { renew => [ 'PVE::API2::ACME', 'renew_certificate', [], { node => $nodename }, $upid_exit ], revoke => [ 'PVE::API2::ACME', 'revoke_certificate', [], { node => $nodename }, $upid_exit ], }, + plugin => { + get => [ 'PVE::API2::ACMEPlugin', 'get_plugin_config', [], {}, + sub { + my $conf = shift; + print "Name\tType\tStatus\tapi\tdata\n"; + foreach my $key (keys %{$conf->{ids}} ) { + my $type = $conf->{ids}->{$key}->{type}; + my $status = $conf->{ids}->{$key}->{disable} ? + "disabled" : "active"; + my $api = $conf->{ids}->{$key}->{api} ? + $conf->{ids}->{$key}->{api} : "none"; + my $data = $conf->{ids}->{$key}->{data} ? + $conf->{ids}->{$key}->{data} : "none"; + + print "$key\t$type\t$status\t$api\t$data\n"; + } + } ], + add => [ 'PVE::API2::ACMEPlugin', 'add_plugin', ['type', 'id'] ], + del => [ 'PVE::API2::ACMEPlugin', 'delete_plugin', ['id'] ], + }, + }, wakeonlan => [ 'PVE::API2::Nodes::Nodeinfo', 'wakeonlan', [ 'node' ], {}, sub { diff --git a/debian/control b/debian/control index edb2833d..5df624df 100644 --- a/debian/control +++ b/debian/control @@ -10,6 +10,7 @@ Build-Depends: debhelper (>= 11~), libpve-cluster-perl, libpve-cluster-api-perl, libpve-common-perl, + libproxmox-acme-perl, libpve-guest-common-perl (>= 3.0-7~), libpve-http-server-perl (>= 2.0-12), libpve-storage-perl (>= 5.0-35), @@ -48,6 +49,7 @@ Depends: apt-transport-https | apt (>= 1.5~), libpve-cluster-perl, libpve-cluster-api-perl, libpve-common-perl (>= 6.0-11), + libproxmox-acme-perl, libpve-guest-common-perl (>= 3.0-3~), libpve-http-server-perl (>= 3.0-4), libpve-storage-perl (>= 6.0-1), -- 2.20.1 _______________________________________________ pve-devel mailing list pve-devel@pve.proxmox.com https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel