]> git.proxmox.com Git - pve-manager-legacy.git/commitdiff
Create ACME Plugin config.
authorWolfgang Link <w.link@proxmox.com>
Thu, 16 Apr 2020 05:18:32 +0000 (07:18 +0200)
committerThomas Lamprecht <t.lamprecht@proxmox.com>
Sun, 3 May 2020 12:10:17 +0000 (14:10 +0200)
With this configuration it is possible to use many different plugins
with different providers and users.

Signed-off-by: Wolfgang Link <w.link@proxmox.com>
PVE/API2/ACMEPlugin.pm [new file with mode: 0644]
PVE/API2/Cluster.pm
PVE/API2/Makefile
PVE/CLI/pvenode.pm
debian/control

diff --git a/PVE/API2/ACMEPlugin.pm b/PVE/API2/ACMEPlugin.pm
new file mode 100644 (file)
index 0000000..df570e6
--- /dev/null
@@ -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;
index c802d4402b4c8e86750d413a2ea5b107039bf6f1..0810da0a4477e039ed197b72876efb99b80b34b9 100644 (file)
@@ -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',
index 8554efa15ab26f6ab834c1979092fe10a2003932..28ecc0706bc55c8b0959506a96052684dbbad4cf 100644 (file)
@@ -19,6 +19,7 @@ PERLSOURCE =                  \
        Certificates.pm         \
        ACME.pm                 \
        ACMEAccount.pm          \
+       ACMEPlugin.pm           \
        NodeConfig.pm           \
        Scan.pm                 \
        Hardware.pm             \
index fd3cf52d47dba806c989d94e18cab26267f58a99..ba01b7a428f72c3025be7ab0e7746221de53b01f 100644 (file)
@@ -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 {
index edb2833d27715fbf15e1b7c6f6482dba11ac784c..5df624df06626bf12d0197ea7baeedbc21796f96 100644 (file)
@@ -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),