commit - 6f0081a0cd3775c9646b81479428172e078019f8
commit + 1f2b28aab3ce59403d35f8ed056e6a02d6972225
blob - c16eb33aecf822e6972947862da982ad25fd136a
blob + 30f9b58226f9e011b82831779ea5aefc47f56901
--- bin/configNow.pl
+++ bin/configNow.pl
use strict;
use warnings;
+use lib qw(./lib);
+use IRCNOW::ConfigNow;
+my $shellname = shift || 'bnsnet';
+my $username = shift || 'izzyb';
+my $shellConfig = new IRCNOW::ConfigNow(
+ type=>'shell',
+ shellname => $shellname,
+ username => $username,
+ ipv4 => '38.87.162.191',
+ ipv6 => '2602:fccf:1:1191::',
+ domain => 'user.planetofnix.com',
+);
-my $ipv4 = '38.87.162.191';
-my $ipv6 = '2602:fccf:1:1191::';
-my $domain = 'user.planetofnix.com';
-
-my $shellname = shift;
-my $username = shift;
-my $password = shift;
-
-
-my $shell = {
- mail_domains => qq{$shellname.$domain\n},
- mail_mailname_config => qq{$shellname.$domain\n},
- dns => qq{
-$shellname 3600 IN A $ipv4
- 3600 IN AAAA $ipv6
- 3600 IN MX 10 mail
-imap.$shellname 3600 IN CNAME imap
-pop.$shellname 3600 IN CNAME pop
-pop3.$shellname 3600 IN CNAME pop3
-smtp.$shellname 3600 IN CNAME smtp
-mail.$shellname 3600 IN CNAME mail
-_xmpp-client._tcp.$shellname 3600 IN SRV 0 5 5222 xmpp
-_xmpp-server._tcp.$shellname 3600 IN SRV 0 5 5269 xmpp
-},
- acme_client => qq{
-domain $shellname.$domain {
- domain key "/etc/ssl/private/$shellname.$domain.key"
- domain full chain certificate "/etc/ssl/$shellname.$domain.fullchain.pem"
- sign with letsencrypt
+for my $module ($shellConfig->list()) {
+ for my $file ($shellConfig->list($module)) {
+ print "$file: ".$shellConfig->filename($file) ."\n";
+ print $shellConfig->output($file) . "\n";
+ }
}
-},
- prosody_config => qq{
-VirtualHost "$shellname.$domain"
-ssl = {
- certificate = "/etc/prosody/certs/$shellname.$domain.fullchain.pem";
- key = "/etc/prosody/certs/$shellname.$domain.key";
-}
-},
-};
-my $user = {
- mail_Virtual => qq{$username\@$shellname.$domain vmail},
- mail_user => qq{$username\@$shellname.$domain: $username\@$shellname.$domain},
- mail_passwd => "$username\@$shellname.$domain:$password"."::::::userdb_quota_rule=*:storage=1G",
-};
-
-use Data::Dumper;
-print Dumper($shell);
-print Dumper($user);
-
blob - /dev/null
blob + 85a6741b472c420bba08903374d9d07528282bba (mode 644)
--- /dev/null
+++ lib/IRCNOW/ConfigNow/Module/AcmeClient.pm
+acme_client => qq{
+domain $shellname.$domain {
+ domain key "/etc/ssl/private/$shellname.$domain.key"
+ domain full chain certificate "/etc/ssl/$shellname.$domain.fullchain.pem"
+ sign with letsencrypt
+}
+
+dns => {
+ filename => "/var/nsd/zones/master/$shellname
+ varlist => [qw(shellname ipv4 ipv6)],
+ template => qq{
+%s 3600 IN A %s
+ 3600 IN AAAA %s
+},
+
blob - /dev/null
blob + b8ee5dca652b3cbb57b41bc62bc82d032d3441f9 (mode 644)
--- /dev/null
+++ lib/IRCNOW/ConfigNow/Module/Prosody.pm
+package IRCNOW::ConfigNow::Module::Prosody;
+use base qw{IRCNOW::ConfigNow::Module};
+use strict;
+use warnings;
+use Carp;
+
+sub new {
+ my $class = shift;
+ my $options = {@_};
+ my $domain = $options->{vars}->{domain} || die "{domain} is a reqired option for IRCNOW::ConfigNow::Module::Prosody";
+ return $class->SUPER::new( vars => $options->{vars}, files=>{
+ prosody => {
+ filename => "/etc/prosody/prosody.cfg.lua",
+ varlist => [qw{shellname domain}],
+ template => sub {
+ my $shellname = shift;
+ my $domain = shift;
+ return qq{
+VirtualHost "$shellname.$domain"
+ssl = {
+ certificate = "/etc/prosody/certs/$shellname.$domain.fullchain.pem";
+ key = "/etc/prosody/certs/$shellname.$domain.key";
+}
+};
+ },
+ },
+ dns => {
+ filename => "/var/nsd/zones/master/$domain",
+ varlist => [qw(shellname shellname)],
+ template => qq{
+_xmpp-client._tcp.%s 3600 IN SRV 0 5 5222 xmpp
+_xmpp-server._tcp.%s 3600 IN SRV 0 5 5269 xmpp
+},
+ },
+ });
+}
+
+1;
blob - /dev/null
blob + 78acf3dd7cdbe0e6862e5411ed3c1d4542295b4e (mode 644)
--- /dev/null
+++ lib/IRCNOW/ConfigNow/Module/SmtpDove.pm
+package IRCNOW::ConfigNow::Module::SmtpDove;
+use base qw{IRCNOW::ConfigNow::Module};
+use strict;
+use warnings;
+use Carp;
+
+sub new {
+ my $class = shift;
+ my $options = {@_};
+ my $domain = $options->{vars}->{domain} || die "{domain} is a reqired option for IRCNOW::ConfigNow::Module::SmtpDove";
+ return $class->SUPER::new( vars => $options->{vars}, files=>{
+ nsd => {
+ filename => qq{/var/nsd/zones/master/$domain},
+ varlist => ['shellname'],
+ template => sub {
+ my $shellname = shift;
+ return qq{
+$shellname 3600 IN MX 10 mail
+imap.$shellname 3600 IN CNAME imap
+pop.$shellname 3600 IN CNAME pop
+pop3.$shellname 3600 IN CNAME pop3
+smtp.$shellname 3600 IN CNAME smtp
+mail.$shellname 3600 IN CNAME mail
+ };
+ },
+ },
+ mail_domains => {
+ filename => qq{/etc/mail/domains},
+ varlist => [qw{shellname domain}],
+ template => qq{%s.%s\n},
+ },
+ mail_mailname => {
+ filename => qq{/etc/mail/mailname},
+ varlist => [qw{shellname domain}],
+ template => qq{%s.%s\n},
+ },
+ mail_Virtual => {
+ filename => qq{/etc/mail/virtuals},
+ varlist => [qw{username shellname domain}],
+ template => qq{%s@%s.%s vmail\n},
+ },
+ mail_user => {
+ filename => qq{/etc/mail/users},
+ varlist => [qw{username shellname domain username shellname domain}],
+ template => qq{%s@%s.%s: %s@%s.%s\n},
+ },
+ mail_passwd => {
+ filename => qq{/etc/mail/passwd},
+ varlist => [qw{username shellname domain password}],
+ template => qq{%s@%s.%s:%s::::::userdb_quota_rule=*:storage=1G\n},
+ },
+ });
+}
+
+sub create_shell {
+}
+sub create_user {
+}
+
+
+1;
blob - /dev/null
blob + a80dc96608099a5dbf17dc77a5fd79e5c0168644 (mode 644)
--- /dev/null
+++ lib/IRCNOW/ConfigNow/Module.pm
+package IRCNOW::ConfigNow::Module;
+use strict;
+use warnings;
+use Carp;
+
+#
+# Each module has a list of files it works with
+# Each file has to have a filename, template, and varlist
+# The template can be a sprintf string or a sub returning a string
+# The varlist will be passed as params to either
+
+# This can be used as a base class for more advanced or complicated
+# needs or by passing the params needed for a new module to new.
+
+sub new {
+ my $class =shift;
+ my $options = {@_};
+ my $self = {
+ vars => [],
+ files => {},
+ };
+ if (exists $options->{vars}) {
+ $self->{vars}= $options->{vars};
+ }
+ bless $self, $class;
+ if (exists $options->{files}) {
+ for my $file (keys %{$options->{files}}) {
+ # Insure we have the required parms; make a copy of them
+ #XXX Not sure if a deep copy is needed but loop need to verify the keys.
+ for my $k (qw{filename varlist template}) {
+ croak "Required param $k missing" unless exists $options->{files}->{$file}->{$k};
+ $self->{files}->{$file}->{$k} = $options->{files}->{$file}->{$k};
+ }
+ }
+ return $self;
+ }
+ croak "Required list of files to manipulate is missing";
+}
+
+sub list {
+ my $self = shift;
+ my @list = keys(%{$self->{files}});
+ return @list;
+}
+
+sub filename {
+ my $self = shift;
+ my $file = shift;
+ return $self->{files}->{$file}->{filename};
+}
+
+sub output {
+ my $self = shift;
+ my $file = shift || carp "File name required";
+ my @params;
+ # Specified file doesn't exist in this module
+ return unless (
+ exists $self->{files}->{$file} and
+ # Shouldn't have $file without {$file}->{template}
+ #XXX should track down where it's being defined into existance
+ exists $self->{files}->{$file}->{template}
+ );
+ my $mod = $self->{files}->{$file};
+
+ for my $param ( @{$mod->{varlist}}) {
+ # Don't have needed param so return undef
+ unless (defined $self->{vars}->{$param}) {
+ return undef;
+ }
+ push @params, $self->{vars}->{$param};
+ }
+ if (ref $mod->{template} eq 'CODE') {
+ return $mod->{template}->(@params);
+ }
+
+ return sprintf($mod->{template}, @params);
+}
+
+
+
+1;
+
blob - /dev/null
blob + beb64851249690758ad47ae26c308a43333b2075 (mode 644)
--- /dev/null
+++ lib/IRCNOW/ConfigNow.pm
+package IRCNOW::ConfigNow;
+#
+#
+#
+#
+use strict;
+use warnings;
+use Carp;
+sub new {
+ my $class = shift;
+ my $options = {@_};
+
+ # set sane defaults.
+ my $self = {
+ vars =>$options, # options could be hash template values
+ modules =>{}, # ConfigNow Modules
+ };
+ bless $self, $class;
+ # Load any modules passed in
+ if (exists $options->{modules}) {
+ for (keys %{$options->{modules}}) {
+ $self->mod_load($_,$options->{modules}->{$_});
+ }
+ }
+ # Check if a type was requested - types provide shortcuts for multiple modules.
+ if (exists $options->{type} and (lc( $options->{type} ) eq 'shell')) {
+ $self->mod_load('mail','IRCNOW::ConfigNow::Module::SmtpDove');
+ $self->mod_load('xmpp','IRCNOW::ConfigNow::Module::Prosody');
+ }
+ return $self;
+}
+
+
+sub filename {
+ my $self = shift;
+ my $file = shift;
+
+ for my $mod (keys %{$self->{modules}}) {
+ my $filename = $self->{modules}->{$mod}->filename($file);
+ return $filename if defined $filename;
+ }
+}
+
+sub list {
+ my $self = shift;
+ my $module = shift;
+ my @list;
+
+ if (defined $module and exists $self->{modules}->{$module}) {
+ @list = $self->{modules}->{$module}->list();
+
+ } else {
+ @list = keys %{$self->{modules}};
+ }
+ return @list;
+}
+
+sub output {
+ my $self = shift;
+ my $file = shift || carp "!!!!!!!!!!! undef for file:";
+ my $output = "";
+ for my $mod (keys %{$self->{modules}}) {
+ $output .= $self->{modules}->{$mod}->output($file) || "";
+ }
+
+ return $output;
+}
+
+
+sub mod_load {
+ my $self=shift;
+ my $modName=shift;
+ my $module=shift;
+ if (ref $module and $module.isa('IRCNOW::ConfigNow::Module')) {
+ # Already have an object so attach it.
+ $self->{modules}->{$modName}=$module;
+ } else {
+ # Lets assume they passed us a full module name.
+ if (not defined eval "require $module") {
+warn $@;
+ # Failed so try prepending IRCNOW::ConfigNow::
+ $module = "IRCNOW::ConfigNow::$module";
+ if (not defined eval "require $module") {
+warn $@;
+ croak "Failed to load $module";
+ }
+ }
+ }
+ # create module object and add to hash
+ my $obj = $module->new(vars => $self->{vars}) || croak 'Failed to load Module: $module';
+ $self->{modules}->{$modName}=$obj;
+ return $obj;
+}
+
+
+sub vars {
+ my $self=shift;
+ my $vars = {@_};
+ for (keys(%$vars)) {
+ $self->{vars}->{$_} = $vars->{$_};
+ }
+}
+
+
+1;
+