Squashed commit of the following:
commit 4081e22202693bd7c4ea00e95daad8e628c6fd5a
Author: Oliver Gorwits <oliver@cpan.org>
Date:   Mon May 29 21:02:07 2023 +0100
    large rename of check_acl* to acl_matches*
commit 3cfa284ddd24d68765c255578cc5c184afbdcd83
Author: Oliver Gorwits <oliver@cpan.org>
Date:   Fri May 19 20:39:03 2023 +0100
    update permission doc
commit 8c7bb93cc5e9fafb770f98f446e45cbd94b14894
Author: Oliver Gorwits <oliver@cpan.org>
Date:   Wed May 17 21:50:07 2023 +0100
    migrate most check_acl_only to acl_matches_only
commit c47f699f2a22f08f2f3e093ed0f24c891e6f9a82
Author: Oliver Gorwits <oliver@cpan.org>
Date:   Wed May 17 21:39:19 2023 +0100
    rename check_acl* to be acl_matches*
commit a884a22c3ab1f3262118c3a47ed8e25b0b0a7336
Author: Oliver Gorwits <oliver@cpan.org>
Date:   Sun May 14 16:50:42 2023 +0100
    update macsuck_no_deviceports to use acl_matches
commit 8c256af728721329b64d071fa529dfc844073ac6
Author: Oliver Gorwits <oliver@cpan.org>
Date:   Sun May 7 22:54:33 2023 +0100
    update hide_deviceports to use acl_matches multi @things
commit cd5d9978aba1da459be4fed4500f395df13f7784
Author: Oliver Gorwits <oliver@cpan.org>
Date:   Sun May 7 22:53:38 2023 +0100
    check_acl fix to allow all @things to offer a property before fallback to missing as empty string
commit 1a3ab9a7646e9f994f03126d45fc36e9e5a13ed5
Author: Oliver Gorwits <oliver@cpan.org>
Date:   Tue May 2 15:31:17 2023 +0100
    add ignore_deviceports to portproperties discover; improve comments
commit 51385ce89458dc939587dae902fda431719c22c9
Merge: b97c07d2 3f8ffe78
Author: Oliver Gorwits <oliver@cpan.org>
Date:   Tue May 2 15:21:48 2023 +0100
    Merge branch 'master' into og-acl_multidict
commit b97c07d237d750c1d9eb3095d8ff3908512eac2a
Author: Oliver Gorwits <oliver@cpan.org>
Date:   Sat Mar 25 14:37:53 2023 +0000
    add support for arrayref of items, and unblessed hash, to check_acl
		
	
		
			
				
	
	
		
			213 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			213 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable File
		
	
	
	
	
| #!/usr/bin/env perl
 | |
| 
 | |
| use strict;
 | |
| use warnings;
 | |
| 
 | |
| our $home;
 | |
| 
 | |
| BEGIN {
 | |
|   use FindBin;
 | |
|   FindBin::again();
 | |
| 
 | |
|   $home = ($ENV{NETDISCO_HOME} || $ENV{HOME});
 | |
| 
 | |
|   # try to find a localenv if one isn't already in place.
 | |
|   if (!exists $ENV{PERL_LOCAL_LIB_ROOT}) {
 | |
|       use File::Spec;
 | |
|       my $localenv = File::Spec->catfile($FindBin::RealBin, 'localenv');
 | |
|       exec($localenv, $0, @ARGV) if -f $localenv;
 | |
|       $localenv = File::Spec->catfile($home, 'perl5', 'bin', 'localenv');
 | |
|       exec($localenv, $0, @ARGV) if -f $localenv;
 | |
| 
 | |
|       die "Sorry, can't find libs required for App::Netdisco.\n"
 | |
|         if !exists $ENV{PERLBREW_PERL};
 | |
|   }
 | |
| }
 | |
| 
 | |
| BEGIN {
 | |
|   use Path::Class;
 | |
| 
 | |
|   # stuff useful locations into @INC and $PATH
 | |
|   unshift @INC,
 | |
|     dir($FindBin::RealBin)->parent->subdir('lib')->stringify,
 | |
|     dir($FindBin::RealBin, 'lib')->stringify;
 | |
| 
 | |
|   use Config;
 | |
|   $ENV{PATH} = $FindBin::RealBin . $Config{path_sep} . $ENV{PATH};
 | |
| }
 | |
