commit - aacad1502bdc25fce80270271b31ead69c9c95b7
commit + adb27c97ca6881b235c352fdf9b9c723cf979564
blob - 75d6a2cd8392a418297e7d4e3d4c24a652381759
blob + fb082187e33ef3726cfa060c46263e39c2672aea
--- bin/configNow.pl
+++ bin/configNow.pl
use File::Basename;
use File::Path qw(make_path);
-my $shellname = shift || 'bnsnet';
-my $username = shift || 'izzyb';
+my $shellname = shift || 'blacklock';
+my @users = qw( izzyb nathan ashley );
my $domain = 'user.planetofnix.com';
my %config=(
type=>'shell',
shellname => $shellname,
- username => $username,
+ users => \@users,
gitAuthor => $shellname,
gitEmail => $shellname . "@" . $domain,
gitWorkDir => './configNow',
- # configNow => './configNow',
ipv4 => '38.87.162.191',
ipv6 => '2602:fccf:1:1191::',
domain => $domain,
);
my $shellConfig = new IRCNOW::ConfigNow( %config );
+#use Data::Dumper;
+#die Dumper($shellConfig->{lists});
if ($shellConfig->repo_ready()) {
$shellConfig->write_config();
blob - b8ee5dca652b3cbb57b41bc62bc82d032d3441f9
blob + f70c6c921f3dfa9eb0326de299e1b0085ef0aff6
--- lib/IRCNOW/ConfigNow/Module/Prosody.pm
+++ lib/IRCNOW/ConfigNow/Module/Prosody.pm
prosody => {
filename => "/etc/prosody/prosody.cfg.lua",
varlist => [qw{shellname domain}],
+ type => 'shell',
template => sub {
my $shellname = shift;
my $domain = shift;
dns => {
filename => "/var/nsd/zones/master/$domain",
varlist => [qw(shellname shellname)],
+ type => 'shell',
template => qq{
_xmpp-client._tcp.%s 3600 IN SRV 0 5 5222 xmpp
_xmpp-server._tcp.%s 3600 IN SRV 0 5 5269 xmpp
blob - 78acf3dd7cdbe0e6862e5411ed3c1d4542295b4e
blob + ae759ba2a3e862a95f975afa61fea0a891b938c4
--- lib/IRCNOW/ConfigNow/Module/SmtpDove.pm
+++ lib/IRCNOW/ConfigNow/Module/SmtpDove.pm
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 => {
+ dns => {
filename => qq{/var/nsd/zones/master/$domain},
varlist => ['shellname'],
+ type => 'shell',
template => sub {
my $shellname = shift;
return qq{
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}],
+ type => 'shell',
template => qq{%s.%s\n},
},
mail_mailname => {
filename => qq{/etc/mail/mailname},
varlist => [qw{shellname domain}],
+ type => 'shell',
template => qq{%s.%s\n},
},
mail_Virtual => {
filename => qq{/etc/mail/virtuals},
varlist => [qw{username shellname domain}],
+ type => 'shelluser',
template => qq{%s@%s.%s vmail\n},
},
mail_user => {
filename => qq{/etc/mail/users},
varlist => [qw{username shellname domain username shellname domain}],
+ type => 'shelluser',
template => qq{%s@%s.%s: %s@%s.%s\n},
},
mail_passwd => {
filename => qq{/etc/mail/passwd},
varlist => [qw{username shellname domain password}],
+ type => 'shelluser',
template => qq{%s@%s.%s:%s::::::userdb_quota_rule=*:storage=1G\n},
},
});
}
-sub create_shell {
-}
-sub create_user {
-}
-
-
1;
blob - a80dc96608099a5dbf17dc77a5fd79e5c0168644
blob + 6124eb6253aa013fd2c751461cfa9120cb95fb17
--- lib/IRCNOW/ConfigNow/Module.pm
+++ lib/IRCNOW/ConfigNow/Module.pm
#
# 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
-
+# Each file has to have a filename, template, varlist, and type
+# {filename} filename with path of the system file being modified.
+# it'll be prefixed with the git repo path.
+# {template} can be a sprintf string or a sub returning a string
+# {varlist} is an array of params to pass to sprintf or the sub()
+# Its an array of param names to be taken from the {vars}
+# passed from the programs %config.
+# {type} is used to distinquish between group accounts or sub
+# accounts of a group. Each module is expected to have
+# a primary type and an optional user type.
+# eg: shell accounts use 'shell', and 'shelluser'
+# The 'user' part is hard coded as $type and $type . 'user';
+#
+#
# 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.
my $class =shift;
my $options = {@_};
my $self = {
- vars => [],
- files => {},
+ vars => [], # array ref of data values for template vars.
+ lists => { # Hash of lists stored for each module
+ filenames => { # Hash of filenames
+ # filename => [], #list of files objects using this filename.
+ },
+ },
+ files => { #hash of files we can create
+ # file => {
+ # filename => /path/to/config/filename,
+ # template => sub(), or sprintf string
+ # varlist => [] # list of vars needed to output template
+ # type => string # template type - group/user
+ },
};
if (exists $options->{vars}) {
$self->{vars}= $options->{vars};
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};
+ for my $k (qw{filename varlist template type}) {
+ croak "Required param $k missing for Module $class; file: $file" unless exists $options->{files}->{$file}->{$k};
+
$self->{files}->{$file}->{$k} = $options->{files}->{$file}->{$k};
}
+ # build a hash of filenames manipulated
+ $self->{files}->{$file}->{filename} =~ s/^\/?//; # remove leading / if it exists
+ my $filename = $self->{files}->{$file}->{filename};
+ $self->{lists}->{filenames}->{ $filename } = $self->{files}->{$file};
}
return $self;
}
croak "Required list of files to manipulate is missing";
}
+#
+
sub list {
my $self = shift;
- my @list = keys(%{$self->{files}});
+ my $type = shift;
+ my @list;
+ for my $file (keys(%{$self->{files}})) {
+ if (defined $type and exists $self->{files}->{type}) {
+ next unless ($self->{files}->{$file}->{type} eq $type);
+ }
+ push @list, $file;
+ }
return @list;
}
+#sub files {
+# my $self = shift;
+# return keys %{$self->{files}};
+#}
+
+sub filenames {
+ my $self = shift;
+ my @filenames;
+ for my $file (keys %{$self->{files}} ) {
+ push @filenames, $self->{files}->{$file}->{filename};
+ }
+ return @filenames;
+}
+
sub filename {
my $self = shift;
my $file = shift;
return $self->{files}->{$file}->{filename};
}
+
+# returns output for filename
sub output {
my $self = shift;
- my $file = shift || carp "File name required";
+ my $filename = shift || carp "Filename Required";
+ my $type = shift;
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;
+ # # 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->{lists}->{filenames}->{$filename};
+ # If we have a type value then limit output to type specified.
+ # Default to outputting all if not defined.
+ #warn "Module::output() Filename: $filename \$type=$type - \$mod->{type} = ".$mod->{type};
+ if (not defined $type or ($type eq $mod->{type})) {
+ for my $param ( @{$mod->{varlist}}) {
+ # Don't have needed param so return undef
+ unless (exists $self->{vars}->{$param}) {
+ return undef;
+ }
+ push @params, $self->{vars}->{$param};
}
- push @params, $self->{vars}->{$param};
+ if (ref $mod->{template} eq 'CODE') {
+ return $mod->{template}->(@params);
+ }
+ return sprintf($mod->{template}, @params);
}
- if (ref $mod->{template} eq 'CODE') {
- return $mod->{template}->(@params);
- }
-
- return sprintf($mod->{template}, @params);
+ return undef; #nothing to output
}
blob - 6c24bf169e69c41dde01da8fd89c8663cd5a2aee
blob + c3976502956c91a82a41b22ea25efc9f8d448282
--- lib/IRCNOW/ConfigNow.pm
+++ lib/IRCNOW/ConfigNow.pm
# set sane defaults.
my $self = {
vars =>$options, # options could be hash template values
+ lists =>{
+ # users =>[],
+ filenames =>{}, # Hash of filenames containing array of module objects
+ modules =>[],
+ },
modules =>{}, # ConfigNow Modules
repo =>undef, #
};
+ my $vars=$self->{vars};
+ # Verify we have critcal
+ $vars->{gitWorkDir} = './configNow' unless exists $vars->{gitWorkDir};
+
bless $self, $class;
# Load any modules passed in
if (exists $options->{modules}) {
return $self;
}
-
-sub filename {
+sub filenames {
my $self = shift;
- my $file = shift;
- my $root = $self->{vars}->{configNow} || './configNow';
- for my $mod (keys %{$self->{modules}}) {
- my $filename = $self->{modules}->{$mod}->filename($file);
- return $root . $filename if defined $filename;
- }
+ return keys %{$self->{lists}->{filenames}};
}
sub list {
my $self = shift;
my $module = shift;
+ my $type = shift;
my @list;
-
+
if (defined $module and exists $self->{modules}->{$module}) {
- @list = $self->{modules}->{$module}->list();
-
+ @list = $self->{modules}->{$module}->list($type);
} 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) || "";
- }
+#sub output {
+# my $self = shift;
+# my $filename = shift || die "!!!!!!!!!!! undef for filename:";
+# my $output = "";
+# # call each modules output()
+# for my $filename
+# for my $mod (keys %{$self->{modules}}) {
+# next unless exists $self->{modules}->{$mod}->{$file};
+# $output .= $self->{modules}->{$mod}->output($file) || "";
+# }
+# return $output;
+#}
- return $output;
-}
-
sub mod_load {
my $self=shift;
my $modName=shift;
my $module=shift;
+ my $obj;
if (ref $module and $module.isa('IRCNOW::ConfigNow::Module')) {
# Already have an object so attach it.
$self->{modules}->{$modName}=$module;
+ $obj = $module;
} else {
# Lets assume they passed us a full module name.
if (not defined eval "require $module") {
+ warn $module . " - " . $@;
# Failed so try prepending IRCNOW::ConfigNow::
$module = "IRCNOW::ConfigNow::$module";
if (not defined eval "require $module") {
croak "Failed to load $module";
}
}
+ # create module object and add to hash
+ $obj = $module->new(vars => $self->{vars}) || croak 'Failed to load Module: $module';
+ $self->{modules}->{$modName}=$obj;
}
- # create module object and add to hash
- my $obj = $module->new(vars => $self->{vars}) || croak 'Failed to load Module: $module';
- $self->{modules}->{$modName}=$obj;
+ # add to loaded modules list.
+ push @{$self->{lists}->{modules}}, $modName;
+ # Build hash of filenames pointing to array of module objects
+ my $filenameList=$self->{lists}->{filenames};
+ for my $filename ($obj->filenames()) {
+ $filenameList->{$filename} = [] unless exists $filenameList->{$filename};
+ push @{$filenameList->{$filename}}, $obj;
+ }
return $obj;
}
}
}
+sub write_file {
+ my $self = shift;
+ my $filename = shift;
+ my $workDir=$self->{vars}->{gitWorkDir};
+ $filename = "$workDir/$filename";
+ my $output = shift;
+ my $path = dirname($filename);
+#print "Making Directory: $path\n";
+ make_path($path);
+print "Writing: $filename\n";
+ #XXX add proper error handling
+ open my $FH, ">>$filename";
+ print $FH $output;
+ close $FH;
+}
+# Delete specified file
+sub delete_file {
+ my $self = shift;
+ my $filename = shift;
+ my $workDir=$self->{vars}->{gitWorkDir};
+ $filename = "$workDir/$filename";
+print "Deleting $filename\n";
+ unlink $filename;
+ # unlink $filename;
+ #unlink $self->{modules}->{$module}->filename($file);
+}
+
sub write_config {
- my $self=shift;
+ my $self = shift;
+ my $type = $self->{vars}->{type};
+ # abort of the repo isn't ready
return 0 unless $self->repo_ready();
- for my $module ($self->list()) {
- for my $file ($self->list($module)) {
- my $filename = $self->filename($file);
- my $path = dirname($filename);
- print "Making Directory: $path\n";
- make_path($path);
- print "Writing: $filename\n";
- #XXX add proper error handling
- open my $FH, ">>$filename";
- print $FH $self->output($file);
- close $FH;
+ # get the output for each module for this filename.
+ for my $filename ($self->filenames()) {
+ #purge existing files before generation.
+ $self->delete_file($filename);
+ my $output="";
+ # Output for main type.
+ for my $obj (@{$self->{lists}->{filenames}->{$filename}}) {
+ my $out = $obj->output($filename,$type);
+ $output .= $out if defined $out;
+ # Output for $type . "users" if we have a user list
+ if (exists $self->{vars}->{users}) {
+ for my $user (@{$self->{vars}->{users}}) {
+ # set the username var to this user.
+ $self->{vars}->{username} = $user;
+ # generate output for $type . 'user'
+ my $out = $obj->output($filename,$type . "user");
+ $output .= $out if defined $out;
+ # delete the username so it doesn't bleed anywhere
+ delete $self->{vars}->{username};
+ }
+ }
}
+ $self->write_file($filename,$output);
}
return 1;
}
+
+# or my $module ($self->list()) {
+# #create the $type root entries. entries.
+# for my $file ($self->list($module,$type)) {
+#warn "write_config() \$type: $type, \$module: $module, \$file: $file\n";
+# $self->write_file($file);
+# }
+#warn "User Loop";
+# #Create entries for users where needed
+# }
+# return 1;
+#}
+
sub repo_ready {
my $self=shift;
my $r = $self->{repo};