Commit Diff


commit - 6f0081a0cd3775c9646b81479428172e078019f8
commit + 1f2b28aab3ce59403d35f8ed056e6a02d6972225
blob - c16eb33aecf822e6972947862da982ad25fd136a
blob + 30f9b58226f9e011b82831779ea5aefc47f56901
--- bin/configNow.pl
+++ bin/configNow.pl
@@ -2,56 +2,25 @@
 
 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
@@ -0,0 +1,15 @@
+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
@@ -0,0 +1,38 @@
+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
@@ -0,0 +1,61 @@
+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
@@ -0,0 +1,82 @@
+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
@@ -0,0 +1,106 @@
+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;
+