| 
 | |
| use App::Netdisco;
 | |
| use Dancer ':script';
 | |
| use Dancer::Plugin::DBIC 'schema';
 | |
| 
 | |
| use App::Netdisco::Util::Permission 'acl_matches';
 | |
| 
 | |
| # silent exit unless explicitly requested
 | |
| exit(0) unless setting('use_legacy_rancidexport');
 | |
| 
 | |
| my $settings = setting( 'rancid' );
 | |
| my $domain_suffix = setting( 'domain_suffix' );
 | |
| my $delimiter = $settings->{ 'delimiter' } || ':';
 | |
| my $down_age = $settings->{ 'down_age' } || '1 day';
 | |
| my $rancidhome = $settings->{ 'rancid_home' } || '/var/lib/rancid';
 | |
| my $config_vendormap = $settings->{ 'vendormap' } || {};
 | |
| 
 | |
| my $by_ip = {};
 | |
| foreach my $g (@{$settings->{ 'by_ip' }}) {
 | |
|   $by_ip->{$g} = 1;
 | |
| }
 | |
| 
 | |
| my $by_hostname = {};
 | |
| foreach my $g (@{$settings->{ 'by_hostname' }}) {
 | |
|   $by_hostname->{$g} = 1;
 | |
| }
 | |
| 
 | |
| my @devices = schema('netdisco')->resultset('Device')->search({},
 | |
|   {
 | |
|     '+columns' => {
 | |
|       old => \"age(LOCALTIMESTAMP, last_discover) > interval '$down_age'"
 | |
|     }
 | |
|   })->all;
 | |
| 
 | |
| my $groups = $settings->{ 'groups' };
 | |
| my $list = {};
 | |
| 
 | |
| foreach my $d (@devices) {
 | |
|   my $old = $d->get_column( 'old' );
 | |
|   my $devgroup = 'other';
 | |
|   foreach my $g (keys %$groups) {
 | |
|     if (acl_matches( $d, $groups->{$g} )) {
 | |
|       $devgroup = $g;
 | |
|       last;
 | |
|     }
 | |
|   }
 | |
|   push(@{$list->{$devgroup}}, $d);
 | |
| }
 | |
| 
 | |
| my %VENDORMAP = (
 | |
| # If netdisco vendor name and rancid vendor name
 | |
| # do not map 1:1, map it here.
 | |
| # eg:
 | |
| # 'dell:2024' => 'dellnseries',
 | |
| # 'dell:3024' => 'dellnseries'
 | |
| );
 | |
| 
 | |
| foreach my $group (keys %$list) {
 | |
|   open(ROUTER, ">${rancidhome}/${group}/router.db") || die "${rancidhome}/${group}/router.db: $!\n";
 | |
|   foreach my $dev (sort {$a->ip cmp $b->ip} @{$list->{$group}}) {
 | |
|     my $vendor = $dev->vendor;
 | |
|     my $vendormodel = join(':',$dev->vendor,$dev->model);
 | |
|     my $name;
 | |
|     if ( $VENDORMAP{$vendor} or $VENDORMAP{$vendormodel} ) {
 | |
|       $vendor = $VENDORMAP{$vendormodel} || $VENDORMAP{$vendor};
 | |
|     }
 | |
|     if ( $config_vendormap->{$vendor} or $config_vendormap->{$vendormodel} ) {
 | |
|       $vendor = $config_vendormap->{$vendormodel} || $config_vendormap->{$vendor};
 | |
|     }
 | |
|     if ($by_ip->{$group}) {
 | |
|       $name = $dev->ip;
 | |
|     } else {
 | |
|       $name = ($dev->dns || $dev->name);
 | |
|     }
 | |
|     if ($by_hostname->{$group}) {
 | |
|       $name =~ s/$domain_suffix//;
 | |
|     }
 | |
|     printf ROUTER "%s$delimiter%s$delimiter%s\n", $name, $vendor,
 | |
|       $dev->get_column( 'old' ) ? "down" : "up";
 | |
|   }
 | |
|   close(ROUTER);
 | |
| }
 | |
