package App::Acmeman::Config; use strict; use warnings; use Carp; use parent 'Config::Parser::Ini'; use Text::ParseWords; use App::Acmeman::Log qw(debug_level :sysexits); sub new { my $class = shift; my $filename = shift; my %args; if (-e $filename) { $args{filename} = $filename; } my $self = $class->SUPER::new(%args); if (!$args{filename}) { $self->commit or croak "configuration failed"; } $self } sub mangle { my $self = shift; my $err; if (debug_level() == 0 && $self->core->verbose) { debug_level($self->core->verbose); } $self->set(qw(core files default)) unless $self->is_set(qw(core files)); unless ($self->is_set(qw(files))) { if ($self->get(qw(core files)) ne 'default') { $self->error("section files." . $self->get(qw(core files))." not defined"); ++$err; } } unless ($self->is_set(qw(files default))) { $self->set(qw(files default type), 'split'); $self->set(qw(files default key-file), '/etc/ssl/acme/$domain/privkey.pem'); $self->set(qw(files default certificate-file), '/etc/ssl/acme/$domain/cert.pem'); $self->set(qw(files default ca-file), '/etc/ssl/acme/$domain/ca.pem'); } if (my $fnode = $self->getnode('files')) { while (my ($k, $v) = each %{$fnode->subtree}) { $v->set('files', $k, 'type', 'split') unless $v->has_key('type', 'split'); if ($v->subtree('type') eq 'single') { unless ($v->has_key('certificate-file')) { $self->error("files.$k.certificate-file not defined"); ++$err; } else { if ($v->has_key('key-file')) { $self->error("files.$k.key-file ignored"); } if ($v->has_key('ca-file')) { $self->error("files.$k.ca-file ignored"); } } } else { unless ($v->has_key('key-file')) { $self->error("files.$k.key-file not defined"); ++$err; } unless ($v->has_key('certificate-file')) { $self->error("files.$k.ca-file not defined"); ++$err; } } } } if (my $files = $self->get(qw(core files))) { unless ($self->is_set('files', $files)) { $self->error("files.$files is referenced from [core], but never declared"); ++$err; } } if (my @source = $self->get(qw(core source))) { $self->unset(qw(core source)); foreach my $s (@source) { my ($name, @args) = quotewords('\s+', 0, $s); my $pack = 'App::Acmeman::Source::' . ucfirst($name); my $obj = eval "use $pack; new $pack(\@args);"; if ($@) { $self->error($@); ++$err; next; } if ($obj->configure($self)) { $self->set(qw(core source), $obj); } else { ++$err; } } } exit(EX_CONFIG) if $err; } 1; __DATA__ [core] postrenew = STRING :array rootdir = STRING :default=/var/www/acme files = STRING time-delta = NUMBER :default=86400 source = STRING :default=apache :array check-alt-names = BOOL :default=0 check-dns = BOOL :default=1 my-ip = STRING :array key-size = NUMBER :default=4096 verbose = NUMBER :default=0 [files ANY] type = STRING :re="^(single|split)$" certificate-file = STRING key-file = STRING ca-file = STRING argument = STRING [domain ANY] alt = STRING :array files = STRING key-size = NUMBER postrenew = STRING