jhthorsen / net-isc-dhcpd

Perl module that interacts with ISC DHCPd
http://search.cpan.org/perldoc?Net::ISC::DHCPd
11 stars 6 forks source link

"Wishlist" - Ability to trump include paths #7

Closed scorpion7-7 closed 10 years ago

scorpion7-7 commented 10 years ago

When parsing conf files, it would be most helpful if there was some "switch" to be able to tell the parser that the 'paths' in the config file should have a regex-replace to switch an absolute to a relative path for the "include" file. Especially traumatic if there are layered includes.

rfdrake commented 10 years ago

I'm not sure if it would be good to make this a feature of the module because it's.. hackish. I do think it's somewhat important since a bunch of config files are processed on machines then deployed to other places.

I've come up with a workaround that may suit you. Let me know if this is what you need or if you think this might be more confusing:

my $included = $config->includes->[0];
my $file = $included->file;
$file =~ s#/etc/dhcpd/#/staging/#;
$included->file($file);
$included->parse;
rfdrake commented 10 years ago

Thinking more about this, and especially about recursive includes, I think having a flag that told it to load include files when it parses the config might be good. If that were the case then there would need to be a way to override paths. Maybe a callback function before ->parse, or just the ability to hard set an include_path variable that changed them.

If I were going the include_path route, I would think it would be best to only prepend it to relative paths and not touch full paths (this is how it works now, but it only tries the directory of the root dhcpd.conf file). Or maybe we could do something sneaky like say:

if (ref(include_path) == 'Regexp') { 
    # run regex on $file
} elsif ($file->is_relative) {
    $file_path = $include_path . $file;
}

I noticed that there was no support for recursive includes at all. I added them in 8209113c539c097f83a3ab4a8f5289951132ca60 so we get something even if it doesn't cover your entire use case.

scorpion7-7 commented 10 years ago

Right. The method that I've been using to adjust include file paths and ease operation was to create one massive config file through recursively pre-processing the dhcpd.conf file. Then feed the new (single large file) to Net::ISC::DHCPd::Config. This enabled me to get around some of the quirks (range issues and "authoritative") as well.

Would simply adding support for a callback - right before processing be more efficient for your purposes and enable this same need? Logically:

if $INCLUDEFILEWITHPATH and defined &include_file_callback { $INCLUDEFILEWITHPATH=&include_file_callback($INCLUDEFILEWITHPATH); } ->parse($INCLUDEFILEWITHPATH);

This would make it much easier (hopefully) for you with far less coding effort. It's simply, if the callback exists, then run it on each/every include file to adjust the path. There might not be any path adjustment depending on the logic in the callback, but it enables the programmer to manipulate the path as desired. The only question/concern becomes - if the programmer decides to 'null' the file (ie: wants to exclude certain files by regex), is the right behavior to adjust as: if ($INCLUDEFILEWITHPATH) { ->parse($INCLUDEFILEWITHPATH); } so that certain files could be safely ignored, again with minimal effort.

Just a thought.

Great news on 8209113.

rfdrake commented 10 years ago

I've made a new version with support for filename_callback.

Here's an example:

my $cb = sub {
    my $file = shift;
    if ($file =~ /catphotos/) {
        return "foo-included.conf";
    }
};

$config->filename_callback($cb);

The callback doesn't get used until $include->parse is called. Because it modifies the filename and not the filehandle directly, it might need to be tweaked again.

I think this may end up putting the wrong paths in when $config->generate is called.

rfdrake commented 10 years ago

Closing this because I think it's done :)