| 
 | |
| =head1 NAME
 | |
| 
 | |
| netdisco-rancid-export - DEPRECATED!
 | |
| 
 | |
| =head1 DEPRECATED!
 | |
| 
 | |
| Note! This script is now deprecated and no longer maintained. The replacement
 | |
| is built in to Netdisco core, so can be scheduled in the backend, and also has
 | |
| more powerful configuration. See
 | |
| L<App::Netdisco::Worker::Plugin::MakeRancidConf>.
 | |
| 
 | |
| =head1 CONFIGURATION
 | |
| 
 | |
| This script requires some configuration to be added to your Netdisco
 | |
| "C<~/environments/deployment.yml>" file, for example:
 | |
| 
 | |
|  rancid:
 | |
|    rancid_home:  /var/lib/rancid
 | |
|    down_age:     '1 day'
 | |
|    delimiter:    ':'
 | |
|    by_ip:        [ other ]
 | |
|    by_hostname:  [ other2 ]
 | |
|    groups:
 | |
|      switch:     [ 'name:.*[Ss][Ww].*' ]
 | |
|      rtr:        [ 'name:[rR]tr.*' ]
 | |
|      ap:         [ 'name:[aA][pP].*' ]
 | |
|    vendormap:
 | |
|      "dell":      force10
 | |
|      "dell:2024": dellnseries
 | |
| 
 | |
| Note that C<netdisco-rancid-export> is not part of the automatic scheduler
 | |
| built in to Netdisco. You should run this script via C<cron> just after your
 | |
| periodic C<discoverall>.
 | |
| 
 | |
| =head2 C<rancid_home>
 | |
| 
 | |
| The location to write RANCID Group configuration files into. A subdirectory
 | |
| for each Group will be created.
 | |
| 
 | |
| Default: "C</var/lib/rancid>".
 | |
| 
 | |
| =head2 C<down_age>
 | |
| 
 | |
| This should be the same or greater than the interval between regular discover
 | |
| jobs on your network. Devices which have not been discovered within this time
 | |
| will be marked as "C<down>" to RANCID.
 | |
| 
 | |
| Default: "C<1 day>".
 | |
| 
 | |
| =head2 C<delimiter>
 | |
| 
 | |
| RANCID version 3 uses a semicolon as delimiter. Set this to the delimiter
 | |
| character if needed to be different from the default.
 | |
| 
 | |
| Default: "C<:>".
 | |
| 
 | |
| =head2 C<vendormap>
 | |
| 
 | |
| If the device Vendor in Netdisco is not the same as the RANCID vendor script,
 | |
| configure a mapping here. The left hand side (key) should be the Netdisco
 | |
| vendor, the right hand side (value) should be the RANCID vendor script name.
 | |
| You can also set the Netdisco vendor to be "C<vendor:model>" for fine-grained
 | |
| control. See the synopsis for an example.
 | |
| 
 | |
| =head2 C<groups>
 | |
| 
 | |
| This dictionary maps RANCID Group names with configuration which will match
 | |
| devices in the Netdisco database. The configuration is the same as any of
 | |
| Netdisco's "C<*_only>" settings, and accepts IP, prefix, device property.
 | |
| 
 | |
| =head2 C<by_ip>
 | |
| 
 | |
| List of RANCID Groups which will have Device IPs written to the RANCID
 | |
| configuration file, instead of DNS or SNMP host names.
 | |
| 
 | |
| =head2 C<by_hostname>
 | |
| 
 | |
| List of RANCID Groups which will have Device Hostname written to the RANCID
 | |
| configuration file, instead of FQDN. This is done simply by stripping the
 | |
| C<domain_suffix> configuration item from the FQDN.
 | |
| 
 | |
| =head1 SEE ALSO
 | |
| 
 | |
| =over 4
 | |
| 
 | |
| =item *
 | |
| 
 | |
| L<App::Netdisco>
 | |
| 
 | |
| =back
 | |
| 
 | |
| =cut
 |